Relax unsafe use check. If there is one unconditional use inside the loop then it...
authorDevang Patel <dpatel@apple.com>
Mon, 1 Oct 2007 18:12:58 +0000 (18:12 +0000)
committerDevang Patel <dpatel@apple.com>
Mon, 1 Oct 2007 18:12:58 +0000 (18:12 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@42493 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Transforms/Scalar/LICM.cpp
test/Transforms/LICM/2007-10-01-PromoteSafeValue.ll [new file with mode: 0644]

index e461c887ea2b36afd56fffe608c7d5fc0a1039da..e795aa9c0c5d39504f0b61bd58bceab05de5e310 100644 (file)
@@ -800,24 +800,15 @@ void LICM::FindPromotableValuesInLoop(
           break;
         }
 
-      // Do not promote null values because it may be unsafe to do so.
-      if (isa<ConstantPointerNull>(V))
-        PointerOk = false;
-
-      if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(V)) {
-        // If GEP base is NULL then the calculated address used by Store or
-        // Load instruction is invalid. Do not promote this value because
-        // it may expose load and store instruction that are covered by
-        // condition which may not yet folded.
-        if (isa<ConstantPointerNull>(GEP->getOperand(0)))
-          PointerOk = false;
-      }
-
-      // If value V use is not dominating loop exit then promoting
-      // it may expose unsafe load and store instructions unconditinally.
-      if (PointerOk)
+      // If one use of value V inside the loop is safe then it is OK to promote 
+      // this value. On the otherside if there is not any unsafe use inside the
+      // looop then also it is OK to  promote this value. Otherwise it is
+      // unsafe to promote this value.
+      if (PointerOk) {
+        bool oneSafeUse = false;
+        bool oneUnsafeUse = false;
         for(Value::use_iterator UI = V->use_begin(), UE = V->use_end();
-            UI != UE && PointerOk; ++UI) {
+            UI != UE; ++UI) {
           Instruction *Use = dyn_cast<Instruction>(*UI);
           if (!Use || !CurLoop->contains(Use->getParent()))
             continue;
@@ -825,16 +816,25 @@ void LICM::FindPromotableValuesInLoop(
                  ExitI = LoopExits.begin(), ExitE = LoopExits.end();
                ExitI != ExitE; ++ExitI) {
             Instruction *Ex = *ExitI;
-            if (!DT->dominates(Use, Ex)){
-              PointerOk = false;
+            if (!isa<PHINode>(Use) && DT->dominates(Use, Ex)) {
+              oneSafeUse = true;
               break;
             }
+            else 
+              oneUnsafeUse = true;
           }
-          
-          if (!PointerOk)
+
+          if (oneSafeUse)
             break;
         }
-      
+
+        if (oneSafeUse)
+          PointerOk = true;
+        else if (!oneUnsafeUse)
+          PointerOk = true;
+        else
+          PointerOk = false;
+      }
       
       if (PointerOk) {
         const Type *Ty = cast<PointerType>(V->getType())->getElementType();
diff --git a/test/Transforms/LICM/2007-10-01-PromoteSafeValue.ll b/test/Transforms/LICM/2007-10-01-PromoteSafeValue.ll
new file mode 100644 (file)
index 0000000..7359cc0
--- /dev/null
@@ -0,0 +1,21 @@
+; RUN: llvm-as < %s | opt -licm | llvm-dis | grep promoted
+; Promote value if at least one use is safe
+
+
+define i32 @f2(i32* %p, i8* %q) {
+entry:
+        br label %loop.head
+
+loop.head:              ; preds = %cond.true, %entry
+        store i32 20, i32* %p
+        %tmp3.i = icmp eq i8* null, %q            ; <i1> [#uses=1]
+        br i1 %tmp3.i, label %exit, label %cond.true
+        
+cond.true:              ; preds = %loop.head
+        store i32 40, i32* %p
+        br label %loop.head
+
+exit:           ; preds = %loop.head
+        ret i32 0
+}
+