From 6774d612d4e9e0ec7a694390ba39f2d5e8b833f6 Mon Sep 17 00:00:00 2001 From: David Majnemer Date: Tue, 26 Jul 2016 17:58:05 +0000 Subject: [PATCH] [InstSimplify] Cast folding can be made more generic Use isEliminableCastPair to determine if a pair of casts are foldable. llvm-svn: 276777 --- llvm/include/llvm/Analysis/InstructionSimplify.h | 20 ++---- llvm/lib/Analysis/InstructionSimplify.cpp | 89 ++++++++++++------------ llvm/test/Transforms/GVN/pr14166.ll | 3 +- 3 files changed, 51 insertions(+), 61 deletions(-) diff --git a/llvm/include/llvm/Analysis/InstructionSimplify.h b/llvm/include/llvm/Analysis/InstructionSimplify.h index 06d7d80..47d6118 100644 --- a/llvm/include/llvm/Analysis/InstructionSimplify.h +++ b/llvm/include/llvm/Analysis/InstructionSimplify.h @@ -238,19 +238,13 @@ namespace llvm { AssumptionCache *AC = nullptr, const Instruction *CxtI = nullptr); - /// Given operands for an TruncInst, fold the result or return null. - Value *SimplifyTruncInst(Value *Op, Type *Ty, const DataLayout &DL, - const TargetLibraryInfo *TLI = nullptr, - const DominatorTree *DT = nullptr, - AssumptionCache *AC = nullptr, - const Instruction *CxtI = nullptr); - - /// Given operands for an BitCastInst, fold the result or return null. - Value *SimplifyBitCastInst(Value *Op, Type *Ty, const DataLayout &DL, - const TargetLibraryInfo *TLI = nullptr, - const DominatorTree *DT = nullptr, - AssumptionCache *AC = nullptr, - const Instruction *CxtI = nullptr); + /// Given operands for a CastInst, fold the result or return null. + Value *SimplifyCastInst(unsigned CastOpc, Value *Op, Type *Ty, + const DataLayout &DL, + const TargetLibraryInfo *TLI = nullptr, + const DominatorTree *DT = nullptr, + AssumptionCache *AC = nullptr, + const Instruction *CxtI = nullptr); //=== Helper functions for higher up the class hierarchy. diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp index 8fde9c7..5b723e5 100644 --- a/llvm/lib/Analysis/InstructionSimplify.cpp +++ b/llvm/lib/Analysis/InstructionSimplify.cpp @@ -69,8 +69,8 @@ static Value *SimplifyCmpInst(unsigned, Value *, Value *, const Query &, unsigned); static Value *SimplifyOrInst(Value *, Value *, const Query &, unsigned); static Value *SimplifyXorInst(Value *, Value *, const Query &, unsigned); -static Value *SimplifyTruncInst(Value *, Type *, const Query &, unsigned); -static Value *SimplifyBitCastInst(Value *, Type *, const Query &, unsigned); +static Value *SimplifyCastInst(unsigned, Value *, Type *, + const Query &, unsigned); /// For a boolean type, or a vector of boolean type, return false, or /// a vector with every element false, as appropriate for the type. @@ -748,7 +748,8 @@ static Value *SimplifySubInst(Value *Op0, Value *Op1, bool isNSW, bool isNUW, // See if "V === X - Y" simplifies. if (Value *V = SimplifyBinOp(Instruction::Sub, X, Y, Q, MaxRecurse-1)) // It does! Now see if "trunc V" simplifies. - if (Value *W = SimplifyTruncInst(V, Op0->getType(), Q, MaxRecurse-1)) + if (Value *W = SimplifyCastInst(Instruction::Trunc, V, Op0->getType(), + Q, MaxRecurse - 1)) // It does, return the simplified "trunc V". return W; @@ -3790,49 +3791,47 @@ static Value *SimplifyPHINode(PHINode *PN, const Query &Q) { return CommonValue; } -static Value *SimplifyTruncInst(Value *Op, Type *Ty, const Query &Q, unsigned) { +static Value *SimplifyCastInst(unsigned CastOpc, Value *Op, + Type *Ty, const Query &Q, unsigned MaxRecurse) { if (auto *C = dyn_cast(Op)) - return ConstantFoldCastOperand(Instruction::Trunc, C, Ty, Q.DL); - - // trunc([zs]ext(x)) -> x if the trunc undoes the work of the [zs]ext. - if (auto *CI = dyn_cast(Op)) - if (isa(CI) || isa(CI)) - if (CI->getOperand(0)->getType() == Ty) - return CI->getOperand(0); - - return nullptr; -} - -Value *llvm::SimplifyTruncInst(Value *Op, Type *Ty, const DataLayout &DL, - const TargetLibraryInfo *TLI, - const DominatorTree *DT, AssumptionCache *AC, - const Instruction *CxtI) { - return ::SimplifyTruncInst(Op, Ty, Query(DL, TLI, DT, AC, CxtI), - RecursionLimit); -} - -static Value *SimplifyBitCastInst(Value *Op, Type *Ty, const Query &Q, unsigned) { - if (auto *C = dyn_cast(Op)) - return ConstantFoldCastOperand(Instruction::BitCast, C, Ty, Q.DL); + return ConstantFoldCastOperand(CastOpc, C, Ty, Q.DL); + + if (auto *CI = dyn_cast(Op)) { + auto *Src = CI->getOperand(0); + Type *SrcTy = Src->getType(); + Type *MidTy = CI->getType(); + Type *DstTy = Ty; + if (Src->getType() == Ty) { + auto FirstOp = static_cast(CI->getOpcode()); + auto SecondOp = static_cast(CastOpc); + Type *SrcIntPtrTy = + SrcTy->isPtrOrPtrVectorTy() ? Q.DL.getIntPtrType(SrcTy) : nullptr; + Type *MidIntPtrTy = + MidTy->isPtrOrPtrVectorTy() ? Q.DL.getIntPtrType(MidTy) : nullptr; + Type *DstIntPtrTy = + DstTy->isPtrOrPtrVectorTy() ? Q.DL.getIntPtrType(DstTy) : nullptr; + if (CastInst::isEliminableCastPair(FirstOp, SecondOp, SrcTy, MidTy, DstTy, + SrcIntPtrTy, MidIntPtrTy, + DstIntPtrTy) == Instruction::BitCast) + return Src; + } + } // bitcast x -> x - if (Op->getType() == Ty) - return Op; - - // bitcast(bitcast x) -> x - if (auto *BC = dyn_cast(Op)) - if (BC->getOperand(0)->getType() == Ty) - return BC->getOperand(0); + if (CastOpc == Instruction::BitCast) + if (Op->getType() == Ty) + return Op; return nullptr; } -Value *llvm::SimplifyBitCastInst(Value *Op, Type *Ty, const DataLayout &DL, - const TargetLibraryInfo *TLI, - const DominatorTree *DT, AssumptionCache *AC, - const Instruction *CxtI) { - return ::SimplifyBitCastInst(Op, Ty, Query(DL, TLI, DT, AC, CxtI), - RecursionLimit); +Value *llvm::SimplifyCastInst(unsigned CastOpc, Value *Op, Type *Ty, + const DataLayout &DL, + const TargetLibraryInfo *TLI, + const DominatorTree *DT, AssumptionCache *AC, + const Instruction *CxtI) { + return ::SimplifyCastInst(CastOpc, Op, Ty, Query(DL, TLI, DT, AC, CxtI), + RecursionLimit); } //=== Helper functions for higher up the class hierarchy. @@ -4301,13 +4300,11 @@ Value *llvm::SimplifyInstruction(Instruction *I, const DataLayout &DL, TLI, DT, AC, I); break; } - case Instruction::Trunc: - Result = - SimplifyTruncInst(I->getOperand(0), I->getType(), DL, TLI, DT, AC, I); - break; - case Instruction::BitCast: - Result = - SimplifyBitCastInst(I->getOperand(0), I->getType(), DL, TLI, DT, AC, I); +#define HANDLE_CAST_INST(num, opc, clas) case Instruction::opc: +#include "llvm/IR/Instruction.def" +#undef HANDLE_CAST_INST + Result = SimplifyCastInst(I->getOpcode(), I->getOperand(0), I->getType(), + DL, TLI, DT, AC, I); break; } diff --git a/llvm/test/Transforms/GVN/pr14166.ll b/llvm/test/Transforms/GVN/pr14166.ll index 2e77496..c652360 100644 --- a/llvm/test/Transforms/GVN/pr14166.ll +++ b/llvm/test/Transforms/GVN/pr14166.ll @@ -17,8 +17,7 @@ define <2 x i32> @test1() { ; CHECK: %v3 = inttoptr <2 x i32> %v2 to <2 x i8*> ; CHECK: %v4 = bitcast <2 x i32>* %v1 to <2 x i8*>* ; CHECK: store <2 x i8*> %v3, <2 x i8*>* %v4 -; CHECK: %1 = ptrtoint <2 x i8*> %v3 to <2 x i32> -; CHECK: ret <2 x i32> %1 +; CHECK: ret <2 x i32> %v2 } declare void @anything(<2 x i32>*) -- 2.7.4