[llvm] [ValueTracking] Teach isGuaranteedNotToBeUndefOrPoison about splats (PR #163570)
Cullen Rhodes via llvm-commits
llvm-commits at lists.llvm.org
Wed Oct 15 08:35:51 PDT 2025
https://github.com/c-rhodes updated https://github.com/llvm/llvm-project/pull/163570
>From c8cdc8c3294453039059dcf4f8340d02f42a4e32 Mon Sep 17 00:00:00 2001
From: Cullen Rhodes <cullen.rhodes at arm.com>
Date: Fri, 10 Oct 2025 14:22:45 +0000
Subject: [PATCH 1/2] [ValueTracking] Teach isGuaranteedNotToBeUndefOrPoison
about splats
Splats include two poison values, but only the poison-ness of the
splatted value actually matters.
---
llvm/lib/Analysis/ValueTracking.cpp | 5 +++++
llvm/unittests/Analysis/ValueTrackingTest.cpp | 10 ++++++++++
2 files changed, 15 insertions(+)
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index 9655c886f4441..b0016c36bf5da 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -7678,6 +7678,7 @@ static bool isGuaranteedNotToBeUndefOrPoison(
return true;
}
+ Value *Splat;
if (!::canCreateUndefOrPoison(Opr, Kind,
/*ConsiderFlagsAndMetadata=*/true)) {
if (const auto *PN = dyn_cast<PHINode>(V)) {
@@ -7695,6 +7696,10 @@ static bool isGuaranteedNotToBeUndefOrPoison(
}
if (IsWellDefined)
return true;
+ } else if (isa<ShuffleVectorInst>(Opr) && (Splat = getSplatValue(Opr))) {
+ // For splats we only need to check the value being splatted.
+ if (OpCheck(Splat))
+ return true;
} else if (all_of(Opr->operands(), OpCheck))
return true;
}
diff --git a/llvm/unittests/Analysis/ValueTrackingTest.cpp b/llvm/unittests/Analysis/ValueTrackingTest.cpp
index 559a0b724f383..bb0280ee69cfd 100644
--- a/llvm/unittests/Analysis/ValueTrackingTest.cpp
+++ b/llvm/unittests/Analysis/ValueTrackingTest.cpp
@@ -1091,6 +1091,16 @@ TEST_F(ValueTrackingTest, isGuaranteedNotToBeUndefOrPoison) {
}
}
+TEST_F(ValueTrackingTest, isGuaranteedNotToBeUndefOrPoison_splat) {
+ parseAssembly(
+ "define <4 x i32> @test(i32 noundef %x) {\n"
+ " %ins = insertelement <4 x i32> poison, i32 %x, i32 0\n"
+ " %A = shufflevector <4 x i32> %ins, <4 x i32> poison, <4 x i32> zeroinitializer\n"
+ " ret <4 x i32> %A\n"
+ "}");
+ EXPECT_TRUE(isGuaranteedNotToBeUndefOrPoison(A));
+}
+
TEST_F(ValueTrackingTest, isGuaranteedNotToBeUndefOrPoison_assume) {
parseAssembly("declare i1 @f_i1()\n"
"declare i32 @f_i32()\n"
>From ec522636a0dc3efb52c62be26a0a7f77caee963a Mon Sep 17 00:00:00 2001
From: Cullen Rhodes <cullen.rhodes at arm.com>
Date: Wed, 15 Oct 2025 15:31:11 +0000
Subject: [PATCH 2/2] address comments
---
llvm/lib/Analysis/ValueTracking.cpp | 2 +-
llvm/test/Transforms/InstSimplify/freeze-noundef.ll | 13 +++++++++++++
2 files changed, 14 insertions(+), 1 deletion(-)
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index b0016c36bf5da..0b65a5a6ed96c 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -7678,9 +7678,9 @@ static bool isGuaranteedNotToBeUndefOrPoison(
return true;
}
- Value *Splat;
if (!::canCreateUndefOrPoison(Opr, Kind,
/*ConsiderFlagsAndMetadata=*/true)) {
+ Value *Splat;
if (const auto *PN = dyn_cast<PHINode>(V)) {
unsigned Num = PN->getNumIncomingValues();
bool IsWellDefined = true;
diff --git a/llvm/test/Transforms/InstSimplify/freeze-noundef.ll b/llvm/test/Transforms/InstSimplify/freeze-noundef.ll
index e6c296994cf6a..de1c2cc74240a 100644
--- a/llvm/test/Transforms/InstSimplify/freeze-noundef.ll
+++ b/llvm/test/Transforms/InstSimplify/freeze-noundef.ll
@@ -156,3 +156,16 @@ define {i8, i32} @noundef_metadata2(ptr %p) {
%v.fr = freeze {i8, i32} %v
ret {i8, i32} %v.fr
}
+
+; For splats only the poison-ness of the value being splatted matters.
+define <4 x i32> @splat(i32 noundef %x) {
+; CHECK-LABEL: @splat(
+; CHECK-NEXT: [[INS:%.*]] = insertelement <4 x i32> poison, i32 [[X:%.*]], i32 0
+; CHECK-NEXT: [[SPLAT:%.*]] = shufflevector <4 x i32> [[INS]], <4 x i32> poison, <4 x i32> zeroinitializer
+; CHECK-NEXT: ret <4 x i32> [[SPLAT]]
+;
+ %ins = insertelement <4 x i32> poison, i32 %x, i32 0
+ %splat = shufflevector <4 x i32> %ins, <4 x i32> poison, <4 x i32> zeroinitializer
+ %splat.fr = freeze <4 x i32> %splat
+ ret <4 x i32> %splat.fr
+}
More information about the llvm-commits
mailing list