[llvm-branch-commits] [llvm] [InstCombine] Enable select freeze poison folding when storing value (PR #129776)
via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Tue Mar 4 19:52:11 PST 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-ir
Author: John McIver (jmciver)
<details>
<summary>Changes</summary>
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
---
Full diff: https://github.com/llvm/llvm-project/pull/129776.diff
3 Files Affected:
- (modified) llvm/include/llvm/IR/PatternMatch.h (+13)
- (modified) llvm/lib/Transforms/InstCombine/InstructionCombining.cpp (+16-6)
- (modified) llvm/test/Transforms/InstCombine/select.ll (+3-6)
``````````diff
diff --git a/llvm/include/llvm/IR/PatternMatch.h b/llvm/include/llvm/IR/PatternMatch.h
index b3eeb1d7ba88a..c66235f33cd9e 100644
--- a/llvm/include/llvm/IR/PatternMatch.h
+++ b/llvm/include/llvm/IR/PatternMatch.h
@@ -3124,6 +3124,19 @@ inline auto m_c_LogicalOp(const LHS &L, const RHS &R) {
return m_LogicalOp<LHS, RHS, /*Commutable=*/true>(L, R);
}
+struct GuaranteedNotToBeUndefOrPoison_match {
+ template <typename ITy> bool match(ITy *V) {
+ if (auto *AsValue = dyn_cast<Value>(V))
+ return isGuaranteedNotToBeUndefOrPoison(AsValue);
+ else
+ return false;
+ }
+};
+
+inline GuaranteedNotToBeUndefOrPoison_match m_guaranteedNotToBeUndefOrPoison() {
+ return GuaranteedNotToBeUndefOrPoison_match();
+}
+
} // end namespace PatternMatch
} // end namespace llvm
diff --git a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
index 4c14dcfb4d75f..6b9254692a857 100644
--- a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
@@ -4813,15 +4813,22 @@ 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);
+ 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);
-
+ else if (I.hasOneUse() &&
+ match(U, m_c_Select(m_Specific(&I),
+ m_guaranteedNotToBeUndefOrPoison()))) {
+ if (match(U->getOperand(1), m_Specific(&I)))
+ C = U->getOperand(2);
+ else
+ C = U->getOperand(1);
+ }
if (!BestValue)
BestValue = C;
else if (BestValue != C)
@@ -4842,8 +4849,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
``````````
</details>
https://github.com/llvm/llvm-project/pull/129776
More information about the llvm-branch-commits
mailing list