[llvm-commits] [llvm] r92402 - in /llvm/trunk: lib/Transforms/Scalar/InstructionCombining.cpp test/Transforms/InstCombine/sub.ll

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


Author: lattner
Date: Fri Jan  1 16:42:29 2010
New Revision: 92402

URL: http://llvm.org/viewvc/llvm-project?rev=92402&view=rev
Log:
generalize the pointer difference optimization to handle
a constantexpr gep on the 'base' side of the expression.
This completes comment #4 in PR3351, which comes from
483.xalancbmk.

Modified:
    llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp
    llvm/trunk/test/Transforms/InstCombine/sub.ll

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

==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Fri Jan  1 16:42:29 2010
@@ -2770,21 +2770,57 @@
   // If LHS is a gep based on RHS or RHS is a gep based on LHS, we can optimize
   // this.
   bool Swapped;
-  GetElementPtrInst *GEP;
+  GetElementPtrInst *GEP = 0;
+  ConstantExpr *CstGEP = 0;
   
-  if ((GEP = dyn_cast<GetElementPtrInst>(LHS)) &&
-      GEP->getOperand(0) == RHS)
-    Swapped = false;
-  else if ((GEP = dyn_cast<GetElementPtrInst>(RHS)) &&
-           GEP->getOperand(0) == LHS)
-    Swapped = true;
-  else
-    return 0;
+  // TODO: Could also optimize &A[i] - &A[j] -> "i-j", and "&A.foo[i] - &A.foo".
+  // For now we require one side to be the base pointer "A" or a constant
+  // expression derived from it.
+  if (GetElementPtrInst *LHSGEP = dyn_cast<GetElementPtrInst>(LHS)) {
+    // (gep X, ...) - X
+    if (LHSGEP->getOperand(0) == RHS) {
+      GEP = LHSGEP;
+      Swapped = false;
+    } else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(RHS)) {
+      // (gep X, ...) - (ce_gep X, ...)
+      if (CE->getOpcode() == Instruction::GetElementPtr &&
+          LHSGEP->getOperand(0) == CE->getOperand(0)) {
+        CstGEP = CE;
+        GEP = LHSGEP;
+        Swapped = false;
+      }
+    }
+  }
   
-  // TODO: Could also optimize &A[i] - &A[j] -> "i-j".
+  if (GetElementPtrInst *RHSGEP = dyn_cast<GetElementPtrInst>(RHS)) {
+    // X - (gep X, ...)
+    if (RHSGEP->getOperand(0) == LHS) {
+      GEP = RHSGEP;
+      Swapped = true;
+    } else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(LHS)) {
+      // (ce_gep X, ...) - (gep X, ...)
+      if (CE->getOpcode() == Instruction::GetElementPtr &&
+          RHSGEP->getOperand(0) == CE->getOperand(0)) {
+        CstGEP = CE;
+        GEP = RHSGEP;
+        Swapped = true;
+      }
+    }
+  }
+  
+  if (GEP == 0)
+    return 0;
   
   // Emit the offset of the GEP and an intptr_t.
   Value *Result = EmitGEPOffset(GEP, *this);
+  
+  // If we had a constant expression GEP on the other side offsetting the
+  // pointer, subtract it from the offset we have.
+  if (CstGEP) {
+    Value *CstOffset = EmitGEPOffset(CstGEP, *this);
+    Result = Builder->CreateSub(Result, CstOffset);
+  }
+  
 
   // If we have p - gep(p, ...)  then we have to negate the result.
   if (Swapped)

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

==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/sub.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/sub.ll Fri Jan  1 16:42:29 2010
@@ -260,3 +260,16 @@
 ; CHECK-NEXT: ret i64 
 }
 
+
+define i64 @test25(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 (i16* getelementptr ([42 x i16]* @Arr, i64 1, i64 0) to i64)
+  ret i64 %G
+; CHECK: @test25
+; CHECK-NEXT: shl i64 %A, 1
+; CHECK-NEXT: add i64 {{.*}}, -84
+; CHECK-NEXT: ret i64 
+}
+
+





More information about the llvm-commits mailing list