[llvm-commits] [llvm] r92401 - in /llvm/trunk: include/llvm/Support/PatternMatch.h lib/Transforms/Scalar/InstructionCombining.cpp test/Transforms/InstCombine/sub.ll

Chris Lattner sabre at nondot.org
Fri Jan 1 14:29:12 PST 2010


Author: lattner
Date: Fri Jan  1 16:29:12 2010
New Revision: 92401

URL: http://llvm.org/viewvc/llvm-project?rev=92401&view=rev
Log:
teach instcombine to optimize pointer difference idioms involving constant
expressions.  This is a step towards comment #4 in PR3351.

Modified:
    llvm/trunk/include/llvm/Support/PatternMatch.h
    llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp
    llvm/trunk/test/Transforms/InstCombine/sub.ll

Modified: llvm/trunk/include/llvm/Support/PatternMatch.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/PatternMatch.h?rev=92401&r1=92400&r2=92401&view=diff

==============================================================================
--- llvm/trunk/include/llvm/Support/PatternMatch.h (original)
+++ llvm/trunk/include/llvm/Support/PatternMatch.h Fri Jan  1 16:29:12 2010
@@ -437,7 +437,7 @@
 // Matchers for CastInst classes
 //
 
-template<typename Op_t, typename Class>
+template<typename Op_t, unsigned Opcode>
 struct CastClass_match {
   Op_t Op;
 
@@ -445,17 +445,28 @@
 
   template<typename OpTy>
   bool match(OpTy *V) {
-    if (Class *I = dyn_cast<Class>(V))
-      return Op.match(I->getOperand(0));
+    if (CastInst *I = dyn_cast<CastInst>(V))
+      return I->getOpcode() == Opcode && Op.match(I->getOperand(0));
+    if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V))
+      return CE->getOpcode() == Opcode && Op.match(CE->getOperand(0));
     return false;
   }
 };
 
-template<typename Class, typename OpTy>
-inline CastClass_match<OpTy, Class> m_Cast(const OpTy &Op) {
-  return CastClass_match<OpTy, Class>(Op);
+/// m_PtrToInt
+template<typename OpTy>
+inline CastClass_match<OpTy, Instruction::PtrToInt>
+m_PtrToInt(const OpTy &Op) {
+  return CastClass_match<OpTy, Instruction::PtrToInt>(Op);
 }
 
+/// m_Trunc
+template<typename OpTy>
+inline CastClass_match<OpTy, Instruction::Trunc>
+m_Trunc(const OpTy &Op) {
+  return CastClass_match<OpTy, Instruction::Trunc>(Op);
+}
+  
 
 //===----------------------------------------------------------------------===//
 // Matchers for unary operators

Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp?rev=92401&r1=92400&r2=92401&view=diff

==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Fri Jan  1 16:29:12 2010
@@ -2950,20 +2950,16 @@
   //  &A[10] - &A[0]: we should compile this to "10".
   if (TD) {
     Value *LHSOp, *RHSOp;
-    if (match(Op0, m_Cast<PtrToIntInst>(m_Value(LHSOp))) &&
-        match(Op1, m_Cast<PtrToIntInst>(m_Value(RHSOp))))
+    if (match(Op0, m_PtrToInt(m_Value(LHSOp))) &&
+        match(Op1, m_PtrToInt(m_Value(RHSOp))))
       if (Value *Res = OptimizePointerDifference(LHSOp, RHSOp, I.getType()))
         return ReplaceInstUsesWith(I, Res);
     
     // trunc(p)-trunc(q) -> trunc(p-q)
-    if (TruncInst *LHST = dyn_cast<TruncInst>(Op0))
-      if (TruncInst *RHST = dyn_cast<TruncInst>(Op1))
-        if (PtrToIntInst *LHS = dyn_cast<PtrToIntInst>(LHST->getOperand(0)))
-          if (PtrToIntInst *RHS = dyn_cast<PtrToIntInst>(RHST->getOperand(0)))
-            if (Value *Res = OptimizePointerDifference(LHS->getOperand(0),
-                                                       RHS->getOperand(0),
-                                                       I.getType()))
-              return ReplaceInstUsesWith(I, Res);
+    if (match(Op0, m_Trunc(m_PtrToInt(m_Value(LHSOp)))) &&
+        match(Op1, m_Trunc(m_PtrToInt(m_Value(RHSOp)))))
+      if (Value *Res = OptimizePointerDifference(LHSOp, RHSOp, I.getType()))
+        return ReplaceInstUsesWith(I, Res);
   }
   
   return 0;

Modified: llvm/trunk/test/Transforms/InstCombine/sub.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/sub.ll?rev=92401&r1=92400&r2=92401&view=diff

==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/sub.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/sub.ll Fri Jan  1 16:29:12 2010
@@ -248,3 +248,15 @@
 ; CHECK-NEXT: ret i64 
 }
 
+ at Arr = external global [42 x i16]
+
+define i64 @test24b(i8* %P, i64 %A){
+  %B = getelementptr inbounds [42 x i16]* @Arr, i64 0, i64 %A
+  %C = ptrtoint i16* %B to i64
+  %G = sub i64 %C, ptrtoint ([42 x i16]* @Arr to i64)
+  ret i64 %G
+; CHECK: @test24b
+; CHECK-NEXT: shl i64 %A, 1
+; CHECK-NEXT: ret i64 
+}
+





More information about the llvm-commits mailing list