[llvm-commits] [llvm] r140210 - in /llvm/trunk: lib/Transforms/Scalar/SCCP.cpp test/Transforms/SCCP/ipsccp-basic.ll

Eli Friedman eli.friedman at gmail.com
Tue Sep 20 16:28:51 PDT 2011


Author: efriedma
Date: Tue Sep 20 18:28:51 2011
New Revision: 140210

URL: http://llvm.org/viewvc/llvm-project?rev=140210&view=rev
Log:
Make sure IPSCCP never marks a tracked call as overdefined in SCCPSolver::ResolvedUndefsIn.  If we do, we can end up in a situation where a function is resolved to return a constant, but the caller is marked overdefined, which confuses the code later.

<rdar://problem/9956541> (again).


Modified:
    llvm/trunk/lib/Transforms/Scalar/SCCP.cpp
    llvm/trunk/test/Transforms/SCCP/ipsccp-basic.ll

Modified: llvm/trunk/lib/Transforms/Scalar/SCCP.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/SCCP.cpp?rev=140210&r1=140209&r2=140210&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/SCCP.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/SCCP.cpp Tue Sep 20 18:28:51 2011
@@ -1433,15 +1433,25 @@
       if (I->getType()->isVoidTy()) continue;
       
       if (StructType *STy = dyn_cast<StructType>(I->getType())) {
-        // Only a few things that can be structs matter for undef.  Just send
-        // all their results to overdefined.  We could be more precise than this
-        // but it isn't worth bothering.
-        if (!isa<ExtractValueInst>(I) && !isa<InsertValueInst>(I)) {
-          for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
-            LatticeVal &LV = getStructValueState(I, i);
-            if (LV.isUndefined())
-              markOverdefined(LV, I);
-          }
+        // Only a few things that can be structs matter for undef.
+
+        // Tracked calls must never be marked overdefined in ResolvedUndefsIn.
+        if (CallSite CS = CallSite(I))
+          if (Function *F = CS.getCalledFunction())
+            if (MRVFunctionsTracked.count(F))
+              continue;
+
+        // extractvalue and insertvalue don't need to be marked; they are
+        // tracked as precisely as their operands. 
+        if (isa<ExtractValueInst>(I) || isa<InsertValueInst>(I))
+          continue;
+
+        // Send the results of everything else to overdefined.  We could be
+        // more precise than this but it isn't worth bothering.
+        for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
+          LatticeVal &LV = getStructValueState(I, i);
+          if (LV.isUndefined())
+            markOverdefined(LV, I);
         }
         continue;
       }
@@ -1594,6 +1604,22 @@
           break;
         markOverdefined(I);
         return true;
+      case Instruction::Call:
+      case Instruction::Invoke: {
+        // There are two reasons a call can have an undef result
+        // 1. It could be tracked.
+        // 2. It could be constant-foldable.
+        // Because of the way we solve return values, tracked calls must
+        // never be marked overdefined in ResolvedUndefsIn.
+        if (Function *F = CallSite(I).getCalledFunction())
+          if (TrackedRetVals.count(F))
+            break;
+
+        // If the call is constant-foldable, we mark it overdefined because
+        // we do not know what return values are valid.
+        markOverdefined(I);
+        return true;
+      }
       default:
         // If we don't know what should happen here, conservatively mark it
         // overdefined.

Modified: llvm/trunk/test/Transforms/SCCP/ipsccp-basic.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/SCCP/ipsccp-basic.ll?rev=140210&r1=140209&r2=140210&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/SCCP/ipsccp-basic.ll (original)
+++ llvm/trunk/test/Transforms/SCCP/ipsccp-basic.ll Tue Sep 20 18:28:51 2011
@@ -209,3 +209,21 @@
 }
 
 declare i32 @__gxx_personality_v0(...)
+
+;;======================== test10
+
+define i32 @test10a() nounwind {
+entry:
+  %call = call i32 @test10b(i32 undef)
+  ret i32 %call
+; CHECK: define i32 @test10a
+; CHECK: ret i32 0
+}
+
+define internal i32 @test10b(i32 %x) nounwind {
+entry:
+  %r = and i32 %x, 1
+  ret i32 %r
+; CHECK: define internal i32 @test10b
+; CHECK: ret i32 undef
+}





More information about the llvm-commits mailing list