mirror of
https://github.com/RPCS3/llvm.git
synced 2025-02-06 02:29:51 +00:00
Fix isEliminableCastPair to work correctly in the presence of pointers
with different sizes. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@167018 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
92b469971e
commit
446cf94cdb
@ -594,7 +594,9 @@ public:
|
||||
Type *SrcTy, ///< SrcTy of 1st cast
|
||||
Type *MidTy, ///< DstTy of 1st cast & SrcTy of 2nd cast
|
||||
Type *DstTy, ///< DstTy of 2nd cast
|
||||
Type *IntPtrTy ///< Integer type corresponding to Ptr types, or null
|
||||
Type *SrcIntPtrTy, ///< Integer type corresponding to Ptr SrcTy, or null
|
||||
Type *MidIntPtrTy, ///< Integer type corresponding to Ptr MidTy, or null
|
||||
Type *DstIntPtrTy ///< Integer type corresponding to Ptr DstTy, or null
|
||||
);
|
||||
|
||||
/// @brief Return the opcode of this CastInst
|
||||
|
@ -238,16 +238,20 @@ isEliminableCastPair(
|
||||
// Get the opcodes of the two Cast instructions
|
||||
Instruction::CastOps firstOp = Instruction::CastOps(CI->getOpcode());
|
||||
Instruction::CastOps secondOp = Instruction::CastOps(opcode);
|
||||
Type *SrcIntPtrTy = TD && SrcTy->isPtrOrPtrVectorTy() ?
|
||||
TD->getIntPtrType(SrcTy) : 0;
|
||||
Type *MidIntPtrTy = TD && MidTy->isPtrOrPtrVectorTy() ?
|
||||
TD->getIntPtrType(MidTy) : 0;
|
||||
Type *DstIntPtrTy = TD && DstTy->isPtrOrPtrVectorTy() ?
|
||||
TD->getIntPtrType(DstTy) : 0;
|
||||
unsigned Res = CastInst::isEliminableCastPair(firstOp, secondOp, SrcTy, MidTy,
|
||||
DstTy,
|
||||
TD ? TD->getIntPtrType(DstTy) : 0);
|
||||
DstTy, SrcIntPtrTy, MidIntPtrTy,
|
||||
DstIntPtrTy);
|
||||
|
||||
// We don't want to form an inttoptr or ptrtoint that converts to an integer
|
||||
// type that differs from the pointer size.
|
||||
if ((Res == Instruction::IntToPtr &&
|
||||
(!TD || SrcTy != TD->getIntPtrType(DstTy))) ||
|
||||
(Res == Instruction::PtrToInt &&
|
||||
(!TD || DstTy != TD->getIntPtrType(SrcTy))))
|
||||
if ((Res == Instruction::IntToPtr && SrcTy != DstIntPtrTy) ||
|
||||
(Res == Instruction::PtrToInt && DstTy != SrcIntPtrTy))
|
||||
Res = 0;
|
||||
|
||||
return Instruction::CastOps(Res);
|
||||
|
@ -87,9 +87,13 @@ foldConstantCastPair(
|
||||
Instruction::CastOps firstOp = Instruction::CastOps(Op->getOpcode());
|
||||
Instruction::CastOps secondOp = Instruction::CastOps(opc);
|
||||
|
||||
// Assume that pointers are never more than 64 bits wide.
|
||||
IntegerType *FakeIntPtrTy = Type::getInt64Ty(DstTy->getContext());
|
||||
|
||||
// Let CastInst::isEliminableCastPair do the heavy lifting.
|
||||
return CastInst::isEliminableCastPair(firstOp, secondOp, SrcTy, MidTy, DstTy,
|
||||
Type::getInt64Ty(DstTy->getContext()));
|
||||
FakeIntPtrTy, FakeIntPtrTy,
|
||||
FakeIntPtrTy);
|
||||
}
|
||||
|
||||
static Constant *FoldBitCast(Constant *V, Type *DestTy) {
|
||||
|
@ -2141,7 +2141,8 @@ bool CastInst::isNoopCast(const DataLayout &DL) const {
|
||||
/// If no such cast is permited, the function returns 0.
|
||||
unsigned CastInst::isEliminableCastPair(
|
||||
Instruction::CastOps firstOp, Instruction::CastOps secondOp,
|
||||
Type *SrcTy, Type *MidTy, Type *DstTy, Type *IntPtrTy) {
|
||||
Type *SrcTy, Type *MidTy, Type *DstTy, Type *SrcIntPtrTy, Type *MidIntPtrTy,
|
||||
Type *DstIntPtrTy) {
|
||||
// Define the 144 possibilities for these two cast instructions. The values
|
||||
// in this matrix determine what to do in a given situation and select the
|
||||
// case in the switch below. The rows correspond to firstOp, the columns
|
||||
@ -2244,9 +2245,9 @@ unsigned CastInst::isEliminableCastPair(
|
||||
return 0;
|
||||
case 7: {
|
||||
// ptrtoint, inttoptr -> bitcast (ptr -> ptr) if int size is >= ptr size
|
||||
if (!IntPtrTy)
|
||||
if (!SrcIntPtrTy || DstIntPtrTy != SrcIntPtrTy)
|
||||
return 0;
|
||||
unsigned PtrSize = IntPtrTy->getScalarSizeInBits();
|
||||
unsigned PtrSize = SrcIntPtrTy->getScalarSizeInBits();
|
||||
unsigned MidSize = MidTy->getScalarSizeInBits();
|
||||
if (MidSize >= PtrSize)
|
||||
return Instruction::BitCast;
|
||||
@ -2285,9 +2286,9 @@ unsigned CastInst::isEliminableCastPair(
|
||||
return 0;
|
||||
case 13: {
|
||||
// inttoptr, ptrtoint -> bitcast if SrcSize<=PtrSize and SrcSize==DstSize
|
||||
if (!IntPtrTy)
|
||||
if (!MidIntPtrTy)
|
||||
return 0;
|
||||
unsigned PtrSize = IntPtrTy->getScalarSizeInBits();
|
||||
unsigned PtrSize = MidIntPtrTy->getScalarSizeInBits();
|
||||
unsigned SrcSize = SrcTy->getScalarSizeInBits();
|
||||
unsigned DstSize = DstTy->getScalarSizeInBits();
|
||||
if (SrcSize <= PtrSize && SrcSize == DstSize)
|
||||
|
@ -243,5 +243,42 @@ TEST(InstructionsTest, FPMathOperator) {
|
||||
delete I;
|
||||
}
|
||||
|
||||
|
||||
TEST(InstructionsTest, isEliminableCastPair) {
|
||||
LLVMContext &C(getGlobalContext());
|
||||
|
||||
Type* Int32Ty = Type::getInt32Ty(C);
|
||||
Type* Int64Ty = Type::getInt64Ty(C);
|
||||
Type* Int64PtrTy = Type::getInt64PtrTy(C);
|
||||
|
||||
// Source and destination pointers have same size -> bitcast.
|
||||
EXPECT_EQ(CastInst::isEliminableCastPair(CastInst::PtrToInt,
|
||||
CastInst::IntToPtr,
|
||||
Int64PtrTy, Int64Ty, Int64PtrTy,
|
||||
Int32Ty, 0, Int32Ty),
|
||||
CastInst::BitCast);
|
||||
|
||||
// Source and destination pointers have different sizes -> fail.
|
||||
EXPECT_EQ(CastInst::isEliminableCastPair(CastInst::PtrToInt,
|
||||
CastInst::IntToPtr,
|
||||
Int64PtrTy, Int64Ty, Int64PtrTy,
|
||||
Int32Ty, 0, Int64Ty),
|
||||
0U);
|
||||
|
||||
// Middle pointer big enough -> bitcast.
|
||||
EXPECT_EQ(CastInst::isEliminableCastPair(CastInst::IntToPtr,
|
||||
CastInst::PtrToInt,
|
||||
Int64Ty, Int64PtrTy, Int64Ty,
|
||||
0, Int64Ty, 0),
|
||||
CastInst::BitCast);
|
||||
|
||||
// Middle pointer too small -> fail.
|
||||
EXPECT_EQ(CastInst::isEliminableCastPair(CastInst::IntToPtr,
|
||||
CastInst::PtrToInt,
|
||||
Int64Ty, Int64PtrTy, Int64Ty,
|
||||
0, Int32Ty, 0),
|
||||
0U);
|
||||
}
|
||||
|
||||
} // end anonymous namespace
|
||||
} // end namespace llvm
|
||||
|
Loading…
x
Reference in New Issue
Block a user