]> granicus.if.org Git - llvm/commitdiff
[ValueTracking] Don't delete assumes of side-effectful instructions
authorHal Finkel <hfinkel@anl.gov>
Mon, 14 Aug 2017 17:11:43 +0000 (17:11 +0000)
committerHal Finkel <hfinkel@anl.gov>
Mon, 14 Aug 2017 17:11:43 +0000 (17:11 +0000)
ValueTracking has to strike a balance when attempting to propagate information
backwards from assumes, because if the information is trivially propagated
backwards, it can appear to LLVM that the assumption is known to be true, and
therefore can be removed.

This is sound (because an assumption has no semantic effect except for causing
UB), but prevents the assume from allowing further optimizations.

The isEphemeralValueOf check exists to try and prevent this issue by not
removing the source of an assumption. This tries to make it a little bit more
general to handle the case of side-effectful instructions, such as in

  %0 = call i1 @get_val()
  %1 = xor i1 %0, true
  call void @llvm.assume(i1 %1)

Patch by Ariel Ben-Yehuda, thanks!

Differential Revision: https://reviews.llvm.org/D36590

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

lib/Analysis/ValueTracking.cpp
test/Analysis/ValueTracking/assume.ll

index b81bf9ec9d1afcbb5b3cc404c04fa44cd71fb174..d73e5f251192b6f08db633c0ee73e43cd04c2f39 100644 (file)
@@ -384,13 +384,13 @@ static bool isEphemeralValueOf(const Instruction *I, const Value *E) {
       if (V == E)
         return true;
 
-      EphValues.insert(V);
-      if (const User *U = dyn_cast<User>(V))
-        for (User::const_op_iterator J = U->op_begin(), JE = U->op_end();
-             J != JE; ++J) {
-          if (isSafeToSpeculativelyExecute(*J))
-            WorkSet.push_back(*J);
-        }
+      if (V == I || isSafeToSpeculativelyExecute(V)) {
+       EphValues.insert(V);
+       if (const User *U = dyn_cast<User>(V))
+         for (User::const_op_iterator J = U->op_begin(), JE = U->op_end();
+              J != JE; ++J)
+           WorkSet.push_back(*J);
+      }
     }
   }
 
index fe0ee53eb4162b7ccebe1313a2010d70d351c767..87ac74c2ad1a47b89e81919f0619ed4eaae370b7 100644 (file)
@@ -18,5 +18,16 @@ define i32 @assume_add(i32 %a, i32 %b) {
   ret i32 %t3
 }
 
-declare void @llvm.assume(i1)
 
+define void @assume_not() {
+; CHECK-LABEL: @assume_not(
+entry-block:
+  %0 = call i1 @get_val()
+; CHECK: call void @llvm.assume
+  %1 = xor i1 %0, true
+  call void @llvm.assume(i1 %1)
+  ret void
+}
+
+declare i1 @get_val()
+declare void @llvm.assume(i1)