aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Analysis/ConstantFolding.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Analysis/ConstantFolding.cpp')
-rwxr-xr-xllvm/lib/Analysis/ConstantFolding.cpp25
1 files changed, 14 insertions, 11 deletions
diff --git a/llvm/lib/Analysis/ConstantFolding.cpp b/llvm/lib/Analysis/ConstantFolding.cpp
index b744537..45c889c 100755
--- a/llvm/lib/Analysis/ConstantFolding.cpp
+++ b/llvm/lib/Analysis/ConstantFolding.cpp
@@ -329,6 +329,7 @@ bool llvm::IsConstantOffsetFromGlobal(Constant *C, GlobalValue *&GV,
// Look through ptr->int and ptr->ptr casts.
if (CE->getOpcode() == Instruction::PtrToInt ||
+ CE->getOpcode() == Instruction::PtrToAddr ||
CE->getOpcode() == Instruction::BitCast)
return IsConstantOffsetFromGlobal(CE->getOperand(0), GV, Offset, DL,
DSOEquiv);
@@ -1495,22 +1496,22 @@ Constant *llvm::ConstantFoldCastOperand(unsigned Opcode, Constant *C,
default:
llvm_unreachable("Missing case");
case Instruction::PtrToAddr:
- // TODO: Add some of the ptrtoint folds here as well.
- break;
case Instruction::PtrToInt:
if (auto *CE = dyn_cast<ConstantExpr>(C)) {
Constant *FoldedValue = nullptr;
- // If the input is a inttoptr, eliminate the pair. This requires knowing
+ // If the input is an inttoptr, eliminate the pair. This requires knowing
// the width of a pointer, so it can't be done in ConstantExpr::getCast.
if (CE->getOpcode() == Instruction::IntToPtr) {
- // zext/trunc the inttoptr to pointer size.
- FoldedValue = ConstantFoldIntegerCast(CE->getOperand(0),
- DL.getIntPtrType(CE->getType()),
+ // zext/trunc the inttoptr to pointer/address size.
+ Type *MidTy = Opcode == Instruction::PtrToInt
+ ? DL.getAddressType(CE->getType())
+ : DL.getIntPtrType(CE->getType());
+ FoldedValue = ConstantFoldIntegerCast(CE->getOperand(0), MidTy,
/*IsSigned=*/false, DL);
} else if (auto *GEP = dyn_cast<GEPOperator>(CE)) {
// If we have GEP, we can perform the following folds:
- // (ptrtoint (gep null, x)) -> x
- // (ptrtoint (gep (gep null, x), y) -> x + y, etc.
+ // (ptrtoint/ptrtoaddr (gep null, x)) -> x
+ // (ptrtoint/ptrtoaddr (gep (gep null, x), y) -> x + y, etc.
unsigned BitWidth = DL.getIndexTypeSizeInBits(GEP->getType());
APInt BaseOffset(BitWidth, 0);
auto *Base = cast<Constant>(GEP->stripAndAccumulateConstantOffsets(
@@ -1518,7 +1519,8 @@ Constant *llvm::ConstantFoldCastOperand(unsigned Opcode, Constant *C,
if (Base->isNullValue()) {
FoldedValue = ConstantInt::get(CE->getContext(), BaseOffset);
} else {
- // ptrtoint (gep i8, Ptr, (sub 0, V)) -> sub (ptrtoint Ptr), V
+ // ptrtoint/ptrtoaddr (gep i8, Ptr, (sub 0, V))
+ // -> sub (ptrtoint/ptrtoaddr Ptr), V
if (GEP->getNumIndices() == 1 &&
GEP->getSourceElementType()->isIntegerTy(8)) {
auto *Ptr = cast<Constant>(GEP->getPointerOperand());
@@ -1528,12 +1530,13 @@ Constant *llvm::ConstantFoldCastOperand(unsigned Opcode, Constant *C,
Sub->getOpcode() == Instruction::Sub &&
Sub->getOperand(0)->isNullValue())
FoldedValue = ConstantExpr::getSub(
- ConstantExpr::getPtrToInt(Ptr, IntIdxTy), Sub->getOperand(1));
+ ConstantExpr::getCast(Opcode, Ptr, IntIdxTy),
+ Sub->getOperand(1));
}
}
}
if (FoldedValue) {
- // Do a zext or trunc to get to the ptrtoint dest size.
+ // Do a zext or trunc to get to the ptrtoint/ptrtoaddr dest size.
return ConstantFoldIntegerCast(FoldedValue, DestTy, /*IsSigned=*/false,
DL);
}