PR9634: Don't unconditionally tell the AliasSetTracker that the PreheaderLoad
authorEli Friedman <eli.friedman@gmail.com>
Thu, 7 Apr 2011 01:35:06 +0000 (01:35 +0000)
committerEli Friedman <eli.friedman@gmail.com>
Thu, 7 Apr 2011 01:35:06 +0000 (01:35 +0000)
is equivalent to any other relevant value; it isn't true in general.
If it is equivalent, the LoopPromoter will tell the AST the equivalence.
Also, delete the PreheaderLoad if it is unused.

Chris, since you were the last one to make major changes here, can you check
that this is sane?

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

lib/Transforms/Scalar/LICM.cpp
test/Analysis/BasicAA/store-promote.ll
test/Transforms/LICM/2007-10-01-PromoteSafeValue.ll
test/Transforms/LICM/2011-04-06-PromoteResultOfPromotion.ll [new file with mode: 0644]

index 6cf1bd3deb51a05f6eb8cc0c96bb2cfb8ea5509e..93de9cf002eb8b0392d970a32623254dde72bcdf 100644 (file)
@@ -743,30 +743,13 @@ void LICM::PromoteAliasSet(AliasSet &AS) {
                  Preheader->getTerminator());
   SSA.AddAvailableValue(Preheader, PreheaderLoad);
 
-  // Copy any value stored to or loaded from a must-alias of the pointer.
-  if (PreheaderLoad->getType()->isPointerTy()) {
-    Value *SomeValue;
-    if (LoadInst *LI = dyn_cast<LoadInst>(LoopUses[0]))
-      SomeValue = LI;
-    else
-      SomeValue = cast<StoreInst>(LoopUses[0])->getValueOperand();
-    
-    CurAST->copyValue(SomeValue, PreheaderLoad);
-  }
-
   // Rewrite all the loads in the loop and remember all the definitions from
   // stores in the loop.
   Promoter.run(LoopUses);
-  
-  // If the preheader load is itself a pointer, we need to tell alias analysis
-  // about the new pointer we created in the preheader block and about any PHI
-  // nodes that just got inserted.
-  if (PreheaderLoad->getType()->isPointerTy()) {
-    for (unsigned i = 0, e = NewPHIs.size(); i != e; ++i)
-      CurAST->copyValue(PreheaderLoad, NewPHIs[i]);
-  }
-  
-  // fwew, we're done!
+
+  // If the SSAUpdater didn't use the load in the preheader, just zap it now.
+  if (PreheaderLoad->use_empty())
+    PreheaderLoad->eraseFromParent();
 }
 
 
index 33d0f3a5449b95376de9b14bd7cafd29c695a869..0db805c3e21e3323cabb4c06fae5fef08246ad29 100644 (file)
@@ -24,7 +24,7 @@ Out:            ; preds = %Loop
         
 ; The Loop block should be empty after the load/store are promoted.
 ; CHECK:     @test1
-; CHECK:        load i32* @B
+; CHECK:        load i32* @A
 ; CHECK:      Loop:
 ; CHECK-NEXT:   br i1 %c, label %Out, label %Loop
 ; CHECK:      Out:
index 59f1dcbe2d7b12198ed7995a2ee75382e8f15195..e3d0d02edd9df0a1504706cb9a7fbfadd7e45887 100644 (file)
@@ -1,4 +1,4 @@
-; RUN: opt < %s -licm -S | grep promoted
+; RUN: opt < %s -licm -S | FileCheck %s
 ; Promote value if at least one use is safe
 
 
@@ -15,6 +15,8 @@ cond.true:              ; preds = %loop.head
         store i32 40, i32* %p
         br label %loop.head
 
+; CHECK: exit:
+; CHECK: store i32 20, i32* %p
 exit:           ; preds = %loop.head
         ret i32 0
 }
diff --git a/test/Transforms/LICM/2011-04-06-PromoteResultOfPromotion.ll b/test/Transforms/LICM/2011-04-06-PromoteResultOfPromotion.ll
new file mode 100644 (file)
index 0000000..86c2679
--- /dev/null
@@ -0,0 +1,37 @@
+; RUN: opt < %s -tbaa -licm -S | FileCheck %s
+; PR9634
+
+@g_58 = common global i32 0, align 4
+@g_116 = common global i32* null, align 8
+
+define void @f() nounwind {
+
+; CHECK: entry:
+; CHECK: alloca [9 x i16]
+; CHECK: load i32* @g_58
+; CHECK: br label %for.body
+
+entry:
+  %l_87.i = alloca [9 x i16], align 16
+  br label %for.body
+
+for.body:                                         ; preds = %entry, %for.inc
+  %inc12 = phi i32 [ 0, %entry ], [ %inc, %for.body ]
+  store i32* @g_58, i32** @g_116, align 8, !tbaa !0
+  %tmp2 = load i32** @g_116, align 8, !tbaa !0
+  %tmp3 = load i32* %tmp2, !tbaa !4
+  %or = or i32 %tmp3, 10
+  store i32 %or, i32* %tmp2, !tbaa !4
+  %inc = add nsw i32 %inc12, 1
+  %cmp = icmp slt i32 %inc, 4
+  br i1 %cmp, label %for.body, label %for.end
+
+for.end:                                          ; preds = %for.inc
+  ret void
+}
+
+!0 = metadata !{metadata !"any pointer", metadata !1}
+!1 = metadata !{metadata !"omnipotent char", metadata !2}
+!2 = metadata !{metadata !"Simple C/C++ TBAA", null}
+!3 = metadata !{metadata !"short", metadata !1}
+!4 = metadata !{metadata !"int", metadata !1}