diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index bdb430c62e0d57..eec4c8089c757d 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -7696,23 +7696,26 @@ Value *CodeGenFunction::EmitARMBuiltinExpr(unsigned BuiltinID, QualType Ty = E->getType(); llvm::Type *RealResTy = ConvertType(Ty); - llvm::Type *PtrTy = llvm::IntegerType::get( - getLLVMContext(), getContext().getTypeSize(Ty))->getPointerTo(); + llvm::Type *IntTy = + llvm::IntegerType::get(getLLVMContext(), getContext().getTypeSize(Ty)); + llvm::Type *PtrTy = IntTy->getPointerTo(); LoadAddr = Builder.CreateBitCast(LoadAddr, PtrTy); Function *F = CGM.getIntrinsic(BuiltinID == ARM::BI__builtin_arm_ldaex ? Intrinsic::arm_ldaex : Intrinsic::arm_ldrex, PtrTy); - Value *Val = Builder.CreateCall(F, LoadAddr, "ldrex"); + CallInst *Val = Builder.CreateCall(F, LoadAddr, "ldrex"); + Val->addParamAttr( + 0, Attribute::get(getLLVMContext(), Attribute::ElementType, IntTy)); if (RealResTy->isPointerTy()) return Builder.CreateIntToPtr(Val, RealResTy); else { llvm::Type *IntResTy = llvm::IntegerType::get( getLLVMContext(), CGM.getDataLayout().getTypeSizeInBits(RealResTy)); - Val = Builder.CreateTruncOrBitCast(Val, IntResTy); - return Builder.CreateBitCast(Val, RealResTy); + return Builder.CreateBitCast(Builder.CreateTruncOrBitCast(Val, IntResTy), + RealResTy); } } @@ -7762,7 +7765,11 @@ Value *CodeGenFunction::EmitARMBuiltinExpr(unsigned BuiltinID, ? Intrinsic::arm_stlex : Intrinsic::arm_strex, StoreAddr->getType()); - return Builder.CreateCall(F, {StoreVal, StoreAddr}, "strex"); + + CallInst *CI = Builder.CreateCall(F, {StoreVal, StoreAddr}, "strex"); + CI->addParamAttr( + 1, Attribute::get(getLLVMContext(), Attribute::ElementType, StoreTy)); + return CI; } if (BuiltinID == ARM::BI__builtin_arm_clrex) { diff --git a/clang/test/CodeGen/arm_acle.c b/clang/test/CodeGen/arm_acle.c index 350aff58146444..837c3a51f5fc25 100644 --- a/clang/test/CodeGen/arm_acle.c +++ b/clang/test/CodeGen/arm_acle.c @@ -141,8 +141,8 @@ void test_dbg(void) { // AArch32-NEXT: [[TMP0:%.*]] = bitcast i8* [[P:%.*]] to i32* // AArch32-NEXT: br label [[DO_BODY_I:%.*]] // AArch32: do.body.i: -// AArch32-NEXT: [[LDREX_I:%.*]] = call i32 @llvm.arm.ldrex.p0i32(i32* [[TMP0]]) [[ATTR1]] -// AArch32-NEXT: [[STREX_I:%.*]] = call i32 @llvm.arm.strex.p0i32(i32 [[X:%.*]], i32* [[TMP0]]) [[ATTR1]] +// AArch32-NEXT: [[LDREX_I:%.*]] = call i32 @llvm.arm.ldrex.p0i32(i32* elementtype(i32) [[TMP0]]) [[ATTR1]] +// AArch32-NEXT: [[STREX_I:%.*]] = call i32 @llvm.arm.strex.p0i32(i32 [[X:%.*]], i32* elementtype(i32) [[TMP0]]) [[ATTR1]] // AArch32-NEXT: [[TOBOOL_I:%.*]] = icmp ne i32 [[STREX_I]], 0 // AArch32-NEXT: br i1 [[TOBOOL_I]], label [[DO_BODY_I]], label [[__SWP_EXIT:%.*]], [[LOOP3:!llvm.loop !.*]] // AArch32: __swp.exit: diff --git a/clang/test/CodeGen/builtins-arm-exclusive.c b/clang/test/CodeGen/builtins-arm-exclusive.c index 5abe888e50ae5a..fe2aad37ff5e7d 100644 --- a/clang/test/CodeGen/builtins-arm-exclusive.c +++ b/clang/test/CodeGen/builtins-arm-exclusive.c @@ -10,7 +10,7 @@ int test_ldrex(char *addr, long long *addr64, float *addrfloat) { // CHECK-ARM64-LABEL: @test_ldrex int sum = 0; sum += __builtin_arm_ldrex(addr); -// CHECK: [[INTRES:%.*]] = call i32 @llvm.arm.ldrex.p0i8(i8* %addr) +// CHECK: [[INTRES:%.*]] = call i32 @llvm.arm.ldrex.p0i8(i8* elementtype(i8) %addr) // CHECK: trunc i32 [[INTRES]] to i8 // CHECK-ARM64: [[INTRES:%.*]] = call i64 @llvm.aarch64.ldxr.p0i8(i8* elementtype(i8) %addr) @@ -18,7 +18,7 @@ int test_ldrex(char *addr, long long *addr64, float *addrfloat) { sum += __builtin_arm_ldrex((short *)addr); // CHECK: [[ADDR16:%.*]] = bitcast i8* %addr to i16* -// CHECK: [[INTRES:%.*]] = call i32 @llvm.arm.ldrex.p0i16(i16* [[ADDR16]]) +// CHECK: [[INTRES:%.*]] = call i32 @llvm.arm.ldrex.p0i16(i16* elementtype(i16) [[ADDR16]]) // CHECK: trunc i32 [[INTRES]] to i16 // CHECK-ARM64: [[ADDR16:%.*]] = bitcast i8* %addr to i16* @@ -27,7 +27,7 @@ int test_ldrex(char *addr, long long *addr64, float *addrfloat) { sum += __builtin_arm_ldrex((int *)addr); // CHECK: [[ADDR32:%.*]] = bitcast i8* %addr to i32* -// CHECK: call i32 @llvm.arm.ldrex.p0i32(i32* [[ADDR32]]) +// CHECK: call i32 @llvm.arm.ldrex.p0i32(i32* elementtype(i32) [[ADDR32]]) // CHECK-ARM64: [[ADDR32:%.*]] = bitcast i8* %addr to i32* // CHECK-ARM64: [[INTRES:%.*]] = call i64 @llvm.aarch64.ldxr.p0i32(i32* elementtype(i32) [[ADDR32]]) @@ -49,7 +49,7 @@ int test_ldrex(char *addr, long long *addr64, float *addrfloat) { sum += __builtin_arm_ldrex(addrfloat); // CHECK: [[INTADDR:%.*]] = bitcast float* %addrfloat to i32* -// CHECK: [[INTRES:%.*]] = call i32 @llvm.arm.ldrex.p0i32(i32* [[INTADDR]]) +// CHECK: [[INTRES:%.*]] = call i32 @llvm.arm.ldrex.p0i32(i32* elementtype(i32) [[INTADDR]]) // CHECK: bitcast i32 [[INTRES]] to float // CHECK-ARM64: [[INTADDR:%.*]] = bitcast float* %addrfloat to i32* @@ -77,7 +77,7 @@ int test_ldrex(char *addr, long long *addr64, float *addrfloat) { sum += *__builtin_arm_ldrex((int **)addr); // CHECK: [[TMP4:%.*]] = bitcast i8* %addr to i32** // CHECK: [[TMP5:%.*]] = bitcast i32** [[TMP4]] to i32* -// CHECK: [[INTRES:%.*]] = call i32 @llvm.arm.ldrex.p0i32(i32* [[TMP5]]) +// CHECK: [[INTRES:%.*]] = call i32 @llvm.arm.ldrex.p0i32(i32* elementtype(i32) [[TMP5]]) // CHECK: inttoptr i32 [[INTRES]] to i32* // CHECK-ARM64: [[TMP4:%.*]] = bitcast i8* %addr to i32** @@ -88,7 +88,7 @@ int test_ldrex(char *addr, long long *addr64, float *addrfloat) { sum += __builtin_arm_ldrex((struct Simple **)addr)->a; // CHECK: [[TMP4:%.*]] = bitcast i8* %addr to %struct.Simple** // CHECK: [[TMP5:%.*]] = bitcast %struct.Simple** [[TMP4]] to i32* -// CHECK: [[INTRES:%.*]] = call i32 @llvm.arm.ldrex.p0i32(i32* [[TMP5]]) +// CHECK: [[INTRES:%.*]] = call i32 @llvm.arm.ldrex.p0i32(i32* elementtype(i32) [[TMP5]]) // CHECK: inttoptr i32 [[INTRES]] to %struct.Simple* // CHECK-ARM64: [[TMP4:%.*]] = bitcast i8* %addr to %struct.Simple** @@ -103,7 +103,7 @@ int test_ldaex(char *addr, long long *addr64, float *addrfloat) { // CHECK-ARM64-LABEL: @test_ldaex int sum = 0; sum += __builtin_arm_ldaex(addr); -// CHECK: [[INTRES:%.*]] = call i32 @llvm.arm.ldaex.p0i8(i8* %addr) +// CHECK: [[INTRES:%.*]] = call i32 @llvm.arm.ldaex.p0i8(i8* elementtype(i8) %addr) // CHECK: trunc i32 [[INTRES]] to i8 // CHECK-ARM64: [[INTRES:%.*]] = call i64 @llvm.aarch64.ldaxr.p0i8(i8* elementtype(i8) %addr) @@ -111,7 +111,7 @@ int test_ldaex(char *addr, long long *addr64, float *addrfloat) { sum += __builtin_arm_ldaex((short *)addr); // CHECK: [[ADDR16:%.*]] = bitcast i8* %addr to i16* -// CHECK: [[INTRES:%.*]] = call i32 @llvm.arm.ldaex.p0i16(i16* [[ADDR16]]) +// CHECK: [[INTRES:%.*]] = call i32 @llvm.arm.ldaex.p0i16(i16* elementtype(i16) [[ADDR16]]) // CHECK: trunc i32 [[INTRES]] to i16 // CHECK-ARM64: [[ADDR16:%.*]] = bitcast i8* %addr to i16* @@ -120,7 +120,7 @@ int test_ldaex(char *addr, long long *addr64, float *addrfloat) { sum += __builtin_arm_ldaex((int *)addr); // CHECK: [[ADDR32:%.*]] = bitcast i8* %addr to i32* -// CHECK: call i32 @llvm.arm.ldaex.p0i32(i32* [[ADDR32]]) +// CHECK: call i32 @llvm.arm.ldaex.p0i32(i32* elementtype(i32) [[ADDR32]]) // CHECK-ARM64: [[ADDR32:%.*]] = bitcast i8* %addr to i32* // CHECK-ARM64: [[INTRES:%.*]] = call i64 @llvm.aarch64.ldaxr.p0i32(i32* elementtype(i32) [[ADDR32]]) @@ -142,7 +142,7 @@ int test_ldaex(char *addr, long long *addr64, float *addrfloat) { sum += __builtin_arm_ldaex(addrfloat); // CHECK: [[INTADDR:%.*]] = bitcast float* %addrfloat to i32* -// CHECK: [[INTRES:%.*]] = call i32 @llvm.arm.ldaex.p0i32(i32* [[INTADDR]]) +// CHECK: [[INTRES:%.*]] = call i32 @llvm.arm.ldaex.p0i32(i32* elementtype(i32) [[INTADDR]]) // CHECK: bitcast i32 [[INTRES]] to float // CHECK-ARM64: [[INTADDR:%.*]] = bitcast float* %addrfloat to i32* @@ -170,7 +170,7 @@ int test_ldaex(char *addr, long long *addr64, float *addrfloat) { sum += *__builtin_arm_ldaex((int **)addr); // CHECK: [[TMP4:%.*]] = bitcast i8* %addr to i32** // CHECK: [[TMP5:%.*]] = bitcast i32** [[TMP4]] to i32* -// CHECK: [[INTRES:%.*]] = call i32 @llvm.arm.ldaex.p0i32(i32* [[TMP5]]) +// CHECK: [[INTRES:%.*]] = call i32 @llvm.arm.ldaex.p0i32(i32* elementtype(i32) [[TMP5]]) // CHECK: inttoptr i32 [[INTRES]] to i32* // CHECK-ARM64: [[TMP4:%.*]] = bitcast i8* %addr to i32** @@ -181,7 +181,7 @@ int test_ldaex(char *addr, long long *addr64, float *addrfloat) { sum += __builtin_arm_ldaex((struct Simple **)addr)->a; // CHECK: [[TMP4:%.*]] = bitcast i8* %addr to %struct.Simple** // CHECK: [[TMP5:%.*]] = bitcast %struct.Simple** [[TMP4]] to i32* -// CHECK: [[INTRES:%.*]] = call i32 @llvm.arm.ldaex.p0i32(i32* [[TMP5]]) +// CHECK: [[INTRES:%.*]] = call i32 @llvm.arm.ldaex.p0i32(i32* elementtype(i32) [[TMP5]]) // CHECK: inttoptr i32 [[INTRES]] to %struct.Simple* // CHECK-ARM64: [[TMP4:%.*]] = bitcast i8* %addr to %struct.Simple** @@ -197,20 +197,20 @@ int test_strex(char *addr) { int res = 0; struct Simple var = {0}; res |= __builtin_arm_strex(4, addr); -// CHECK: call i32 @llvm.arm.strex.p0i8(i32 4, i8* %addr) +// CHECK: call i32 @llvm.arm.strex.p0i8(i32 4, i8* elementtype(i8) %addr) // CHECK-ARM64: call i32 @llvm.aarch64.stxr.p0i8(i64 4, i8* elementtype(i8) %addr) res |= __builtin_arm_strex(42, (short *)addr); // CHECK: [[ADDR16:%.*]] = bitcast i8* %addr to i16* -// CHECK: call i32 @llvm.arm.strex.p0i16(i32 42, i16* [[ADDR16]]) +// CHECK: call i32 @llvm.arm.strex.p0i16(i32 42, i16* elementtype(i16) [[ADDR16]]) // CHECK-ARM64: [[ADDR16:%.*]] = bitcast i8* %addr to i16* // CHECK-ARM64: call i32 @llvm.aarch64.stxr.p0i16(i64 42, i16* elementtype(i16) [[ADDR16]]) res |= __builtin_arm_strex(42, (int *)addr); // CHECK: [[ADDR32:%.*]] = bitcast i8* %addr to i32* -// CHECK: call i32 @llvm.arm.strex.p0i32(i32 42, i32* [[ADDR32]]) +// CHECK: call i32 @llvm.arm.strex.p0i32(i32 42, i32* elementtype(i32) [[ADDR32]]) // CHECK-ARM64: [[ADDR32:%.*]] = bitcast i8* %addr to i32* // CHECK-ARM64: call i32 @llvm.aarch64.stxr.p0i32(i64 42, i32* elementtype(i32) [[ADDR32]]) @@ -231,7 +231,7 @@ int test_strex(char *addr) { res |= __builtin_arm_strex(2.71828f, (float *)addr); // CHECK: [[TMP4:%.*]] = bitcast i8* %addr to float* // CHECK: [[TMP5:%.*]] = bitcast float* [[TMP4]] to i32* -// CHECK: call i32 @llvm.arm.strex.p0i32(i32 1076754509, i32* [[TMP5]]) +// CHECK: call i32 @llvm.arm.strex.p0i32(i32 1076754509, i32* elementtype(i32) [[TMP5]]) // CHECK-ARM64: [[TMP4:%.*]] = bitcast i8* %addr to float* // CHECK-ARM64: [[TMP5:%.*]] = bitcast float* [[TMP4]] to i32* @@ -255,7 +255,7 @@ int test_strex(char *addr) { // CHECK: [[TMP4:%.*]] = bitcast i8* %addr to %struct.Simple** // CHECK: [[TMP5:%.*]] = bitcast %struct.Simple** [[TMP4]] to i32* // CHECK: [[INTVAL:%.*]] = ptrtoint %struct.Simple* %var to i32 -// CHECK: call i32 @llvm.arm.strex.p0i32(i32 [[INTVAL]], i32* [[TMP5]]) +// CHECK: call i32 @llvm.arm.strex.p0i32(i32 [[INTVAL]], i32* elementtype(i32) [[TMP5]]) // CHECK-ARM64: [[TMP4:%.*]] = bitcast i8* %addr to %struct.Simple** // CHECK-ARM64: [[TMP5:%.*]] = bitcast %struct.Simple** [[TMP4]] to i64* @@ -271,20 +271,20 @@ int test_stlex(char *addr) { int res = 0; struct Simple var = {0}; res |= __builtin_arm_stlex(4, addr); -// CHECK: call i32 @llvm.arm.stlex.p0i8(i32 4, i8* %addr) +// CHECK: call i32 @llvm.arm.stlex.p0i8(i32 4, i8* elementtype(i8) %addr) // CHECK-ARM64: call i32 @llvm.aarch64.stlxr.p0i8(i64 4, i8* elementtype(i8) %addr) res |= __builtin_arm_stlex(42, (short *)addr); // CHECK: [[ADDR16:%.*]] = bitcast i8* %addr to i16* -// CHECK: call i32 @llvm.arm.stlex.p0i16(i32 42, i16* [[ADDR16]]) +// CHECK: call i32 @llvm.arm.stlex.p0i16(i32 42, i16* elementtype(i16) [[ADDR16]]) // CHECK-ARM64: [[ADDR16:%.*]] = bitcast i8* %addr to i16* // CHECK-ARM64: call i32 @llvm.aarch64.stlxr.p0i16(i64 42, i16* elementtype(i16) [[ADDR16]]) res |= __builtin_arm_stlex(42, (int *)addr); // CHECK: [[ADDR32:%.*]] = bitcast i8* %addr to i32* -// CHECK: call i32 @llvm.arm.stlex.p0i32(i32 42, i32* [[ADDR32]]) +// CHECK: call i32 @llvm.arm.stlex.p0i32(i32 42, i32* elementtype(i32) [[ADDR32]]) // CHECK-ARM64: [[ADDR32:%.*]] = bitcast i8* %addr to i32* // CHECK-ARM64: call i32 @llvm.aarch64.stlxr.p0i32(i64 42, i32* elementtype(i32) [[ADDR32]]) @@ -305,7 +305,7 @@ int test_stlex(char *addr) { res |= __builtin_arm_stlex(2.71828f, (float *)addr); // CHECK: [[TMP4:%.*]] = bitcast i8* %addr to float* // CHECK: [[TMP5:%.*]] = bitcast float* [[TMP4]] to i32* -// CHECK: call i32 @llvm.arm.stlex.p0i32(i32 1076754509, i32* [[TMP5]]) +// CHECK: call i32 @llvm.arm.stlex.p0i32(i32 1076754509, i32* elementtype(i32) [[TMP5]]) // CHECK-ARM64: [[TMP4:%.*]] = bitcast i8* %addr to float* // CHECK-ARM64: [[TMP5:%.*]] = bitcast float* [[TMP4]] to i32* @@ -329,7 +329,7 @@ int test_stlex(char *addr) { // CHECK: [[TMP4:%.*]] = bitcast i8* %addr to %struct.Simple** // CHECK: [[TMP5:%.*]] = bitcast %struct.Simple** [[TMP4]] to i32* // CHECK: [[INTVAL:%.*]] = ptrtoint %struct.Simple* %var to i32 -// CHECK: call i32 @llvm.arm.stlex.p0i32(i32 [[INTVAL]], i32* [[TMP5]]) +// CHECK: call i32 @llvm.arm.stlex.p0i32(i32 [[INTVAL]], i32* elementtype(i32) [[TMP5]]) // CHECK-ARM64: [[TMP4:%.*]] = bitcast i8* %addr to %struct.Simple** // CHECK-ARM64: [[TMP5:%.*]] = bitcast %struct.Simple** [[TMP4]] to i64* diff --git a/clang/test/CodeGenCXX/builtins-arm-exclusive.cpp b/clang/test/CodeGenCXX/builtins-arm-exclusive.cpp index 05cb330a4ddae8..e927eb9f91b221 100644 --- a/clang/test/CodeGenCXX/builtins-arm-exclusive.cpp +++ b/clang/test/CodeGenCXX/builtins-arm-exclusive.cpp @@ -4,7 +4,7 @@ bool b; // CHECK-LABEL: @_Z10test_ldrexv() -// CHECK: call i32 @llvm.arm.ldrex.p0i8(i8* @b) +// CHECK: call i32 @llvm.arm.ldrex.p0i8(i8* elementtype(i8) @b) // CHECK-ARM64-LABEL: @_Z10test_ldrexv() // CHECK-ARM64: call i64 @llvm.aarch64.ldxr.p0i8(i8* elementtype(i8) @b) @@ -14,7 +14,7 @@ void test_ldrex() { } // CHECK-LABEL: @_Z10tset_strexv() -// CHECK: %{{.*}} = call i32 @llvm.arm.strex.p0i8(i32 1, i8* @b) +// CHECK: %{{.*}} = call i32 @llvm.arm.strex.p0i8(i32 1, i8* elementtype(i8) @b) // CHECK-ARM64-LABEL: @_Z10tset_strexv() // CHECK-ARM64: %{{.*}} = call i32 @llvm.aarch64.stxr.p0i8(i64 1, i8* elementtype(i8) @b) diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp index 3ad5fd7171db86..afe18c556cdaa9 100644 --- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp @@ -52,6 +52,7 @@ #include "llvm/IR/Instructions.h" #include "llvm/IR/Intrinsics.h" #include "llvm/IR/IntrinsicsAArch64.h" +#include "llvm/IR/IntrinsicsARM.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/Metadata.h" #include "llvm/IR/Module.h" @@ -4144,11 +4145,23 @@ Error BitcodeReader::propagateAttributeTypes(CallBase *CB, case Intrinsic::aarch64_ldaxr: case Intrinsic::aarch64_ldxr: case Intrinsic::aarch64_stlxr: - case Intrinsic::aarch64_stxr: { - unsigned ArgNo = CB->getIntrinsicID() == Intrinsic::aarch64_stlxr || - CB->getIntrinsicID() == Intrinsic::aarch64_stxr - ? 1 - : 0; + case Intrinsic::aarch64_stxr: + case Intrinsic::arm_ldaex: + case Intrinsic::arm_ldrex: + case Intrinsic::arm_stlex: + case Intrinsic::arm_strex: { + unsigned ArgNo; + switch (CB->getIntrinsicID()) { + case Intrinsic::aarch64_stlxr: + case Intrinsic::aarch64_stxr: + case Intrinsic::arm_stlex: + case Intrinsic::arm_strex: + ArgNo = 1; + break; + default: + ArgNo = 0; + break; + } if (!Attrs.getParamElementType(ArgNo)) { Type *ElTy = getPtrElementTypeByID(ArgTyIDs[ArgNo]); if (!ElTy) diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp index 632cc0af3846cd..ec15f5f1efae21 100644 --- a/llvm/lib/IR/Verifier.cpp +++ b/llvm/lib/IR/Verifier.cpp @@ -85,6 +85,7 @@ #include "llvm/IR/IntrinsicInst.h" #include "llvm/IR/Intrinsics.h" #include "llvm/IR/IntrinsicsAArch64.h" +#include "llvm/IR/IntrinsicsARM.h" #include "llvm/IR/IntrinsicsWebAssembly.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/Metadata.h" @@ -5523,7 +5524,9 @@ void Verifier::visitIntrinsicCall(Intrinsic::ID ID, CallBase &Call) { case Intrinsic::preserve_array_access_index: case Intrinsic::preserve_struct_access_index: case Intrinsic::aarch64_ldaxr: - case Intrinsic::aarch64_ldxr: { + case Intrinsic::aarch64_ldxr: + case Intrinsic::arm_ldaex: + case Intrinsic::arm_ldrex: { Type *ElemTy = Call.getParamElementType(0); Assert(ElemTy, "Intrinsic requires elementtype attribute on first argument.", @@ -5531,7 +5534,9 @@ void Verifier::visitIntrinsicCall(Intrinsic::ID ID, CallBase &Call) { break; } case Intrinsic::aarch64_stlxr: - case Intrinsic::aarch64_stxr: { + case Intrinsic::aarch64_stxr: + case Intrinsic::arm_stlex: + case Intrinsic::arm_strex: { Type *ElemTy = Call.getAttributes().getParamElementType(1); Assert(ElemTy, "Intrinsic requires elementtype attribute on second argument.", diff --git a/llvm/lib/Target/ARM/ARMISelLowering.cpp b/llvm/lib/Target/ARM/ARMISelLowering.cpp index 987b67fcae485e..583b6b8afb5f3b 100644 --- a/llvm/lib/Target/ARM/ARMISelLowering.cpp +++ b/llvm/lib/Target/ARM/ARMISelLowering.cpp @@ -20807,24 +20807,24 @@ bool ARMTargetLowering::getTgtMemIntrinsic(IntrinsicInfo &Info, case Intrinsic::arm_ldaex: case Intrinsic::arm_ldrex: { auto &DL = I.getCalledFunction()->getParent()->getDataLayout(); - PointerType *PtrTy = cast(I.getArgOperand(0)->getType()); + Type *ValTy = I.getParamElementType(0); Info.opc = ISD::INTRINSIC_W_CHAIN; - Info.memVT = MVT::getVT(PtrTy->getPointerElementType()); + Info.memVT = MVT::getVT(ValTy); Info.ptrVal = I.getArgOperand(0); Info.offset = 0; - Info.align = DL.getABITypeAlign(PtrTy->getPointerElementType()); + Info.align = DL.getABITypeAlign(ValTy); Info.flags = MachineMemOperand::MOLoad | MachineMemOperand::MOVolatile; return true; } case Intrinsic::arm_stlex: case Intrinsic::arm_strex: { auto &DL = I.getCalledFunction()->getParent()->getDataLayout(); - PointerType *PtrTy = cast(I.getArgOperand(1)->getType()); + Type *ValTy = I.getParamElementType(1); Info.opc = ISD::INTRINSIC_W_CHAIN; - Info.memVT = MVT::getVT(PtrTy->getPointerElementType()); + Info.memVT = MVT::getVT(ValTy); Info.ptrVal = I.getArgOperand(1); Info.offset = 0; - Info.align = DL.getABITypeAlign(PtrTy->getPointerElementType()); + Info.align = DL.getABITypeAlign(ValTy); Info.flags = MachineMemOperand::MOStore | MachineMemOperand::MOVolatile; return true; } @@ -21119,8 +21119,11 @@ Value *ARMTargetLowering::emitLoadLinked(IRBuilderBase &Builder, Type *ValueTy, Type *Tys[] = { Addr->getType() }; Intrinsic::ID Int = IsAcquire ? Intrinsic::arm_ldaex : Intrinsic::arm_ldrex; Function *Ldrex = Intrinsic::getDeclaration(M, Int, Tys); + CallInst *CI = Builder.CreateCall(Ldrex, Addr); - return Builder.CreateTruncOrBitCast(Builder.CreateCall(Ldrex, Addr), ValueTy); + CI->addParamAttr( + 0, Attribute::get(M->getContext(), Attribute::ElementType, ValueTy)); + return Builder.CreateTruncOrBitCast(CI, ValueTy); } void ARMTargetLowering::emitAtomicCmpXchgNoStoreLLBalance( @@ -21158,10 +21161,13 @@ Value *ARMTargetLowering::emitStoreConditional(IRBuilderBase &Builder, Type *Tys[] = { Addr->getType() }; Function *Strex = Intrinsic::getDeclaration(M, Int, Tys); - return Builder.CreateCall( + CallInst *CI = Builder.CreateCall( Strex, {Builder.CreateZExtOrBitCast( Val, Strex->getFunctionType()->getParamType(0)), Addr}); + CI->addParamAttr(1, Attribute::get(M->getContext(), Attribute::ElementType, + Val->getType())); + return CI; } diff --git a/llvm/test/Bitcode/arm-intrinsics.bc b/llvm/test/Bitcode/arm-intrinsics.bc new file mode 100644 index 00000000000000..92a5f263fd18a8 Binary files /dev/null and b/llvm/test/Bitcode/arm-intrinsics.bc differ diff --git a/llvm/test/Bitcode/arm-intrinsics.ll b/llvm/test/Bitcode/arm-intrinsics.ll new file mode 100644 index 00000000000000..42066c60298211 --- /dev/null +++ b/llvm/test/Bitcode/arm-intrinsics.ll @@ -0,0 +1,19 @@ +; RUN: llvm-dis < %S/arm-intrinsics.bc | FileCheck %s + +define void @f(i32* %p) { +; CHECK: call i32 @llvm.arm.ldrex.p0i32(i32* elementtype(i32) + %a = call i32 @llvm.arm.ldrex.p0i32(i32* %p) +; CHECK: call i32 @llvm.arm.strex.p0i32(i32 0, i32* elementtype(i32) + %c = call i32 @llvm.arm.strex.p0i32(i32 0, i32* %p) + +; CHECK: call i32 @llvm.arm.ldaex.p0i32(i32* elementtype(i32) + %a2 = call i32 @llvm.arm.ldaex.p0i32(i32* %p) +; CHECK: call i32 @llvm.arm.stlex.p0i32(i32 0, i32* elementtype(i32) + %c2 = call i32 @llvm.arm.stlex.p0i32(i32 0, i32* %p) + ret void +} + +declare i32 @llvm.arm.ldrex.p0i32(i32*) +declare i32 @llvm.arm.ldaex.p0i32(i32*) +declare i32 @llvm.arm.stlex.p0i32(i32, i32*) +declare i32 @llvm.arm.strex.p0i32(i32, i32*) \ No newline at end of file diff --git a/llvm/test/CodeGen/ARM/ldaex-stlex.ll b/llvm/test/CodeGen/ARM/ldaex-stlex.ll index bfdfea3315630c..fc9dded9e875da 100644 --- a/llvm/test/CodeGen/ARM/ldaex-stlex.ll +++ b/llvm/test/CodeGen/ARM/ldaex-stlex.ll @@ -36,7 +36,7 @@ declare i32 @llvm.arm.stlexd(i32, i32, i8*) nounwind ; CHECK-NOT: uxtb ; CHECK-NOT: and define zeroext i8 @test_load_i8(i8* %addr) { - %val = call i32 @llvm.arm.ldaex.p0i8(i8* %addr) + %val = call i32 @llvm.arm.ldaex.p0i8(i8* elementtype(i8) %addr) %val8 = trunc i32 %val to i8 ret i8 %val8 } @@ -46,7 +46,7 @@ define zeroext i8 @test_load_i8(i8* %addr) { ; CHECK-NOT: uxth ; CHECK-NOT: and define zeroext i16 @test_load_i16(i16* %addr) { - %val = call i32 @llvm.arm.ldaex.p0i16(i16* %addr) + %val = call i32 @llvm.arm.ldaex.p0i16(i16* elementtype(i16) %addr) %val16 = trunc i32 %val to i16 ret i16 %val16 } @@ -54,7 +54,7 @@ define zeroext i16 @test_load_i16(i16* %addr) { ; CHECK-LABEL: test_load_i32: ; CHECK: ldaex r0, [r0] define i32 @test_load_i32(i32* %addr) { - %val = call i32 @llvm.arm.ldaex.p0i32(i32* %addr) + %val = call i32 @llvm.arm.ldaex.p0i32(i32* elementtype(i32) %addr) ret i32 %val } @@ -67,7 +67,7 @@ declare i32 @llvm.arm.ldaex.p0i32(i32*) nounwind readonly ; CHECK: stlexb r0, r1, [r2] define i32 @test_store_i8(i32, i8 %val, i8* %addr) { %extval = zext i8 %val to i32 - %res = call i32 @llvm.arm.stlex.p0i8(i32 %extval, i8* %addr) + %res = call i32 @llvm.arm.stlex.p0i8(i32 %extval, i8* elementtype(i8) %addr) ret i32 %res } @@ -76,14 +76,14 @@ define i32 @test_store_i8(i32, i8 %val, i8* %addr) { ; CHECK: stlexh r0, r1, [r2] define i32 @test_store_i16(i32, i16 %val, i16* %addr) { %extval = zext i16 %val to i32 - %res = call i32 @llvm.arm.stlex.p0i16(i32 %extval, i16* %addr) + %res = call i32 @llvm.arm.stlex.p0i16(i32 %extval, i16* elementtype(i16) %addr) ret i32 %res } ; CHECK-LABEL: test_store_i32: ; CHECK: stlex r0, r1, [r2] define i32 @test_store_i32(i32, i32 %val, i32* %addr) { - %res = call i32 @llvm.arm.stlex.p0i32(i32 %val, i32* %addr) + %res = call i32 @llvm.arm.stlex.p0i32(i32 %val, i32* elementtype(i32) %addr) ret i32 %res } diff --git a/llvm/test/CodeGen/ARM/ldrex-frame-size.ll b/llvm/test/CodeGen/ARM/ldrex-frame-size.ll index f34fb8f4d22df6..8766e024649c58 100644 --- a/llvm/test/CodeGen/ARM/ldrex-frame-size.ll +++ b/llvm/test/CodeGen/ARM/ldrex-frame-size.ll @@ -16,7 +16,7 @@ define void @test_large_frame() { %ptr = alloca i32, i32 252 %addr = getelementptr i32, i32* %ptr, i32 1 - call i32 @llvm.arm.ldrex.p0i32(i32* %addr) + call i32 @llvm.arm.ldrex.p0i32(i32* elementtype(i32) %addr) ret void } @@ -29,7 +29,7 @@ define void @test_small_frame() { %ptr = alloca i32, i32 251 %addr = getelementptr i32, i32* %ptr, i32 1 - call i32 @llvm.arm.ldrex.p0i32(i32* %addr) + call i32 @llvm.arm.ldrex.p0i32(i32* elementtype(i32) %addr) ret void } diff --git a/llvm/test/CodeGen/ARM/ldstrex.ll b/llvm/test/CodeGen/ARM/ldstrex.ll index 73afa0e27469e9..7c97163854f158 100644 --- a/llvm/test/CodeGen/ARM/ldstrex.ll +++ b/llvm/test/CodeGen/ARM/ldstrex.ll @@ -38,7 +38,7 @@ declare i32 @llvm.arm.strexd(i32, i32, i8*) nounwind ; CHECK-NOT: uxtb ; CHECK-NOT: and define zeroext i8 @test_load_i8(i8* %addr) { - %val = call i32 @llvm.arm.ldrex.p0i8(i8* %addr) + %val = call i32 @llvm.arm.ldrex.p0i8(i8* elementtype(i8) %addr) %val8 = trunc i32 %val to i8 ret i8 %val8 } @@ -48,7 +48,7 @@ define zeroext i8 @test_load_i8(i8* %addr) { ; CHECK-NOT: uxth ; CHECK-NOT: and define zeroext i16 @test_load_i16(i16* %addr) { - %val = call i32 @llvm.arm.ldrex.p0i16(i16* %addr) + %val = call i32 @llvm.arm.ldrex.p0i16(i16* elementtype(i16) %addr) %val16 = trunc i32 %val to i16 ret i16 %val16 } @@ -56,7 +56,7 @@ define zeroext i16 @test_load_i16(i16* %addr) { ; CHECK-LABEL: test_load_i32: ; CHECK: ldrex r0, [r0] define i32 @test_load_i32(i32* %addr) { - %val = call i32 @llvm.arm.ldrex.p0i32(i32* %addr) + %val = call i32 @llvm.arm.ldrex.p0i32(i32* elementtype(i32) %addr) ret i32 %val } @@ -69,7 +69,7 @@ declare i32 @llvm.arm.ldrex.p0i32(i32*) nounwind readonly ; CHECK: strexb r0, r1, [r2] define i32 @test_store_i8(i32, i8 %val, i8* %addr) { %extval = zext i8 %val to i32 - %res = call i32 @llvm.arm.strex.p0i8(i32 %extval, i8* %addr) + %res = call i32 @llvm.arm.strex.p0i8(i32 %extval, i8* elementtype(i8) %addr) ret i32 %res } @@ -78,14 +78,14 @@ define i32 @test_store_i8(i32, i8 %val, i8* %addr) { ; CHECK: strexh r0, r1, [r2] define i32 @test_store_i16(i32, i16 %val, i16* %addr) { %extval = zext i16 %val to i32 - %res = call i32 @llvm.arm.strex.p0i16(i32 %extval, i16* %addr) + %res = call i32 @llvm.arm.strex.p0i16(i32 %extval, i16* elementtype(i16) %addr) ret i32 %res } ; CHECK-LABEL: test_store_i32: ; CHECK: strex r0, r1, [r2] define i32 @test_store_i32(i32, i32 %val, i32* %addr) { - %res = call i32 @llvm.arm.strex.p0i32(i32 %val, i32* %addr) + %res = call i32 @llvm.arm.strex.p0i32(i32 %val, i32* elementtype(i32) %addr) ret i32 %res } @@ -108,15 +108,15 @@ define void @excl_addrmode() { ; CHECK-T2ADDRMODE-LABEL: excl_addrmode: %base1020 = load i32*, i32** @base %offset1020 = getelementptr i32, i32* %base1020, i32 255 - call i32 @llvm.arm.ldrex.p0i32(i32* %offset1020) - call i32 @llvm.arm.strex.p0i32(i32 0, i32* %offset1020) + call i32 @llvm.arm.ldrex.p0i32(i32* elementtype(i32) %offset1020) + call i32 @llvm.arm.strex.p0i32(i32 0, i32* elementtype(i32) %offset1020) ; CHECK-T2ADDRMODE: ldrex {{r[0-9]+}}, [{{r[0-9]+}}, #1020] ; CHECK-T2ADDRMODE: strex {{r[0-9]+}}, {{r[0-9]+}}, [{{r[0-9]+}}, #1020] %base1024 = load i32*, i32** @base %offset1024 = getelementptr i32, i32* %base1024, i32 256 - call i32 @llvm.arm.ldrex.p0i32(i32* %offset1024) - call i32 @llvm.arm.strex.p0i32(i32 0, i32* %offset1024) + call i32 @llvm.arm.ldrex.p0i32(i32* elementtype(i32) %offset1024) + call i32 @llvm.arm.strex.p0i32(i32 0, i32* elementtype(i32) %offset1024) ; CHECK-T2ADDRMODE: add.w r[[ADDR:[0-9]+]], {{r[0-9]+}}, #1024 ; CHECK-T2ADDRMODE: ldrex {{r[0-9]+}}, [r[[ADDR]]] ; CHECK-T2ADDRMODE: strex {{r[0-9]+}}, {{r[0-9]+}}, [r[[ADDR]]] @@ -125,16 +125,16 @@ define void @excl_addrmode() { %addr8 = bitcast i32* %base1 to i8* %offset1_8 = getelementptr i8, i8* %addr8, i32 1 %offset1 = bitcast i8* %offset1_8 to i32* - call i32 @llvm.arm.ldrex.p0i32(i32* %offset1) - call i32 @llvm.arm.strex.p0i32(i32 0, i32* %offset1) + call i32 @llvm.arm.ldrex.p0i32(i32* elementtype(i32) %offset1) + call i32 @llvm.arm.strex.p0i32(i32 0, i32* elementtype(i32) %offset1) ; CHECK-T2ADDRMODE: adds r[[ADDR:[0-9]+]], #1 ; CHECK-T2ADDRMODE: ldrex {{r[0-9]+}}, [r[[ADDR]]] ; CHECK-T2ADDRMODE: strex {{r[0-9]+}}, {{r[0-9]+}}, [r[[ADDR]]] %local = alloca i8, i32 1024 %local32 = bitcast i8* %local to i32* - call i32 @llvm.arm.ldrex.p0i32(i32* %local32) - call i32 @llvm.arm.strex.p0i32(i32 0, i32* %local32) + call i32 @llvm.arm.ldrex.p0i32(i32* elementtype(i32) %local32) + call i32 @llvm.arm.strex.p0i32(i32 0, i32* elementtype(i32) %local32) ; CHECK-T2ADDRMODE: mov r[[ADDR:[0-9]+]], sp ; CHECK-T2ADDRMODE: ldrex {{r[0-9]+}}, [r[[ADDR]]] ; CHECK-T2ADDRMODE: strex {{r[0-9]+}}, {{r[0-9]+}}, [r[[ADDR]]] @@ -148,15 +148,15 @@ define void @test_excl_addrmode_folded() { %local.0 = getelementptr i8, i8* %local, i32 4 %local32.0 = bitcast i8* %local.0 to i32* - call i32 @llvm.arm.ldrex.p0i32(i32* %local32.0) - call i32 @llvm.arm.strex.p0i32(i32 0, i32* %local32.0) + call i32 @llvm.arm.ldrex.p0i32(i32* elementtype(i32) %local32.0) + call i32 @llvm.arm.strex.p0i32(i32 0, i32* elementtype(i32) %local32.0) ; CHECK-T2ADDRMODE: ldrex {{r[0-9]+}}, [sp, #4] ; CHECK-T2ADDRMODE: strex {{r[0-9]+}}, {{r[0-9]+}}, [sp, #4] %local.1 = getelementptr i8, i8* %local, i32 1020 %local32.1 = bitcast i8* %local.1 to i32* - call i32 @llvm.arm.ldrex.p0i32(i32* %local32.1) - call i32 @llvm.arm.strex.p0i32(i32 0, i32* %local32.1) + call i32 @llvm.arm.ldrex.p0i32(i32* elementtype(i32) %local32.1) + call i32 @llvm.arm.strex.p0i32(i32 0, i32* elementtype(i32) %local32.1) ; CHECK-T2ADDRMODE: ldrex {{r[0-9]+}}, [sp, #1020] ; CHECK-T2ADDRMODE: strex {{r[0-9]+}}, {{r[0-9]+}}, [sp, #1020] @@ -169,8 +169,8 @@ define void @test_excl_addrmode_range() { %local.0 = getelementptr i8, i8* %local, i32 1024 %local32.0 = bitcast i8* %local.0 to i32* - call i32 @llvm.arm.ldrex.p0i32(i32* %local32.0) - call i32 @llvm.arm.strex.p0i32(i32 0, i32* %local32.0) + call i32 @llvm.arm.ldrex.p0i32(i32* elementtype(i32) %local32.0) + call i32 @llvm.arm.strex.p0i32(i32 0, i32* elementtype(i32) %local32.0) ; CHECK-T2ADDRMODE: mov r[[TMP:[0-9]+]], sp ; CHECK-T2ADDRMODE: add.w r[[ADDR:[0-9]+]], r[[TMP]], #1024 ; CHECK-T2ADDRMODE: ldrex {{r[0-9]+}}, [r[[ADDR]]] @@ -185,8 +185,8 @@ define void @test_excl_addrmode_align() { %local.0 = getelementptr i8, i8* %local, i32 2 %local32.0 = bitcast i8* %local.0 to i32* - call i32 @llvm.arm.ldrex.p0i32(i32* %local32.0) - call i32 @llvm.arm.strex.p0i32(i32 0, i32* %local32.0) + call i32 @llvm.arm.ldrex.p0i32(i32* elementtype(i32) %local32.0) + call i32 @llvm.arm.strex.p0i32(i32 0, i32* elementtype(i32) %local32.0) ; CHECK-T2ADDRMODE: mov r[[ADDR:[0-9]+]], sp ; CHECK-T2ADDRMODE: adds r[[ADDR:[0-9]+]], #2 ; CHECK-T2ADDRMODE: ldrex {{r[0-9]+}}, [r[[ADDR]]] @@ -201,8 +201,8 @@ define void @test_excl_addrmode_sign() { %local.0 = getelementptr i8, i8* %local, i32 -4 %local32.0 = bitcast i8* %local.0 to i32* - call i32 @llvm.arm.ldrex.p0i32(i32* %local32.0) - call i32 @llvm.arm.strex.p0i32(i32 0, i32* %local32.0) + call i32 @llvm.arm.ldrex.p0i32(i32* elementtype(i32) %local32.0) + call i32 @llvm.arm.strex.p0i32(i32 0, i32* elementtype(i32) %local32.0) ; CHECK-T2ADDRMODE: mov r[[ADDR:[0-9]+]], sp ; CHECK-T2ADDRMODE: subs r[[ADDR:[0-9]+]], #4 ; CHECK-T2ADDRMODE: ldrex {{r[0-9]+}}, [r[[ADDR]]] @@ -218,8 +218,8 @@ define void @test_excl_addrmode_combination() { %local.0 = getelementptr i8, i8* %local, i32 4 %local32.0 = bitcast i8* %local.0 to i32* - call i32 @llvm.arm.ldrex.p0i32(i32* %local32.0) - call i32 @llvm.arm.strex.p0i32(i32 0, i32* %local32.0) + call i32 @llvm.arm.ldrex.p0i32(i32* elementtype(i32) %local32.0) + call i32 @llvm.arm.strex.p0i32(i32 0, i32* elementtype(i32) %local32.0) ; CHECK-T2ADDRMODE: ldrex {{r[0-9]+}}, [sp, #68] ; CHECK-T2ADDRMODE: strex {{r[0-9]+}}, {{r[0-9]+}}, [sp, #68] @@ -234,7 +234,7 @@ define zeroext i8 @test_cross_block_zext_i8(i1 %tst, i8* %addr) { ; CHECK-NOT: uxtb ; CHECK-NOT: and ; CHECK: bx lr - %val = call i32 @llvm.arm.ldrex.p0i8(i8* %addr) + %val = call i32 @llvm.arm.ldrex.p0i8(i8* elementtype(i8) %addr) br i1 %tst, label %end, label %mid mid: ret i8 42 diff --git a/llvm/test/Transforms/AtomicExpand/ARM/atomic-expansion-v7.ll b/llvm/test/Transforms/AtomicExpand/ARM/atomic-expansion-v7.ll index 39108874b7f983..1cc20eb9f71e44 100644 --- a/llvm/test/Transforms/AtomicExpand/ARM/atomic-expansion-v7.ll +++ b/llvm/test/Transforms/AtomicExpand/ARM/atomic-expansion-v7.ll @@ -5,10 +5,10 @@ define i8 @test_atomic_xchg_i8(i8* %ptr, i8 %xchgend) { ; CHECK-NOT: dmb ; CHECK: br label %[[LOOP:.*]] ; CHECK: [[LOOP]]: -; CHECK: [[OLDVAL32:%.*]] = call i32 @llvm.arm.ldrex.p0i8(i8* %ptr) +; CHECK: [[OLDVAL32:%.*]] = call i32 @llvm.arm.ldrex.p0i8(i8* elementtype(i8) %ptr) ; CHECK: [[OLDVAL:%.*]] = trunc i32 [[OLDVAL32]] to i8 ; CHECK: [[NEWVAL32:%.*]] = zext i8 %xchgend to i32 -; CHECK: [[TRYAGAIN:%.*]] = call i32 @llvm.arm.strex.p0i8(i32 [[NEWVAL32]], i8* %ptr) +; CHECK: [[TRYAGAIN:%.*]] = call i32 @llvm.arm.strex.p0i8(i32 [[NEWVAL32]], i8* elementtype(i8) %ptr) ; CHECK: [[TST:%.*]] = icmp ne i32 [[TRYAGAIN]], 0 ; CHECK: br i1 [[TST]], label %[[LOOP]], label %[[END:.*]] ; CHECK: [[END]]: @@ -23,11 +23,11 @@ define i16 @test_atomic_add_i16(i16* %ptr, i16 %addend) { ; CHECK: call void @llvm.arm.dmb(i32 11) ; CHECK: br label %[[LOOP:.*]] ; CHECK: [[LOOP]]: -; CHECK: [[OLDVAL32:%.*]] = call i32 @llvm.arm.ldrex.p0i16(i16* %ptr) +; CHECK: [[OLDVAL32:%.*]] = call i32 @llvm.arm.ldrex.p0i16(i16* elementtype(i16) %ptr) ; CHECK: [[OLDVAL:%.*]] = trunc i32 [[OLDVAL32]] to i16 ; CHECK: [[NEWVAL:%.*]] = add i16 [[OLDVAL]], %addend ; CHECK: [[NEWVAL32:%.*]] = zext i16 [[NEWVAL]] to i32 -; CHECK: [[TRYAGAIN:%.*]] = call i32 @llvm.arm.strex.p0i16(i32 [[NEWVAL32]], i16* %ptr) +; CHECK: [[TRYAGAIN:%.*]] = call i32 @llvm.arm.strex.p0i16(i32 [[NEWVAL32]], i16* elementtype(i16) %ptr) ; CHECK: [[TST:%.*]] = icmp ne i32 [[TRYAGAIN]], 0 ; CHECK: br i1 [[TST]], label %[[LOOP]], label %[[END:.*]] ; CHECK: [[END]]: @@ -42,9 +42,9 @@ define i32 @test_atomic_sub_i32(i32* %ptr, i32 %subend) { ; CHECK-NOT: dmb ; CHECK: br label %[[LOOP:.*]] ; CHECK: [[LOOP]]: -; CHECK: [[OLDVAL:%.*]] = call i32 @llvm.arm.ldrex.p0i32(i32* %ptr) +; CHECK: [[OLDVAL:%.*]] = call i32 @llvm.arm.ldrex.p0i32(i32* elementtype(i32) %ptr) ; CHECK: [[NEWVAL:%.*]] = sub i32 [[OLDVAL]], %subend -; CHECK: [[TRYAGAIN:%.*]] = call i32 @llvm.arm.strex.p0i32(i32 [[NEWVAL]], i32* %ptr) +; CHECK: [[TRYAGAIN:%.*]] = call i32 @llvm.arm.strex.p0i32(i32 [[NEWVAL]], i32* elementtype(i32) %ptr) ; CHECK: [[TST:%.*]] = icmp ne i32 [[TRYAGAIN]], 0 ; CHECK: br i1 [[TST]], label %[[LOOP]], label %[[END:.*]] ; CHECK: [[END]]: @@ -59,11 +59,11 @@ define i8 @test_atomic_and_i8(i8* %ptr, i8 %andend) { ; CHECK: call void @llvm.arm.dmb(i32 11) ; CHECK: br label %[[LOOP:.*]] ; CHECK: [[LOOP]]: -; CHECK: [[OLDVAL32:%.*]] = call i32 @llvm.arm.ldrex.p0i8(i8* %ptr) +; CHECK: [[OLDVAL32:%.*]] = call i32 @llvm.arm.ldrex.p0i8(i8* elementtype(i8) %ptr) ; CHECK: [[OLDVAL:%.*]] = trunc i32 [[OLDVAL32]] to i8 ; CHECK: [[NEWVAL:%.*]] = and i8 [[OLDVAL]], %andend ; CHECK: [[NEWVAL32:%.*]] = zext i8 [[NEWVAL]] to i32 -; CHECK: [[TRYAGAIN:%.*]] = call i32 @llvm.arm.strex.p0i8(i32 [[NEWVAL32]], i8* %ptr) +; CHECK: [[TRYAGAIN:%.*]] = call i32 @llvm.arm.strex.p0i8(i32 [[NEWVAL32]], i8* elementtype(i8) %ptr) ; CHECK: [[TST:%.*]] = icmp ne i32 [[TRYAGAIN]], 0 ; CHECK: br i1 [[TST]], label %[[LOOP]], label %[[END:.*]] ; CHECK: [[END]]: @@ -78,12 +78,12 @@ define i16 @test_atomic_nand_i16(i16* %ptr, i16 %nandend) { ; CHECK: call void @llvm.arm.dmb(i32 11) ; CHECK: br label %[[LOOP:.*]] ; CHECK: [[LOOP]]: -; CHECK: [[OLDVAL32:%.*]] = call i32 @llvm.arm.ldrex.p0i16(i16* %ptr) +; CHECK: [[OLDVAL32:%.*]] = call i32 @llvm.arm.ldrex.p0i16(i16* elementtype(i16) %ptr) ; CHECK: [[OLDVAL:%.*]] = trunc i32 [[OLDVAL32]] to i16 ; CHECK: [[NEWVAL_TMP:%.*]] = and i16 [[OLDVAL]], %nandend ; CHECK: [[NEWVAL:%.*]] = xor i16 [[NEWVAL_TMP]], -1 ; CHECK: [[NEWVAL32:%.*]] = zext i16 [[NEWVAL]] to i32 -; CHECK: [[TRYAGAIN:%.*]] = call i32 @llvm.arm.strex.p0i16(i32 [[NEWVAL32]], i16* %ptr) +; CHECK: [[TRYAGAIN:%.*]] = call i32 @llvm.arm.strex.p0i16(i32 [[NEWVAL32]], i16* elementtype(i16) %ptr) ; CHECK: [[TST:%.*]] = icmp ne i32 [[TRYAGAIN]], 0 ; CHECK: br i1 [[TST]], label %[[LOOP]], label %[[END:.*]] ; CHECK: [[END]]: @@ -126,11 +126,11 @@ define i8 @test_atomic_xor_i8(i8* %ptr, i8 %xorend) { ; CHECK: call void @llvm.arm.dmb(i32 11) ; CHECK: br label %[[LOOP:.*]] ; CHECK: [[LOOP]]: -; CHECK: [[OLDVAL32:%.*]] = call i32 @llvm.arm.ldrex.p0i8(i8* %ptr) +; CHECK: [[OLDVAL32:%.*]] = call i32 @llvm.arm.ldrex.p0i8(i8* elementtype(i8) %ptr) ; CHECK: [[OLDVAL:%.*]] = trunc i32 [[OLDVAL32]] to i8 ; CHECK: [[NEWVAL:%.*]] = xor i8 [[OLDVAL]], %xorend ; CHECK: [[NEWVAL32:%.*]] = zext i8 [[NEWVAL]] to i32 -; CHECK: [[TRYAGAIN:%.*]] = call i32 @llvm.arm.strex.p0i8(i32 [[NEWVAL32]], i8* %ptr) +; CHECK: [[TRYAGAIN:%.*]] = call i32 @llvm.arm.strex.p0i8(i32 [[NEWVAL32]], i8* elementtype(i8) %ptr) ; CHECK: [[TST:%.*]] = icmp ne i32 [[TRYAGAIN]], 0 ; CHECK: br i1 [[TST]], label %[[LOOP]], label %[[END:.*]] ; CHECK: [[END]]: @@ -145,12 +145,12 @@ define i8 @test_atomic_max_i8(i8* %ptr, i8 %maxend) { ; CHECK: call void @llvm.arm.dmb(i32 11) ; CHECK: br label %[[LOOP:.*]] ; CHECK: [[LOOP]]: -; CHECK: [[OLDVAL32:%.*]] = call i32 @llvm.arm.ldrex.p0i8(i8* %ptr) +; CHECK: [[OLDVAL32:%.*]] = call i32 @llvm.arm.ldrex.p0i8(i8* elementtype(i8) %ptr) ; CHECK: [[OLDVAL:%.*]] = trunc i32 [[OLDVAL32]] to i8 ; CHECK: [[WANT_OLD:%.*]] = icmp sgt i8 [[OLDVAL]], %maxend ; CHECK: [[NEWVAL:%.*]] = select i1 [[WANT_OLD]], i8 [[OLDVAL]], i8 %maxend ; CHECK: [[NEWVAL32:%.*]] = zext i8 [[NEWVAL]] to i32 -; CHECK: [[TRYAGAIN:%.*]] = call i32 @llvm.arm.strex.p0i8(i32 [[NEWVAL32]], i8* %ptr) +; CHECK: [[TRYAGAIN:%.*]] = call i32 @llvm.arm.strex.p0i8(i32 [[NEWVAL32]], i8* elementtype(i8) %ptr) ; CHECK: [[TST:%.*]] = icmp ne i32 [[TRYAGAIN]], 0 ; CHECK: br i1 [[TST]], label %[[LOOP]], label %[[END:.*]] ; CHECK: [[END]]: @@ -165,12 +165,12 @@ define i8 @test_atomic_min_i8(i8* %ptr, i8 %minend) { ; CHECK: call void @llvm.arm.dmb(i32 11) ; CHECK: br label %[[LOOP:.*]] ; CHECK: [[LOOP]]: -; CHECK: [[OLDVAL32:%.*]] = call i32 @llvm.arm.ldrex.p0i8(i8* %ptr) +; CHECK: [[OLDVAL32:%.*]] = call i32 @llvm.arm.ldrex.p0i8(i8* elementtype(i8) %ptr) ; CHECK: [[OLDVAL:%.*]] = trunc i32 [[OLDVAL32]] to i8 ; CHECK: [[WANT_OLD:%.*]] = icmp sle i8 [[OLDVAL]], %minend ; CHECK: [[NEWVAL:%.*]] = select i1 [[WANT_OLD]], i8 [[OLDVAL]], i8 %minend ; CHECK: [[NEWVAL32:%.*]] = zext i8 [[NEWVAL]] to i32 -; CHECK: [[TRYAGAIN:%.*]] = call i32 @llvm.arm.strex.p0i8(i32 [[NEWVAL32]], i8* %ptr) +; CHECK: [[TRYAGAIN:%.*]] = call i32 @llvm.arm.strex.p0i8(i32 [[NEWVAL32]], i8* elementtype(i8) %ptr) ; CHECK: [[TST:%.*]] = icmp ne i32 [[TRYAGAIN]], 0 ; CHECK: br i1 [[TST]], label %[[LOOP]], label %[[END:.*]] ; CHECK: [[END]]: @@ -185,12 +185,12 @@ define i8 @test_atomic_umax_i8(i8* %ptr, i8 %umaxend) { ; CHECK: call void @llvm.arm.dmb(i32 11) ; CHECK: br label %[[LOOP:.*]] ; CHECK: [[LOOP]]: -; CHECK: [[OLDVAL32:%.*]] = call i32 @llvm.arm.ldrex.p0i8(i8* %ptr) +; CHECK: [[OLDVAL32:%.*]] = call i32 @llvm.arm.ldrex.p0i8(i8* elementtype(i8) %ptr) ; CHECK: [[OLDVAL:%.*]] = trunc i32 [[OLDVAL32]] to i8 ; CHECK: [[WANT_OLD:%.*]] = icmp ugt i8 [[OLDVAL]], %umaxend ; CHECK: [[NEWVAL:%.*]] = select i1 [[WANT_OLD]], i8 [[OLDVAL]], i8 %umaxend ; CHECK: [[NEWVAL32:%.*]] = zext i8 [[NEWVAL]] to i32 -; CHECK: [[TRYAGAIN:%.*]] = call i32 @llvm.arm.strex.p0i8(i32 [[NEWVAL32]], i8* %ptr) +; CHECK: [[TRYAGAIN:%.*]] = call i32 @llvm.arm.strex.p0i8(i32 [[NEWVAL32]], i8* elementtype(i8) %ptr) ; CHECK: [[TST:%.*]] = icmp ne i32 [[TRYAGAIN]], 0 ; CHECK: br i1 [[TST]], label %[[LOOP]], label %[[END:.*]] ; CHECK: [[END]]: @@ -205,12 +205,12 @@ define i8 @test_atomic_umin_i8(i8* %ptr, i8 %uminend) { ; CHECK: call void @llvm.arm.dmb(i32 11) ; CHECK: br label %[[LOOP:.*]] ; CHECK: [[LOOP]]: -; CHECK: [[OLDVAL32:%.*]] = call i32 @llvm.arm.ldrex.p0i8(i8* %ptr) +; CHECK: [[OLDVAL32:%.*]] = call i32 @llvm.arm.ldrex.p0i8(i8* elementtype(i8) %ptr) ; CHECK: [[OLDVAL:%.*]] = trunc i32 [[OLDVAL32]] to i8 ; CHECK: [[WANT_OLD:%.*]] = icmp ule i8 [[OLDVAL]], %uminend ; CHECK: [[NEWVAL:%.*]] = select i1 [[WANT_OLD]], i8 [[OLDVAL]], i8 %uminend ; CHECK: [[NEWVAL32:%.*]] = zext i8 [[NEWVAL]] to i32 -; CHECK: [[TRYAGAIN:%.*]] = call i32 @llvm.arm.strex.p0i8(i32 [[NEWVAL32]], i8* %ptr) +; CHECK: [[TRYAGAIN:%.*]] = call i32 @llvm.arm.strex.p0i8(i32 [[NEWVAL32]], i8* elementtype(i8) %ptr) ; CHECK: [[TST:%.*]] = icmp ne i32 [[TRYAGAIN]], 0 ; CHECK: br i1 [[TST]], label %[[LOOP]], label %[[END:.*]] ; CHECK: [[END]]: @@ -225,7 +225,7 @@ define i8 @test_cmpxchg_i8_seqcst_seqcst(i8* %ptr, i8 %desired, i8 %newval) { ; CHECK: br label %[[START:.*]] ; CHECK: [[START]]: -; CHECK: [[OLDVAL32:%.*]] = call i32 @llvm.arm.ldrex.p0i8(i8* %ptr) +; CHECK: [[OLDVAL32:%.*]] = call i32 @llvm.arm.ldrex.p0i8(i8* elementtype(i8) %ptr) ; CHECK: [[OLDVAL:%.*]] = trunc i32 [[OLDVAL32]] to i8 ; CHECK: [[SHOULD_STORE:%.*]] = icmp eq i8 [[OLDVAL]], %desired ; CHECK: br i1 [[SHOULD_STORE]], label %[[FENCED_STORE:.*]], label %[[NO_STORE_BB:.*]] @@ -237,12 +237,12 @@ define i8 @test_cmpxchg_i8_seqcst_seqcst(i8* %ptr, i8 %desired, i8 %newval) { ; CHECK: [[LOOP]]: ; CHECK: [[LOADED_LOOP:%.*]] = phi i8 [ [[OLDVAL]], %[[FENCED_STORE]] ], [ [[OLDVAL_LOOP:%.*]], %[[RELEASED_LOAD:.*]] ] ; CHECK: [[NEWVAL32:%.*]] = zext i8 %newval to i32 -; CHECK: [[TRYAGAIN:%.*]] = call i32 @llvm.arm.strex.p0i8(i32 [[NEWVAL32]], i8* %ptr) +; CHECK: [[TRYAGAIN:%.*]] = call i32 @llvm.arm.strex.p0i8(i32 [[NEWVAL32]], i8* elementtype(i8) %ptr) ; CHECK: [[TST:%.*]] = icmp eq i32 [[TRYAGAIN]], 0 ; CHECK: br i1 [[TST]], label %[[SUCCESS_BB:.*]], label %[[RELEASED_LOAD]] ; CHECK: [[RELEASED_LOAD]]: -; CHECK: [[OLDVAL32_LOOP:%.*]] = call i32 @llvm.arm.ldrex.p0i8(i8* %ptr) +; CHECK: [[OLDVAL32_LOOP:%.*]] = call i32 @llvm.arm.ldrex.p0i8(i8* elementtype(i8) %ptr) ; CHECK: [[OLDVAL_LOOP]] = trunc i32 [[OLDVAL32_LOOP]] to i8 ; CHECK: [[SHOULD_STORE_LOOP:%.*]] = icmp eq i8 [[OLDVAL_LOOP]], %desired ; CHECK: br i1 [[SHOULD_STORE_LOOP]], label %[[LOOP]], label %[[NO_STORE_BB]] @@ -276,7 +276,7 @@ define i16 @test_cmpxchg_i16_seqcst_monotonic(i16* %ptr, i16 %desired, i16 %newv ; CHECK: br label %[[LOOP:.*]] ; CHECK: [[LOOP]]: -; CHECK: [[OLDVAL32:%.*]] = call i32 @llvm.arm.ldrex.p0i16(i16* %ptr) +; CHECK: [[OLDVAL32:%.*]] = call i32 @llvm.arm.ldrex.p0i16(i16* elementtype(i16) %ptr) ; CHECK: [[OLDVAL:%.*]] = trunc i32 %1 to i16 ; CHECK: [[SHOULD_STORE:%.*]] = icmp eq i16 [[OLDVAL]], %desired ; CHECK: br i1 [[SHOULD_STORE]], label %[[FENCED_STORE:.*]], label %[[NO_STORE_BB:.*]] @@ -288,12 +288,12 @@ define i16 @test_cmpxchg_i16_seqcst_monotonic(i16* %ptr, i16 %desired, i16 %newv ; CHECK: [[LOOP]]: ; CHECK: [[LOADED_LOOP:%.*]] = phi i16 [ [[OLDVAL]], %[[FENCED_STORE]] ], [ [[OLDVAL_LOOP:%.*]], %[[RELEASED_LOAD:.*]] ] ; CHECK: [[NEWVAL32:%.*]] = zext i16 %newval to i32 -; CHECK: [[TRYAGAIN:%.*]] = call i32 @llvm.arm.strex.p0i16(i32 [[NEWVAL32]], i16* %ptr) +; CHECK: [[TRYAGAIN:%.*]] = call i32 @llvm.arm.strex.p0i16(i32 [[NEWVAL32]], i16* elementtype(i16) %ptr) ; CHECK: [[TST:%.*]] = icmp eq i32 [[TRYAGAIN]], 0 ; CHECK: br i1 [[TST]], label %[[SUCCESS_BB:.*]], label %[[RELEASED_LOAD:.*]] ; CHECK: [[RELEASED_LOAD]]: -; CHECK: [[OLDVAL32_LOOP:%.*]] = call i32 @llvm.arm.ldrex.p0i16(i16* %ptr) +; CHECK: [[OLDVAL32_LOOP:%.*]] = call i32 @llvm.arm.ldrex.p0i16(i16* elementtype(i16) %ptr) ; CHECK: [[OLDVAL_LOOP]] = trunc i32 [[OLDVAL32_LOOP]] to i16 ; CHECK: [[SHOULD_STORE_LOOP:%.*]] = icmp eq i16 [[OLDVAL_LOOP]], %desired ; CHECK: br i1 [[SHOULD_STORE_LOOP]], label %[[LOOP]], label %[[NO_STORE_BB]] @@ -328,7 +328,7 @@ define i32 @test_cmpxchg_i32_acquire_acquire(i32* %ptr, i32 %desired, i32 %newva ; CHECK: br label %[[LOOP:.*]] ; CHECK: [[LOOP]]: -; CHECK: [[OLDVAL:%.*]] = call i32 @llvm.arm.ldrex.p0i32(i32* %ptr) +; CHECK: [[OLDVAL:%.*]] = call i32 @llvm.arm.ldrex.p0i32(i32* elementtype(i32) %ptr) ; CHECK: [[SHOULD_STORE:%.*]] = icmp eq i32 [[OLDVAL]], %desired ; CHECK: br i1 [[SHOULD_STORE]], label %[[FENCED_STORE:.*]], label %[[NO_STORE_BB:.*]] @@ -337,7 +337,7 @@ define i32 @test_cmpxchg_i32_acquire_acquire(i32* %ptr, i32 %desired, i32 %newva ; CHECK: [[TRY_STORE]]: ; CHECK: [[LOADED_TRYSTORE:%.*]] = phi i32 [ [[OLDVAL]], %[[FENCED_STORE]] ] -; CHECK: [[TRYAGAIN:%.*]] = call i32 @llvm.arm.strex.p0i32(i32 %newval, i32* %ptr) +; CHECK: [[TRYAGAIN:%.*]] = call i32 @llvm.arm.strex.p0i32(i32 %newval, i32* elementtype(i32) %ptr) ; CHECK: [[TST:%.*]] = icmp eq i32 [[TRYAGAIN]], 0 ; CHECK: br i1 [[TST]], label %[[SUCCESS_BB:.*]], label %[[LOOP]] @@ -425,7 +425,7 @@ define i32 @test_cmpxchg_minsize(i32* %addr, i32 %desired, i32 %new) minsize { ; CHECK: br label %[[START:.*]] ; CHECK: [[START]]: -; CHECK: [[LOADED:%.*]] = call i32 @llvm.arm.ldrex.p0i32(i32* %addr) +; CHECK: [[LOADED:%.*]] = call i32 @llvm.arm.ldrex.p0i32(i32* elementtype(i32) %addr) ; CHECK: [[SHOULD_STORE:%.*]] = icmp eq i32 [[LOADED]], %desired ; CHECK: br i1 [[SHOULD_STORE]], label %[[FENCED_STORE:.*]], label %[[NO_STORE_BB:.*]] @@ -434,7 +434,7 @@ define i32 @test_cmpxchg_minsize(i32* %addr, i32 %desired, i32 %new) minsize { ; CHECK: [[TRY_STORE]]: ; CHECK: [[LOADED_TRYSTORE:%.*]] = phi i32 [ [[LOADED]], %[[FENCED_STORE]] ] -; CHECK: [[STREX:%.*]] = call i32 @llvm.arm.strex.p0i32(i32 %new, i32* %addr) +; CHECK: [[STREX:%.*]] = call i32 @llvm.arm.strex.p0i32(i32 %new, i32* elementtype(i32) %addr) ; CHECK: [[SUCCESS:%.*]] = icmp eq i32 [[STREX]], 0 ; CHECK: br i1 [[SUCCESS]], label %[[SUCCESS_BB:.*]], label %[[START]] diff --git a/llvm/test/Transforms/AtomicExpand/ARM/atomic-expansion-v8.ll b/llvm/test/Transforms/AtomicExpand/ARM/atomic-expansion-v8.ll index deecf01f24365d..cce8799ad11989 100644 --- a/llvm/test/Transforms/AtomicExpand/ARM/atomic-expansion-v8.ll +++ b/llvm/test/Transforms/AtomicExpand/ARM/atomic-expansion-v8.ll @@ -5,10 +5,10 @@ define i8 @test_atomic_xchg_i8(i8* %ptr, i8 %xchgend) { ; CHECK-NOT: fence ; CHECK: br label %[[LOOP:.*]] ; CHECK: [[LOOP]]: -; CHECK: [[OLDVAL32:%.*]] = call i32 @llvm.arm.ldrex.p0i8(i8* %ptr) +; CHECK: [[OLDVAL32:%.*]] = call i32 @llvm.arm.ldrex.p0i8(i8* elementtype(i8) %ptr) ; CHECK: [[OLDVAL:%.*]] = trunc i32 [[OLDVAL32]] to i8 ; CHECK: [[NEWVAL32:%.*]] = zext i8 %xchgend to i32 -; CHECK: [[TRYAGAIN:%.*]] = call i32 @llvm.arm.strex.p0i8(i32 [[NEWVAL32]], i8* %ptr) +; CHECK: [[TRYAGAIN:%.*]] = call i32 @llvm.arm.strex.p0i8(i32 [[NEWVAL32]], i8* elementtype(i8) %ptr) ; CHECK: [[TST:%.*]] = icmp ne i32 [[TRYAGAIN]], 0 ; CHECK: br i1 [[TST]], label %[[LOOP]], label %[[END:.*]] ; CHECK: [[END]]: @@ -23,11 +23,11 @@ define i16 @test_atomic_add_i16(i16* %ptr, i16 %addend) { ; CHECK-NOT: fence ; CHECK: br label %[[LOOP:.*]] ; CHECK: [[LOOP]]: -; CHECK: [[OLDVAL32:%.*]] = call i32 @llvm.arm.ldaex.p0i16(i16* %ptr) +; CHECK: [[OLDVAL32:%.*]] = call i32 @llvm.arm.ldaex.p0i16(i16* elementtype(i16) %ptr) ; CHECK: [[OLDVAL:%.*]] = trunc i32 [[OLDVAL32]] to i16 ; CHECK: [[NEWVAL:%.*]] = add i16 [[OLDVAL]], %addend ; CHECK: [[NEWVAL32:%.*]] = zext i16 [[NEWVAL]] to i32 -; CHECK: [[TRYAGAIN:%.*]] = call i32 @llvm.arm.stlex.p0i16(i32 [[NEWVAL32]], i16* %ptr) +; CHECK: [[TRYAGAIN:%.*]] = call i32 @llvm.arm.stlex.p0i16(i32 [[NEWVAL32]], i16* elementtype(i16) %ptr) ; CHECK: [[TST:%.*]] = icmp ne i32 [[TRYAGAIN]], 0 ; CHECK: br i1 [[TST]], label %[[LOOP]], label %[[END:.*]] ; CHECK: [[END]]: @@ -42,9 +42,9 @@ define i32 @test_atomic_sub_i32(i32* %ptr, i32 %subend) { ; CHECK-NOT: fence ; CHECK: br label %[[LOOP:.*]] ; CHECK: [[LOOP]]: -; CHECK: [[OLDVAL:%.*]] = call i32 @llvm.arm.ldaex.p0i32(i32* %ptr) +; CHECK: [[OLDVAL:%.*]] = call i32 @llvm.arm.ldaex.p0i32(i32* elementtype(i32) %ptr) ; CHECK: [[NEWVAL:%.*]] = sub i32 [[OLDVAL]], %subend -; CHECK: [[TRYAGAIN:%.*]] = call i32 @llvm.arm.strex.p0i32(i32 [[NEWVAL]], i32* %ptr) +; CHECK: [[TRYAGAIN:%.*]] = call i32 @llvm.arm.strex.p0i32(i32 [[NEWVAL]], i32* elementtype(i32) %ptr) ; CHECK: [[TST:%.*]] = icmp ne i32 [[TRYAGAIN]], 0 ; CHECK: br i1 [[TST]], label %[[LOOP]], label %[[END:.*]] ; CHECK: [[END]]: @@ -88,7 +88,7 @@ define i8 @test_cmpxchg_i8_seqcst_seqcst(i8* %ptr, i8 %desired, i8 %newval) { ; CHECK: br label %[[LOOP:.*]] ; CHECK: [[LOOP]]: -; CHECK: [[OLDVAL32:%.*]] = call i32 @llvm.arm.ldaex.p0i8(i8* %ptr) +; CHECK: [[OLDVAL32:%.*]] = call i32 @llvm.arm.ldaex.p0i8(i8* elementtype(i8) %ptr) ; CHECK: [[OLDVAL:%.*]] = trunc i32 %1 to i8 ; CHECK: [[SHOULD_STORE:%.*]] = icmp eq i8 [[OLDVAL]], %desired ; CHECK: br i1 [[SHOULD_STORE]], label %[[FENCED_STORE:.*]], label %[[NO_STORE_BB:.*]] @@ -99,7 +99,7 @@ define i8 @test_cmpxchg_i8_seqcst_seqcst(i8* %ptr, i8 %desired, i8 %newval) { ; CHECK: [[TRY_STORE]]: ; CHECK: [[LOADED_TRYSTORE:%.*]] = phi i8 [ [[OLDVAL]], %[[FENCED_STORE]] ] ; CHECK: [[NEWVAL32:%.*]] = zext i8 %newval to i32 -; CHECK: [[TRYAGAIN:%.*]] = call i32 @llvm.arm.stlex.p0i8(i32 [[NEWVAL32]], i8* %ptr) +; CHECK: [[TRYAGAIN:%.*]] = call i32 @llvm.arm.stlex.p0i8(i32 [[NEWVAL32]], i8* elementtype(i8) %ptr) ; CHECK: [[TST:%.*]] = icmp eq i32 [[TRYAGAIN]], 0 ; CHECK: br i1 [[TST]], label %[[SUCCESS_BB:.*]], label %[[LOOP]] @@ -133,7 +133,7 @@ define i16 @test_cmpxchg_i16_seqcst_monotonic(i16* %ptr, i16 %desired, i16 %newv ; CHECK: br label %[[LOOP:.*]] ; CHECK: [[LOOP]]: -; CHECK: [[OLDVAL32:%.*]] = call i32 @llvm.arm.ldaex.p0i16(i16* %ptr) +; CHECK: [[OLDVAL32:%.*]] = call i32 @llvm.arm.ldaex.p0i16(i16* elementtype(i16) %ptr) ; CHECK: [[OLDVAL:%.*]] = trunc i32 %1 to i16 ; CHECK: [[SHOULD_STORE:%.*]] = icmp eq i16 [[OLDVAL]], %desired ; CHECK: br i1 [[SHOULD_STORE]], label %[[FENCED_STORE:.*]], label %[[NO_STORE_BB:.*]] @@ -144,7 +144,7 @@ define i16 @test_cmpxchg_i16_seqcst_monotonic(i16* %ptr, i16 %desired, i16 %newv ; CHECK: [[TRY_STORE]]: ; CHECK: [[LOADED_TRYSTORE:%.*]] = phi i16 [ [[OLDVAL]], %[[FENCED_STORE]] ] ; CHECK: [[NEWVAL32:%.*]] = zext i16 %newval to i32 -; CHECK: [[TRYAGAIN:%.*]] = call i32 @llvm.arm.stlex.p0i16(i32 [[NEWVAL32]], i16* %ptr) +; CHECK: [[TRYAGAIN:%.*]] = call i32 @llvm.arm.stlex.p0i16(i32 [[NEWVAL32]], i16* elementtype(i16) %ptr) ; CHECK: [[TST:%.*]] = icmp eq i32 [[TRYAGAIN]], 0 ; CHECK: br i1 [[TST]], label %[[SUCCESS_BB:.*]], label %[[LOOP]] @@ -179,7 +179,7 @@ define i32 @test_cmpxchg_i32_acquire_acquire(i32* %ptr, i32 %desired, i32 %newva ; CHECK: br label %[[LOOP:.*]] ; CHECK: [[LOOP]]: -; CHECK: [[OLDVAL:%.*]] = call i32 @llvm.arm.ldaex.p0i32(i32* %ptr) +; CHECK: [[OLDVAL:%.*]] = call i32 @llvm.arm.ldaex.p0i32(i32* elementtype(i32) %ptr) ; CHECK: [[SHOULD_STORE:%.*]] = icmp eq i32 [[OLDVAL]], %desired ; CHECK: br i1 [[SHOULD_STORE]], label %[[FENCED_STORE:.*]], label %[[NO_STORE_BB:.*]] @@ -188,7 +188,7 @@ define i32 @test_cmpxchg_i32_acquire_acquire(i32* %ptr, i32 %desired, i32 %newva ; CHECK: [[TRY_STORE]]: ; CHECK: [[LOADED_TRYSTORE:%.*]] = phi i32 [ [[OLDVAL]], %[[FENCED_STORE]] ] -; CHECK: [[TRYAGAIN:%.*]] = call i32 @llvm.arm.strex.p0i32(i32 %newval, i32* %ptr) +; CHECK: [[TRYAGAIN:%.*]] = call i32 @llvm.arm.strex.p0i32(i32 %newval, i32* elementtype(i32) %ptr) ; CHECK: [[TST:%.*]] = icmp eq i32 [[TRYAGAIN]], 0 ; CHECK: br i1 [[TST]], label %[[SUCCESS_BB:.*]], label %[[LOOP]] diff --git a/llvm/test/Transforms/AtomicExpand/ARM/cmpxchg-weak.ll b/llvm/test/Transforms/AtomicExpand/ARM/cmpxchg-weak.ll index 828c1c4cb3b7ec..1b90ac999dcdbe 100644 --- a/llvm/test/Transforms/AtomicExpand/ARM/cmpxchg-weak.ll +++ b/llvm/test/Transforms/AtomicExpand/ARM/cmpxchg-weak.ll @@ -6,7 +6,7 @@ define i32 @test_cmpxchg_seq_cst(i32* %addr, i32 %desired, i32 %new) { ; CHECK: br label %[[START:.*]] ; CHECK: [[START]]: -; CHECK: [[LOADED:%.*]] = call i32 @llvm.arm.ldrex.p0i32(i32* %addr) +; CHECK: [[LOADED:%.*]] = call i32 @llvm.arm.ldrex.p0i32(i32* elementtype(i32) %addr) ; CHECK: [[SHOULD_STORE:%.*]] = icmp eq i32 [[LOADED]], %desired ; CHECK: br i1 [[SHOULD_STORE]], label %[[FENCED_STORE:.*]], label %[[NO_STORE_BB:.*]] @@ -16,7 +16,7 @@ define i32 @test_cmpxchg_seq_cst(i32* %addr, i32 %desired, i32 %new) { ; CHECK: [[TRY_STORE]]: ; CHECK: [[LOADED_TRYSTORE:%.*]] = phi i32 [ [[LOADED]], %[[FENCED_STORE]] ] -; CHECK: [[STREX:%.*]] = call i32 @llvm.arm.strex.p0i32(i32 %new, i32* %addr) +; CHECK: [[STREX:%.*]] = call i32 @llvm.arm.strex.p0i32(i32 %new, i32* elementtype(i32) %addr) ; CHECK: [[SUCCESS:%.*]] = icmp eq i32 [[STREX]], 0 ; CHECK: br i1 [[SUCCESS]], label %[[SUCCESS_BB:.*]], label %[[FAILURE_BB:.*]] @@ -49,7 +49,7 @@ define i1 @test_cmpxchg_weak_fail(i32* %addr, i32 %desired, i32 %new) { ; CHECK: br label %[[START:.*]] ; CHECK: [[START]]: -; CHECK: [[LOADED:%.*]] = call i32 @llvm.arm.ldrex.p0i32(i32* %addr) +; CHECK: [[LOADED:%.*]] = call i32 @llvm.arm.ldrex.p0i32(i32* elementtype(i32) %addr) ; CHECK: [[SHOULD_STORE:%.*]] = icmp eq i32 [[LOADED]], %desired ; CHECK: br i1 [[SHOULD_STORE]], label %[[FENCED_STORE:.*]], label %[[NO_STORE_BB:.*]] @@ -58,7 +58,7 @@ define i1 @test_cmpxchg_weak_fail(i32* %addr, i32 %desired, i32 %new) { ; CHECK: br label %[[TRY_STORE:.*]] ; CHECK: [[TRY_STORE]]: -; CHECK: [[STREX:%.*]] = call i32 @llvm.arm.strex.p0i32(i32 %new, i32* %addr) +; CHECK: [[STREX:%.*]] = call i32 @llvm.arm.strex.p0i32(i32 %new, i32* elementtype(i32) %addr) ; CHECK: [[SUCCESS:%.*]] = icmp eq i32 [[STREX]], 0 ; CHECK: br i1 [[SUCCESS]], label %[[SUCCESS_BB:.*]], label %[[FAILURE_BB:.*]] @@ -89,7 +89,7 @@ define i32 @test_cmpxchg_monotonic(i32* %addr, i32 %desired, i32 %new) { ; CHECK: br label %[[START:.*]] ; CHECK: [[START]]: -; CHECK: [[LOADED:%.*]] = call i32 @llvm.arm.ldrex.p0i32(i32* %addr) +; CHECK: [[LOADED:%.*]] = call i32 @llvm.arm.ldrex.p0i32(i32* elementtype(i32) %addr) ; CHECK: [[SHOULD_STORE:%.*]] = icmp eq i32 [[LOADED]], %desired ; CHECK: br i1 [[SHOULD_STORE]], label %[[FENCED_STORE:.*]], label %[[NO_STORE_BB:.*]] @@ -98,7 +98,7 @@ define i32 @test_cmpxchg_monotonic(i32* %addr, i32 %desired, i32 %new) { ; CHECK: [[TRY_STORE]]: ; CHECK: [[LOADED_TRYSTORE:%.*]] = phi i32 [ [[LOADED]], %[[FENCED_STORE]] ] -; CHECK: [[STREX:%.*]] = call i32 @llvm.arm.strex.p0i32(i32 %new, i32* %addr) +; CHECK: [[STREX:%.*]] = call i32 @llvm.arm.strex.p0i32(i32 %new, i32* elementtype(i32) %addr) ; CHECK: [[SUCCESS:%.*]] = icmp eq i32 [[STREX]], 0 ; CHECK: br i1 [[SUCCESS]], label %[[SUCCESS_BB:.*]], label %[[FAILURE_BB:.*]] @@ -131,7 +131,7 @@ define i32 @test_cmpxchg_seq_cst_minsize(i32* %addr, i32 %desired, i32 %new) min ; CHECK: br label %[[START:.*]] ; CHECK: [[START]]: -; CHECK: [[LOADED:%.*]] = call i32 @llvm.arm.ldrex.p0i32(i32* %addr) +; CHECK: [[LOADED:%.*]] = call i32 @llvm.arm.ldrex.p0i32(i32* elementtype(i32) %addr) ; CHECK: [[SHOULD_STORE:%.*]] = icmp eq i32 [[LOADED]], %desired ; CHECK: br i1 [[SHOULD_STORE]], label %[[FENCED_STORE:.*]], label %[[NO_STORE_BB:.*]] @@ -141,7 +141,7 @@ define i32 @test_cmpxchg_seq_cst_minsize(i32* %addr, i32 %desired, i32 %new) min ; CHECK: [[TRY_STORE]]: ; CHECK: [[LOADED_TRYSTORE:%.*]] = phi i32 [ [[LOADED]], %[[FENCED_STORE]] ] -; CHECK: [[STREX:%.*]] = call i32 @llvm.arm.strex.p0i32(i32 %new, i32* %addr) +; CHECK: [[STREX:%.*]] = call i32 @llvm.arm.strex.p0i32(i32 %new, i32* elementtype(i32) %addr) ; CHECK: [[SUCCESS:%.*]] = icmp eq i32 [[STREX]], 0 ; CHECK: br i1 [[SUCCESS]], label %[[SUCCESS_BB:.*]], label %[[FAILURE_BB:.*]] diff --git a/llvm/test/Verifier/arm-intrinsics.ll b/llvm/test/Verifier/arm-intrinsics.ll new file mode 100644 index 00000000000000..a9f2fe94f5685a --- /dev/null +++ b/llvm/test/Verifier/arm-intrinsics.ll @@ -0,0 +1,19 @@ +; RUN: not opt -passes=verify -S < %s 2>&1 | FileCheck %s + +define void @f(i32* %p) { +; CHECK: Intrinsic requires elementtype attribute on first argument + %a = call i32 @llvm.arm.ldrex.p0i32(i32* %p) +; CHECK: Intrinsic requires elementtype attribute on second argument + %c = call i32 @llvm.arm.strex.p0i32(i32 0, i32* %p) + +; CHECK: Intrinsic requires elementtype attribute on first argument + %a2 = call i32 @llvm.arm.ldaex.p0i32(i32* %p) +; CHECK: Intrinsic requires elementtype attribute on second argument + %c2 = call i32 @llvm.arm.stlex.p0i32(i32 0, i32* %p) + ret void +} + +declare i32 @llvm.arm.ldrex.p0i32(i32*) +declare i32 @llvm.arm.ldaex.p0i32(i32*) +declare i32 @llvm.arm.stlex.p0i32(i32, i32*) +declare i32 @llvm.arm.strex.p0i32(i32, i32*) \ No newline at end of file