1 // XFAIL: hexagon,sparc 2 // (due to not having native load atomic support) 3 // RUN: %clang_cc1 -emit-llvm %s -o - | FileCheck %s 4 // RUN: %clang_cc1 -triple mips-linux-gnu -emit-llvm %s -o - | FileCheck %s 5 6 void foo(int x) 7 { 8 _Atomic(int) i = 0; 9 _Atomic(short) j = 0; 10 // Check that multiply / divides on atomics produce a cmpxchg loop 11 i *= 2; 12 // CHECK: mul nsw i32 13 // CHECK: {{(cmpxchg i32*|i1 @__atomic_compare_exchange\(i32 4,)}} 14 i /= 2; 15 // CHECK: sdiv i32 16 // CHECK: {{(cmpxchg i32*|i1 @__atomic_compare_exchange\(i32 4, )}} 17 j /= x; 18 // CHECK: sdiv i32 19 // CHECK: {{(cmpxchg i16*|i1 @__atomic_compare_exchange\(i32 2, )}} 20 21 } 22 23 extern _Atomic _Bool b; 24 25 _Bool bar() { 26 // CHECK-LABEL: @bar 27 // CHECK: %[[load:.*]] = load atomic i8, i8* @b seq_cst 28 // CHECK: %[[tobool:.*]] = trunc i8 %[[load]] to i1 29 // CHECK: ret i1 %[[tobool]] 30 return b; 31 } 32 33 extern _Atomic(_Complex int) x; 34 35 void baz(int y) { 36 // CHECK-LABEL: @baz 37 // CHECK: {{store atomic|call void @__atomic_store}} 38 x += y; 39 } 40 41 _Atomic(int) compound_add(_Atomic(int) in) { 42 // CHECK-LABEL: @compound_add 43 // CHECK: [[OLD:%.*]] = atomicrmw add i32* {{.*}}, i32 5 seq_cst 44 // CHECK: [[NEW:%.*]] = add i32 [[OLD]], 5 45 // CHECK: ret i32 [[NEW]] 46 47 return (in += 5); 48 } 49 50 _Atomic(int) compound_sub(_Atomic(int) in) { 51 // CHECK-LABEL: @compound_sub 52 // CHECK: [[OLD:%.*]] = atomicrmw sub i32* {{.*}}, i32 5 seq_cst 53 // CHECK: [[NEW:%.*]] = sub i32 [[OLD]], 5 54 // CHECK: ret i32 [[NEW]] 55 56 return (in -= 5); 57 } 58 59 _Atomic(int) compound_xor(_Atomic(int) in) { 60 // CHECK-LABEL: @compound_xor 61 // CHECK: [[OLD:%.*]] = atomicrmw xor i32* {{.*}}, i32 5 seq_cst 62 // CHECK: [[NEW:%.*]] = xor i32 [[OLD]], 5 63 // CHECK: ret i32 [[NEW]] 64 65 return (in ^= 5); 66 } 67 68 _Atomic(int) compound_or(_Atomic(int) in) { 69 // CHECK-LABEL: @compound_or 70 // CHECK: [[OLD:%.*]] = atomicrmw or i32* {{.*}}, i32 5 seq_cst 71 // CHECK: [[NEW:%.*]] = or i32 [[OLD]], 5 72 // CHECK: ret i32 [[NEW]] 73 74 return (in |= 5); 75 } 76 77 _Atomic(int) compound_and(_Atomic(int) in) { 78 // CHECK-LABEL: @compound_and 79 // CHECK: [[OLD:%.*]] = atomicrmw and i32* {{.*}}, i32 5 seq_cst 80 // CHECK: [[NEW:%.*]] = and i32 [[OLD]], 5 81 // CHECK: ret i32 [[NEW]] 82 83 return (in &= 5); 84 } 85 86 _Atomic(int) compound_mul(_Atomic(int) in) { 87 // CHECK-LABEL: @compound_mul 88 // CHECK: cmpxchg i32* {{%.*}}, i32 {{%.*}}, i32 [[NEW:%.*]] seq_cst seq_cst 89 // CHECK: ret i32 [[NEW]] 90 91 return (in *= 5); 92 } 93