teach phi translation of GEPs to simplify geps like 'gep x, 0'.
authorChris Lattner <sabre@nondot.org>
Fri, 27 Nov 2009 00:34:38 +0000 (00:34 +0000)
committerChris Lattner <sabre@nondot.org>
Fri, 27 Nov 2009 00:34:38 +0000 (00:34 +0000)
This allows us to compile the example from PR5313 into:

LBB1_2:                                                     ## %bb
incl %ecx
movb %al, (%rsi)
movslq %ecx, %rax
movb (%rdi,%rax), %al
testb %al, %al
jne LBB1_2

instead of:

LBB1_2:                                                     ## %bb
movslq %eax, %rcx
incl %eax
movb (%rdi,%rcx), %cl
movb %cl, (%rsi)
movslq %eax, %rcx
cmpb $0, (%rdi,%rcx)
jne LBB1_2

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@89981 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Analysis/MemoryDependenceAnalysis.cpp
test/Transforms/GVN/rle-phi-translate.ll

index 6bffca61e0e7d1bcff4b34cc9c43b39282aafb02..d7497514f511b68d8a235b7bcbf245520943a94b 100644 (file)
@@ -20,6 +20,7 @@
 #include "llvm/IntrinsicInst.h"
 #include "llvm/Function.h"
 #include "llvm/Analysis/AliasAnalysis.h"
+#include "llvm/Analysis/InstructionSimplify.h"
 #include "llvm/Analysis/MemoryBuiltins.h"
 #include "llvm/ADT/Statistic.h"
 #include "llvm/ADT/STLExtras.h"
@@ -716,7 +717,8 @@ static bool isPHITranslatable(Instruction *Inst) {
 /// PHITranslateForPred - Given a computation that satisfied the
 /// isPHITranslatable predicate, see if we can translate the computation into
 /// the specified predecessor block.  If so, return that value.
-static Value *PHITranslateForPred(Instruction *Inst, BasicBlock *Pred) {
+static Value *PHITranslateForPred(Instruction *Inst, BasicBlock *Pred,
+                                  const TargetData *TD) {
   if (PHINode *PN = dyn_cast<PHINode>(Inst))
     return PN->getIncomingValueForBlock(Pred);
   
@@ -751,7 +753,9 @@ static Value *PHITranslateForPred(Instruction *Inst, BasicBlock *Pred) {
           GEPOps.back() = APHIOp = PN->getIncomingValueForBlock(Pred);
     }
     
-    // TODO: Simplify the GEP to handle 'gep x, 0' -> x etc.
+    // Simplify the GEP to handle 'gep x, 0' -> x etc.
+    if (Value *V = SimplifyGEPInst(&GEPOps[0], GEPOps.size(), TD))
+      return V;
     
     // Scan to see if we have this GEP available.
     for (Value::use_iterator UI = APHIOp->use_begin(), E = APHIOp->use_end();
@@ -926,7 +930,7 @@ getNonLocalPointerDepFromBB(Value *Pointer, uint64_t PointeeSize,
       
       for (BasicBlock **PI = PredCache->GetPreds(BB); *PI; ++PI) {
         BasicBlock *Pred = *PI;
-        Value *PredPtr = PHITranslateForPred(PtrInst, Pred);
+        Value *PredPtr = PHITranslateForPred(PtrInst, Pred, TD);
         
         // If PHI translation fails, bail out.
         if (PredPtr == 0)
index ac9e7aaedc85eab4a0e5707e6728f1babd2dbb0e..912f58064a26a64ddb8a3870fde70499d87e7686 100644 (file)
@@ -86,3 +86,29 @@ bb2:
        ret i32 %dv
 }
 
+; PR5313
+define i32 @test4(i1 %cond, i32* %b, i32* %c) nounwind {
+; CHECK: @test4
+entry:
+       br i1 %cond, label %bb, label %bb1
+
+bb:
+  store i32 4, i32* %b
+       br label %bb2
+
+bb1:
+  %c1 = getelementptr i32* %c, i32 7
+  store i32 82, i32* %c1
+       br label %bb2
+
+bb2:
+       %d = phi i32* [ %c, %bb1 ], [ %b, %bb ]
+       %i = phi i32 [ 7, %bb1 ], [ 0, %bb ]
+  %d1 = getelementptr i32* %d, i32 %i
+       %dv = load i32* %d1
+; CHECK: %dv = phi i32 [ 82, %bb1 ], [ 4, %bb ]
+; CHECK-NOT: load
+; CHECK: ret i32 %dv
+       ret i32 %dv
+}
+