llvm.org GIT mirror llvm / 446cf94
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 Duncan Sands 7 years ago
5 changed file(s) with 61 addition(s) and 13 deletion(s). Raw diff Collapse all Expand all
593593 Type *SrcTy, ///< SrcTy of 1st cast
594594 Type *MidTy, ///< DstTy of 1st cast & SrcTy of 2nd cast
595595 Type *DstTy, ///< DstTy of 2nd cast
596 Type *IntPtrTy ///< Integer type corresponding to Ptr types, or null
596 Type *SrcIntPtrTy, ///< Integer type corresponding to Ptr SrcTy, or null
597 Type *MidIntPtrTy, ///< Integer type corresponding to Ptr MidTy, or null
598 Type *DstIntPtrTy ///< Integer type corresponding to Ptr DstTy, or null
597599 );
598600
599601 /// @brief Return the opcode of this CastInst
237237 // Get the opcodes of the two Cast instructions
238238 Instruction::CastOps firstOp = Instruction::CastOps(CI->getOpcode());
239239 Instruction::CastOps secondOp = Instruction::CastOps(opcode);
240 Type *SrcIntPtrTy = TD && SrcTy->isPtrOrPtrVectorTy() ?
241 TD->getIntPtrType(SrcTy) : 0;
242 Type *MidIntPtrTy = TD && MidTy->isPtrOrPtrVectorTy() ?
243 TD->getIntPtrType(MidTy) : 0;
244 Type *DstIntPtrTy = TD && DstTy->isPtrOrPtrVectorTy() ?
245 TD->getIntPtrType(DstTy) : 0;
240246 unsigned Res = CastInst::isEliminableCastPair(firstOp, secondOp, SrcTy, MidTy,
241 DstTy,
242 TD ? TD->getIntPtrType(DstTy) : 0);
247 DstTy, SrcIntPtrTy, MidIntPtrTy,
248 DstIntPtrTy);
243249
244250 // We don't want to form an inttoptr or ptrtoint that converts to an integer
245251 // type that differs from the pointer size.
246 if ((Res == Instruction::IntToPtr &&
247 (!TD || SrcTy != TD->getIntPtrType(DstTy))) ||
248 (Res == Instruction::PtrToInt &&
249 (!TD || DstTy != TD->getIntPtrType(SrcTy))))
252 if ((Res == Instruction::IntToPtr && SrcTy != DstIntPtrTy) ||
253 (Res == Instruction::PtrToInt && DstTy != SrcIntPtrTy))
250254 Res = 0;
251255
252256 return Instruction::CastOps(Res);
8686 Instruction::CastOps firstOp = Instruction::CastOps(Op->getOpcode());
8787 Instruction::CastOps secondOp = Instruction::CastOps(opc);
8888
89 // Assume that pointers are never more than 64 bits wide.
90 IntegerType *FakeIntPtrTy = Type::getInt64Ty(DstTy->getContext());
91
8992 // Let CastInst::isEliminableCastPair do the heavy lifting.
9093 return CastInst::isEliminableCastPair(firstOp, secondOp, SrcTy, MidTy, DstTy,
91 Type::getInt64Ty(DstTy->getContext()));
94 FakeIntPtrTy, FakeIntPtrTy,
95 FakeIntPtrTy);
9296 }
9397
9498 static Constant *FoldBitCast(Constant *V, Type *DestTy) {
21402140 /// If no such cast is permited, the function returns 0.
21412141 unsigned CastInst::isEliminableCastPair(
21422142 Instruction::CastOps firstOp, Instruction::CastOps secondOp,
2143 Type *SrcTy, Type *MidTy, Type *DstTy, Type *IntPtrTy) {
2143 Type *SrcTy, Type *MidTy, Type *DstTy, Type *SrcIntPtrTy, Type *MidIntPtrTy,
2144 Type *DstIntPtrTy) {
21442145 // Define the 144 possibilities for these two cast instructions. The values
21452146 // in this matrix determine what to do in a given situation and select the
21462147 // case in the switch below. The rows correspond to firstOp, the columns
22432244 return 0;
22442245 case 7: {
22452246 // ptrtoint, inttoptr -> bitcast (ptr -> ptr) if int size is >= ptr size
2246 if (!IntPtrTy)
2247 if (!SrcIntPtrTy || DstIntPtrTy != SrcIntPtrTy)
22472248 return 0;
2248 unsigned PtrSize = IntPtrTy->getScalarSizeInBits();
2249 unsigned PtrSize = SrcIntPtrTy->getScalarSizeInBits();
22492250 unsigned MidSize = MidTy->getScalarSizeInBits();
22502251 if (MidSize >= PtrSize)
22512252 return Instruction::BitCast;
22842285 return 0;
22852286 case 13: {
22862287 // inttoptr, ptrtoint -> bitcast if SrcSize<=PtrSize and SrcSize==DstSize
2287 if (!IntPtrTy)
2288 if (!MidIntPtrTy)
22882289 return 0;
2289 unsigned PtrSize = IntPtrTy->getScalarSizeInBits();
2290 unsigned PtrSize = MidIntPtrTy->getScalarSizeInBits();
22902291 unsigned SrcSize = SrcTy->getScalarSizeInBits();
22912292 unsigned DstSize = DstTy->getScalarSizeInBits();
22922293 if (SrcSize <= PtrSize && SrcSize == DstSize)
242242 delete I;
243243 }
244244
245
246 TEST(InstructionsTest, isEliminableCastPair) {
247 LLVMContext &C(getGlobalContext());
248
249 Type* Int32Ty = Type::getInt32Ty(C);
250 Type* Int64Ty = Type::getInt64Ty(C);
251 Type* Int64PtrTy = Type::getInt64PtrTy(C);
252
253 // Source and destination pointers have same size -> bitcast.
254 EXPECT_EQ(CastInst::isEliminableCastPair(CastInst::PtrToInt,
255 CastInst::IntToPtr,
256 Int64PtrTy, Int64Ty, Int64PtrTy,
257 Int32Ty, 0, Int32Ty),
258 CastInst::BitCast);
259
260 // Source and destination pointers have different sizes -> fail.
261 EXPECT_EQ(CastInst::isEliminableCastPair(CastInst::PtrToInt,
262 CastInst::IntToPtr,
263 Int64PtrTy, Int64Ty, Int64PtrTy,
264 Int32Ty, 0, Int64Ty),
265 0U);
266
267 // Middle pointer big enough -> bitcast.
268 EXPECT_EQ(CastInst::isEliminableCastPair(CastInst::IntToPtr,
269 CastInst::PtrToInt,
270 Int64Ty, Int64PtrTy, Int64Ty,
271 0, Int64Ty, 0),
272 CastInst::BitCast);
273
274 // Middle pointer too small -> fail.
275 EXPECT_EQ(CastInst::isEliminableCastPair(CastInst::IntToPtr,
276 CastInst::PtrToInt,
277 Int64Ty, Int64PtrTy, Int64Ty,
278 0, Int32Ty, 0),
279 0U);
280 }
281
245282 } // end anonymous namespace
246283 } // end namespace llvm