diff options
Diffstat (limited to 'llvm/lib/IR/ConstantFold.cpp')
| -rw-r--r-- | llvm/lib/IR/ConstantFold.cpp | 34 |
1 files changed, 34 insertions, 0 deletions
diff --git a/llvm/lib/IR/ConstantFold.cpp b/llvm/lib/IR/ConstantFold.cpp index 6a9ef2efa321..c77f47c2ed99 100644 --- a/llvm/lib/IR/ConstantFold.cpp +++ b/llvm/lib/IR/ConstantFold.cpp @@ -126,6 +126,40 @@ Constant *llvm::ConstantFoldCastInstruction(unsigned opc, Constant *V, if (isa<PoisonValue>(V)) return PoisonValue::get(DestTy); + if (opc == Instruction::IntToPtr) { + // We can't fold inttoptr(0) to ConstantPointerNull without checking the + // target data layout. However, since data layout is not available here, we + // can't do this. + if (V->isZeroValue()) + return nullptr; + // If the input is a ptrtoint(0), we can fold it to the corresponding zero + // value pointer. + if (auto *CE = dyn_cast<ConstantExpr>(V)) { + if (CE->getOpcode() == Instruction::PtrToInt) { + if (CE->getOperand(0)->isZeroValue()) + return Constant::getZeroValue(DestTy); + } + } + } + if (opc == Instruction::PtrToInt) { + // Similarly, we can't fold ptrtoint(nullptr) to null. + if (V->isNullValue()) + return nullptr; + // If the input is a inttoptr(0), we can fold it to the corresponding + // zero value. + if (auto *CE = dyn_cast<ConstantExpr>(V)) { + if (CE->getOpcode() == Instruction::IntToPtr) { + if (CE->getOperand(0)->isZeroValue()) + return Constant::getZeroValue(DestTy); + } + } + } + // However, since the recent change of the semantic of `ptr addrspace(N) + // null`, we can fold address space cast of a nullptr to the corresponding + // nullptr in the destination address space. + if (opc == Instruction::AddrSpaceCast && V->isNullValue()) + return Constant::getNullValue(DestTy); + if (isa<UndefValue>(V)) { // zext(undef) = 0, because the top bits will be zero. // sext(undef) = 0, because the top bits will all be the same. |
