Skip to content

Commit 7d25bce

Browse files
authored
[InstCombine] Recursively replace condition with constant in select arms (#120011)
This patch is proposed to reduce the number of selects with undefs introduced by #119884.
1 parent 8dd27d4 commit 7d25bce

File tree

2 files changed

+89
-6
lines changed

2 files changed

+89
-6
lines changed

llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3800,6 +3800,12 @@ Instruction *InstCombinerImpl::visitSelectInst(SelectInst &SI) {
38003800
ConstantInt::getFalse(CondType), SQ,
38013801
/* AllowRefinement */ true))
38023802
return replaceOperand(SI, 2, S);
3803+
3804+
if (replaceInInstruction(TrueVal, CondVal,
3805+
ConstantInt::getTrue(CondType)) ||
3806+
replaceInInstruction(FalseVal, CondVal,
3807+
ConstantInt::getFalse(CondType)))
3808+
return &SI;
38033809
}
38043810

38053811
if (Instruction *R = foldSelectOfBools(SI))

llvm/test/Transforms/InstCombine/select.ll

Lines changed: 83 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4580,9 +4580,8 @@ define i32 @src_select_xxory_eq0_xorxy_y(i32 %x, i32 %y) {
45804580

45814581
define i32 @sequence_select_with_same_cond_false(i1 %c1, i1 %c2){
45824582
; CHECK-LABEL: @sequence_select_with_same_cond_false(
4583-
; CHECK-NEXT: [[S1:%.*]] = select i1 [[C1:%.*]], i32 23, i32 45
4584-
; CHECK-NEXT: [[S2:%.*]] = select i1 [[C2:%.*]], i32 666, i32 [[S1]]
4585-
; CHECK-NEXT: [[S3:%.*]] = select i1 [[C1]], i32 789, i32 [[S2]]
4583+
; CHECK-NEXT: [[S2:%.*]] = select i1 [[C2:%.*]], i32 666, i32 45
4584+
; CHECK-NEXT: [[S3:%.*]] = select i1 [[C1:%.*]], i32 789, i32 [[S2]]
45864585
; CHECK-NEXT: ret i32 [[S3]]
45874586
;
45884587
%s1 = select i1 %c1, i32 23, i32 45
@@ -4593,9 +4592,8 @@ define i32 @sequence_select_with_same_cond_false(i1 %c1, i1 %c2){
45934592

45944593
define i32 @sequence_select_with_same_cond_true(i1 %c1, i1 %c2){
45954594
; CHECK-LABEL: @sequence_select_with_same_cond_true(
4596-
; CHECK-NEXT: [[S1:%.*]] = select i1 [[C1:%.*]], i32 45, i32 23
4597-
; CHECK-NEXT: [[S2:%.*]] = select i1 [[C2:%.*]], i32 [[S1]], i32 666
4598-
; CHECK-NEXT: [[S3:%.*]] = select i1 [[C1]], i32 [[S2]], i32 789
4595+
; CHECK-NEXT: [[S2:%.*]] = select i1 [[C2:%.*]], i32 45, i32 666
4596+
; CHECK-NEXT: [[S3:%.*]] = select i1 [[C1:%.*]], i32 [[S2]], i32 789
45994597
; CHECK-NEXT: ret i32 [[S3]]
46004598
;
46014599
%s1 = select i1 %c1, i32 45, i32 23
@@ -4766,3 +4764,82 @@ define i32 @sel_extractvalue_simplify(i1 %c, { i32, i32 } %agg1, i32 %x, i32 %y)
47664764
%res = extractvalue { i32, i32 } %sel, 1
47674765
ret i32 %res
47684766
}
4767+
4768+
define i1 @replace_select_cond_true(i1 %cond, i32 %v1, i32 %v2, i32 %v3) {
4769+
; CHECK-LABEL: @replace_select_cond_true(
4770+
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[SEL:%.*]], [[V2:%.*]]
4771+
; CHECK-NEXT: [[AND:%.*]] = select i1 [[COND:%.*]], i1 [[CMP]], i1 false
4772+
; CHECK-NEXT: ret i1 [[AND]]
4773+
;
4774+
%sel = select i1 %cond, i32 %v1, i32 %v3
4775+
%cmp = icmp eq i32 %sel, %v2
4776+
%and = select i1 %cond, i1 %cmp, i1 false
4777+
ret i1 %and
4778+
}
4779+
4780+
define i1 @replace_select_cond_false(i1 %cond, i32 %v1, i32 %v2, i32 %v3) {
4781+
; CHECK-LABEL: @replace_select_cond_false(
4782+
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[SEL:%.*]], [[V2:%.*]]
4783+
; CHECK-NEXT: [[OR:%.*]] = select i1 [[COND:%.*]], i1 true, i1 [[CMP]]
4784+
; CHECK-NEXT: ret i1 [[OR]]
4785+
;
4786+
%sel = select i1 %cond, i32 %v1, i32 %v3
4787+
%cmp = icmp eq i32 %sel, %v2
4788+
%or = select i1 %cond, i1 true, i1 %cmp
4789+
ret i1 %or
4790+
}
4791+
4792+
define i32 @replace_and_cond(i1 %cond1, i1 %cond2) {
4793+
; CHECK-LABEL: @replace_and_cond(
4794+
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[AND:%.*]], i32 3, i32 2
4795+
; CHECK-NEXT: [[MUX:%.*]] = select i1 [[COND1:%.*]], i32 [[SEL]], i32 1
4796+
; CHECK-NEXT: ret i32 [[MUX]]
4797+
;
4798+
%and = and i1 %cond1, %cond2
4799+
%sel = select i1 %and, i32 3, i32 2
4800+
%mux = select i1 %cond1, i32 %sel, i32 1
4801+
ret i32 %mux
4802+
}
4803+
4804+
define <2 x i32> @replace_and_cond_vec(<2 x i1> %cond1, <2 x i1> %cond2) {
4805+
; CHECK-LABEL: @replace_and_cond_vec(
4806+
; CHECK-NEXT: [[SEL:%.*]] = select <2 x i1> [[COND2:%.*]], <2 x i32> splat (i32 3), <2 x i32> splat (i32 2)
4807+
; CHECK-NEXT: [[MUX:%.*]] = select <2 x i1> [[COND1:%.*]], <2 x i32> [[SEL]], <2 x i32> splat (i32 1)
4808+
; CHECK-NEXT: ret <2 x i32> [[MUX]]
4809+
;
4810+
%and = and <2 x i1> %cond1, %cond2
4811+
%sel = select <2 x i1> %and, <2 x i32> splat(i32 3), <2 x i32> splat(i32 2)
4812+
%mux = select <2 x i1> %cond1, <2 x i32> %sel, <2 x i32> splat(i32 1)
4813+
ret <2 x i32> %mux
4814+
}
4815+
4816+
; TODO: We can still replace the use of %and with %cond2
4817+
define i32 @replace_and_cond_multiuse1(i1 %cond1, i1 %cond2) {
4818+
; CHECK-LABEL: @replace_and_cond_multiuse1(
4819+
; CHECK-NEXT: [[AND:%.*]] = and i1 [[COND1:%.*]], [[COND2:%.*]]
4820+
; CHECK-NEXT: call void @use(i1 [[AND]])
4821+
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[AND]], i32 3, i32 2
4822+
; CHECK-NEXT: [[MUX:%.*]] = select i1 [[COND1]], i32 [[SEL]], i32 1
4823+
; CHECK-NEXT: ret i32 [[MUX]]
4824+
;
4825+
%and = and i1 %cond1, %cond2
4826+
call void @use(i1 %and)
4827+
%sel = select i1 %and, i32 3, i32 2
4828+
%mux = select i1 %cond1, i32 %sel, i32 1
4829+
ret i32 %mux
4830+
}
4831+
4832+
define i32 @replace_and_cond_multiuse2(i1 %cond1, i1 %cond2) {
4833+
; CHECK-LABEL: @replace_and_cond_multiuse2(
4834+
; CHECK-NEXT: [[AND:%.*]] = and i1 [[COND1:%.*]], [[COND2:%.*]]
4835+
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[AND]], i32 3, i32 2
4836+
; CHECK-NEXT: call void @use32(i32 [[SEL]])
4837+
; CHECK-NEXT: [[MUX:%.*]] = select i1 [[COND1]], i32 [[SEL]], i32 1
4838+
; CHECK-NEXT: ret i32 [[MUX]]
4839+
;
4840+
%and = and i1 %cond1, %cond2
4841+
%sel = select i1 %and, i32 3, i32 2
4842+
call void @use32(i32 %sel)
4843+
%mux = select i1 %cond1, i32 %sel, i32 1
4844+
ret i32 %mux
4845+
}

0 commit comments

Comments
 (0)