Index: include/llvm/Analysis/ConstantFolding.h =================================================================== --- include/llvm/Analysis/ConstantFolding.h +++ include/llvm/Analysis/ConstantFolding.h @@ -71,6 +71,11 @@ 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. Index: lib/Analysis/ConstantFolding.cpp =================================================================== --- lib/Analysis/ConstantFolding.cpp +++ lib/Analysis/ConstantFolding.cpp @@ -1013,6 +1013,9 @@ 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 @@ 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(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(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,66 @@ return ConstantExpr::get(Opcode, LHS, RHS); } +Constant *llvm::ConstantFoldCastOperand(unsigned Opcode, Constant *C, + Type *DestTy, const DataLayout &DL) { + 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(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(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. Index: lib/Analysis/InstructionSimplify.cpp =================================================================== --- lib/Analysis/InstructionSimplify.cpp +++ lib/Analysis/InstructionSimplify.cpp @@ -3639,7 +3639,7 @@ static Value *SimplifyTruncInst(Value *Op, Type *Ty, const Query &Q, unsigned) { if (Constant *C = dyn_cast(Op)) - return ConstantFoldInstOperands(Instruction::Trunc, Ty, C, Q.DL, Q.TLI); + return ConstantFoldCastOperand(Instruction::Trunc, C, Ty, Q.DL); return nullptr; } Index: lib/CodeGen/MachineFunction.cpp =================================================================== --- lib/CodeGen/MachineFunction.cpp +++ lib/CodeGen/MachineFunction.cpp @@ -895,17 +895,17 @@ // the constant folding APIs to do this so that we get the benefit of // DataLayout. if (isa(A->getType())) - A = ConstantFoldInstOperands(Instruction::PtrToInt, IntTy, - const_cast(A), DL); + A = ConstantFoldCastOperand(Instruction::PtrToInt, + const_cast(A), IntTy, DL); else if (A->getType() != IntTy) - A = ConstantFoldInstOperands(Instruction::BitCast, IntTy, - const_cast(A), DL); + A = ConstantFoldCastOperand(Instruction::BitCast, const_cast(A), + IntTy, DL); if (isa(B->getType())) - B = ConstantFoldInstOperands(Instruction::PtrToInt, IntTy, - const_cast(B), DL); + B = ConstantFoldCastOperand(Instruction::PtrToInt, + const_cast(B), IntTy, DL); else if (B->getType() != IntTy) - B = ConstantFoldInstOperands(Instruction::BitCast, IntTy, - const_cast(B), DL); + B = ConstantFoldCastOperand(Instruction::BitCast, const_cast(B), + IntTy, DL); return A == B; }