summaryrefslogtreecommitdiff
path: root/lib/IR/Instructions.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/IR/Instructions.cpp')
-rw-r--r--lib/IR/Instructions.cpp57
1 files changed, 47 insertions, 10 deletions
diff --git a/lib/IR/Instructions.cpp b/lib/IR/Instructions.cpp
index 665fe66ccc..49a9e8c18d 100644
--- a/lib/IR/Instructions.cpp
+++ b/lib/IR/Instructions.cpp
@@ -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)