mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-28 19:31:58 +00:00
Respect address space sizes in isEliminableCastPair.
This avoids constant folding bitcast/ptrtoint/inttoptr combinations that have illegal bitcasts between differently sized address spaces. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@187455 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
485c7fd76b
commit
3181f5900f
@ -75,7 +75,7 @@ static unsigned
|
||||
foldConstantCastPair(
|
||||
unsigned opc, ///< opcode of the second cast constant expression
|
||||
ConstantExpr *Op, ///< the first cast constant expression
|
||||
Type *DstTy ///< desintation type of the first cast
|
||||
Type *DstTy ///< destination type of the first cast
|
||||
) {
|
||||
assert(Op && Op->isCast() && "Can't fold cast of cast without a cast!");
|
||||
assert(DstTy && DstTy->isFirstClassType() && "Invalid cast destination type");
|
||||
@ -87,13 +87,14 @@ foldConstantCastPair(
|
||||
Instruction::CastOps firstOp = Instruction::CastOps(Op->getOpcode());
|
||||
Instruction::CastOps secondOp = Instruction::CastOps(opc);
|
||||
|
||||
// Assume that pointers are never more than 64 bits wide.
|
||||
// Assume that pointers are never more than 64 bits wide, and only use this
|
||||
// for the middle type. Otherwise we could end up folding away illegal
|
||||
// bitcasts between address spaces with different sizes.
|
||||
IntegerType *FakeIntPtrTy = Type::getInt64Ty(DstTy->getContext());
|
||||
|
||||
// Let CastInst::isEliminableCastPair do the heavy lifting.
|
||||
return CastInst::isEliminableCastPair(firstOp, secondOp, SrcTy, MidTy, DstTy,
|
||||
FakeIntPtrTy, FakeIntPtrTy,
|
||||
FakeIntPtrTy);
|
||||
0, FakeIntPtrTy, 0);
|
||||
}
|
||||
|
||||
static Constant *FoldBitCast(Constant *V, Type *DestTy) {
|
||||
|
@ -2224,12 +2224,20 @@ unsigned CastInst::isEliminableCastPair(
|
||||
if (SrcTy->isFloatingPointTy())
|
||||
return secondOp;
|
||||
return 0;
|
||||
case 7: {
|
||||
// ptrtoint, inttoptr -> bitcast (ptr -> ptr) if int size is >= ptr size
|
||||
case 7: {
|
||||
unsigned MidSize = MidTy->getScalarSizeInBits();
|
||||
// Check the address spaces first. If we know they are in the same address
|
||||
// space, the pointer sizes must be the same so we can still fold this
|
||||
// without knowing the actual sizes as long we know that the intermediate
|
||||
// pointer is the largest possible pointer size.
|
||||
if (MidSize == 64 &&
|
||||
SrcTy->getPointerAddressSpace() == DstTy->getPointerAddressSpace())
|
||||
return Instruction::BitCast;
|
||||
|
||||
// ptrtoint, inttoptr -> bitcast (ptr -> ptr) if int size is >= ptr size.
|
||||
if (!SrcIntPtrTy || DstIntPtrTy != SrcIntPtrTy)
|
||||
return 0;
|
||||
unsigned PtrSize = SrcIntPtrTy->getScalarSizeInBits();
|
||||
unsigned MidSize = MidTy->getScalarSizeInBits();
|
||||
if (MidSize >= PtrSize)
|
||||
return Instruction::BitCast;
|
||||
return 0;
|
||||
@ -2254,17 +2262,46 @@ unsigned CastInst::isEliminableCastPair(
|
||||
if (SrcTy == DstTy)
|
||||
return Instruction::BitCast;
|
||||
return 0; // If the types are not the same we can't eliminate it.
|
||||
case 11:
|
||||
// bitcast followed by ptrtoint is allowed as long as the bitcast
|
||||
// is a pointer to pointer cast.
|
||||
if (SrcTy->isPointerTy() && MidTy->isPointerTy())
|
||||
case 11: {
|
||||
// bitcast followed by ptrtoint is allowed as long as the bitcast is a
|
||||
// pointer to pointer cast, and the pointers are the same size.
|
||||
PointerType *SrcPtrTy = dyn_cast<PointerType>(SrcTy);
|
||||
PointerType *MidPtrTy = dyn_cast<PointerType>(MidTy);
|
||||
if (!SrcPtrTy || !MidPtrTy)
|
||||
return 0;
|
||||
|
||||
// If the address spaces are the same, we know they are the same size
|
||||
// without size information
|
||||
if (SrcPtrTy->getAddressSpace() == MidPtrTy->getAddressSpace())
|
||||
return secondOp;
|
||||
|
||||
if (!SrcIntPtrTy || !MidIntPtrTy)
|
||||
return 0;
|
||||
|
||||
if (SrcIntPtrTy->getScalarSizeInBits() ==
|
||||
MidIntPtrTy->getScalarSizeInBits())
|
||||
return secondOp;
|
||||
|
||||
return 0;
|
||||
case 12:
|
||||
// inttoptr, bitcast -> intptr if bitcast is a ptr to ptr cast
|
||||
if (MidTy->isPointerTy() && DstTy->isPointerTy())
|
||||
}
|
||||
case 12: {
|
||||
// inttoptr, bitcast -> inttoptr if bitcast is a ptr to ptr cast
|
||||
// and the ptrs are to address spaces of the same size
|
||||
PointerType *MidPtrTy = dyn_cast<PointerType>(MidTy);
|
||||
PointerType *DstPtrTy = dyn_cast<PointerType>(DstTy);
|
||||
if (!MidPtrTy || !DstPtrTy)
|
||||
return 0;
|
||||
|
||||
if (MidPtrTy->getAddressSpace() == DstPtrTy->getAddressSpace())
|
||||
return firstOp;
|
||||
|
||||
if (MidIntPtrTy &&
|
||||
DstIntPtrTy &&
|
||||
MidIntPtrTy->getScalarSizeInBits() ==
|
||||
DstIntPtrTy->getScalarSizeInBits())
|
||||
return firstOp;
|
||||
return 0;
|
||||
}
|
||||
case 13: {
|
||||
// inttoptr, ptrtoint -> bitcast if SrcSize<=PtrSize and SrcSize==DstSize
|
||||
if (!MidIntPtrTy)
|
||||
|
@ -318,6 +318,7 @@ TEST(InstructionsTest, FPMathOperator) {
|
||||
TEST(InstructionsTest, isEliminableCastPair) {
|
||||
LLVMContext &C(getGlobalContext());
|
||||
|
||||
Type* Int16Ty = Type::getInt16Ty(C);
|
||||
Type* Int32Ty = Type::getInt32Ty(C);
|
||||
Type* Int64Ty = Type::getInt64Ty(C);
|
||||
Type* Int64PtrTy = Type::getInt64PtrTy(C);
|
||||
@ -329,11 +330,20 @@ TEST(InstructionsTest, isEliminableCastPair) {
|
||||
Int32Ty, 0, Int32Ty),
|
||||
CastInst::BitCast);
|
||||
|
||||
// Source and destination pointers have different sizes -> fail.
|
||||
// Source and destination have unknown sizes, but the same address space and
|
||||
// the intermediate int is the maximum pointer size -> bitcast
|
||||
EXPECT_EQ(CastInst::isEliminableCastPair(CastInst::PtrToInt,
|
||||
CastInst::IntToPtr,
|
||||
Int64PtrTy, Int64Ty, Int64PtrTy,
|
||||
Int32Ty, 0, Int64Ty),
|
||||
0, 0, 0),
|
||||
CastInst::BitCast);
|
||||
|
||||
// Source and destination have unknown sizes, but the same address space and
|
||||
// the intermediate int is not the maximum pointer size -> nothing
|
||||
EXPECT_EQ(CastInst::isEliminableCastPair(CastInst::PtrToInt,
|
||||
CastInst::IntToPtr,
|
||||
Int64PtrTy, Int32Ty, Int64PtrTy,
|
||||
0, 0, 0),
|
||||
0U);
|
||||
|
||||
// Middle pointer big enough -> bitcast.
|
||||
@ -349,7 +359,74 @@ TEST(InstructionsTest, isEliminableCastPair) {
|
||||
Int64Ty, Int64PtrTy, Int64Ty,
|
||||
0, Int32Ty, 0),
|
||||
0U);
|
||||
|
||||
|
||||
// Test that we don't eliminate bitcasts between different address spaces,
|
||||
// or if we don't have available pointer size information.
|
||||
DataLayout DL("e-p:32:32:32-p1:16:16:16-p2:64:64:64-i1:8:8-i8:8:8-i16:16:16"
|
||||
"-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64"
|
||||
"-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128");
|
||||
|
||||
Type* Int64PtrTyAS1 = Type::getInt64PtrTy(C, 1);
|
||||
Type* Int64PtrTyAS2 = Type::getInt64PtrTy(C, 2);
|
||||
|
||||
IntegerType *Int16SizePtr = DL.getIntPtrType(C, 1);
|
||||
IntegerType *Int64SizePtr = DL.getIntPtrType(C, 2);
|
||||
|
||||
// Fail since the ptr int types are not provided
|
||||
EXPECT_EQ(CastInst::isEliminableCastPair(CastInst::IntToPtr,
|
||||
CastInst::BitCast,
|
||||
Int16Ty, Int64PtrTyAS1, Int64PtrTyAS2,
|
||||
0, 0, 0),
|
||||
0U);
|
||||
|
||||
// Fail since the the bitcast is between different sized address spaces
|
||||
EXPECT_EQ(CastInst::isEliminableCastPair(
|
||||
CastInst::IntToPtr,
|
||||
CastInst::BitCast,
|
||||
Int16Ty, Int64PtrTyAS1, Int64PtrTyAS2,
|
||||
0, Int16SizePtr, Int64SizePtr),
|
||||
0U);
|
||||
|
||||
// Fail since the the bitcast is between different sized address spaces
|
||||
EXPECT_EQ(CastInst::isEliminableCastPair(CastInst::IntToPtr,
|
||||
CastInst::BitCast,
|
||||
Int16Ty, Int64PtrTyAS1, Int64PtrTyAS2,
|
||||
0, Int16SizePtr, Int64SizePtr),
|
||||
0U);
|
||||
|
||||
// Pass since the bitcast address spaces are the same
|
||||
EXPECT_EQ(CastInst::isEliminableCastPair(CastInst::IntToPtr,
|
||||
CastInst::BitCast,
|
||||
Int16Ty, Int64PtrTyAS1, Int64PtrTyAS1,
|
||||
0, 0, 0),
|
||||
CastInst::IntToPtr);
|
||||
|
||||
|
||||
// Fail without known pointer sizes and different address spaces
|
||||
EXPECT_EQ(CastInst::isEliminableCastPair(CastInst::BitCast,
|
||||
CastInst::PtrToInt,
|
||||
Int64PtrTyAS1, Int64PtrTyAS2, Int16Ty,
|
||||
0, 0, 0),
|
||||
0U);
|
||||
|
||||
// Pass since the address spaces are the same, even though the pointer sizes
|
||||
// are unknown
|
||||
EXPECT_EQ(CastInst::isEliminableCastPair(CastInst::BitCast,
|
||||
CastInst::PtrToInt,
|
||||
Int64PtrTyAS1, Int64PtrTyAS1, Int32Ty,
|
||||
0, 0, 0),
|
||||
Instruction::PtrToInt);
|
||||
|
||||
// Fail since the bitcast is the wrong size
|
||||
EXPECT_EQ(CastInst::isEliminableCastPair(CastInst::BitCast,
|
||||
CastInst::PtrToInt,
|
||||
Int64PtrTyAS1, Int64PtrTyAS2, Int64Ty,
|
||||
Int16SizePtr, Int64SizePtr, 0),
|
||||
0U);
|
||||
}
|
||||
|
||||
} // end anonymous namespace
|
||||
} // end namespace llvm
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user