Skip to content

Commit

Permalink
[InstCombine] Recursively replace condition with constant in select a…
Browse files Browse the repository at this point in the history
…rms (#120011)

This patch is proposed to reduce the number of selects with undefs
introduced by #119884.
  • Loading branch information
dtcxzyw authored Dec 16, 2024
1 parent 8dd27d4 commit 7d25bce
Show file tree
Hide file tree
Showing 2 changed files with 89 additions and 6 deletions.
6 changes: 6 additions & 0 deletions llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down
89 changes: 83 additions & 6 deletions llvm/test/Transforms/InstCombine/select.ll
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -4766,3 +4764,82 @@ 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
}

define <2 x i32> @replace_and_cond_vec(<2 x i1> %cond1, <2 x i1> %cond2) {
; CHECK-LABEL: @replace_and_cond_vec(
; CHECK-NEXT: [[SEL:%.*]] = select <2 x i1> [[COND2:%.*]], <2 x i32> splat (i32 3), <2 x i32> splat (i32 2)
; CHECK-NEXT: [[MUX:%.*]] = select <2 x i1> [[COND1:%.*]], <2 x i32> [[SEL]], <2 x i32> splat (i32 1)
; CHECK-NEXT: ret <2 x i32> [[MUX]]
;
%and = and <2 x i1> %cond1, %cond2
%sel = select <2 x i1> %and, <2 x i32> splat(i32 3), <2 x i32> splat(i32 2)
%mux = select <2 x i1> %cond1, <2 x i32> %sel, <2 x i32> splat(i32 1)
ret <2 x 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
}

0 comments on commit 7d25bce

Please sign in to comment.