forked from OSchip/llvm-project
[CodeGen][ARM] Make sure the value and type used to create a bitcast
have the same size. This fixes an asset that is triggered when an address of a boolean variable is passed to __builtin_arm_ldrex or __builtin_arm_strex. rdar://problem/29269006 llvm-svn: 288404
This commit is contained in:
parent
0134152cb4
commit
6c299ca6e7
|
@ -4438,19 +4438,21 @@ Value *CodeGenFunction::EmitARMBuiltinExpr(unsigned BuiltinID,
|
||||||
|
|
||||||
QualType Ty = E->getType();
|
QualType Ty = E->getType();
|
||||||
llvm::Type *RealResTy = ConvertType(Ty);
|
llvm::Type *RealResTy = ConvertType(Ty);
|
||||||
llvm::Type *IntResTy = llvm::IntegerType::get(getLLVMContext(),
|
llvm::Type *PtrTy = llvm::IntegerType::get(
|
||||||
getContext().getTypeSize(Ty));
|
getLLVMContext(), getContext().getTypeSize(Ty))->getPointerTo();
|
||||||
LoadAddr = Builder.CreateBitCast(LoadAddr, IntResTy->getPointerTo());
|
LoadAddr = Builder.CreateBitCast(LoadAddr, PtrTy);
|
||||||
|
|
||||||
Function *F = CGM.getIntrinsic(BuiltinID == ARM::BI__builtin_arm_ldaex
|
Function *F = CGM.getIntrinsic(BuiltinID == ARM::BI__builtin_arm_ldaex
|
||||||
? Intrinsic::arm_ldaex
|
? Intrinsic::arm_ldaex
|
||||||
: Intrinsic::arm_ldrex,
|
: Intrinsic::arm_ldrex,
|
||||||
LoadAddr->getType());
|
PtrTy);
|
||||||
Value *Val = Builder.CreateCall(F, LoadAddr, "ldrex");
|
Value *Val = Builder.CreateCall(F, LoadAddr, "ldrex");
|
||||||
|
|
||||||
if (RealResTy->isPointerTy())
|
if (RealResTy->isPointerTy())
|
||||||
return Builder.CreateIntToPtr(Val, RealResTy);
|
return Builder.CreateIntToPtr(Val, RealResTy);
|
||||||
else {
|
else {
|
||||||
|
llvm::Type *IntResTy = llvm::IntegerType::get(
|
||||||
|
getLLVMContext(), CGM.getDataLayout().getTypeSizeInBits(RealResTy));
|
||||||
Val = Builder.CreateTruncOrBitCast(Val, IntResTy);
|
Val = Builder.CreateTruncOrBitCast(Val, IntResTy);
|
||||||
return Builder.CreateBitCast(Val, RealResTy);
|
return Builder.CreateBitCast(Val, RealResTy);
|
||||||
}
|
}
|
||||||
|
@ -4491,7 +4493,10 @@ Value *CodeGenFunction::EmitARMBuiltinExpr(unsigned BuiltinID,
|
||||||
if (StoreVal->getType()->isPointerTy())
|
if (StoreVal->getType()->isPointerTy())
|
||||||
StoreVal = Builder.CreatePtrToInt(StoreVal, Int32Ty);
|
StoreVal = Builder.CreatePtrToInt(StoreVal, Int32Ty);
|
||||||
else {
|
else {
|
||||||
StoreVal = Builder.CreateBitCast(StoreVal, StoreTy);
|
llvm::Type *IntTy = llvm::IntegerType::get(
|
||||||
|
getLLVMContext(),
|
||||||
|
CGM.getDataLayout().getTypeSizeInBits(StoreVal->getType()));
|
||||||
|
StoreVal = Builder.CreateBitCast(StoreVal, IntTy);
|
||||||
StoreVal = Builder.CreateZExtOrBitCast(StoreVal, Int32Ty);
|
StoreVal = Builder.CreateZExtOrBitCast(StoreVal, Int32Ty);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5265,19 +5270,21 @@ Value *CodeGenFunction::EmitAArch64BuiltinExpr(unsigned BuiltinID,
|
||||||
|
|
||||||
QualType Ty = E->getType();
|
QualType Ty = E->getType();
|
||||||
llvm::Type *RealResTy = ConvertType(Ty);
|
llvm::Type *RealResTy = ConvertType(Ty);
|
||||||
llvm::Type *IntResTy = llvm::IntegerType::get(getLLVMContext(),
|
llvm::Type *PtrTy = llvm::IntegerType::get(
|
||||||
getContext().getTypeSize(Ty));
|
getLLVMContext(), getContext().getTypeSize(Ty))->getPointerTo();
|
||||||
LoadAddr = Builder.CreateBitCast(LoadAddr, IntResTy->getPointerTo());
|
LoadAddr = Builder.CreateBitCast(LoadAddr, PtrTy);
|
||||||
|
|
||||||
Function *F = CGM.getIntrinsic(BuiltinID == AArch64::BI__builtin_arm_ldaex
|
Function *F = CGM.getIntrinsic(BuiltinID == AArch64::BI__builtin_arm_ldaex
|
||||||
? Intrinsic::aarch64_ldaxr
|
? Intrinsic::aarch64_ldaxr
|
||||||
: Intrinsic::aarch64_ldxr,
|
: Intrinsic::aarch64_ldxr,
|
||||||
LoadAddr->getType());
|
PtrTy);
|
||||||
Value *Val = Builder.CreateCall(F, LoadAddr, "ldxr");
|
Value *Val = Builder.CreateCall(F, LoadAddr, "ldxr");
|
||||||
|
|
||||||
if (RealResTy->isPointerTy())
|
if (RealResTy->isPointerTy())
|
||||||
return Builder.CreateIntToPtr(Val, RealResTy);
|
return Builder.CreateIntToPtr(Val, RealResTy);
|
||||||
|
|
||||||
|
llvm::Type *IntResTy = llvm::IntegerType::get(
|
||||||
|
getLLVMContext(), CGM.getDataLayout().getTypeSizeInBits(RealResTy));
|
||||||
Val = Builder.CreateTruncOrBitCast(Val, IntResTy);
|
Val = Builder.CreateTruncOrBitCast(Val, IntResTy);
|
||||||
return Builder.CreateBitCast(Val, RealResTy);
|
return Builder.CreateBitCast(Val, RealResTy);
|
||||||
}
|
}
|
||||||
|
@ -5316,7 +5323,10 @@ Value *CodeGenFunction::EmitAArch64BuiltinExpr(unsigned BuiltinID,
|
||||||
if (StoreVal->getType()->isPointerTy())
|
if (StoreVal->getType()->isPointerTy())
|
||||||
StoreVal = Builder.CreatePtrToInt(StoreVal, Int64Ty);
|
StoreVal = Builder.CreatePtrToInt(StoreVal, Int64Ty);
|
||||||
else {
|
else {
|
||||||
StoreVal = Builder.CreateBitCast(StoreVal, StoreTy);
|
llvm::Type *IntTy = llvm::IntegerType::get(
|
||||||
|
getLLVMContext(),
|
||||||
|
CGM.getDataLayout().getTypeSizeInBits(StoreVal->getType()));
|
||||||
|
StoreVal = Builder.CreateBitCast(StoreVal, IntTy);
|
||||||
StoreVal = Builder.CreateZExtOrBitCast(StoreVal, Int64Ty);
|
StoreVal = Builder.CreateZExtOrBitCast(StoreVal, Int64Ty);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
// RUN: %clang_cc1 -Wall -Werror -triple thumbv8-linux-gnueabi -fno-signed-char -emit-llvm -o - %s | FileCheck %s
|
||||||
|
// RUN: %clang_cc1 -Wall -Werror -triple arm64-apple-ios7.0 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-ARM64
|
||||||
|
|
||||||
|
bool b;
|
||||||
|
|
||||||
|
// CHECK-LABEL: @_Z10test_ldrexv()
|
||||||
|
// CHECK: call i32 @llvm.arm.ldrex.p0i8(i8* @b)
|
||||||
|
|
||||||
|
// CHECK-ARM64-LABEL: @_Z10test_ldrexv()
|
||||||
|
// CHECK-ARM64: call i64 @llvm.aarch64.ldxr.p0i8(i8* @b)
|
||||||
|
|
||||||
|
void test_ldrex() {
|
||||||
|
b = __builtin_arm_ldrex(&b);
|
||||||
|
}
|
||||||
|
|
||||||
|
// CHECK-LABEL: @_Z10tset_strexv()
|
||||||
|
// CHECK: %{{.*}} = call i32 @llvm.arm.strex.p0i8(i32 1, i8* @b)
|
||||||
|
|
||||||
|
// CHECK-ARM64-LABEL: @_Z10tset_strexv()
|
||||||
|
// CHECK-ARM64: %{{.*}} = call i32 @llvm.aarch64.stxr.p0i8(i64 1, i8* @b)
|
||||||
|
|
||||||
|
void tset_strex() {
|
||||||
|
__builtin_arm_strex(true, &b);
|
||||||
|
}
|
Loading…
Reference in New Issue