[llvm] r276777 - [InstSimplify] Cast folding can be made more generic

David Majnemer via llvm-commits llvm-commits at lists.llvm.org
Tue Jul 26 10:58:06 PDT 2016


Author: majnemer
Date: Tue Jul 26 12:58:05 2016
New Revision: 276777

URL: http://llvm.org/viewvc/llvm-project?rev=276777&view=rev
Log:
[InstSimplify] Cast folding can be made more generic

Use isEliminableCastPair to determine if a pair of casts are foldable.

Modified:
    llvm/trunk/include/llvm/Analysis/InstructionSimplify.h
    llvm/trunk/lib/Analysis/InstructionSimplify.cpp
    llvm/trunk/test/Transforms/GVN/pr14166.ll

Modified: llvm/trunk/include/llvm/Analysis/InstructionSimplify.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/InstructionSimplify.h?rev=276777&r1=276776&r2=276777&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Analysis/InstructionSimplify.h (original)
+++ llvm/trunk/include/llvm/Analysis/InstructionSimplify.h Tue Jul 26 12:58:05 2016
@@ -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.
 

Modified: llvm/trunk/lib/Analysis/InstructionSimplify.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/InstructionSimplify.cpp?rev=276777&r1=276776&r2=276777&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/InstructionSimplify.cpp (original)
+++ llvm/trunk/lib/Analysis/InstructionSimplify.cpp Tue Jul 26 12:58:05 2016
@@ -69,8 +69,8 @@ static Value *SimplifyCmpInst(unsigned,
                               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
       // 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 *P
   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<Constant>(Op))
-    return ConstantFoldCastOperand(Instruction::Trunc, C, Ty, Q.DL);
+    return ConstantFoldCastOperand(CastOpc, C, Ty, Q.DL);
 
-  // trunc([zs]ext(x)) -> x if the trunc undoes the work of the [zs]ext.
-  if (auto *CI = dyn_cast<CastInst>(Op))
-    if (isa<ZExtInst>(CI) || isa<SExtInst>(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<Constant>(Op))
-    return ConstantFoldCastOperand(Instruction::BitCast, C, Ty, Q.DL);
+  if (auto *CI = dyn_cast<CastInst>(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<Instruction::CastOps>(CI->getOpcode());
+      auto SecondOp = static_cast<Instruction::CastOps>(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<BitCastInst>(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(Instruc
                           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;
   }
 

Modified: llvm/trunk/test/Transforms/GVN/pr14166.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/GVN/pr14166.ll?rev=276777&r1=276776&r2=276777&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/GVN/pr14166.ll (original)
+++ llvm/trunk/test/Transforms/GVN/pr14166.ll Tue Jul 26 12:58:05 2016
@@ -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>*)




More information about the llvm-commits mailing list