aboutsummaryrefslogtreecommitdiff
path: root/llvm/unittests/Analysis/ValueTrackingTest.cpp
diff options
context:
space:
mode:
authorFlorian Hahn <flo@fhahn.com>2022-12-19 11:47:51 +0000
committerFlorian Hahn <flo@fhahn.com>2022-12-19 11:47:51 +0000
commit8a3efcd40b48543d5b77ff9d6e0d1950847e824e (patch)
treea98a70d166d481156cc1d0b55fe228b02af2d405 /llvm/unittests/Analysis/ValueTrackingTest.cpp
parent60228733726e25d011b1f9221e005732191cc077 (diff)
downloadllvm-8a3efcd40b48543d5b77ff9d6e0d1950847e824e.zip
llvm-8a3efcd40b48543d5b77ff9d6e0d1950847e824e.tar.gz
llvm-8a3efcd40b48543d5b77ff9d6e0d1950847e824e.tar.bz2
[ValueTracking] Consider single poison operands in propgatesPoison.
This patch updates propgatesPoison to take a Use as argument and propagatesPoison now returns true if the passed in operand causes the user to yield poison if the operand is poison This allows propagating poison if the condition of a select is poison. This helps improve results for programUndefinedIfUndefOrPoison. Reviewed By: nikic Differential Revision: https://reviews.llvm.org/D111643
Diffstat (limited to 'llvm/unittests/Analysis/ValueTrackingTest.cpp')
-rw-r--r--llvm/unittests/Analysis/ValueTrackingTest.cpp143
1 files changed, 83 insertions, 60 deletions
diff --git a/llvm/unittests/Analysis/ValueTrackingTest.cpp b/llvm/unittests/Analysis/ValueTrackingTest.cpp
index 7e59841..ef13052 100644
--- a/llvm/unittests/Analysis/ValueTrackingTest.cpp
+++ b/llvm/unittests/Analysis/ValueTrackingTest.cpp
@@ -847,68 +847,89 @@ TEST(ValueTracking, propagatesPoison) {
"i1 %cond, i8* %p) {\n";
std::string AsmTail = " ret void\n}";
// (propagates poison?, IR instruction)
- SmallVector<std::pair<bool, std::string>, 32> Data = {
- {true, "add i32 %x, %y"},
- {true, "add nsw nuw i32 %x, %y"},
- {true, "ashr i32 %x, %y"},
- {true, "lshr exact i32 %x, 31"},
- {true, "fadd float %fx, %fy"},
- {true, "fsub float %fx, %fy"},
- {true, "fmul float %fx, %fy"},
- {true, "fdiv float %fx, %fy"},
- {true, "frem float %fx, %fy"},
- {true, "fneg float %fx"},
- {true, "fcmp oeq float %fx, %fy"},
- {true, "icmp eq i32 %x, %y"},
- {true, "getelementptr i8, i8* %p, i32 %x"},
- {true, "getelementptr inbounds i8, i8* %p, i32 %x"},
- {true, "bitcast float %fx to i32"},
- {false, "select i1 %cond, i32 %x, i32 %y"},
- {false, "freeze i32 %x"},
- {true, "udiv i32 %x, %y"},
- {true, "urem i32 %x, %y"},
- {true, "sdiv exact i32 %x, %y"},
- {true, "srem i32 %x, %y"},
- {false, "call i32 @g(i32 %x)"},
- {true, "call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %x, i32 %y)"},
- {true, "call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %x, i32 %y)"},
- {true, "call {i32, i1} @llvm.smul.with.overflow.i32(i32 %x, i32 %y)"},
- {true, "call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %x, i32 %y)"},
- {true, "call {i32, i1} @llvm.usub.with.overflow.i32(i32 %x, i32 %y)"},
- {true, "call {i32, i1} @llvm.umul.with.overflow.i32(i32 %x, i32 %y)"},
- {false, "call float @llvm.sqrt.f32(float %fx)"},
- {false, "call float @llvm.powi.f32.i32(float %fx, i32 %x)"},
- {false, "call float @llvm.sin.f32(float %fx)"},
- {false, "call float @llvm.cos.f32(float %fx)"},
- {false, "call float @llvm.pow.f32(float %fx, float %fy)"},
- {false, "call float @llvm.exp.f32(float %fx)"},
- {false, "call float @llvm.exp2.f32(float %fx)"},
- {false, "call float @llvm.log.f32(float %fx)"},
- {false, "call float @llvm.log10.f32(float %fx)"},
- {false, "call float @llvm.log2.f32(float %fx)"},
- {false, "call float @llvm.fma.f32(float %fx, float %fx, float %fy)"},
- {false, "call float @llvm.fabs.f32(float %fx)"},
- {false, "call float @llvm.minnum.f32(float %fx, float %fy)"},
- {false, "call float @llvm.maxnum.f32(float %fx, float %fy)"},
- {false, "call float @llvm.minimum.f32(float %fx, float %fy)"},
- {false, "call float @llvm.maximum.f32(float %fx, float %fy)"},
- {false, "call float @llvm.copysign.f32(float %fx, float %fy)"},
- {false, "call float @llvm.floor.f32(float %fx)"},
- {false, "call float @llvm.ceil.f32(float %fx)"},
- {false, "call float @llvm.trunc.f32(float %fx)"},
- {false, "call float @llvm.rint.f32(float %fx)"},
- {false, "call float @llvm.nearbyint.f32(float %fx)"},
- {false, "call float @llvm.round.f32(float %fx)"},
- {false, "call float @llvm.roundeven.f32(float %fx)"},
- {false, "call i32 @llvm.lround.f32(float %fx)"},
- {false, "call i64 @llvm.llround.f32(float %fx)"},
- {false, "call i32 @llvm.lrint.f32(float %fx)"},
- {false, "call i64 @llvm.llrint.f32(float %fx)"},
- {false, "call float @llvm.fmuladd.f32(float %fx, float %fx, float %fy)"}};
+ SmallVector<std::tuple<bool, std::string, unsigned>, 32> Data = {
+ {true, "add i32 %x, %y", 0},
+ {true, "add i32 %x, %y", 1},
+ {true, "add nsw nuw i32 %x, %y", 0},
+ {true, "add nsw nuw i32 %x, %y", 1},
+ {true, "ashr i32 %x, %y", 0},
+ {true, "ashr i32 %x, %y", 1},
+ {true, "lshr exact i32 %x, 31", 0},
+ {true, "lshr exact i32 %x, 31", 1},
+ {true, "fadd float %fx, %fy", 0},
+ {true, "fadd float %fx, %fy", 1},
+ {true, "fsub float %fx, %fy", 0},
+ {true, "fsub float %fx, %fy", 1},
+ {true, "fmul float %fx, %fy", 0},
+ {true, "fmul float %fx, %fy", 1},
+ {true, "fdiv float %fx, %fy", 0},
+ {true, "fdiv float %fx, %fy", 1},
+ {true, "frem float %fx, %fy", 0},
+ {true, "frem float %fx, %fy", 1},
+ {true, "fneg float %fx", 0},
+ {true, "fcmp oeq float %fx, %fy", 0},
+ {true, "fcmp oeq float %fx, %fy", 1},
+ {true, "icmp eq i32 %x, %y", 0},
+ {true, "icmp eq i32 %x, %y", 1},
+ {true, "getelementptr i8, i8* %p, i32 %x", 0},
+ {true, "getelementptr i8, i8* %p, i32 %x", 1},
+ {true, "getelementptr inbounds i8, i8* %p, i32 %x", 0},
+ {true, "getelementptr inbounds i8, i8* %p, i32 %x", 1},
+ {true, "bitcast float %fx to i32", 0},
+ {true, "select i1 %cond, i32 %x, i32 %y", 0},
+ {false, "select i1 %cond, i32 %x, i32 %y", 1},
+ {false, "select i1 %cond, i32 %x, i32 %y", 2},
+ {false, "freeze i32 %x", 0},
+ {true, "udiv i32 %x, %y", 0},
+ {true, "udiv i32 %x, %y", 1},
+ {true, "urem i32 %x, %y", 0},
+ {true, "urem i32 %x, %y", 1},
+ {true, "sdiv exact i32 %x, %y", 0},
+ {true, "sdiv exact i32 %x, %y", 1},
+ {true, "srem i32 %x, %y", 0},
+ {true, "srem i32 %x, %y", 1},
+ {false, "call i32 @g(i32 %x)", 0},
+ {false, "call i32 @g(i32 %x)", 1},
+ {true, "call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %x, i32 %y)", 0},
+ {true, "call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %x, i32 %y)", 0},
+ {true, "call {i32, i1} @llvm.smul.with.overflow.i32(i32 %x, i32 %y)", 0},
+ {true, "call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %x, i32 %y)", 0},
+ {true, "call {i32, i1} @llvm.usub.with.overflow.i32(i32 %x, i32 %y)", 0},
+ {true, "call {i32, i1} @llvm.umul.with.overflow.i32(i32 %x, i32 %y)", 0},
+ {false, "call float @llvm.sqrt.f32(float %fx)", 0},
+ {false, "call float @llvm.powi.f32.i32(float %fx, i32 %x)", 0},
+ {false, "call float @llvm.sin.f32(float %fx)", 0},
+ {false, "call float @llvm.cos.f32(float %fx)", 0},
+ {false, "call float @llvm.pow.f32(float %fx, float %fy)", 0},
+ {false, "call float @llvm.exp.f32(float %fx)", 0},
+ {false, "call float @llvm.exp2.f32(float %fx)", 0},
+ {false, "call float @llvm.log.f32(float %fx)", 0},
+ {false, "call float @llvm.log10.f32(float %fx)", 0},
+ {false, "call float @llvm.log2.f32(float %fx)", 0},
+ {false, "call float @llvm.fma.f32(float %fx, float %fx, float %fy)", 0},
+ {false, "call float @llvm.fabs.f32(float %fx)", 0},
+ {false, "call float @llvm.minnum.f32(float %fx, float %fy)", 0},
+ {false, "call float @llvm.maxnum.f32(float %fx, float %fy)", 0},
+ {false, "call float @llvm.minimum.f32(float %fx, float %fy)", 0},
+ {false, "call float @llvm.maximum.f32(float %fx, float %fy)", 0},
+ {false, "call float @llvm.copysign.f32(float %fx, float %fy)", 0},
+ {false, "call float @llvm.floor.f32(float %fx)", 0},
+ {false, "call float @llvm.ceil.f32(float %fx)", 0},
+ {false, "call float @llvm.trunc.f32(float %fx)", 0},
+ {false, "call float @llvm.rint.f32(float %fx)", 0},
+ {false, "call float @llvm.nearbyint.f32(float %fx)", 0},
+ {false, "call float @llvm.round.f32(float %fx)", 0},
+ {false, "call float @llvm.roundeven.f32(float %fx)", 0},
+ {false, "call i32 @llvm.lround.f32(float %fx)", 0},
+ {false, "call i64 @llvm.llround.f32(float %fx)", 0},
+ {false, "call i32 @llvm.lrint.f32(float %fx)", 0},
+ {false, "call i64 @llvm.llrint.f32(float %fx)", 0},
+ {false, "call float @llvm.fmuladd.f32(float %fx, float %fx, float %fy)",
+ 0}};
std::string AssemblyStr = AsmHead;
for (auto &Itm : Data)
- AssemblyStr += Itm.second + "\n";
+ AssemblyStr += std::get<1>(Itm) + "\n";
AssemblyStr += AsmTail;
LLVMContext Context;
@@ -925,7 +946,9 @@ TEST(ValueTracking, propagatesPoison) {
for (auto &I : BB) {
if (isa<ReturnInst>(&I))
break;
- EXPECT_EQ(propagatesPoison(cast<Operator>(&I)), Data[Index].first)
+ bool ExpectedVal = std::get<0>(Data[Index]);
+ unsigned OpIdx = std::get<2>(Data[Index]);
+ EXPECT_EQ(propagatesPoison(I.getOperandUse(OpIdx)), ExpectedVal)
<< "Incorrect answer at instruction " << Index << " = " << I;
Index++;
}