1// REQUIRES: arm-registered-target 2// RUN: %clang_cc1 -Wall -Werror -triple thumbv8-linux-gnueabi -fno-signed-char -O3 -emit-llvm -o - %s | FileCheck %s 3// RUN: %clang_cc1 -Wall -Werror -triple arm64-apple-ios7.0 -O3 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-ARM64 4 5// Make sure the canonical use works before going into smaller details: 6int atomic_inc(int *addr) { 7 int Failure, OldVal; 8 do { 9 OldVal = __builtin_arm_ldrex(addr); 10 Failure = __builtin_arm_strex(OldVal + 1, addr); 11 } while (Failure); 12 13 return OldVal; 14} 15 16// CHECK-LABEL: @atomic_inc 17// CHECK: [[OLDVAL:%.*]] = tail call i32 @llvm.arm.ldrex.p0i32(i32* %addr) 18// CHECK: [[INC:%.*]] = add nsw i32 [[OLDVAL]], 1 19// CHECK: [[FAILURE:%.*]] = tail call i32 @llvm.arm.strex.p0i32(i32 [[INC]], i32* %addr) 20// CHECK: [[TST:%.*]] = icmp eq i32 [[FAILURE]], 0 21// CHECK: br i1 [[TST]], label {{%[a-zA-Z0-9.]+}}, label {{%[a-zA-Z0-9.]+}} 22 23// CHECK-ARM64-LABEL: @atomic_inc 24// CHECK-ARM64: [[OLDVAL:%.*]] = tail call i64 @llvm.aarch64.ldxr.p0i32(i32* %addr) 25// CHECK-ARM64: [[INC:%.*]] = add i64 [[OLDVAL]], 1 26// CHECK-ARM64: [[TRUNC:%.*]] = and i64 [[INC]], 4294967295 27// CHECK-ARM64: [[FAILURE:%.*]] = tail call i32 @llvm.aarch64.stxr.p0i32(i64 [[TRUNC]], i32* %addr) 28// CHECK-ARM64: [[TST:%.*]] = icmp eq i32 [[FAILURE]], 0 29// CHECK-ARM64: br i1 [[TST]], label {{%[a-zA-Z0-9.]+}}, label {{%[a-zA-Z0-9.]+}} 30 31struct Simple { 32 char a, b; 33}; 34 35int test_ldrex(char *addr, long long *addr64, float *addrfloat) { 36// CHECK-LABEL: @test_ldrex 37// CHECK-ARM64-LABEL: @test_ldrex 38 int sum = 0; 39 sum += __builtin_arm_ldrex(addr); 40// CHECK: [[INTRES:%.*]] = tail call i32 @llvm.arm.ldrex.p0i8(i8* %addr) 41// CHECK: and i32 [[INTRES]], 255 42 43// CHECK-ARM64: [[INTRES:%.*]] = tail call i64 @llvm.aarch64.ldxr.p0i8(i8* %addr) 44// CHECK-ARM64: [[TRUNCRES:%.*]] = trunc i64 [[INTRES]] to i32 45// CHECK-ARM64: [[SEXTTMP:%.*]] = shl i32 [[TRUNCRES]], 24 46// CHECK-ARM64: ashr exact i32 [[SEXTTMP]], 24 47 48 sum += __builtin_arm_ldrex((short *)addr); 49// CHECK: [[ADDR16:%.*]] = bitcast i8* %addr to i16* 50// CHECK: [[INTRES:%.*]] = tail call i32 @llvm.arm.ldrex.p0i16(i16* [[ADDR16]]) 51// CHECK: [[TMPSEXT:%.*]] = shl i32 [[INTRES]], 16 52// CHECK: ashr exact i32 [[TMPSEXT]], 16 53 54// CHECK-ARM64: [[ADDR16:%.*]] = bitcast i8* %addr to i16* 55// CHECK-ARM64: [[INTRES:%.*]] = tail call i64 @llvm.aarch64.ldxr.p0i16(i16* [[ADDR16]]) 56// CHECK-ARM64: [[TRUNCRES:%.*]] = trunc i64 [[INTRES]] to i32 57// CHECK-ARM64: [[TMPSEXT:%.*]] = shl i32 [[TRUNCRES]], 16 58// CHECK-ARM64: ashr exact i32 [[TMPSEXT]], 16 59 60 sum += __builtin_arm_ldrex((int *)addr); 61// CHECK: [[ADDR32:%.*]] = bitcast i8* %addr to i32* 62// CHECK: call i32 @llvm.arm.ldrex.p0i32(i32* [[ADDR32]]) 63 64// CHECK-ARM64: [[ADDR32:%.*]] = bitcast i8* %addr to i32* 65// CHECK-ARM64: [[INTRES:%.*]] = tail call i64 @llvm.aarch64.ldxr.p0i32(i32* [[ADDR32]]) 66// CHECK-ARM64: trunc i64 [[INTRES]] to i32 67 68 sum += __builtin_arm_ldrex((long long *)addr); 69// CHECK: call { i32, i32 } @llvm.arm.ldrexd(i8* %addr) 70 71// CHECK-ARM64: [[ADDR64:%.*]] = bitcast i8* %addr to i64* 72// CHECK-ARM64: call i64 @llvm.aarch64.ldxr.p0i64(i64* [[ADDR64]]) 73 74 sum += __builtin_arm_ldrex(addr64); 75// CHECK: [[ADDR64_AS8:%.*]] = bitcast i64* %addr64 to i8* 76// CHECK: call { i32, i32 } @llvm.arm.ldrexd(i8* [[ADDR64_AS8]]) 77 78// CHECK-ARM64: call i64 @llvm.aarch64.ldxr.p0i64(i64* %addr64) 79 80 sum += __builtin_arm_ldrex(addrfloat); 81// CHECK: [[INTADDR:%.*]] = bitcast float* %addrfloat to i32* 82// CHECK: [[INTRES:%.*]] = tail call i32 @llvm.arm.ldrex.p0i32(i32* [[INTADDR]]) 83// CHECK: bitcast i32 [[INTRES]] to float 84 85// CHECK-ARM64: [[INTADDR:%.*]] = bitcast float* %addrfloat to i32* 86// CHECK-ARM64: [[INTRES:%.*]] = tail call i64 @llvm.aarch64.ldxr.p0i32(i32* [[INTADDR]]) 87// CHECK-ARM64: [[TRUNCRES:%.*]] = trunc i64 [[INTRES]] to i32 88// CHECK-ARM64: bitcast i32 [[TRUNCRES]] to float 89 90 sum += __builtin_arm_ldrex((double *)addr); 91// CHECK: [[STRUCTRES:%.*]] = tail call { i32, i32 } @llvm.arm.ldrexd(i8* %addr) 92// CHECK: [[RESHI:%.*]] = extractvalue { i32, i32 } [[STRUCTRES]], 1 93// CHECK: [[RESLO:%.*]] = extractvalue { i32, i32 } [[STRUCTRES]], 0 94// CHECK: [[RESHI64:%.*]] = zext i32 [[RESHI]] to i64 95// CHECK: [[RESLO64:%.*]] = zext i32 [[RESLO]] to i64 96// CHECK: [[RESHIHI:%.*]] = shl nuw i64 [[RESHI64]], 32 97// CHECK: [[INTRES:%.*]] = or i64 [[RESHIHI]], [[RESLO64]] 98// CHECK: bitcast i64 [[INTRES]] to double 99 100// CHECK-ARM64: [[INTRES:%.*]] = tail call i64 @llvm.aarch64.ldxr.p0i64(i64* [[ADDR64]]) 101// CHECK-ARM64: bitcast i64 [[INTRES]] to double 102 103 sum += *__builtin_arm_ldrex((int **)addr); 104// CHECK: [[INTRES:%.*]] = tail call i32 @llvm.arm.ldrex.p0i32(i32* [[ADDR32]]) 105// CHECK: inttoptr i32 [[INTRES]] to i32* 106 107// CHECK-ARM64: [[INTRES:%.*]] = tail call i64 @llvm.aarch64.ldxr.p0i64(i64* [[ADDR64]]) 108// CHECK-ARM64: inttoptr i64 [[INTRES]] to i32* 109 110 sum += __builtin_arm_ldrex((struct Simple **)addr)->a; 111// CHECK: [[INTRES:%.*]] = tail call i32 @llvm.arm.ldrex.p0i32(i32* [[ADDR32]]) 112// CHECK: inttoptr i32 [[INTRES]] to %struct.Simple* 113 114// CHECK-ARM64: [[INTRES:%.*]] = tail call i64 @llvm.aarch64.ldxr.p0i64(i64* [[ADDR64]]) 115// CHECK-ARM64: inttoptr i64 [[INTRES]] to %struct.Simple* 116 return sum; 117} 118 119int test_ldaex(char *addr, long long *addr64, float *addrfloat) { 120// CHECK-LABEL: @test_ldaex 121// CHECK-ARM64-LABEL: @test_ldaex 122 int sum = 0; 123 sum += __builtin_arm_ldaex(addr); 124// CHECK: [[INTRES:%.*]] = tail call i32 @llvm.arm.ldaex.p0i8(i8* %addr) 125// CHECK: and i32 [[INTRES]], 255 126 127// CHECK-ARM64: [[INTRES:%.*]] = tail call i64 @llvm.aarch64.ldaxr.p0i8(i8* %addr) 128// CHECK-ARM64: [[TRUNCRES:%.*]] = trunc i64 [[INTRES]] to i32 129// CHECK-ARM64: [[SEXTTMP:%.*]] = shl i32 [[TRUNCRES]], 24 130// CHECK-ARM64: ashr exact i32 [[SEXTTMP]], 24 131 132 sum += __builtin_arm_ldaex((short *)addr); 133// CHECK: [[ADDR16:%.*]] = bitcast i8* %addr to i16* 134// CHECK: [[INTRES:%.*]] = tail call i32 @llvm.arm.ldaex.p0i16(i16* [[ADDR16]]) 135// CHECK: [[TMPSEXT:%.*]] = shl i32 [[INTRES]], 16 136// CHECK: ashr exact i32 [[TMPSEXT]], 16 137 138// CHECK-ARM64: [[ADDR16:%.*]] = bitcast i8* %addr to i16* 139// CHECK-ARM64: [[INTRES:%.*]] = tail call i64 @llvm.aarch64.ldaxr.p0i16(i16* [[ADDR16]]) 140// CHECK-ARM64: [[TRUNCRES:%.*]] = trunc i64 [[INTRES]] to i32 141// CHECK-ARM64: [[TMPSEXT:%.*]] = shl i32 [[TRUNCRES]], 16 142// CHECK-ARM64: ashr exact i32 [[TMPSEXT]], 16 143 144 sum += __builtin_arm_ldaex((int *)addr); 145// CHECK: [[ADDR32:%.*]] = bitcast i8* %addr to i32* 146// CHECK: call i32 @llvm.arm.ldaex.p0i32(i32* [[ADDR32]]) 147 148// CHECK-ARM64: [[ADDR32:%.*]] = bitcast i8* %addr to i32* 149// CHECK-ARM64: [[INTRES:%.*]] = tail call i64 @llvm.aarch64.ldaxr.p0i32(i32* [[ADDR32]]) 150// CHECK-ARM64: trunc i64 [[INTRES]] to i32 151 152 sum += __builtin_arm_ldaex((long long *)addr); 153// CHECK: call { i32, i32 } @llvm.arm.ldaexd(i8* %addr) 154 155// CHECK-ARM64: [[ADDR64:%.*]] = bitcast i8* %addr to i64* 156// CHECK-ARM64: call i64 @llvm.aarch64.ldaxr.p0i64(i64* [[ADDR64]]) 157 158 sum += __builtin_arm_ldaex(addr64); 159// CHECK: [[ADDR64_AS8:%.*]] = bitcast i64* %addr64 to i8* 160// CHECK: call { i32, i32 } @llvm.arm.ldaexd(i8* [[ADDR64_AS8]]) 161 162// CHECK-ARM64: call i64 @llvm.aarch64.ldaxr.p0i64(i64* %addr64) 163 164 sum += __builtin_arm_ldaex(addrfloat); 165// CHECK: [[INTADDR:%.*]] = bitcast float* %addrfloat to i32* 166// CHECK: [[INTRES:%.*]] = tail call i32 @llvm.arm.ldaex.p0i32(i32* [[INTADDR]]) 167// CHECK: bitcast i32 [[INTRES]] to float 168 169// CHECK-ARM64: [[INTADDR:%.*]] = bitcast float* %addrfloat to i32* 170// CHECK-ARM64: [[INTRES:%.*]] = tail call i64 @llvm.aarch64.ldaxr.p0i32(i32* [[INTADDR]]) 171// CHECK-ARM64: [[TRUNCRES:%.*]] = trunc i64 [[INTRES]] to i32 172// CHECK-ARM64: bitcast i32 [[TRUNCRES]] to float 173 174 sum += __builtin_arm_ldaex((double *)addr); 175// CHECK: [[STRUCTRES:%.*]] = tail call { i32, i32 } @llvm.arm.ldaexd(i8* %addr) 176// CHECK: [[RESHI:%.*]] = extractvalue { i32, i32 } [[STRUCTRES]], 1 177// CHECK: [[RESLO:%.*]] = extractvalue { i32, i32 } [[STRUCTRES]], 0 178// CHECK: [[RESHI64:%.*]] = zext i32 [[RESHI]] to i64 179// CHECK: [[RESLO64:%.*]] = zext i32 [[RESLO]] to i64 180// CHECK: [[RESHIHI:%.*]] = shl nuw i64 [[RESHI64]], 32 181// CHECK: [[INTRES:%.*]] = or i64 [[RESHIHI]], [[RESLO64]] 182// CHECK: bitcast i64 [[INTRES]] to double 183 184// CHECK-ARM64: [[INTRES:%.*]] = tail call i64 @llvm.aarch64.ldaxr.p0i64(i64* [[ADDR64]]) 185// CHECK-ARM64: bitcast i64 [[INTRES]] to double 186 187 sum += *__builtin_arm_ldaex((int **)addr); 188// CHECK: [[INTRES:%.*]] = tail call i32 @llvm.arm.ldaex.p0i32(i32* [[ADDR32]]) 189// CHECK: inttoptr i32 [[INTRES]] to i32* 190 191// CHECK-ARM64: [[INTRES:%.*]] = tail call i64 @llvm.aarch64.ldaxr.p0i64(i64* [[ADDR64]]) 192// CHECK-ARM64: inttoptr i64 [[INTRES]] to i32* 193 194 sum += __builtin_arm_ldaex((struct Simple **)addr)->a; 195// CHECK: [[INTRES:%.*]] = tail call i32 @llvm.arm.ldaex.p0i32(i32* [[ADDR32]]) 196// CHECK: inttoptr i32 [[INTRES]] to %struct.Simple* 197 198// CHECK-ARM64: [[INTRES:%.*]] = tail call i64 @llvm.aarch64.ldaxr.p0i64(i64* [[ADDR64]]) 199// CHECK-ARM64: inttoptr i64 [[INTRES]] to %struct.Simple* 200 return sum; 201} 202 203int test_strex(char *addr) { 204// CHECK-LABEL: @test_strex 205// CHECK-ARM64-LABEL: @test_strex 206 int res = 0; 207 struct Simple var = {0}; 208 res |= __builtin_arm_strex(4, addr); 209// CHECK: call i32 @llvm.arm.strex.p0i8(i32 4, i8* %addr) 210 211// CHECK-ARM64: call i32 @llvm.aarch64.stxr.p0i8(i64 4, i8* %addr) 212 213 res |= __builtin_arm_strex(42, (short *)addr); 214// CHECK: [[ADDR16:%.*]] = bitcast i8* %addr to i16* 215// CHECK: call i32 @llvm.arm.strex.p0i16(i32 42, i16* [[ADDR16]]) 216 217// CHECK-ARM64: [[ADDR16:%.*]] = bitcast i8* %addr to i16* 218// CHECK-ARM64: call i32 @llvm.aarch64.stxr.p0i16(i64 42, i16* [[ADDR16]]) 219 220 res |= __builtin_arm_strex(42, (int *)addr); 221// CHECK: [[ADDR32:%.*]] = bitcast i8* %addr to i32* 222// CHECK: call i32 @llvm.arm.strex.p0i32(i32 42, i32* [[ADDR32]]) 223 224// CHECK-ARM64: [[ADDR32:%.*]] = bitcast i8* %addr to i32* 225// CHECK-ARM64: call i32 @llvm.aarch64.stxr.p0i32(i64 42, i32* [[ADDR32]]) 226 227 res |= __builtin_arm_strex(42, (long long *)addr); 228// CHECK: call i32 @llvm.arm.strexd(i32 42, i32 0, i8* %addr) 229 230// CHECK-ARM64: [[ADDR64:%.*]] = bitcast i8* %addr to i64* 231// CHECK-ARM64: call i32 @llvm.aarch64.stxr.p0i64(i64 42, i64* [[ADDR64]]) 232 233 res |= __builtin_arm_strex(2.71828f, (float *)addr); 234// CHECK: call i32 @llvm.arm.strex.p0i32(i32 1076754509, i32* [[ADDR32]]) 235 236// CHECK-ARM64: call i32 @llvm.aarch64.stxr.p0i32(i64 1076754509, i32* [[ADDR32]]) 237 238 res |= __builtin_arm_strex(3.14159, (double *)addr); 239// CHECK: call i32 @llvm.arm.strexd(i32 -266631570, i32 1074340345, i8* %addr) 240 241// CHECK-ARM64: call i32 @llvm.aarch64.stxr.p0i64(i64 4614256650576692846, i64* [[ADDR64]]) 242 243 res |= __builtin_arm_strex(&var, (struct Simple **)addr); 244// CHECK: [[INTVAL:%.*]] = ptrtoint i16* %var to i32 245// CHECK: call i32 @llvm.arm.strex.p0i32(i32 [[INTVAL]], i32* [[ADDR32]]) 246 247// CHECK-ARM64: [[INTVAL:%.*]] = ptrtoint i16* %var to i64 248// CHECK-ARM64: call i32 @llvm.aarch64.stxr.p0i64(i64 [[INTVAL]], i64* [[ADDR64]]) 249 250 return res; 251} 252 253int test_stlex(char *addr) { 254// CHECK-LABEL: @test_stlex 255// CHECK-ARM64-LABEL: @test_stlex 256 int res = 0; 257 struct Simple var = {0}; 258 res |= __builtin_arm_stlex(4, addr); 259// CHECK: call i32 @llvm.arm.stlex.p0i8(i32 4, i8* %addr) 260 261// CHECK-ARM64: call i32 @llvm.aarch64.stlxr.p0i8(i64 4, i8* %addr) 262 263 res |= __builtin_arm_stlex(42, (short *)addr); 264// CHECK: [[ADDR16:%.*]] = bitcast i8* %addr to i16* 265// CHECK: call i32 @llvm.arm.stlex.p0i16(i32 42, i16* [[ADDR16]]) 266 267// CHECK-ARM64: [[ADDR16:%.*]] = bitcast i8* %addr to i16* 268// CHECK-ARM64: call i32 @llvm.aarch64.stlxr.p0i16(i64 42, i16* [[ADDR16]]) 269 270 res |= __builtin_arm_stlex(42, (int *)addr); 271// CHECK: [[ADDR32:%.*]] = bitcast i8* %addr to i32* 272// CHECK: call i32 @llvm.arm.stlex.p0i32(i32 42, i32* [[ADDR32]]) 273 274// CHECK-ARM64: [[ADDR32:%.*]] = bitcast i8* %addr to i32* 275// CHECK-ARM64: call i32 @llvm.aarch64.stlxr.p0i32(i64 42, i32* [[ADDR32]]) 276 277 res |= __builtin_arm_stlex(42, (long long *)addr); 278// CHECK: call i32 @llvm.arm.stlexd(i32 42, i32 0, i8* %addr) 279 280// CHECK-ARM64: [[ADDR64:%.*]] = bitcast i8* %addr to i64* 281// CHECK-ARM64: call i32 @llvm.aarch64.stlxr.p0i64(i64 42, i64* [[ADDR64]]) 282 283 res |= __builtin_arm_stlex(2.71828f, (float *)addr); 284// CHECK: call i32 @llvm.arm.stlex.p0i32(i32 1076754509, i32* [[ADDR32]]) 285 286// CHECK-ARM64: call i32 @llvm.aarch64.stlxr.p0i32(i64 1076754509, i32* [[ADDR32]]) 287 288 res |= __builtin_arm_stlex(3.14159, (double *)addr); 289// CHECK: call i32 @llvm.arm.stlexd(i32 -266631570, i32 1074340345, i8* %addr) 290 291// CHECK-ARM64: call i32 @llvm.aarch64.stlxr.p0i64(i64 4614256650576692846, i64* [[ADDR64]]) 292 293 res |= __builtin_arm_stlex(&var, (struct Simple **)addr); 294// CHECK: [[INTVAL:%.*]] = ptrtoint i16* %var to i32 295// CHECK: call i32 @llvm.arm.stlex.p0i32(i32 [[INTVAL]], i32* [[ADDR32]]) 296 297// CHECK-ARM64: [[INTVAL:%.*]] = ptrtoint i16* %var to i64 298// CHECK-ARM64: call i32 @llvm.aarch64.stlxr.p0i64(i64 [[INTVAL]], i64* [[ADDR64]]) 299 300 return res; 301} 302 303void test_clrex() { 304// CHECK-LABEL: @test_clrex 305// CHECK-ARM64-LABEL: @test_clrex 306 307 __builtin_arm_clrex(); 308// CHECK: call void @llvm.arm.clrex() 309// CHECK-ARM64: call void @llvm.aarch64.clrex() 310} 311 312#ifdef __aarch64__ 313// 128-bit tests 314 315__int128 test_ldrex_128(__int128 *addr) { 316// CHECK-ARM64-LABEL: @test_ldrex_128 317 318 return __builtin_arm_ldrex(addr); 319// CHECK-ARM64: [[ADDR8:%.*]] = bitcast i128* %addr to i8* 320// CHECK-ARM64: [[STRUCTRES:%.*]] = tail call { i64, i64 } @llvm.aarch64.ldxp(i8* [[ADDR8]]) 321// CHECK-ARM64: [[RESHI:%.*]] = extractvalue { i64, i64 } [[STRUCTRES]], 1 322// CHECK-ARM64: [[RESLO:%.*]] = extractvalue { i64, i64 } [[STRUCTRES]], 0 323// CHECK-ARM64: [[RESHI64:%.*]] = zext i64 [[RESHI]] to i128 324// CHECK-ARM64: [[RESLO64:%.*]] = zext i64 [[RESLO]] to i128 325// CHECK-ARM64: [[RESHIHI:%.*]] = shl nuw i128 [[RESHI64]], 64 326// CHECK-ARM64: [[INTRES:%.*]] = or i128 [[RESHIHI]], [[RESLO64]] 327// CHECK-ARM64: ret i128 [[INTRES]] 328} 329 330int test_strex_128(__int128 *addr, __int128 val) { 331// CHECK-ARM64-LABEL: @test_strex_128 332 333 return __builtin_arm_strex(val, addr); 334// CHECK-ARM64: [[VALLO:%.*]] = trunc i128 %val to i64 335// CHECK-ARM64: [[VALHI128:%.*]] = lshr i128 %val, 64 336// CHECK-ARM64: [[VALHI:%.*]] = trunc i128 [[VALHI128]] to i64 337// CHECK-ARM64: [[ADDR8:%.*]] = bitcast i128* %addr to i8* 338// CHECK-ARM64: [[RES:%.*]] = tail call i32 @llvm.aarch64.stxp(i64 [[VALLO]], i64 [[VALHI]], i8* [[ADDR8]]) 339} 340 341__int128 test_ldaex_128(__int128 *addr) { 342// CHECK-ARM64-LABEL: @test_ldaex_128 343 344 return __builtin_arm_ldaex(addr); 345// CHECK-ARM64: [[ADDR8:%.*]] = bitcast i128* %addr to i8* 346// CHECK-ARM64: [[STRUCTRES:%.*]] = tail call { i64, i64 } @llvm.aarch64.ldaxp(i8* [[ADDR8]]) 347// CHECK-ARM64: [[RESHI:%.*]] = extractvalue { i64, i64 } [[STRUCTRES]], 1 348// CHECK-ARM64: [[RESLO:%.*]] = extractvalue { i64, i64 } [[STRUCTRES]], 0 349// CHECK-ARM64: [[RESHI64:%.*]] = zext i64 [[RESHI]] to i128 350// CHECK-ARM64: [[RESLO64:%.*]] = zext i64 [[RESLO]] to i128 351// CHECK-ARM64: [[RESHIHI:%.*]] = shl nuw i128 [[RESHI64]], 64 352// CHECK-ARM64: [[INTRES:%.*]] = or i128 [[RESHIHI]], [[RESLO64]] 353// CHECK-ARM64: ret i128 [[INTRES]] 354} 355 356int test_stlex_128(__int128 *addr, __int128 val) { 357// CHECK-ARM64-LABEL: @test_stlex_128 358 359 return __builtin_arm_stlex(val, addr); 360// CHECK-ARM64: [[VALLO:%.*]] = trunc i128 %val to i64 361// CHECK-ARM64: [[VALHI128:%.*]] = lshr i128 %val, 64 362// CHECK-ARM64: [[VALHI:%.*]] = trunc i128 [[VALHI128]] to i64 363// CHECK-ARM64: [[ADDR8:%.*]] = bitcast i128* %addr to i8* 364// CHECK-ARM64: [[RES:%.*]] = tail call i32 @llvm.aarch64.stlxp(i64 [[VALLO]], i64 [[VALHI]], i8* [[ADDR8]]) 365} 366 367#endif 368