[llvm] [InstCombine] Recursively replace condition with constant in select arms (PR #120011)
via llvm-commits
llvm-commits at lists.llvm.org
Sun Dec 15 07:39:39 PST 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-transforms
Author: Yingwei Zheng (dtcxzyw)
<details>
<summary>Changes</summary>
This patch is proposed to reduce the number of selects with undefs introduced by https://github.com/llvm/llvm-project/pull/119884.
It is an alternative to https://github.com/llvm/llvm-project/pull/83405.
---
Full diff: https://github.com/llvm/llvm-project/pull/120011.diff
2 Files Affected:
- (modified) llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp (+6)
- (modified) llvm/test/Transforms/InstCombine/select.ll (+71-6)
``````````diff
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
index 50dfb58cadb17b..5eebfdb774d2e2 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
@@ -3800,6 +3800,12 @@ Instruction *InstCombinerImpl::visitSelectInst(SelectInst &SI) {
ConstantInt::getFalse(CondType), SQ,
/* AllowRefinement */ true))
return replaceOperand(SI, 2, S);
+
+ if (replaceInInstruction(TrueVal, CondVal,
+ ConstantInt::getTrue(CondType)) ||
+ replaceInInstruction(FalseVal, CondVal,
+ ConstantInt::getFalse(CondType)))
+ return &SI;
}
if (Instruction *R = foldSelectOfBools(SI))
diff --git a/llvm/test/Transforms/InstCombine/select.ll b/llvm/test/Transforms/InstCombine/select.ll
index 82c079d681284d..48af18b00ff5a7 100644
--- a/llvm/test/Transforms/InstCombine/select.ll
+++ b/llvm/test/Transforms/InstCombine/select.ll
@@ -4580,9 +4580,8 @@ define i32 @src_select_xxory_eq0_xorxy_y(i32 %x, i32 %y) {
define i32 @sequence_select_with_same_cond_false(i1 %c1, i1 %c2){
; CHECK-LABEL: @sequence_select_with_same_cond_false(
-; CHECK-NEXT: [[S1:%.*]] = select i1 [[C1:%.*]], i32 23, i32 45
-; CHECK-NEXT: [[S2:%.*]] = select i1 [[C2:%.*]], i32 666, i32 [[S1]]
-; CHECK-NEXT: [[S3:%.*]] = select i1 [[C1]], i32 789, i32 [[S2]]
+; CHECK-NEXT: [[S2:%.*]] = select i1 [[C2:%.*]], i32 666, i32 45
+; CHECK-NEXT: [[S3:%.*]] = select i1 [[C1:%.*]], i32 789, i32 [[S2]]
; CHECK-NEXT: ret i32 [[S3]]
;
%s1 = select i1 %c1, i32 23, i32 45
@@ -4593,9 +4592,8 @@ define i32 @sequence_select_with_same_cond_false(i1 %c1, i1 %c2){
define i32 @sequence_select_with_same_cond_true(i1 %c1, i1 %c2){
; CHECK-LABEL: @sequence_select_with_same_cond_true(
-; CHECK-NEXT: [[S1:%.*]] = select i1 [[C1:%.*]], i32 45, i32 23
-; CHECK-NEXT: [[S2:%.*]] = select i1 [[C2:%.*]], i32 [[S1]], i32 666
-; CHECK-NEXT: [[S3:%.*]] = select i1 [[C1]], i32 [[S2]], i32 789
+; CHECK-NEXT: [[S2:%.*]] = select i1 [[C2:%.*]], i32 45, i32 666
+; CHECK-NEXT: [[S3:%.*]] = select i1 [[C1:%.*]], i32 [[S2]], i32 789
; CHECK-NEXT: ret i32 [[S3]]
;
%s1 = select i1 %c1, i32 45, i32 23
@@ -4766,3 +4764,70 @@ define i32 @sel_extractvalue_simplify(i1 %c, { i32, i32 } %agg1, i32 %x, i32 %y)
%res = extractvalue { i32, i32 } %sel, 1
ret i32 %res
}
+
+define i1 @replace_select_cond_true(i1 %cond, i32 %v1, i32 %v2, i32 %v3) {
+; CHECK-LABEL: @replace_select_cond_true(
+; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[SEL:%.*]], [[V2:%.*]]
+; CHECK-NEXT: [[AND:%.*]] = select i1 [[COND:%.*]], i1 [[CMP]], i1 false
+; CHECK-NEXT: ret i1 [[AND]]
+;
+ %sel = select i1 %cond, i32 %v1, i32 %v3
+ %cmp = icmp eq i32 %sel, %v2
+ %and = select i1 %cond, i1 %cmp, i1 false
+ ret i1 %and
+}
+
+define i1 @replace_select_cond_false(i1 %cond, i32 %v1, i32 %v2, i32 %v3) {
+; CHECK-LABEL: @replace_select_cond_false(
+; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[SEL:%.*]], [[V2:%.*]]
+; CHECK-NEXT: [[OR:%.*]] = select i1 [[COND:%.*]], i1 true, i1 [[CMP]]
+; CHECK-NEXT: ret i1 [[OR]]
+;
+ %sel = select i1 %cond, i32 %v1, i32 %v3
+ %cmp = icmp eq i32 %sel, %v2
+ %or = select i1 %cond, i1 true, i1 %cmp
+ ret i1 %or
+}
+
+define i32 @replace_and_cond(i1 %cond1, i1 %cond2) {
+; CHECK-LABEL: @replace_and_cond(
+; CHECK-NEXT: [[SEL:%.*]] = select i1 [[AND:%.*]], i32 3, i32 2
+; CHECK-NEXT: [[MUX:%.*]] = select i1 [[COND1:%.*]], i32 [[SEL]], i32 1
+; CHECK-NEXT: ret i32 [[MUX]]
+;
+ %and = and i1 %cond1, %cond2
+ %sel = select i1 %and, i32 3, i32 2
+ %mux = select i1 %cond1, i32 %sel, i32 1
+ ret i32 %mux
+}
+
+; TODO: We can still replace the use of %and with %cond2
+define i32 @replace_and_cond_multiuse1(i1 %cond1, i1 %cond2) {
+; CHECK-LABEL: @replace_and_cond_multiuse1(
+; CHECK-NEXT: [[AND:%.*]] = and i1 [[COND1:%.*]], [[COND2:%.*]]
+; CHECK-NEXT: call void @use(i1 [[AND]])
+; CHECK-NEXT: [[SEL:%.*]] = select i1 [[AND]], i32 3, i32 2
+; CHECK-NEXT: [[MUX:%.*]] = select i1 [[COND1]], i32 [[SEL]], i32 1
+; CHECK-NEXT: ret i32 [[MUX]]
+;
+ %and = and i1 %cond1, %cond2
+ call void @use(i1 %and)
+ %sel = select i1 %and, i32 3, i32 2
+ %mux = select i1 %cond1, i32 %sel, i32 1
+ ret i32 %mux
+}
+
+define i32 @replace_and_cond_multiuse2(i1 %cond1, i1 %cond2) {
+; CHECK-LABEL: @replace_and_cond_multiuse2(
+; CHECK-NEXT: [[AND:%.*]] = and i1 [[COND1:%.*]], [[COND2:%.*]]
+; CHECK-NEXT: [[SEL:%.*]] = select i1 [[AND]], i32 3, i32 2
+; CHECK-NEXT: call void @use32(i32 [[SEL]])
+; CHECK-NEXT: [[MUX:%.*]] = select i1 [[COND1]], i32 [[SEL]], i32 1
+; CHECK-NEXT: ret i32 [[MUX]]
+;
+ %and = and i1 %cond1, %cond2
+ %sel = select i1 %and, i32 3, i32 2
+ call void @use32(i32 %sel)
+ %mux = select i1 %cond1, i32 %sel, i32 1
+ ret i32 %mux
+}
``````````
</details>
https://github.com/llvm/llvm-project/pull/120011
More information about the llvm-commits
mailing list