diff options
Diffstat (limited to 'llvm')
-rw-r--r-- | llvm/include/llvm/Analysis/ConstantFolding.h | 5 | ||||
-rw-r--r-- | llvm/lib/Analysis/ConstantFolding.cpp | 116 | ||||
-rw-r--r-- | llvm/lib/Analysis/InstructionSimplify.cpp | 2 | ||||
-rw-r--r-- | llvm/lib/CodeGen/MachineFunction.cpp | 16 |
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; } |