[llvm] [InstCombine] Enable select freeze poison folding when storing value (PR #129776)
John McIver via llvm-commits
llvm-commits at lists.llvm.org
Thu Mar 6 19:58:39 PST 2025
https://github.com/jmciver updated https://github.com/llvm/llvm-project/pull/129776
>From 97d6bec011195a57d792ea33cd90f19517c9c5d3 Mon Sep 17 00:00:00 2001
From: John McIver <john.mciver.iii at gmail.com>
Date: Tue, 4 Mar 2025 14:10:38 -0700
Subject: [PATCH] [InstCombine] Enable select freeze poison folding when
storing value
The non-freeze poison argument to select can be one of the following: global,
constant, and noundef arguments.
Alive2 test validation: https://alive2.llvm.org/ce/z/jbtCS6
---
.../InstCombine/InstructionCombining.cpp | 22 +++++++++++++------
llvm/test/Transforms/InstCombine/select.ll | 9 +++-----
2 files changed, 18 insertions(+), 13 deletions(-)
diff --git a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
index 4c14dcfb4d75f..f40436f8ecf10 100644
--- a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
@@ -4812,16 +4812,21 @@ Instruction *InstCombinerImpl::visitFreeze(FreezeInst &I) {
//
// TODO: This could use getBinopAbsorber() / getBinopIdentity() to avoid
// duplicating logic for binops at least.
- auto getUndefReplacement = [&I](Type *Ty) {
- Constant *BestValue = nullptr;
- Constant *NullValue = Constant::getNullValue(Ty);
+ auto getUndefReplacement = [&I, &AC = this->AC, &DT = this->DT](Type *Ty) {
+ Value *SelectArgument = nullptr;
+ if (I.hasOneUse() &&
+ match(I.user_back(),
+ m_c_Select(m_Specific(&I), m_Value(SelectArgument))) &&
+ isGuaranteedNotToBeUndefOrPoison(SelectArgument, &AC, &I, &DT))
+ return SelectArgument;
+ Value *BestValue = nullptr;
+ Value *NullValue = Constant::getNullValue(Ty);
for (const auto *U : I.users()) {
- Constant *C = NullValue;
+ Value *C = NullValue;
if (match(U, m_Or(m_Value(), m_Value())))
C = ConstantInt::getAllOnesValue(Ty);
else if (match(U, m_Select(m_Specific(&I), m_Constant(), m_Value())))
C = ConstantInt::getTrue(Ty);
-
if (!BestValue)
BestValue = C;
else if (BestValue != C)
@@ -4842,8 +4847,11 @@ Instruction *InstCombinerImpl::visitFreeze(FreezeInst &I) {
Constant *C;
if (match(Op0, m_Constant(C)) && C->containsUndefOrPoisonElement()) {
- Constant *ReplaceC = getUndefReplacement(I.getType()->getScalarType());
- return replaceInstUsesWith(I, Constant::replaceUndefsWith(C, ReplaceC));
+ Value *Replace = getUndefReplacement(I.getType()->getScalarType());
+ if (Constant *ReplaceC = dyn_cast<Constant>(Replace))
+ return replaceInstUsesWith(I, Constant::replaceUndefsWith(C, ReplaceC));
+ else
+ return replaceInstUsesWith(I, Replace);
}
// Replace uses of Op with freeze(Op).
diff --git a/llvm/test/Transforms/InstCombine/select.ll b/llvm/test/Transforms/InstCombine/select.ll
index cc25f4ce24d9a..789d98197d878 100644
--- a/llvm/test/Transforms/InstCombine/select.ll
+++ b/llvm/test/Transforms/InstCombine/select.ll
@@ -4904,8 +4904,7 @@ define i32 @src_simplify_2x_at_once_and(i32 %x, i32 %y) {
define void @select_freeze_poison_parameter(ptr noundef %addr.src, ptr %addr.tgt, i1 %cond) {
; CHECK-LABEL: @select_freeze_poison_parameter(
-; CHECK-NEXT: [[ADDR_SRC:%.*]] = select i1 [[COND:%.*]], ptr [[ADDR_SRC1:%.*]], ptr null
-; CHECK-NEXT: store ptr [[ADDR_SRC]], ptr [[ADDR_TGT:%.*]], align 8
+; CHECK-NEXT: store ptr [[ADDR_SRC:%.*]], ptr [[ADDR_TGT:%.*]], align 8
; CHECK-NEXT: ret void
;
%freeze = freeze ptr poison
@@ -4918,8 +4917,7 @@ define void @select_freeze_poison_parameter(ptr noundef %addr.src, ptr %addr.tgt
define void @select_freeze_poison_global(ptr %addr.tgt, i1 %cond) {
; CHECK-LABEL: @select_freeze_poison_global(
-; CHECK-NEXT: [[SELECT_ADDR:%.*]] = select i1 [[COND:%.*]], ptr @glb, ptr null
-; CHECK-NEXT: store ptr [[SELECT_ADDR]], ptr [[ADDR_TGT:%.*]], align 8
+; CHECK-NEXT: store ptr @glb, ptr [[ADDR_TGT:%.*]], align 8
; CHECK-NEXT: ret void
;
%freeze = freeze ptr poison
@@ -4930,8 +4928,7 @@ define void @select_freeze_poison_global(ptr %addr.tgt, i1 %cond) {
define void @select_freeze_poison_constant(ptr %addr.tgt, i1 %cond) {
; CHECK-LABEL: @select_freeze_poison_constant(
-; CHECK-NEXT: [[SELECT_ADDR:%.*]] = select i1 [[COND:%.*]], i32 72, i32 0
-; CHECK-NEXT: store i32 [[SELECT_ADDR]], ptr [[ADDR_TGT:%.*]], align 4
+; CHECK-NEXT: store i32 72, ptr [[ADDR_TGT:%.*]], align 4
; CHECK-NEXT: ret void
;
%freeze = freeze i32 poison
More information about the llvm-commits
mailing list