diff --git a/lib/Analysis/ConstantFolding.cpp b/lib/Analysis/ConstantFolding.cpp index 1a0e4b410c3..d3d0eb61ec1 100644 --- a/lib/Analysis/ConstantFolding.cpp +++ b/lib/Analysis/ConstantFolding.cpp @@ -378,6 +378,19 @@ Constant *llvm::ConstantFoldInstOperands(unsigned Opcode, const Type *DestTy, } return ConstantExpr::getCast(Opcode, Ops[0], DestTy); case Instruction::IntToPtr: + // If the input is a ptrtoint, turn the pair into a ptr to ptr bitcast if + // the int size is >= the ptr size. This requires knowing the width of a + // pointer, so it can't be done in ConstantExpr::getCast. + if (ConstantExpr *CE = dyn_cast(Ops[0])) { + if (TD && CE->getOpcode() == Instruction::PtrToInt && + TD->getPointerSizeInBits() <= + CE->getType()->getPrimitiveSizeInBits()) { + Constant *Input = CE->getOperand(0); + Constant *C = FoldBitCast(Input, DestTy, *TD); + return C ? C : ConstantExpr::getBitCast(Input, DestTy); + } + } + return ConstantExpr::getCast(Opcode, Ops[0], DestTy); case Instruction::Trunc: case Instruction::ZExt: case Instruction::SExt: diff --git a/test/FrontendAda/constant_fold.ads b/test/FrontendAda/constant_fold.ads new file mode 100644 index 00000000000..6223e7cb64d --- /dev/null +++ b/test/FrontendAda/constant_fold.ads @@ -0,0 +1,4 @@ +-- RUN: %llvmgcc -S -emit-llvm %s -o - | not grep ptrtoint +package Constant_Fold is + Error : exception; +end;