builtins-arm-exclusive.c revision 6bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89
109df2b066221d869f17f4b5762405f111a65f983Tim Northover// REQUIRES: arm-registered-target 209df2b066221d869f17f4b5762405f111a65f983Tim Northover// RUN: %clang_cc1 -Wall -Werror -triple thumbv7-linux-gnueabi -fno-signed-char -O3 -emit-llvm -o - %s | FileCheck %s 3651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// RUN: %clang_cc1 -Wall -Werror -triple arm64-apple-ios7.0 -O3 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-ARM64 409df2b066221d869f17f4b5762405f111a65f983Tim Northover 509df2b066221d869f17f4b5762405f111a65f983Tim Northover// Make sure the canonical use works before going into smaller details: 609df2b066221d869f17f4b5762405f111a65f983Tim Northoverint atomic_inc(int *addr) { 709df2b066221d869f17f4b5762405f111a65f983Tim Northover int Failure, OldVal; 809df2b066221d869f17f4b5762405f111a65f983Tim Northover do { 909df2b066221d869f17f4b5762405f111a65f983Tim Northover OldVal = __builtin_arm_ldrex(addr); 1009df2b066221d869f17f4b5762405f111a65f983Tim Northover Failure = __builtin_arm_strex(OldVal + 1, addr); 1109df2b066221d869f17f4b5762405f111a65f983Tim Northover } while (Failure); 1209df2b066221d869f17f4b5762405f111a65f983Tim Northover 1309df2b066221d869f17f4b5762405f111a65f983Tim Northover return OldVal; 1409df2b066221d869f17f4b5762405f111a65f983Tim Northover} 1509df2b066221d869f17f4b5762405f111a65f983Tim Northover 16651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK-LABEL: @atomic_inc 1709df2b066221d869f17f4b5762405f111a65f983Tim Northover// CHECK: [[OLDVAL:%.*]] = tail call i32 @llvm.arm.ldrex.p0i32(i32* %addr) 1809df2b066221d869f17f4b5762405f111a65f983Tim Northover// CHECK: [[INC:%.*]] = add nsw i32 [[OLDVAL]], 1 1909df2b066221d869f17f4b5762405f111a65f983Tim Northover// CHECK: [[FAILURE:%.*]] = tail call i32 @llvm.arm.strex.p0i32(i32 [[INC]], i32* %addr) 2009df2b066221d869f17f4b5762405f111a65f983Tim Northover// CHECK: [[TST:%.*]] = icmp eq i32 [[FAILURE]], 0 216cbe66fc2d10e6d63efabb851877ea2521f23ccaTim Northover// CHECK: br i1 [[TST]], label {{%[a-zA-Z0-9.]+}}, label {{%[a-zA-Z0-9.]+}} 2209df2b066221d869f17f4b5762405f111a65f983Tim Northover 23651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK-ARM64-LABEL: @atomic_inc 246bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// CHECK-ARM64: [[OLDVAL:%.*]] = tail call i64 @llvm.aarch64.ldxr.p0i32(i32* %addr) 25651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK-ARM64: [[INC:%.*]] = add i64 [[OLDVAL]], 1 26651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK-ARM64: [[TRUNC:%.*]] = and i64 [[INC]], 4294967295 276bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// CHECK-ARM64: [[FAILURE:%.*]] = tail call i32 @llvm.aarch64.stxr.p0i32(i64 [[TRUNC]], i32* %addr) 28651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK-ARM64: [[TST:%.*]] = icmp eq i32 [[FAILURE]], 0 29651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK-ARM64: br i1 [[TST]], label {{%[a-zA-Z0-9.]+}}, label {{%[a-zA-Z0-9.]+}} 30651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 3109df2b066221d869f17f4b5762405f111a65f983Tim Northoverstruct Simple { 3209df2b066221d869f17f4b5762405f111a65f983Tim Northover char a, b; 3309df2b066221d869f17f4b5762405f111a65f983Tim Northover}; 3409df2b066221d869f17f4b5762405f111a65f983Tim Northover 3509df2b066221d869f17f4b5762405f111a65f983Tim Northoverint test_ldrex(char *addr, long long *addr64, float *addrfloat) { 36651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK-LABEL: @test_ldrex 37651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK-ARM64-LABEL: @test_ldrex 3809df2b066221d869f17f4b5762405f111a65f983Tim Northover int sum = 0; 3909df2b066221d869f17f4b5762405f111a65f983Tim Northover sum += __builtin_arm_ldrex(addr); 4009df2b066221d869f17f4b5762405f111a65f983Tim Northover// CHECK: [[INTRES:%.*]] = tail call i32 @llvm.arm.ldrex.p0i8(i8* %addr) 4109df2b066221d869f17f4b5762405f111a65f983Tim Northover// CHECK: and i32 [[INTRES]], 255 4209df2b066221d869f17f4b5762405f111a65f983Tim Northover 436bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// CHECK-ARM64: [[INTRES:%.*]] = tail call i64 @llvm.aarch64.ldxr.p0i8(i8* %addr) 44651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK-ARM64: [[TRUNCRES:%.*]] = trunc i64 [[INTRES]] to i32 45651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK-ARM64: [[SEXTTMP:%.*]] = shl i32 [[TRUNCRES]], 24 46651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK-ARM64: ashr exact i32 [[SEXTTMP]], 24 47651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 4809df2b066221d869f17f4b5762405f111a65f983Tim Northover sum += __builtin_arm_ldrex((short *)addr); 4909df2b066221d869f17f4b5762405f111a65f983Tim Northover// CHECK: [[ADDR16:%.*]] = bitcast i8* %addr to i16* 5009df2b066221d869f17f4b5762405f111a65f983Tim Northover// CHECK: [[INTRES:%.*]] = tail call i32 @llvm.arm.ldrex.p0i16(i16* [[ADDR16]]) 5109df2b066221d869f17f4b5762405f111a65f983Tim Northover// CHECK: [[TMPSEXT:%.*]] = shl i32 [[INTRES]], 16 5209df2b066221d869f17f4b5762405f111a65f983Tim Northover// CHECK: ashr exact i32 [[TMPSEXT]], 16 5309df2b066221d869f17f4b5762405f111a65f983Tim Northover 54651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK-ARM64: [[ADDR16:%.*]] = bitcast i8* %addr to i16* 556bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// CHECK-ARM64: [[INTRES:%.*]] = tail call i64 @llvm.aarch64.ldxr.p0i16(i16* [[ADDR16]]) 56651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK-ARM64: [[TRUNCRES:%.*]] = trunc i64 [[INTRES]] to i32 57651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK-ARM64: [[TMPSEXT:%.*]] = shl i32 [[TRUNCRES]], 16 58651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK-ARM64: ashr exact i32 [[TMPSEXT]], 16 59651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 6009df2b066221d869f17f4b5762405f111a65f983Tim Northover sum += __builtin_arm_ldrex((int *)addr); 6109df2b066221d869f17f4b5762405f111a65f983Tim Northover// CHECK: [[ADDR32:%.*]] = bitcast i8* %addr to i32* 6209df2b066221d869f17f4b5762405f111a65f983Tim Northover// CHECK: call i32 @llvm.arm.ldrex.p0i32(i32* [[ADDR32]]) 6309df2b066221d869f17f4b5762405f111a65f983Tim Northover 64651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK-ARM64: [[ADDR32:%.*]] = bitcast i8* %addr to i32* 656bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// CHECK-ARM64: [[INTRES:%.*]] = tail call i64 @llvm.aarch64.ldxr.p0i32(i32* [[ADDR32]]) 66651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK-ARM64: trunc i64 [[INTRES]] to i32 67651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 6809df2b066221d869f17f4b5762405f111a65f983Tim Northover sum += __builtin_arm_ldrex((long long *)addr); 6909df2b066221d869f17f4b5762405f111a65f983Tim Northover// CHECK: call { i32, i32 } @llvm.arm.ldrexd(i8* %addr) 7009df2b066221d869f17f4b5762405f111a65f983Tim Northover 71651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK-ARM64: [[ADDR64:%.*]] = bitcast i8* %addr to i64* 726bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// CHECK-ARM64: call i64 @llvm.aarch64.ldxr.p0i64(i64* [[ADDR64]]) 73651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 7409df2b066221d869f17f4b5762405f111a65f983Tim Northover sum += __builtin_arm_ldrex(addr64); 7509df2b066221d869f17f4b5762405f111a65f983Tim Northover// CHECK: [[ADDR64_AS8:%.*]] = bitcast i64* %addr64 to i8* 7609df2b066221d869f17f4b5762405f111a65f983Tim Northover// CHECK: call { i32, i32 } @llvm.arm.ldrexd(i8* [[ADDR64_AS8]]) 7709df2b066221d869f17f4b5762405f111a65f983Tim Northover 786bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// CHECK-ARM64: call i64 @llvm.aarch64.ldxr.p0i64(i64* %addr64) 79651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 8009df2b066221d869f17f4b5762405f111a65f983Tim Northover sum += __builtin_arm_ldrex(addrfloat); 8109df2b066221d869f17f4b5762405f111a65f983Tim Northover// CHECK: [[INTADDR:%.*]] = bitcast float* %addrfloat to i32* 8209df2b066221d869f17f4b5762405f111a65f983Tim Northover// CHECK: [[INTRES:%.*]] = tail call i32 @llvm.arm.ldrex.p0i32(i32* [[INTADDR]]) 8309df2b066221d869f17f4b5762405f111a65f983Tim Northover// CHECK: bitcast i32 [[INTRES]] to float 8409df2b066221d869f17f4b5762405f111a65f983Tim Northover 85651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK-ARM64: [[INTADDR:%.*]] = bitcast float* %addrfloat to i32* 866bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// CHECK-ARM64: [[INTRES:%.*]] = tail call i64 @llvm.aarch64.ldxr.p0i32(i32* [[INTADDR]]) 87651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK-ARM64: [[TRUNCRES:%.*]] = trunc i64 [[INTRES]] to i32 88651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK-ARM64: bitcast i32 [[TRUNCRES]] to float 89651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 9009df2b066221d869f17f4b5762405f111a65f983Tim Northover sum += __builtin_arm_ldrex((double *)addr); 9109df2b066221d869f17f4b5762405f111a65f983Tim Northover// CHECK: [[STRUCTRES:%.*]] = tail call { i32, i32 } @llvm.arm.ldrexd(i8* %addr) 9209df2b066221d869f17f4b5762405f111a65f983Tim Northover// CHECK: [[RESHI:%.*]] = extractvalue { i32, i32 } [[STRUCTRES]], 1 9309df2b066221d869f17f4b5762405f111a65f983Tim Northover// CHECK: [[RESLO:%.*]] = extractvalue { i32, i32 } [[STRUCTRES]], 0 9409df2b066221d869f17f4b5762405f111a65f983Tim Northover// CHECK: [[RESHI64:%.*]] = zext i32 [[RESHI]] to i64 9509df2b066221d869f17f4b5762405f111a65f983Tim Northover// CHECK: [[RESLO64:%.*]] = zext i32 [[RESLO]] to i64 9609df2b066221d869f17f4b5762405f111a65f983Tim Northover// CHECK: [[RESHIHI:%.*]] = shl nuw i64 [[RESHI64]], 32 9709df2b066221d869f17f4b5762405f111a65f983Tim Northover// CHECK: [[INTRES:%.*]] = or i64 [[RESHIHI]], [[RESLO64]] 9809df2b066221d869f17f4b5762405f111a65f983Tim Northover// CHECK: bitcast i64 [[INTRES]] to double 9909df2b066221d869f17f4b5762405f111a65f983Tim Northover 1006bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// CHECK-ARM64: [[INTRES:%.*]] = tail call i64 @llvm.aarch64.ldxr.p0i64(i64* [[ADDR64]]) 101651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK-ARM64: bitcast i64 [[INTRES]] to double 102651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 10309df2b066221d869f17f4b5762405f111a65f983Tim Northover sum += *__builtin_arm_ldrex((int **)addr); 10409df2b066221d869f17f4b5762405f111a65f983Tim Northover// CHECK: [[INTRES:%.*]] = tail call i32 @llvm.arm.ldrex.p0i32(i32* [[ADDR32]]) 10509df2b066221d869f17f4b5762405f111a65f983Tim Northover// CHECK: inttoptr i32 [[INTRES]] to i32* 10609df2b066221d869f17f4b5762405f111a65f983Tim Northover 1076bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// CHECK-ARM64: [[INTRES:%.*]] = tail call i64 @llvm.aarch64.ldxr.p0i64(i64* [[ADDR64]]) 108651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK-ARM64: inttoptr i64 [[INTRES]] to i32* 109651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 11009df2b066221d869f17f4b5762405f111a65f983Tim Northover sum += __builtin_arm_ldrex((struct Simple **)addr)->a; 11109df2b066221d869f17f4b5762405f111a65f983Tim Northover// CHECK: [[INTRES:%.*]] = tail call i32 @llvm.arm.ldrex.p0i32(i32* [[ADDR32]]) 11209df2b066221d869f17f4b5762405f111a65f983Tim Northover// CHECK: inttoptr i32 [[INTRES]] to %struct.Simple* 11309df2b066221d869f17f4b5762405f111a65f983Tim Northover 1146bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// CHECK-ARM64: [[INTRES:%.*]] = tail call i64 @llvm.aarch64.ldxr.p0i64(i64* [[ADDR64]]) 115651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK-ARM64: inttoptr i64 [[INTRES]] to %struct.Simple* 11609df2b066221d869f17f4b5762405f111a65f983Tim Northover return sum; 11709df2b066221d869f17f4b5762405f111a65f983Tim Northover} 11809df2b066221d869f17f4b5762405f111a65f983Tim Northover 11909df2b066221d869f17f4b5762405f111a65f983Tim Northoverint test_strex(char *addr) { 120651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK-LABEL: @test_strex 121651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK-ARM64-LABEL: @test_strex 12209df2b066221d869f17f4b5762405f111a65f983Tim Northover int res = 0; 12309df2b066221d869f17f4b5762405f111a65f983Tim Northover struct Simple var = {0}; 12409df2b066221d869f17f4b5762405f111a65f983Tim Northover res |= __builtin_arm_strex(4, addr); 12509df2b066221d869f17f4b5762405f111a65f983Tim Northover// CHECK: call i32 @llvm.arm.strex.p0i8(i32 4, i8* %addr) 12609df2b066221d869f17f4b5762405f111a65f983Tim Northover 1276bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// CHECK-ARM64: call i32 @llvm.aarch64.stxr.p0i8(i64 4, i8* %addr) 128651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 12909df2b066221d869f17f4b5762405f111a65f983Tim Northover res |= __builtin_arm_strex(42, (short *)addr); 13009df2b066221d869f17f4b5762405f111a65f983Tim Northover// CHECK: [[ADDR16:%.*]] = bitcast i8* %addr to i16* 13109df2b066221d869f17f4b5762405f111a65f983Tim Northover// CHECK: call i32 @llvm.arm.strex.p0i16(i32 42, i16* [[ADDR16]]) 13209df2b066221d869f17f4b5762405f111a65f983Tim Northover 133651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK-ARM64: [[ADDR16:%.*]] = bitcast i8* %addr to i16* 1346bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// CHECK-ARM64: call i32 @llvm.aarch64.stxr.p0i16(i64 42, i16* [[ADDR16]]) 135651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 13609df2b066221d869f17f4b5762405f111a65f983Tim Northover res |= __builtin_arm_strex(42, (int *)addr); 13709df2b066221d869f17f4b5762405f111a65f983Tim Northover// CHECK: [[ADDR32:%.*]] = bitcast i8* %addr to i32* 13809df2b066221d869f17f4b5762405f111a65f983Tim Northover// CHECK: call i32 @llvm.arm.strex.p0i32(i32 42, i32* [[ADDR32]]) 13909df2b066221d869f17f4b5762405f111a65f983Tim Northover 140651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK-ARM64: [[ADDR32:%.*]] = bitcast i8* %addr to i32* 1416bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// CHECK-ARM64: call i32 @llvm.aarch64.stxr.p0i32(i64 42, i32* [[ADDR32]]) 142651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 14309df2b066221d869f17f4b5762405f111a65f983Tim Northover res |= __builtin_arm_strex(42, (long long *)addr); 14409df2b066221d869f17f4b5762405f111a65f983Tim Northover// CHECK: call i32 @llvm.arm.strexd(i32 42, i32 0, i8* %addr) 14509df2b066221d869f17f4b5762405f111a65f983Tim Northover 146651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK-ARM64: [[ADDR64:%.*]] = bitcast i8* %addr to i64* 1476bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// CHECK-ARM64: call i32 @llvm.aarch64.stxr.p0i64(i64 42, i64* [[ADDR64]]) 148651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 14909df2b066221d869f17f4b5762405f111a65f983Tim Northover res |= __builtin_arm_strex(2.71828f, (float *)addr); 15009df2b066221d869f17f4b5762405f111a65f983Tim Northover// CHECK: call i32 @llvm.arm.strex.p0i32(i32 1076754509, i32* [[ADDR32]]) 15109df2b066221d869f17f4b5762405f111a65f983Tim Northover 1526bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// CHECK-ARM64: call i32 @llvm.aarch64.stxr.p0i32(i64 1076754509, i32* [[ADDR32]]) 153651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 15409df2b066221d869f17f4b5762405f111a65f983Tim Northover res |= __builtin_arm_strex(3.14159, (double *)addr); 15509df2b066221d869f17f4b5762405f111a65f983Tim Northover// CHECK: call i32 @llvm.arm.strexd(i32 -266631570, i32 1074340345, i8* %addr) 15609df2b066221d869f17f4b5762405f111a65f983Tim Northover 1576bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// CHECK-ARM64: call i32 @llvm.aarch64.stxr.p0i64(i64 4614256650576692846, i64* [[ADDR64]]) 158651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 15909df2b066221d869f17f4b5762405f111a65f983Tim Northover res |= __builtin_arm_strex(&var, (struct Simple **)addr); 16009df2b066221d869f17f4b5762405f111a65f983Tim Northover// CHECK: [[INTVAL:%.*]] = ptrtoint i16* %var to i32 16109df2b066221d869f17f4b5762405f111a65f983Tim Northover// CHECK: call i32 @llvm.arm.strex.p0i32(i32 [[INTVAL]], i32* [[ADDR32]]) 16209df2b066221d869f17f4b5762405f111a65f983Tim Northover 163651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK-ARM64: [[INTVAL:%.*]] = ptrtoint i16* %var to i64 1646bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// CHECK-ARM64: call i32 @llvm.aarch64.stxr.p0i64(i64 [[INTVAL]], i64* [[ADDR64]]) 165651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 16609df2b066221d869f17f4b5762405f111a65f983Tim Northover return res; 16709df2b066221d869f17f4b5762405f111a65f983Tim Northover} 16809df2b066221d869f17f4b5762405f111a65f983Tim Northover 16909df2b066221d869f17f4b5762405f111a65f983Tim Northovervoid test_clrex() { 170651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK-LABEL: @test_clrex 171651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK-ARM64-LABEL: @test_clrex 17209df2b066221d869f17f4b5762405f111a65f983Tim Northover 17309df2b066221d869f17f4b5762405f111a65f983Tim Northover __builtin_arm_clrex(); 17409df2b066221d869f17f4b5762405f111a65f983Tim Northover// CHECK: call void @llvm.arm.clrex() 1756bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// CHECK-ARM64: call void @llvm.aarch64.clrex() 176651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 177651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 178651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#ifdef __aarch64__ 179651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// 128-bit tests 180651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 181651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines__int128 test_ldrex_128(__int128 *addr) { 182651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK-ARM64-LABEL: @test_ldrex_128 183651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 184651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return __builtin_arm_ldrex(addr); 185651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK-ARM64: [[ADDR8:%.*]] = bitcast i128* %addr to i8* 1866bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// CHECK-ARM64: [[STRUCTRES:%.*]] = tail call { i64, i64 } @llvm.aarch64.ldxp(i8* [[ADDR8]]) 187651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK-ARM64: [[RESHI:%.*]] = extractvalue { i64, i64 } [[STRUCTRES]], 1 188651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK-ARM64: [[RESLO:%.*]] = extractvalue { i64, i64 } [[STRUCTRES]], 0 189651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK-ARM64: [[RESHI64:%.*]] = zext i64 [[RESHI]] to i128 190651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK-ARM64: [[RESLO64:%.*]] = zext i64 [[RESLO]] to i128 191651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK-ARM64: [[RESHIHI:%.*]] = shl nuw i128 [[RESHI64]], 64 192651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK-ARM64: [[INTRES:%.*]] = or i128 [[RESHIHI]], [[RESLO64]] 193651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK-ARM64: ret i128 [[INTRES]] 194651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 195651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 196651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesint test_strex_128(__int128 *addr, __int128 val) { 197651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK-ARM64-LABEL: @test_strex_128 198651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 199651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return __builtin_arm_strex(val, addr); 200651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK-ARM64: [[VALLO:%.*]] = trunc i128 %val to i64 201651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK-ARM64: [[VALHI128:%.*]] = lshr i128 %val, 64 202651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK-ARM64: [[VALHI:%.*]] = trunc i128 [[VALHI128]] to i64 203651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK-ARM64: [[ADDR8:%.*]] = bitcast i128* %addr to i8* 2046bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// CHECK-ARM64: [[RES:%.*]] = tail call i32 @llvm.aarch64.stxp(i64 [[VALLO]], i64 [[VALHI]], i8* [[ADDR8]]) 20509df2b066221d869f17f4b5762405f111a65f983Tim Northover} 206651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#endif 207