1*c4ef805bSOliver Stannard // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 5 2*c4ef805bSOliver Stannard // RUN: %clang_cc1 %s -emit-llvm -o - -triple=aarch64-none-elf | FileCheck %s 3*c4ef805bSOliver Stannard // REQUIRES: aarch64-registered-target 4*c4ef805bSOliver Stannard 5*c4ef805bSOliver Stannard #include <stdatomic.h> 6*c4ef805bSOliver Stannard 7*c4ef805bSOliver Stannard // CHECK-LABEL: define dso_local void @clear_relaxed( 8*c4ef805bSOliver Stannard // CHECK-SAME: ptr noundef [[PTR:%.*]]) #[[ATTR0:[0-9]+]] { 9*c4ef805bSOliver Stannard // CHECK-NEXT: [[ENTRY:.*:]] 10*c4ef805bSOliver Stannard // CHECK-NEXT: [[PTR_ADDR:%.*]] = alloca ptr, align 8 11*c4ef805bSOliver Stannard // CHECK-NEXT: store ptr [[PTR]], ptr [[PTR_ADDR]], align 8 12*c4ef805bSOliver Stannard // CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[PTR_ADDR]], align 8 13*c4ef805bSOliver Stannard // CHECK-NEXT: store atomic i8 0, ptr [[TMP0]] monotonic, align 1 14*c4ef805bSOliver Stannard // CHECK-NEXT: ret void 15*c4ef805bSOliver Stannard // 16*c4ef805bSOliver Stannard void clear_relaxed(char *ptr) { 17*c4ef805bSOliver Stannard __atomic_clear(ptr, memory_order_relaxed); 18*c4ef805bSOliver Stannard } 19*c4ef805bSOliver Stannard 20*c4ef805bSOliver Stannard // CHECK-LABEL: define dso_local void @clear_seq_cst( 21*c4ef805bSOliver Stannard // CHECK-SAME: ptr noundef [[PTR:%.*]]) #[[ATTR0]] { 22*c4ef805bSOliver Stannard // CHECK-NEXT: [[ENTRY:.*:]] 23*c4ef805bSOliver Stannard // CHECK-NEXT: [[PTR_ADDR:%.*]] = alloca ptr, align 8 24*c4ef805bSOliver Stannard // CHECK-NEXT: store ptr [[PTR]], ptr [[PTR_ADDR]], align 8 25*c4ef805bSOliver Stannard // CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[PTR_ADDR]], align 8 26*c4ef805bSOliver Stannard // CHECK-NEXT: store atomic i8 0, ptr [[TMP0]] seq_cst, align 1 27*c4ef805bSOliver Stannard // CHECK-NEXT: ret void 28*c4ef805bSOliver Stannard // 29*c4ef805bSOliver Stannard void clear_seq_cst(char *ptr) { 30*c4ef805bSOliver Stannard __atomic_clear(ptr, memory_order_seq_cst); 31*c4ef805bSOliver Stannard } 32*c4ef805bSOliver Stannard 33*c4ef805bSOliver Stannard // CHECK-LABEL: define dso_local void @clear_release( 34*c4ef805bSOliver Stannard // CHECK-SAME: ptr noundef [[PTR:%.*]]) #[[ATTR0]] { 35*c4ef805bSOliver Stannard // CHECK-NEXT: [[ENTRY:.*:]] 36*c4ef805bSOliver Stannard // CHECK-NEXT: [[PTR_ADDR:%.*]] = alloca ptr, align 8 37*c4ef805bSOliver Stannard // CHECK-NEXT: store ptr [[PTR]], ptr [[PTR_ADDR]], align 8 38*c4ef805bSOliver Stannard // CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[PTR_ADDR]], align 8 39*c4ef805bSOliver Stannard // CHECK-NEXT: store atomic i8 0, ptr [[TMP0]] release, align 1 40*c4ef805bSOliver Stannard // CHECK-NEXT: ret void 41*c4ef805bSOliver Stannard // 42*c4ef805bSOliver Stannard void clear_release(char *ptr) { 43*c4ef805bSOliver Stannard __atomic_clear(ptr, memory_order_release); 44*c4ef805bSOliver Stannard } 45*c4ef805bSOliver Stannard 46*c4ef805bSOliver Stannard // CHECK-LABEL: define dso_local void @clear_dynamic( 47*c4ef805bSOliver Stannard // CHECK-SAME: ptr noundef [[PTR:%.*]], i32 noundef [[ORDER:%.*]]) #[[ATTR0]] { 48*c4ef805bSOliver Stannard // CHECK-NEXT: [[ENTRY:.*:]] 49*c4ef805bSOliver Stannard // CHECK-NEXT: [[PTR_ADDR:%.*]] = alloca ptr, align 8 50*c4ef805bSOliver Stannard // CHECK-NEXT: [[ORDER_ADDR:%.*]] = alloca i32, align 4 51*c4ef805bSOliver Stannard // CHECK-NEXT: store ptr [[PTR]], ptr [[PTR_ADDR]], align 8 52*c4ef805bSOliver Stannard // CHECK-NEXT: store i32 [[ORDER]], ptr [[ORDER_ADDR]], align 4 53*c4ef805bSOliver Stannard // CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[PTR_ADDR]], align 8 54*c4ef805bSOliver Stannard // CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[ORDER_ADDR]], align 4 55*c4ef805bSOliver Stannard // CHECK-NEXT: switch i32 [[TMP1]], label %[[MONOTONIC:.*]] [ 56*c4ef805bSOliver Stannard // CHECK-NEXT: i32 3, label %[[RELEASE:.*]] 57*c4ef805bSOliver Stannard // CHECK-NEXT: i32 5, label %[[SEQCST:.*]] 58*c4ef805bSOliver Stannard // CHECK-NEXT: ] 59*c4ef805bSOliver Stannard // CHECK: [[MONOTONIC]]: 60*c4ef805bSOliver Stannard // CHECK-NEXT: store atomic i8 0, ptr [[TMP0]] monotonic, align 1 61*c4ef805bSOliver Stannard // CHECK-NEXT: br label %[[ATOMIC_CONTINUE:.*]] 62*c4ef805bSOliver Stannard // CHECK: [[RELEASE]]: 63*c4ef805bSOliver Stannard // CHECK-NEXT: store atomic i8 0, ptr [[TMP0]] release, align 1 64*c4ef805bSOliver Stannard // CHECK-NEXT: br label %[[ATOMIC_CONTINUE]] 65*c4ef805bSOliver Stannard // CHECK: [[SEQCST]]: 66*c4ef805bSOliver Stannard // CHECK-NEXT: store atomic i8 0, ptr [[TMP0]] seq_cst, align 1 67*c4ef805bSOliver Stannard // CHECK-NEXT: br label %[[ATOMIC_CONTINUE]] 68*c4ef805bSOliver Stannard // CHECK: [[ATOMIC_CONTINUE]]: 69*c4ef805bSOliver Stannard // CHECK-NEXT: ret void 70*c4ef805bSOliver Stannard // 71*c4ef805bSOliver Stannard void clear_dynamic(char *ptr, int order) { 72*c4ef805bSOliver Stannard __atomic_clear(ptr, order); 73*c4ef805bSOliver Stannard } 74*c4ef805bSOliver Stannard 75*c4ef805bSOliver Stannard // CHECK-LABEL: define dso_local void @test_and_set_relaxed( 76*c4ef805bSOliver Stannard // CHECK-SAME: ptr noundef [[PTR:%.*]]) #[[ATTR0]] { 77*c4ef805bSOliver Stannard // CHECK-NEXT: [[ENTRY:.*:]] 78*c4ef805bSOliver Stannard // CHECK-NEXT: [[PTR_ADDR:%.*]] = alloca ptr, align 8 79*c4ef805bSOliver Stannard // CHECK-NEXT: [[ATOMIC_TEMP:%.*]] = alloca i8, align 1 80*c4ef805bSOliver Stannard // CHECK-NEXT: store ptr [[PTR]], ptr [[PTR_ADDR]], align 8 81*c4ef805bSOliver Stannard // CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[PTR_ADDR]], align 8 82*c4ef805bSOliver Stannard // CHECK-NEXT: [[TMP1:%.*]] = atomicrmw xchg ptr [[TMP0]], i8 1 monotonic, align 1 83*c4ef805bSOliver Stannard // CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i8 [[TMP1]], 0 84*c4ef805bSOliver Stannard // CHECK-NEXT: store i1 [[TOBOOL]], ptr [[ATOMIC_TEMP]], align 1 85*c4ef805bSOliver Stannard // CHECK-NEXT: [[TMP2:%.*]] = load i8, ptr [[ATOMIC_TEMP]], align 1 86*c4ef805bSOliver Stannard // CHECK-NEXT: [[LOADEDV:%.*]] = trunc i8 [[TMP2]] to i1 87*c4ef805bSOliver Stannard // CHECK-NEXT: ret void 88*c4ef805bSOliver Stannard // 89*c4ef805bSOliver Stannard void test_and_set_relaxed(char *ptr) { 90*c4ef805bSOliver Stannard __atomic_test_and_set(ptr, memory_order_relaxed); 91*c4ef805bSOliver Stannard } 92*c4ef805bSOliver Stannard 93*c4ef805bSOliver Stannard // CHECK-LABEL: define dso_local void @test_and_set_consume( 94*c4ef805bSOliver Stannard // CHECK-SAME: ptr noundef [[PTR:%.*]]) #[[ATTR0]] { 95*c4ef805bSOliver Stannard // CHECK-NEXT: [[ENTRY:.*:]] 96*c4ef805bSOliver Stannard // CHECK-NEXT: [[PTR_ADDR:%.*]] = alloca ptr, align 8 97*c4ef805bSOliver Stannard // CHECK-NEXT: [[ATOMIC_TEMP:%.*]] = alloca i8, align 1 98*c4ef805bSOliver Stannard // CHECK-NEXT: store ptr [[PTR]], ptr [[PTR_ADDR]], align 8 99*c4ef805bSOliver Stannard // CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[PTR_ADDR]], align 8 100*c4ef805bSOliver Stannard // CHECK-NEXT: [[TMP1:%.*]] = atomicrmw xchg ptr [[TMP0]], i8 1 acquire, align 1 101*c4ef805bSOliver Stannard // CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i8 [[TMP1]], 0 102*c4ef805bSOliver Stannard // CHECK-NEXT: store i1 [[TOBOOL]], ptr [[ATOMIC_TEMP]], align 1 103*c4ef805bSOliver Stannard // CHECK-NEXT: [[TMP2:%.*]] = load i8, ptr [[ATOMIC_TEMP]], align 1 104*c4ef805bSOliver Stannard // CHECK-NEXT: [[LOADEDV:%.*]] = trunc i8 [[TMP2]] to i1 105*c4ef805bSOliver Stannard // CHECK-NEXT: ret void 106*c4ef805bSOliver Stannard // 107*c4ef805bSOliver Stannard void test_and_set_consume(char *ptr) { 108*c4ef805bSOliver Stannard __atomic_test_and_set(ptr, memory_order_consume); 109*c4ef805bSOliver Stannard } 110*c4ef805bSOliver Stannard 111*c4ef805bSOliver Stannard // CHECK-LABEL: define dso_local void @test_and_set_acquire( 112*c4ef805bSOliver Stannard // CHECK-SAME: ptr noundef [[PTR:%.*]]) #[[ATTR0]] { 113*c4ef805bSOliver Stannard // CHECK-NEXT: [[ENTRY:.*:]] 114*c4ef805bSOliver Stannard // CHECK-NEXT: [[PTR_ADDR:%.*]] = alloca ptr, align 8 115*c4ef805bSOliver Stannard // CHECK-NEXT: [[ATOMIC_TEMP:%.*]] = alloca i8, align 1 116*c4ef805bSOliver Stannard // CHECK-NEXT: store ptr [[PTR]], ptr [[PTR_ADDR]], align 8 117*c4ef805bSOliver Stannard // CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[PTR_ADDR]], align 8 118*c4ef805bSOliver Stannard // CHECK-NEXT: [[TMP1:%.*]] = atomicrmw xchg ptr [[TMP0]], i8 1 acquire, align 1 119*c4ef805bSOliver Stannard // CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i8 [[TMP1]], 0 120*c4ef805bSOliver Stannard // CHECK-NEXT: store i1 [[TOBOOL]], ptr [[ATOMIC_TEMP]], align 1 121*c4ef805bSOliver Stannard // CHECK-NEXT: [[TMP2:%.*]] = load i8, ptr [[ATOMIC_TEMP]], align 1 122*c4ef805bSOliver Stannard // CHECK-NEXT: [[LOADEDV:%.*]] = trunc i8 [[TMP2]] to i1 123*c4ef805bSOliver Stannard // CHECK-NEXT: ret void 124*c4ef805bSOliver Stannard // 125*c4ef805bSOliver Stannard void test_and_set_acquire(char *ptr) { 126*c4ef805bSOliver Stannard __atomic_test_and_set(ptr, memory_order_acquire); 127*c4ef805bSOliver Stannard } 128*c4ef805bSOliver Stannard 129*c4ef805bSOliver Stannard // CHECK-LABEL: define dso_local void @test_and_set_release( 130*c4ef805bSOliver Stannard // CHECK-SAME: ptr noundef [[PTR:%.*]]) #[[ATTR0]] { 131*c4ef805bSOliver Stannard // CHECK-NEXT: [[ENTRY:.*:]] 132*c4ef805bSOliver Stannard // CHECK-NEXT: [[PTR_ADDR:%.*]] = alloca ptr, align 8 133*c4ef805bSOliver Stannard // CHECK-NEXT: [[ATOMIC_TEMP:%.*]] = alloca i8, align 1 134*c4ef805bSOliver Stannard // CHECK-NEXT: store ptr [[PTR]], ptr [[PTR_ADDR]], align 8 135*c4ef805bSOliver Stannard // CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[PTR_ADDR]], align 8 136*c4ef805bSOliver Stannard // CHECK-NEXT: [[TMP1:%.*]] = atomicrmw xchg ptr [[TMP0]], i8 1 release, align 1 137*c4ef805bSOliver Stannard // CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i8 [[TMP1]], 0 138*c4ef805bSOliver Stannard // CHECK-NEXT: store i1 [[TOBOOL]], ptr [[ATOMIC_TEMP]], align 1 139*c4ef805bSOliver Stannard // CHECK-NEXT: [[TMP2:%.*]] = load i8, ptr [[ATOMIC_TEMP]], align 1 140*c4ef805bSOliver Stannard // CHECK-NEXT: [[LOADEDV:%.*]] = trunc i8 [[TMP2]] to i1 141*c4ef805bSOliver Stannard // CHECK-NEXT: ret void 142*c4ef805bSOliver Stannard // 143*c4ef805bSOliver Stannard void test_and_set_release(char *ptr) { 144*c4ef805bSOliver Stannard __atomic_test_and_set(ptr, memory_order_release); 145*c4ef805bSOliver Stannard } 146*c4ef805bSOliver Stannard 147*c4ef805bSOliver Stannard // CHECK-LABEL: define dso_local void @test_and_set_acq_rel( 148*c4ef805bSOliver Stannard // CHECK-SAME: ptr noundef [[PTR:%.*]]) #[[ATTR0]] { 149*c4ef805bSOliver Stannard // CHECK-NEXT: [[ENTRY:.*:]] 150*c4ef805bSOliver Stannard // CHECK-NEXT: [[PTR_ADDR:%.*]] = alloca ptr, align 8 151*c4ef805bSOliver Stannard // CHECK-NEXT: [[ATOMIC_TEMP:%.*]] = alloca i8, align 1 152*c4ef805bSOliver Stannard // CHECK-NEXT: store ptr [[PTR]], ptr [[PTR_ADDR]], align 8 153*c4ef805bSOliver Stannard // CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[PTR_ADDR]], align 8 154*c4ef805bSOliver Stannard // CHECK-NEXT: [[TMP1:%.*]] = atomicrmw xchg ptr [[TMP0]], i8 1 acq_rel, align 1 155*c4ef805bSOliver Stannard // CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i8 [[TMP1]], 0 156*c4ef805bSOliver Stannard // CHECK-NEXT: store i1 [[TOBOOL]], ptr [[ATOMIC_TEMP]], align 1 157*c4ef805bSOliver Stannard // CHECK-NEXT: [[TMP2:%.*]] = load i8, ptr [[ATOMIC_TEMP]], align 1 158*c4ef805bSOliver Stannard // CHECK-NEXT: [[LOADEDV:%.*]] = trunc i8 [[TMP2]] to i1 159*c4ef805bSOliver Stannard // CHECK-NEXT: ret void 160*c4ef805bSOliver Stannard // 161*c4ef805bSOliver Stannard void test_and_set_acq_rel(char *ptr) { 162*c4ef805bSOliver Stannard __atomic_test_and_set(ptr, memory_order_acq_rel); 163*c4ef805bSOliver Stannard } 164*c4ef805bSOliver Stannard 165*c4ef805bSOliver Stannard // CHECK-LABEL: define dso_local void @test_and_set_seq_cst( 166*c4ef805bSOliver Stannard // CHECK-SAME: ptr noundef [[PTR:%.*]]) #[[ATTR0]] { 167*c4ef805bSOliver Stannard // CHECK-NEXT: [[ENTRY:.*:]] 168*c4ef805bSOliver Stannard // CHECK-NEXT: [[PTR_ADDR:%.*]] = alloca ptr, align 8 169*c4ef805bSOliver Stannard // CHECK-NEXT: [[ATOMIC_TEMP:%.*]] = alloca i8, align 1 170*c4ef805bSOliver Stannard // CHECK-NEXT: store ptr [[PTR]], ptr [[PTR_ADDR]], align 8 171*c4ef805bSOliver Stannard // CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[PTR_ADDR]], align 8 172*c4ef805bSOliver Stannard // CHECK-NEXT: [[TMP1:%.*]] = atomicrmw xchg ptr [[TMP0]], i8 1 seq_cst, align 1 173*c4ef805bSOliver Stannard // CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i8 [[TMP1]], 0 174*c4ef805bSOliver Stannard // CHECK-NEXT: store i1 [[TOBOOL]], ptr [[ATOMIC_TEMP]], align 1 175*c4ef805bSOliver Stannard // CHECK-NEXT: [[TMP2:%.*]] = load i8, ptr [[ATOMIC_TEMP]], align 1 176*c4ef805bSOliver Stannard // CHECK-NEXT: [[LOADEDV:%.*]] = trunc i8 [[TMP2]] to i1 177*c4ef805bSOliver Stannard // CHECK-NEXT: ret void 178*c4ef805bSOliver Stannard // 179*c4ef805bSOliver Stannard void test_and_set_seq_cst(char *ptr) { 180*c4ef805bSOliver Stannard __atomic_test_and_set(ptr, memory_order_seq_cst); 181*c4ef805bSOliver Stannard } 182*c4ef805bSOliver Stannard 183*c4ef805bSOliver Stannard // CHECK-LABEL: define dso_local void @test_and_set_dynamic( 184*c4ef805bSOliver Stannard // CHECK-SAME: ptr noundef [[PTR:%.*]], i32 noundef [[ORDER:%.*]]) #[[ATTR0]] { 185*c4ef805bSOliver Stannard // CHECK-NEXT: [[ENTRY:.*:]] 186*c4ef805bSOliver Stannard // CHECK-NEXT: [[PTR_ADDR:%.*]] = alloca ptr, align 8 187*c4ef805bSOliver Stannard // CHECK-NEXT: [[ORDER_ADDR:%.*]] = alloca i32, align 4 188*c4ef805bSOliver Stannard // CHECK-NEXT: [[ATOMIC_TEMP:%.*]] = alloca i8, align 1 189*c4ef805bSOliver Stannard // CHECK-NEXT: store ptr [[PTR]], ptr [[PTR_ADDR]], align 8 190*c4ef805bSOliver Stannard // CHECK-NEXT: store i32 [[ORDER]], ptr [[ORDER_ADDR]], align 4 191*c4ef805bSOliver Stannard // CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[PTR_ADDR]], align 8 192*c4ef805bSOliver Stannard // CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[ORDER_ADDR]], align 4 193*c4ef805bSOliver Stannard // CHECK-NEXT: switch i32 [[TMP1]], label %[[MONOTONIC:.*]] [ 194*c4ef805bSOliver Stannard // CHECK-NEXT: i32 1, label %[[ACQUIRE:.*]] 195*c4ef805bSOliver Stannard // CHECK-NEXT: i32 2, label %[[ACQUIRE]] 196*c4ef805bSOliver Stannard // CHECK-NEXT: i32 3, label %[[RELEASE:.*]] 197*c4ef805bSOliver Stannard // CHECK-NEXT: i32 4, label %[[ACQREL:.*]] 198*c4ef805bSOliver Stannard // CHECK-NEXT: i32 5, label %[[SEQCST:.*]] 199*c4ef805bSOliver Stannard // CHECK-NEXT: ] 200*c4ef805bSOliver Stannard // CHECK: [[MONOTONIC]]: 201*c4ef805bSOliver Stannard // CHECK-NEXT: [[TMP2:%.*]] = atomicrmw xchg ptr [[TMP0]], i8 1 monotonic, align 1 202*c4ef805bSOliver Stannard // CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i8 [[TMP2]], 0 203*c4ef805bSOliver Stannard // CHECK-NEXT: store i1 [[TOBOOL]], ptr [[ATOMIC_TEMP]], align 1 204*c4ef805bSOliver Stannard // CHECK-NEXT: br label %[[ATOMIC_CONTINUE:.*]] 205*c4ef805bSOliver Stannard // CHECK: [[ACQUIRE]]: 206*c4ef805bSOliver Stannard // CHECK-NEXT: [[TMP3:%.*]] = atomicrmw xchg ptr [[TMP0]], i8 1 acquire, align 1 207*c4ef805bSOliver Stannard // CHECK-NEXT: [[TOBOOL1:%.*]] = icmp ne i8 [[TMP3]], 0 208*c4ef805bSOliver Stannard // CHECK-NEXT: store i1 [[TOBOOL1]], ptr [[ATOMIC_TEMP]], align 1 209*c4ef805bSOliver Stannard // CHECK-NEXT: br label %[[ATOMIC_CONTINUE]] 210*c4ef805bSOliver Stannard // CHECK: [[RELEASE]]: 211*c4ef805bSOliver Stannard // CHECK-NEXT: [[TMP4:%.*]] = atomicrmw xchg ptr [[TMP0]], i8 1 release, align 1 212*c4ef805bSOliver Stannard // CHECK-NEXT: [[TOBOOL2:%.*]] = icmp ne i8 [[TMP4]], 0 213*c4ef805bSOliver Stannard // CHECK-NEXT: store i1 [[TOBOOL2]], ptr [[ATOMIC_TEMP]], align 1 214*c4ef805bSOliver Stannard // CHECK-NEXT: br label %[[ATOMIC_CONTINUE]] 215*c4ef805bSOliver Stannard // CHECK: [[ACQREL]]: 216*c4ef805bSOliver Stannard // CHECK-NEXT: [[TMP5:%.*]] = atomicrmw xchg ptr [[TMP0]], i8 1 acq_rel, align 1 217*c4ef805bSOliver Stannard // CHECK-NEXT: [[TOBOOL3:%.*]] = icmp ne i8 [[TMP5]], 0 218*c4ef805bSOliver Stannard // CHECK-NEXT: store i1 [[TOBOOL3]], ptr [[ATOMIC_TEMP]], align 1 219*c4ef805bSOliver Stannard // CHECK-NEXT: br label %[[ATOMIC_CONTINUE]] 220*c4ef805bSOliver Stannard // CHECK: [[SEQCST]]: 221*c4ef805bSOliver Stannard // CHECK-NEXT: [[TMP6:%.*]] = atomicrmw xchg ptr [[TMP0]], i8 1 seq_cst, align 1 222*c4ef805bSOliver Stannard // CHECK-NEXT: [[TOBOOL4:%.*]] = icmp ne i8 [[TMP6]], 0 223*c4ef805bSOliver Stannard // CHECK-NEXT: store i1 [[TOBOOL4]], ptr [[ATOMIC_TEMP]], align 1 224*c4ef805bSOliver Stannard // CHECK-NEXT: br label %[[ATOMIC_CONTINUE]] 225*c4ef805bSOliver Stannard // CHECK: [[ATOMIC_CONTINUE]]: 226*c4ef805bSOliver Stannard // CHECK-NEXT: [[TMP7:%.*]] = load i8, ptr [[ATOMIC_TEMP]], align 1 227*c4ef805bSOliver Stannard // CHECK-NEXT: [[LOADEDV:%.*]] = trunc i8 [[TMP7]] to i1 228*c4ef805bSOliver Stannard // CHECK-NEXT: ret void 229*c4ef805bSOliver Stannard // 230*c4ef805bSOliver Stannard void test_and_set_dynamic(char *ptr, int order) { 231*c4ef805bSOliver Stannard __atomic_test_and_set(ptr, order); 232*c4ef805bSOliver Stannard } 233*c4ef805bSOliver Stannard 234*c4ef805bSOliver Stannard // CHECK-LABEL: define dso_local void @test_and_set_array( 235*c4ef805bSOliver Stannard // CHECK-SAME: ) #[[ATTR0]] { 236*c4ef805bSOliver Stannard // CHECK-NEXT: [[ENTRY:.*:]] 237*c4ef805bSOliver Stannard // CHECK-NEXT: [[X:%.*]] = alloca [10 x i32], align 4 238*c4ef805bSOliver Stannard // CHECK-NEXT: [[ATOMIC_TEMP:%.*]] = alloca i8, align 1 239*c4ef805bSOliver Stannard // CHECK-NEXT: [[ARRAYDECAY:%.*]] = getelementptr inbounds [10 x i32], ptr [[X]], i64 0, i64 0 240*c4ef805bSOliver Stannard // CHECK-NEXT: [[TMP0:%.*]] = atomicrmw volatile xchg ptr [[ARRAYDECAY]], i8 1 seq_cst, align 4 241*c4ef805bSOliver Stannard // CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i8 [[TMP0]], 0 242*c4ef805bSOliver Stannard // CHECK-NEXT: store i1 [[TOBOOL]], ptr [[ATOMIC_TEMP]], align 1 243*c4ef805bSOliver Stannard // CHECK-NEXT: [[TMP1:%.*]] = load i8, ptr [[ATOMIC_TEMP]], align 1 244*c4ef805bSOliver Stannard // CHECK-NEXT: [[LOADEDV:%.*]] = trunc i8 [[TMP1]] to i1 245*c4ef805bSOliver Stannard // CHECK-NEXT: ret void 246*c4ef805bSOliver Stannard // 247*c4ef805bSOliver Stannard void test_and_set_array() { 248*c4ef805bSOliver Stannard volatile int x[10]; 249*c4ef805bSOliver Stannard __atomic_test_and_set(x, memory_order_seq_cst); 250*c4ef805bSOliver Stannard } 251*c4ef805bSOliver Stannard 252*c4ef805bSOliver Stannard // These intrinsics accept any pointer type, including void and incomplete 253*c4ef805bSOliver Stannard // structs, and always access the first byte regardless of the actual type 254*c4ef805bSOliver Stannard // size. 255*c4ef805bSOliver Stannard 256*c4ef805bSOliver Stannard struct incomplete; 257*c4ef805bSOliver Stannard 258*c4ef805bSOliver Stannard // CHECK-LABEL: define dso_local void @clear_int( 259*c4ef805bSOliver Stannard // CHECK-SAME: ptr noundef [[PTR:%.*]]) #[[ATTR0]] { 260*c4ef805bSOliver Stannard // CHECK-NEXT: [[ENTRY:.*:]] 261*c4ef805bSOliver Stannard // CHECK-NEXT: [[PTR_ADDR:%.*]] = alloca ptr, align 8 262*c4ef805bSOliver Stannard // CHECK-NEXT: store ptr [[PTR]], ptr [[PTR_ADDR]], align 8 263*c4ef805bSOliver Stannard // CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[PTR_ADDR]], align 8 264*c4ef805bSOliver Stannard // CHECK-NEXT: store atomic i8 0, ptr [[TMP0]] monotonic, align 4 265*c4ef805bSOliver Stannard // CHECK-NEXT: ret void 266*c4ef805bSOliver Stannard // 267*c4ef805bSOliver Stannard void clear_int(int *ptr) { 268*c4ef805bSOliver Stannard __atomic_clear(ptr, memory_order_relaxed); 269*c4ef805bSOliver Stannard } 270*c4ef805bSOliver Stannard // CHECK-LABEL: define dso_local void @clear_void( 271*c4ef805bSOliver Stannard // CHECK-SAME: ptr noundef [[PTR:%.*]]) #[[ATTR0]] { 272*c4ef805bSOliver Stannard // CHECK-NEXT: [[ENTRY:.*:]] 273*c4ef805bSOliver Stannard // CHECK-NEXT: [[PTR_ADDR:%.*]] = alloca ptr, align 8 274*c4ef805bSOliver Stannard // CHECK-NEXT: store ptr [[PTR]], ptr [[PTR_ADDR]], align 8 275*c4ef805bSOliver Stannard // CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[PTR_ADDR]], align 8 276*c4ef805bSOliver Stannard // CHECK-NEXT: store atomic i8 0, ptr [[TMP0]] monotonic, align 1 277*c4ef805bSOliver Stannard // CHECK-NEXT: ret void 278*c4ef805bSOliver Stannard // 279*c4ef805bSOliver Stannard void clear_void(void *ptr) { 280*c4ef805bSOliver Stannard __atomic_clear(ptr, memory_order_relaxed); 281*c4ef805bSOliver Stannard } 282*c4ef805bSOliver Stannard // CHECK-LABEL: define dso_local void @clear_incomplete( 283*c4ef805bSOliver Stannard // CHECK-SAME: ptr noundef [[PTR:%.*]]) #[[ATTR0]] { 284*c4ef805bSOliver Stannard // CHECK-NEXT: [[ENTRY:.*:]] 285*c4ef805bSOliver Stannard // CHECK-NEXT: [[PTR_ADDR:%.*]] = alloca ptr, align 8 286*c4ef805bSOliver Stannard // CHECK-NEXT: store ptr [[PTR]], ptr [[PTR_ADDR]], align 8 287*c4ef805bSOliver Stannard // CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[PTR_ADDR]], align 8 288*c4ef805bSOliver Stannard // CHECK-NEXT: store atomic i8 0, ptr [[TMP0]] monotonic, align 1 289*c4ef805bSOliver Stannard // CHECK-NEXT: ret void 290*c4ef805bSOliver Stannard // 291*c4ef805bSOliver Stannard void clear_incomplete(struct incomplete *ptr) { 292*c4ef805bSOliver Stannard __atomic_clear(ptr, memory_order_relaxed); 293*c4ef805bSOliver Stannard } 294*c4ef805bSOliver Stannard 295*c4ef805bSOliver Stannard // CHECK-LABEL: define dso_local void @test_and_set_int( 296*c4ef805bSOliver Stannard // CHECK-SAME: ptr noundef [[PTR:%.*]]) #[[ATTR0]] { 297*c4ef805bSOliver Stannard // CHECK-NEXT: [[ENTRY:.*:]] 298*c4ef805bSOliver Stannard // CHECK-NEXT: [[PTR_ADDR:%.*]] = alloca ptr, align 8 299*c4ef805bSOliver Stannard // CHECK-NEXT: [[ATOMIC_TEMP:%.*]] = alloca i8, align 1 300*c4ef805bSOliver Stannard // CHECK-NEXT: store ptr [[PTR]], ptr [[PTR_ADDR]], align 8 301*c4ef805bSOliver Stannard // CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[PTR_ADDR]], align 8 302*c4ef805bSOliver Stannard // CHECK-NEXT: [[TMP1:%.*]] = atomicrmw xchg ptr [[TMP0]], i8 1 monotonic, align 4 303*c4ef805bSOliver Stannard // CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i8 [[TMP1]], 0 304*c4ef805bSOliver Stannard // CHECK-NEXT: store i1 [[TOBOOL]], ptr [[ATOMIC_TEMP]], align 1 305*c4ef805bSOliver Stannard // CHECK-NEXT: [[TMP2:%.*]] = load i8, ptr [[ATOMIC_TEMP]], align 1 306*c4ef805bSOliver Stannard // CHECK-NEXT: [[LOADEDV:%.*]] = trunc i8 [[TMP2]] to i1 307*c4ef805bSOliver Stannard // CHECK-NEXT: ret void 308*c4ef805bSOliver Stannard // 309*c4ef805bSOliver Stannard void test_and_set_int(int *ptr) { 310*c4ef805bSOliver Stannard __atomic_test_and_set(ptr, memory_order_relaxed); 311*c4ef805bSOliver Stannard } 312*c4ef805bSOliver Stannard // CHECK-LABEL: define dso_local void @test_and_set_void( 313*c4ef805bSOliver Stannard // CHECK-SAME: ptr noundef [[PTR:%.*]]) #[[ATTR0]] { 314*c4ef805bSOliver Stannard // CHECK-NEXT: [[ENTRY:.*:]] 315*c4ef805bSOliver Stannard // CHECK-NEXT: [[PTR_ADDR:%.*]] = alloca ptr, align 8 316*c4ef805bSOliver Stannard // CHECK-NEXT: [[ATOMIC_TEMP:%.*]] = alloca i8, align 1 317*c4ef805bSOliver Stannard // CHECK-NEXT: store ptr [[PTR]], ptr [[PTR_ADDR]], align 8 318*c4ef805bSOliver Stannard // CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[PTR_ADDR]], align 8 319*c4ef805bSOliver Stannard // CHECK-NEXT: [[TMP1:%.*]] = atomicrmw xchg ptr [[TMP0]], i8 1 monotonic, align 1 320*c4ef805bSOliver Stannard // CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i8 [[TMP1]], 0 321*c4ef805bSOliver Stannard // CHECK-NEXT: store i1 [[TOBOOL]], ptr [[ATOMIC_TEMP]], align 1 322*c4ef805bSOliver Stannard // CHECK-NEXT: [[TMP2:%.*]] = load i8, ptr [[ATOMIC_TEMP]], align 1 323*c4ef805bSOliver Stannard // CHECK-NEXT: [[LOADEDV:%.*]] = trunc i8 [[TMP2]] to i1 324*c4ef805bSOliver Stannard // CHECK-NEXT: ret void 325*c4ef805bSOliver Stannard // 326*c4ef805bSOliver Stannard void test_and_set_void(void *ptr) { 327*c4ef805bSOliver Stannard __atomic_test_and_set(ptr, memory_order_relaxed); 328*c4ef805bSOliver Stannard } 329*c4ef805bSOliver Stannard // CHECK-LABEL: define dso_local void @test_and_set_incomplete( 330*c4ef805bSOliver Stannard // CHECK-SAME: ptr noundef [[PTR:%.*]]) #[[ATTR0]] { 331*c4ef805bSOliver Stannard // CHECK-NEXT: [[ENTRY:.*:]] 332*c4ef805bSOliver Stannard // CHECK-NEXT: [[PTR_ADDR:%.*]] = alloca ptr, align 8 333*c4ef805bSOliver Stannard // CHECK-NEXT: [[ATOMIC_TEMP:%.*]] = alloca i8, align 1 334*c4ef805bSOliver Stannard // CHECK-NEXT: store ptr [[PTR]], ptr [[PTR_ADDR]], align 8 335*c4ef805bSOliver Stannard // CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[PTR_ADDR]], align 8 336*c4ef805bSOliver Stannard // CHECK-NEXT: [[TMP1:%.*]] = atomicrmw xchg ptr [[TMP0]], i8 1 monotonic, align 1 337*c4ef805bSOliver Stannard // CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i8 [[TMP1]], 0 338*c4ef805bSOliver Stannard // CHECK-NEXT: store i1 [[TOBOOL]], ptr [[ATOMIC_TEMP]], align 1 339*c4ef805bSOliver Stannard // CHECK-NEXT: [[TMP2:%.*]] = load i8, ptr [[ATOMIC_TEMP]], align 1 340*c4ef805bSOliver Stannard // CHECK-NEXT: [[LOADEDV:%.*]] = trunc i8 [[TMP2]] to i1 341*c4ef805bSOliver Stannard // CHECK-NEXT: ret void 342*c4ef805bSOliver Stannard // 343*c4ef805bSOliver Stannard void test_and_set_incomplete(struct incomplete *ptr) { 344*c4ef805bSOliver Stannard __atomic_test_and_set(ptr, memory_order_relaxed); 345*c4ef805bSOliver Stannard } 346