Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions llvm/lib/Analysis/ValueTracking.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7680,6 +7680,7 @@ static bool isGuaranteedNotToBeUndefOrPoison(

if (!::canCreateUndefOrPoison(Opr, Kind,
/*ConsiderFlagsAndMetadata=*/true)) {
Value *Splat;
if (const auto *PN = dyn_cast<PHINode>(V)) {
unsigned Num = PN->getNumIncomingValues();
bool IsWellDefined = true;
Expand All @@ -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;
}
Expand Down
13 changes: 13 additions & 0 deletions llvm/test/Transforms/InstSimplify/freeze-noundef.ll
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
10 changes: 10 additions & 0 deletions llvm/unittests/Analysis/ValueTrackingTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
Loading