summaryrefslogtreecommitdiffstats
path: root/llvm
diff options
context:
space:
mode:
Diffstat (limited to 'llvm')
-rw-r--r--llvm/include/llvm/Analysis/ConstantFolding.h5
-rw-r--r--llvm/lib/Analysis/ConstantFolding.cpp116
-rw-r--r--llvm/lib/Analysis/InstructionSimplify.cpp2
-rw-r--r--llvm/lib/CodeGen/MachineFunction.cpp16
4 files changed, 78 insertions, 61 deletions
diff --git a/llvm/include/llvm/Analysis/ConstantFolding.h b/llvm/include/llvm/Analysis/ConstantFolding.h
index 6b4d57c8842..0137dad368a 100644
--- a/llvm/include/llvm/Analysis/ConstantFolding.h
+++ b/llvm/include/llvm/Analysis/ConstantFolding.h
@@ -71,6 +71,11 @@ ConstantFoldCompareInstOperands(unsigned Predicate, Constant *LHS,
Constant *ConstantFoldBinaryOpOperands(unsigned Opcode, Constant *LHS,
Constant *RHS, const DataLayout &DL);
+/// \brief Attempt to constant fold a cast with the specified operand. If it
+/// fails, it returns a constant expression of the specified operand.
+Constant *ConstantFoldCastOperand(unsigned Opcode, Constant *C, Type *DestTy,
+ const DataLayout &DL);
+
/// ConstantFoldInsertValueInstruction - Attempt to constant fold an insertvalue
/// instruction with the specified operands and indices. The constant result is
/// returned if successful; if not, null is returned.
diff --git a/llvm/lib/Analysis/ConstantFolding.cpp b/llvm/lib/Analysis/ConstantFolding.cpp
index 3ddc10a080b..95c56b96dea 100644
--- a/llvm/lib/Analysis/ConstantFolding.cpp
+++ b/llvm/lib/Analysis/ConstantFolding.cpp
@@ -1013,6 +1013,9 @@ Constant *llvm::ConstantFoldInstOperands(unsigned Opcode, Type *DestTy,
if (Instruction::isBinaryOp(Opcode))
return ConstantFoldBinaryOpOperands(Opcode, Ops[0], Ops[1], DL);
+ if (Instruction::isCast(Opcode))
+ return ConstantFoldCastOperand(Opcode, Ops[0], DestTy, DL);
+
switch (Opcode) {
default: return nullptr;
case Instruction::ICmp:
@@ -1022,58 +1025,6 @@ Constant *llvm::ConstantFoldInstOperands(unsigned Opcode, Type *DestTy,
if (canConstantFoldCallTo(F))
return ConstantFoldCall(F, Ops.slice(0, Ops.size() - 1), TLI);
return nullptr;
- case Instruction::PtrToInt:
- // If the input is a inttoptr, eliminate the pair. This requires knowing
- // the width of a pointer, so it can't be done in ConstantExpr::getCast.
- if (ConstantExpr *CE = dyn_cast<ConstantExpr>(Ops[0])) {
- if (CE->getOpcode() == Instruction::IntToPtr) {
- Constant *Input = CE->getOperand(0);
- unsigned InWidth = Input->getType()->getScalarSizeInBits();
- unsigned PtrWidth = DL.getPointerTypeSizeInBits(CE->getType());
- if (PtrWidth < InWidth) {
- Constant *Mask =
- ConstantInt::get(CE->getContext(),
- APInt::getLowBitsSet(InWidth, PtrWidth));
- Input = ConstantExpr::getAnd(Input, Mask);
- }
- // Do a zext or trunc to get to the dest size.
- return ConstantExpr::getIntegerCast(Input, DestTy, false);
- }
- }
- 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 and the address spaces are the same.
- // This requires knowing the width of a pointer, so it can't be done in
- // ConstantExpr::getCast.
- if (ConstantExpr *CE = dyn_cast<ConstantExpr>(Ops[0])) {
- if (CE->getOpcode() == Instruction::PtrToInt) {
- Constant *SrcPtr = CE->getOperand(0);
- unsigned SrcPtrSize = DL.getPointerTypeSizeInBits(SrcPtr->getType());
- unsigned MidIntSize = CE->getType()->getScalarSizeInBits();
-
- if (MidIntSize >= SrcPtrSize) {
- unsigned SrcAS = SrcPtr->getType()->getPointerAddressSpace();
- if (SrcAS == DestTy->getPointerAddressSpace())
- return FoldBitCast(CE->getOperand(0), DestTy, DL);
- }
- }
- }
-
- return ConstantExpr::getCast(Opcode, Ops[0], DestTy);
- case Instruction::Trunc:
- case Instruction::ZExt:
- case Instruction::SExt:
- case Instruction::FPTrunc:
- case Instruction::FPExt:
- case Instruction::UIToFP:
- case Instruction::SIToFP:
- case Instruction::FPToUI:
- case Instruction::FPToSI:
- case Instruction::AddrSpaceCast:
- return ConstantExpr::getCast(Opcode, Ops[0], DestTy);
- case Instruction::BitCast:
- return FoldBitCast(Ops[0], DestTy, DL);
case Instruction::Select:
return ConstantExpr::getSelect(Ops[0], Ops[1], Ops[2]);
case Instruction::ExtractElement:
@@ -1188,6 +1139,67 @@ Constant *llvm::ConstantFoldBinaryOpOperands(unsigned Opcode, Constant *LHS,
return ConstantExpr::get(Opcode, LHS, RHS);
}
+Constant *llvm::ConstantFoldCastOperand(unsigned Opcode, Constant *C,
+ Type *DestTy, const DataLayout &DL) {
+ assert(Instruction::isCast(Opcode));
+ switch (Opcode) {
+ default:
+ llvm_unreachable("Missing case");
+ case Instruction::PtrToInt:
+ // If the input is a inttoptr, eliminate the pair. This requires knowing
+ // the width of a pointer, so it can't be done in ConstantExpr::getCast.
+ if (ConstantExpr *CE = dyn_cast<ConstantExpr>(C)) {
+ if (CE->getOpcode() == Instruction::IntToPtr) {
+ Constant *Input = CE->getOperand(0);
+ unsigned InWidth = Input->getType()->getScalarSizeInBits();
+ unsigned PtrWidth = DL.getPointerTypeSizeInBits(CE->getType());
+ if (PtrWidth < InWidth) {
+ Constant *Mask =
+ ConstantInt::get(CE->getContext(),
+ APInt::getLowBitsSet(InWidth, PtrWidth));
+ Input = ConstantExpr::getAnd(Input, Mask);
+ }
+ // Do a zext or trunc to get to the dest size.
+ return ConstantExpr::getIntegerCast(Input, DestTy, false);
+ }
+ }
+ return ConstantExpr::getCast(Opcode, C, 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 and the address spaces are the same.
+ // This requires knowing the width of a pointer, so it can't be done in
+ // ConstantExpr::getCast.
+ if (ConstantExpr *CE = dyn_cast<ConstantExpr>(C)) {
+ if (CE->getOpcode() == Instruction::PtrToInt) {
+ Constant *SrcPtr = CE->getOperand(0);
+ unsigned SrcPtrSize = DL.getPointerTypeSizeInBits(SrcPtr->getType());
+ unsigned MidIntSize = CE->getType()->getScalarSizeInBits();
+
+ if (MidIntSize >= SrcPtrSize) {
+ unsigned SrcAS = SrcPtr->getType()->getPointerAddressSpace();
+ if (SrcAS == DestTy->getPointerAddressSpace())
+ return FoldBitCast(CE->getOperand(0), DestTy, DL);
+ }
+ }
+ }
+
+ return ConstantExpr::getCast(Opcode, C, DestTy);
+ case Instruction::Trunc:
+ case Instruction::ZExt:
+ case Instruction::SExt:
+ case Instruction::FPTrunc:
+ case Instruction::FPExt:
+ case Instruction::UIToFP:
+ case Instruction::SIToFP:
+ case Instruction::FPToUI:
+ case Instruction::FPToSI:
+ case Instruction::AddrSpaceCast:
+ return ConstantExpr::getCast(Opcode, C, DestTy);
+ case Instruction::BitCast:
+ return FoldBitCast(C, DestTy, DL);
+ }
+}
+
/// Given a constant and a getelementptr constantexpr, return the constant value
/// being addressed by the constant expression, or null if something is funny
/// and we can't decide.
diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp
index 1f4c329f2cf..fc21a14cb10 100644
--- a/llvm/lib/Analysis/InstructionSimplify.cpp
+++ b/llvm/lib/Analysis/InstructionSimplify.cpp
@@ -3639,7 +3639,7 @@ static Value *SimplifyPHINode(PHINode *PN, const Query &Q) {
static Value *SimplifyTruncInst(Value *Op, Type *Ty, const Query &Q, unsigned) {
if (Constant *C = dyn_cast<Constant>(Op))
- return ConstantFoldInstOperands(Instruction::Trunc, Ty, C, Q.DL, Q.TLI);
+ return ConstantFoldCastOperand(Instruction::Trunc, C, Ty, Q.DL);
return nullptr;
}
diff --git a/llvm/lib/CodeGen/MachineFunction.cpp b/llvm/lib/CodeGen/MachineFunction.cpp
index f6604f38722..0170236553e 100644
--- a/llvm/lib/CodeGen/MachineFunction.cpp
+++ b/llvm/lib/CodeGen/MachineFunction.cpp
@@ -895,17 +895,17 @@ static bool CanShareConstantPoolEntry(const Constant *A, const Constant *B,
// the constant folding APIs to do this so that we get the benefit of
// DataLayout.
if (isa<PointerType>(A->getType()))
- A = ConstantFoldInstOperands(Instruction::PtrToInt, IntTy,
- const_cast<Constant *>(A), DL);
+ A = ConstantFoldCastOperand(Instruction::PtrToInt,
+ const_cast<Constant *>(A), IntTy, DL);
else if (A->getType() != IntTy)
- A = ConstantFoldInstOperands(Instruction::BitCast, IntTy,
- const_cast<Constant *>(A), DL);
+ A = ConstantFoldCastOperand(Instruction::BitCast, const_cast<Constant *>(A),
+ IntTy, DL);
if (isa<PointerType>(B->getType()))
- B = ConstantFoldInstOperands(Instruction::PtrToInt, IntTy,
- const_cast<Constant *>(B), DL);
+ B = ConstantFoldCastOperand(Instruction::PtrToInt,
+ const_cast<Constant *>(B), IntTy, DL);
else if (B->getType() != IntTy)
- B = ConstantFoldInstOperands(Instruction::BitCast, IntTy,
- const_cast<Constant *>(B), DL);
+ B = ConstantFoldCastOperand(Instruction::BitCast, const_cast<Constant *>(B),
+ IntTy, DL);
return A == B;
}
OpenPOWER on IntegriCloud