[PATCH] D149427: Handle `select` in programUndefinedIfPoison.

Justin Lebar via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Thu Apr 27 23:32:13 PDT 2023


jlebar created this revision.
Herald added a subscriber: hiraditya.
Herald added a project: All.
jlebar requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

If both the true and false operands of a `select` are poison, then the `select`
is poison.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D149427

Files:
  llvm/lib/Analysis/ValueTracking.cpp
  llvm/unittests/Analysis/ValueTrackingTest.cpp


Index: llvm/unittests/Analysis/ValueTrackingTest.cpp
===================================================================
--- llvm/unittests/Analysis/ValueTrackingTest.cpp
+++ llvm/unittests/Analysis/ValueTrackingTest.cpp
@@ -982,6 +982,20 @@
   EXPECT_EQ(programUndefinedIfPoison(A), true);
 }
 
+TEST_F(ValueTrackingTest, programUndefinedIfPoisonSelect) {
+  parseAssembly("declare i32 @any_num()"
+                "define void @test(i1 %Cond) {\n"
+                "  %A = call i32 @any_num()\n"
+                "  %B = add i32 %A, 1\n"
+                "  %C = select i1 %Cond, i32 %A, i32 %B\n"
+                "  udiv i32 1, %C"
+                "  ret void\n"
+                "}\n");
+  // If A is poison, B is also poison, and therefore C is poison regardless of
+  // the value of %Cond.
+  EXPECT_EQ(programUndefinedIfPoison(A), true);
+}
+
 TEST_F(ValueTrackingTest, programUndefinedIfUndefOrPoison) {
   parseAssembly("declare i32 @any_num()"
                 "define void @test(i32 %mask) {\n"
Index: llvm/lib/Analysis/ValueTracking.cpp
===================================================================
--- llvm/lib/Analysis/ValueTracking.cpp
+++ llvm/lib/Analysis/ValueTracking.cpp
@@ -6701,7 +6701,7 @@
   return ::isGuaranteedNotToBeUndefOrPoison(V, AC, CtxI, DT, Depth, true);
 }
 
-/// Return true if undefined behavior would provable be executed on the path to
+/// Return true if undefined behavior would provably be executed on the path to
 /// OnPathTo if Root produced a posion result.  Note that this doesn't say
 /// anything about whether OnPathTo is actually executed or whether Root is
 /// actually poison.  This can be used to assess whether a new use of Root can
@@ -7035,6 +7035,15 @@
           break;
         }
       }
+
+      // Special handling for select, which returns poison if its operand 0 is
+      // poison (handled in the loop above) *or* if both its true/false operands
+      // are poison (handled here).
+      if (I.getOpcode() == Instruction::Select &&
+          YieldsPoison.count(I.getOperand(1)) &&
+          YieldsPoison.count(I.getOperand(2))) {
+        YieldsPoison.insert(&I);
+      }
     }
 
     BB = BB->getSingleSuccessor();


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D149427.517811.patch
Type: text/x-patch
Size: 2199 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20230428/a06af259/attachment.bin>


More information about the llvm-commits mailing list