1; RUN: llc -mtriple=arm64_32-apple-ios7.0 -o - %s | FileCheck %s 2 3define i8 @test_load_8(i8* %addr) { 4; CHECK-LABAL: test_load_8: 5; CHECK: ldarb w0, [x0] 6 %val = load atomic i8, i8* %addr seq_cst, align 1 7 ret i8 %val 8} 9 10define i16 @test_load_16(i16* %addr) { 11; CHECK-LABAL: test_load_16: 12; CHECK: ldarh w0, [x0] 13 %val = load atomic i16, i16* %addr acquire, align 2 14 ret i16 %val 15} 16 17define i32 @test_load_32(i32* %addr) { 18; CHECK-LABAL: test_load_32: 19; CHECK: ldar w0, [x0] 20 %val = load atomic i32, i32* %addr seq_cst, align 4 21 ret i32 %val 22} 23 24define i64 @test_load_64(i64* %addr) { 25; CHECK-LABAL: test_load_64: 26; CHECK: ldar x0, [x0] 27 %val = load atomic i64, i64* %addr seq_cst, align 8 28 ret i64 %val 29} 30 31define i8* @test_load_ptr(i8** %addr) { 32; CHECK-LABAL: test_load_ptr: 33; CHECK: ldar w0, [x0] 34 %val = load atomic i8*, i8** %addr seq_cst, align 8 35 ret i8* %val 36} 37 38define void @test_store_8(i8* %addr) { 39; CHECK-LABAL: test_store_8: 40; CHECK: stlrb wzr, [x0] 41 store atomic i8 0, i8* %addr seq_cst, align 1 42 ret void 43} 44 45define void @test_store_16(i16* %addr) { 46; CHECK-LABAL: test_store_16: 47; CHECK: stlrh wzr, [x0] 48 store atomic i16 0, i16* %addr seq_cst, align 2 49 ret void 50} 51 52define void @test_store_32(i32* %addr) { 53; CHECK-LABAL: test_store_32: 54; CHECK: stlr wzr, [x0] 55 store atomic i32 0, i32* %addr seq_cst, align 4 56 ret void 57} 58 59define void @test_store_64(i64* %addr) { 60; CHECK-LABAL: test_store_64: 61; CHECK: stlr xzr, [x0] 62 store atomic i64 0, i64* %addr seq_cst, align 8 63 ret void 64} 65 66define void @test_store_ptr(i8** %addr) { 67; CHECK-LABAL: test_store_ptr: 68; CHECK: stlr wzr, [x0] 69 store atomic i8* null, i8** %addr seq_cst, align 8 70 ret void 71} 72 73declare i64 @llvm.aarch64.ldxr.p0i8(i8* %addr) 74declare i64 @llvm.aarch64.ldxr.p0i16(i16* %addr) 75declare i64 @llvm.aarch64.ldxr.p0i32(i32* %addr) 76declare i64 @llvm.aarch64.ldxr.p0i64(i64* %addr) 77 78define i8 @test_ldxr_8(i8* %addr) { 79; CHECK-LABEL: test_ldxr_8: 80; CHECK: ldxrb w0, [x0] 81 82 %val = call i64 @llvm.aarch64.ldxr.p0i8(i8* %addr) 83 %val8 = trunc i64 %val to i8 84 ret i8 %val8 85} 86 87define i16 @test_ldxr_16(i16* %addr) { 88; CHECK-LABEL: test_ldxr_16: 89; CHECK: ldxrh w0, [x0] 90 91 %val = call i64 @llvm.aarch64.ldxr.p0i16(i16* %addr) 92 %val16 = trunc i64 %val to i16 93 ret i16 %val16 94} 95 96define i32 @test_ldxr_32(i32* %addr) { 97; CHECK-LABEL: test_ldxr_32: 98; CHECK: ldxr w0, [x0] 99 100 %val = call i64 @llvm.aarch64.ldxr.p0i32(i32* %addr) 101 %val32 = trunc i64 %val to i32 102 ret i32 %val32 103} 104 105define i64 @test_ldxr_64(i64* %addr) { 106; CHECK-LABEL: test_ldxr_64: 107; CHECK: ldxr x0, [x0] 108 109 %val = call i64 @llvm.aarch64.ldxr.p0i64(i64* %addr) 110 ret i64 %val 111} 112 113declare i64 @llvm.aarch64.ldaxr.p0i8(i8* %addr) 114declare i64 @llvm.aarch64.ldaxr.p0i16(i16* %addr) 115declare i64 @llvm.aarch64.ldaxr.p0i32(i32* %addr) 116declare i64 @llvm.aarch64.ldaxr.p0i64(i64* %addr) 117 118define i8 @test_ldaxr_8(i8* %addr) { 119; CHECK-LABEL: test_ldaxr_8: 120; CHECK: ldaxrb w0, [x0] 121 122 %val = call i64 @llvm.aarch64.ldaxr.p0i8(i8* %addr) 123 %val8 = trunc i64 %val to i8 124 ret i8 %val8 125} 126 127define i16 @test_ldaxr_16(i16* %addr) { 128; CHECK-LABEL: test_ldaxr_16: 129; CHECK: ldaxrh w0, [x0] 130 131 %val = call i64 @llvm.aarch64.ldaxr.p0i16(i16* %addr) 132 %val16 = trunc i64 %val to i16 133 ret i16 %val16 134} 135 136define i32 @test_ldaxr_32(i32* %addr) { 137; CHECK-LABEL: test_ldaxr_32: 138; CHECK: ldaxr w0, [x0] 139 140 %val = call i64 @llvm.aarch64.ldaxr.p0i32(i32* %addr) 141 %val32 = trunc i64 %val to i32 142 ret i32 %val32 143} 144 145define i64 @test_ldaxr_64(i64* %addr) { 146; CHECK-LABEL: test_ldaxr_64: 147; CHECK: ldaxr x0, [x0] 148 149 %val = call i64 @llvm.aarch64.ldaxr.p0i64(i64* %addr) 150 ret i64 %val 151} 152 153declare i32 @llvm.aarch64.stxr.p0i8(i64, i8*) 154declare i32 @llvm.aarch64.stxr.p0i16(i64, i16*) 155declare i32 @llvm.aarch64.stxr.p0i32(i64, i32*) 156declare i32 @llvm.aarch64.stxr.p0i64(i64, i64*) 157 158define i32 @test_stxr_8(i8* %addr, i8 %val) { 159; CHECK-LABEL: test_stxr_8: 160; CHECK: stxrb [[TMP:w[0-9]+]], w1, [x0] 161; CHECK: mov w0, [[TMP]] 162 163 %extval = zext i8 %val to i64 164 %success = call i32 @llvm.aarch64.stxr.p0i8(i64 %extval, i8* %addr) 165 ret i32 %success 166} 167 168define i32 @test_stxr_16(i16* %addr, i16 %val) { 169; CHECK-LABEL: test_stxr_16: 170; CHECK: stxrh [[TMP:w[0-9]+]], w1, [x0] 171; CHECK: mov w0, [[TMP]] 172 173 %extval = zext i16 %val to i64 174 %success = call i32 @llvm.aarch64.stxr.p0i16(i64 %extval, i16* %addr) 175 ret i32 %success 176} 177 178define i32 @test_stxr_32(i32* %addr, i32 %val) { 179; CHECK-LABEL: test_stxr_32: 180; CHECK: stxr [[TMP:w[0-9]+]], w1, [x0] 181; CHECK: mov w0, [[TMP]] 182 183 %extval = zext i32 %val to i64 184 %success = call i32 @llvm.aarch64.stxr.p0i32(i64 %extval, i32* %addr) 185 ret i32 %success 186} 187 188define i32 @test_stxr_64(i64* %addr, i64 %val) { 189; CHECK-LABEL: test_stxr_64: 190; CHECK: stxr [[TMP:w[0-9]+]], x1, [x0] 191; CHECK: mov w0, [[TMP]] 192 193 %success = call i32 @llvm.aarch64.stxr.p0i64(i64 %val, i64* %addr) 194 ret i32 %success 195} 196 197declare i32 @llvm.aarch64.stlxr.p0i8(i64, i8*) 198declare i32 @llvm.aarch64.stlxr.p0i16(i64, i16*) 199declare i32 @llvm.aarch64.stlxr.p0i32(i64, i32*) 200declare i32 @llvm.aarch64.stlxr.p0i64(i64, i64*) 201 202define i32 @test_stlxr_8(i8* %addr, i8 %val) { 203; CHECK-LABEL: test_stlxr_8: 204; CHECK: stlxrb [[TMP:w[0-9]+]], w1, [x0] 205; CHECK: mov w0, [[TMP]] 206 207 %extval = zext i8 %val to i64 208 %success = call i32 @llvm.aarch64.stlxr.p0i8(i64 %extval, i8* %addr) 209 ret i32 %success 210} 211 212define i32 @test_stlxr_16(i16* %addr, i16 %val) { 213; CHECK-LABEL: test_stlxr_16: 214; CHECK: stlxrh [[TMP:w[0-9]+]], w1, [x0] 215; CHECK: mov w0, [[TMP]] 216 217 %extval = zext i16 %val to i64 218 %success = call i32 @llvm.aarch64.stlxr.p0i16(i64 %extval, i16* %addr) 219 ret i32 %success 220} 221 222define i32 @test_stlxr_32(i32* %addr, i32 %val) { 223; CHECK-LABEL: test_stlxr_32: 224; CHECK: stlxr [[TMP:w[0-9]+]], w1, [x0] 225; CHECK: mov w0, [[TMP]] 226 227 %extval = zext i32 %val to i64 228 %success = call i32 @llvm.aarch64.stlxr.p0i32(i64 %extval, i32* %addr) 229 ret i32 %success 230} 231 232define i32 @test_stlxr_64(i64* %addr, i64 %val) { 233; CHECK-LABEL: test_stlxr_64: 234; CHECK: stlxr [[TMP:w[0-9]+]], x1, [x0] 235; CHECK: mov w0, [[TMP]] 236 237 %success = call i32 @llvm.aarch64.stlxr.p0i64(i64 %val, i64* %addr) 238 ret i32 %success 239} 240 241define {i8*, i1} @test_cmpxchg_ptr(i8** %addr, i8* %cmp, i8* %new) { 242; CHECK-LABEL: test_cmpxchg_ptr: 243; CHECK: [[LOOP:LBB[0-9]+_[0-9]+]]: 244; CHECK: ldaxr [[OLD:w[0-9]+]], [x0] 245; CHECK: cmp [[OLD]], w1 246; CHECK: b.ne [[DONE:LBB[0-9]+_[0-9]+]] 247; CHECK: stlxr [[SUCCESS:w[0-9]+]], w2, [x0] 248; CHECK: cbnz [[SUCCESS]], [[LOOP]] 249 250; CHECK: mov w1, #1 251; CHECK: mov w0, [[OLD]] 252; CHECK: ret 253 254; CHECK: [[DONE]]: 255; CHECK: clrex 256; CHECK: mov w1, wzr 257; CHECK: mov w0, [[OLD]] 258; CHECK: ret 259 %res = cmpxchg i8** %addr, i8* %cmp, i8* %new acq_rel acquire 260 ret {i8*, i1} %res 261} 262