mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-07-21 02:29:22 +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(
|
foldConstantCastPair(
|
||||||
unsigned opc, ///< opcode of the second cast constant expression
|
unsigned opc, ///< opcode of the second cast constant expression
|
||||||
ConstantExpr *Op, ///< the first 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(Op && Op->isCast() && "Can't fold cast of cast without a cast!");
|
||||||
assert(DstTy && DstTy->isFirstClassType() && "Invalid cast destination type");
|
assert(DstTy && DstTy->isFirstClassType() && "Invalid cast destination type");
|
||||||
@ -87,13 +87,14 @@ foldConstantCastPair(
|
|||||||
Instruction::CastOps firstOp = Instruction::CastOps(Op->getOpcode());
|
Instruction::CastOps firstOp = Instruction::CastOps(Op->getOpcode());
|
||||||
Instruction::CastOps secondOp = Instruction::CastOps(opc);
|
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());
|
IntegerType *FakeIntPtrTy = Type::getInt64Ty(DstTy->getContext());
|
||||||
|
|
||||||
// Let CastInst::isEliminableCastPair do the heavy lifting.
|
// Let CastInst::isEliminableCastPair do the heavy lifting.
|
||||||
return CastInst::isEliminableCastPair(firstOp, secondOp, SrcTy, MidTy, DstTy,
|
return CastInst::isEliminableCastPair(firstOp, secondOp, SrcTy, MidTy, DstTy,
|
||||||
FakeIntPtrTy, FakeIntPtrTy,
|
0, FakeIntPtrTy, 0);
|
||||||
FakeIntPtrTy);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static Constant *FoldBitCast(Constant *V, Type *DestTy) {
|
static Constant *FoldBitCast(Constant *V, Type *DestTy) {
|
||||||
|
@ -2224,12 +2224,20 @@ unsigned CastInst::isEliminableCastPair(
|
|||||||
if (SrcTy->isFloatingPointTy())
|
if (SrcTy->isFloatingPointTy())
|
||||||
return secondOp;
|
return secondOp;
|
||||||
return 0;
|
return 0;
|
||||||
case 7: {
|
case 7: {
|
||||||
// ptrtoint, inttoptr -> bitcast (ptr -> ptr) if int size is >= ptr size
|
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)
|
if (!SrcIntPtrTy || DstIntPtrTy != SrcIntPtrTy)
|
||||||
return 0;
|
return 0;
|
||||||
unsigned PtrSize = SrcIntPtrTy->getScalarSizeInBits();
|
unsigned PtrSize = SrcIntPtrTy->getScalarSizeInBits();
|
||||||
unsigned MidSize = MidTy->getScalarSizeInBits();
|
|
||||||
if (MidSize >= PtrSize)
|
if (MidSize >= PtrSize)
|
||||||
return Instruction::BitCast;
|
return Instruction::BitCast;
|
||||||
return 0;
|
return 0;
|
||||||
@ -2254,17 +2262,46 @@ unsigned CastInst::isEliminableCastPair(
|
|||||||
if (SrcTy == DstTy)
|
if (SrcTy == DstTy)
|
||||||
return Instruction::BitCast;
|
return Instruction::BitCast;
|
||||||
return 0; // If the types are not the same we can't eliminate it.
|
return 0; // If the types are not the same we can't eliminate it.
|
||||||
case 11:
|
case 11: {
|
||||||
// bitcast followed by ptrtoint is allowed as long as the bitcast
|
// bitcast followed by ptrtoint is allowed as long as the bitcast is a
|
||||||
// is a pointer to pointer cast.
|
// pointer to pointer cast, and the pointers are the same size.
|
||||||
if (SrcTy->isPointerTy() && MidTy->isPointerTy())
|
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;
|
return secondOp;
|
||||||
|
|
||||||
|
if (!SrcIntPtrTy || !MidIntPtrTy)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (SrcIntPtrTy->getScalarSizeInBits() ==
|
||||||
|
MidIntPtrTy->getScalarSizeInBits())
|
||||||
|
return secondOp;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
case 12:
|
}
|
||||||
// inttoptr, bitcast -> intptr if bitcast is a ptr to ptr cast
|
case 12: {
|
||||||
if (MidTy->isPointerTy() && DstTy->isPointerTy())
|
// 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 firstOp;
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
case 13: {
|
case 13: {
|
||||||
// inttoptr, ptrtoint -> bitcast if SrcSize<=PtrSize and SrcSize==DstSize
|
// inttoptr, ptrtoint -> bitcast if SrcSize<=PtrSize and SrcSize==DstSize
|
||||||
if (!MidIntPtrTy)
|
if (!MidIntPtrTy)
|
||||||
|
@ -318,6 +318,7 @@ TEST(InstructionsTest, FPMathOperator) {
|
|||||||
TEST(InstructionsTest, isEliminableCastPair) {
|
TEST(InstructionsTest, isEliminableCastPair) {
|
||||||
LLVMContext &C(getGlobalContext());
|
LLVMContext &C(getGlobalContext());
|
||||||
|
|
||||||
|
Type* Int16Ty = Type::getInt16Ty(C);
|
||||||
Type* Int32Ty = Type::getInt32Ty(C);
|
Type* Int32Ty = Type::getInt32Ty(C);
|
||||||
Type* Int64Ty = Type::getInt64Ty(C);
|
Type* Int64Ty = Type::getInt64Ty(C);
|
||||||
Type* Int64PtrTy = Type::getInt64PtrTy(C);
|
Type* Int64PtrTy = Type::getInt64PtrTy(C);
|
||||||
@ -329,11 +330,20 @@ TEST(InstructionsTest, isEliminableCastPair) {
|
|||||||
Int32Ty, 0, Int32Ty),
|
Int32Ty, 0, Int32Ty),
|
||||||
CastInst::BitCast);
|
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,
|
EXPECT_EQ(CastInst::isEliminableCastPair(CastInst::PtrToInt,
|
||||||
CastInst::IntToPtr,
|
CastInst::IntToPtr,
|
||||||
Int64PtrTy, Int64Ty, Int64PtrTy,
|
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);
|
0U);
|
||||||
|
|
||||||
// Middle pointer big enough -> bitcast.
|
// Middle pointer big enough -> bitcast.
|
||||||
@ -349,7 +359,74 @@ TEST(InstructionsTest, isEliminableCastPair) {
|
|||||||
Int64Ty, Int64PtrTy, Int64Ty,
|
Int64Ty, Int64PtrTy, Int64Ty,
|
||||||
0, Int32Ty, 0),
|
0, Int32Ty, 0),
|
||||||
0U);
|
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 anonymous namespace
|
||||||
} // end namespace llvm
|
} // end namespace llvm
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user