Skip to content

Commit 9568f88

Browse files
authored
InstCombine: support floating-point equivalences (#114975)
Since cd16b07 (IR: introduce CmpInst::isEquivalence), there is now an isEquivalence routine in CmpInst that we can use to determine equivalence in foldSelectValueEquivalence. Implement this, extending it to include floating-point equivalences as well.
1 parent 09c4124 commit 9568f88

File tree

4 files changed

+51
-53
lines changed

4 files changed

+51
-53
lines changed

llvm/lib/Transforms/InstCombine/InstCombineInternal.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -750,7 +750,7 @@ class LLVM_LIBRARY_VISIBILITY InstCombinerImpl final
750750
Value *A, Value *B, Instruction &Outer,
751751
SelectPatternFlavor SPF2, Value *C);
752752
Instruction *foldSelectInstWithICmp(SelectInst &SI, ICmpInst *ICI);
753-
Instruction *foldSelectValueEquivalence(SelectInst &SI, ICmpInst &ICI);
753+
Instruction *foldSelectValueEquivalence(SelectInst &SI, CmpInst &CI);
754754
bool replaceInInstruction(Value *V, Value *Old, Value *New,
755755
unsigned Depth = 0);
756756

llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1327,16 +1327,16 @@ bool InstCombinerImpl::replaceInInstruction(Value *V, Value *Old, Value *New,
13271327
/// We can't replace %sel with %add unless we strip away the flags.
13281328
/// TODO: Wrapping flags could be preserved in some cases with better analysis.
13291329
Instruction *InstCombinerImpl::foldSelectValueEquivalence(SelectInst &Sel,
1330-
ICmpInst &Cmp) {
1331-
if (!Cmp.isEquality())
1332-
return nullptr;
1333-
1334-
// Canonicalize the pattern to ICMP_EQ by swapping the select operands.
1330+
CmpInst &Cmp) {
1331+
// Canonicalize the pattern to an equivalence on the predicate by swapping the
1332+
// select operands.
13351333
Value *TrueVal = Sel.getTrueValue(), *FalseVal = Sel.getFalseValue();
13361334
bool Swapped = false;
1337-
if (Cmp.getPredicate() == ICmpInst::ICMP_NE) {
1335+
if (Cmp.isEquivalence(/*Invert=*/true)) {
13381336
std::swap(TrueVal, FalseVal);
13391337
Swapped = true;
1338+
} else if (!Cmp.isEquivalence()) {
1339+
return nullptr;
13401340
}
13411341

13421342
Value *CmpLHS = Cmp.getOperand(0), *CmpRHS = Cmp.getOperand(1);
@@ -1347,7 +1347,7 @@ Instruction *InstCombinerImpl::foldSelectValueEquivalence(SelectInst &Sel,
13471347
// would lead to an infinite replacement cycle.
13481348
// If we will be able to evaluate f(Y) to a constant, we can allow undef,
13491349
// otherwise Y cannot be undef as we might pick different values for undef
1350-
// in the icmp and in f(Y).
1350+
// in the cmp and in f(Y).
13511351
if (TrueVal == OldOp)
13521352
return nullptr;
13531353

@@ -1901,9 +1901,6 @@ static Instruction *foldSelectICmpEq(SelectInst &SI, ICmpInst *ICI,
19011901
/// Visit a SelectInst that has an ICmpInst as its first operand.
19021902
Instruction *InstCombinerImpl::foldSelectInstWithICmp(SelectInst &SI,
19031903
ICmpInst *ICI) {
1904-
if (Instruction *NewSel = foldSelectValueEquivalence(SI, *ICI))
1905-
return NewSel;
1906-
19071904
if (Value *V =
19081905
canonicalizeSPF(*ICI, SI.getTrueValue(), SI.getFalseValue(), *this))
19091906
return replaceInstUsesWith(SI, V);
@@ -3848,6 +3845,10 @@ Instruction *InstCombinerImpl::visitSelectInst(SelectInst &SI) {
38483845
return Fabs;
38493846

38503847
// See if we are selecting two values based on a comparison of the two values.
3848+
if (CmpInst *CI = dyn_cast<CmpInst>(CondVal))
3849+
if (Instruction *NewSel = foldSelectValueEquivalence(SI, *CI))
3850+
return NewSel;
3851+
38513852
if (ICmpInst *ICI = dyn_cast<ICmpInst>(CondVal))
38523853
if (Instruction *Result = foldSelectInstWithICmp(SI, ICI))
38533854
return Result;

llvm/test/Transforms/InstCombine/select-binop-cmp.ll

Lines changed: 31 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -706,11 +706,10 @@ define i32 @select_lshr_icmp_const_different_values(i32 %x, i32 %y) {
706706
ret i32 %C
707707
}
708708

709-
; Invalid identity constant for FP op
710-
define float @select_fadd_fcmp_bad(float %x, float %y, float %z) {
711-
; CHECK-LABEL: @select_fadd_fcmp_bad(
709+
define float @select_fadd_fcmp_equiv(float %x, float %y, float %z) {
710+
; CHECK-LABEL: @select_fadd_fcmp_equiv(
712711
; CHECK-NEXT: [[A:%.*]] = fcmp oeq float [[X:%.*]], -1.000000e+00
713-
; CHECK-NEXT: [[B:%.*]] = fadd nsz float [[X]], [[Z:%.*]]
712+
; CHECK-NEXT: [[B:%.*]] = fadd nsz float [[Z:%.*]], -1.000000e+00
714713
; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[B]], float [[Y:%.*]]
715714
; CHECK-NEXT: ret float [[C]]
716715
;
@@ -720,6 +719,19 @@ define float @select_fadd_fcmp_bad(float %x, float %y, float %z) {
720719
ret float %C
721720
}
722721

722+
define float @select_fadd_fcmp_equiv2(float %x, float %y, float %z) {
723+
; CHECK-LABEL: @select_fadd_fcmp_equiv2(
724+
; CHECK-NEXT: [[A:%.*]] = fcmp une float [[X:%.*]], -1.000000e+00
725+
; CHECK-NEXT: [[B:%.*]] = fadd nsz float [[Z:%.*]], -1.000000e+00
726+
; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[Y:%.*]], float [[B]]
727+
; CHECK-NEXT: ret float [[C]]
728+
;
729+
%A = fcmp une float %x, -1.0
730+
%B = fadd nsz float %x, %z
731+
%C = select i1 %A, float %y, float %B
732+
ret float %C
733+
}
734+
723735
; Invalid comparison type
724736
define float @select_fadd_fcmp_bad_2(float %x, float %y, float %z) {
725737
; CHECK-LABEL: @select_fadd_fcmp_bad_2(
@@ -893,24 +905,10 @@ define float @select_fadd_fcmp_bad_13(float %x, float %y, float %z) {
893905
ret float %C
894906
}
895907

896-
; Invalid identity constant for FP op
897-
define float @select_fadd_fcmp_bad_14(float %x, float %y, float %z) {
898-
; CHECK-LABEL: @select_fadd_fcmp_bad_14(
899-
; CHECK-NEXT: [[A:%.*]] = fcmp une float [[X:%.*]], -1.000000e+00
900-
; CHECK-NEXT: [[B:%.*]] = fadd nsz float [[X]], [[Z:%.*]]
901-
; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[Y:%.*]], float [[B]]
902-
; CHECK-NEXT: ret float [[C]]
903-
;
904-
%A = fcmp une float %x, -1.0
905-
%B = fadd nsz float %x, %z
906-
%C = select i1 %A, float %y, float %B
907-
ret float %C
908-
}
909-
910-
define float @select_fmul_fcmp_bad(float %x, float %y, float %z) {
911-
; CHECK-LABEL: @select_fmul_fcmp_bad(
908+
define float @select_fmul_fcmp_equiv(float %x, float %y, float %z) {
909+
; CHECK-LABEL: @select_fmul_fcmp_equiv(
912910
; CHECK-NEXT: [[A:%.*]] = fcmp oeq float [[X:%.*]], 3.000000e+00
913-
; CHECK-NEXT: [[B:%.*]] = fmul nsz float [[X]], [[Z:%.*]]
911+
; CHECK-NEXT: [[B:%.*]] = fmul nsz float [[Z:%.*]], 3.000000e+00
914912
; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[B]], float [[Y:%.*]]
915913
; CHECK-NEXT: ret float [[C]]
916914
;
@@ -920,11 +918,10 @@ define float @select_fmul_fcmp_bad(float %x, float %y, float %z) {
920918
ret float %C
921919
}
922920

923-
define float @select_fmul_fcmp_bad_2(float %x, float %y, float %z) {
924-
; CHECK-LABEL: @select_fmul_fcmp_bad_2(
921+
define float @select_fmul_fcmp_equiv2(float %x, float %y, float %z) {
922+
; CHECK-LABEL: @select_fmul_fcmp_equiv2(
925923
; CHECK-NEXT: [[A:%.*]] = fcmp oeq float [[X:%.*]], 1.000000e+00
926-
; CHECK-NEXT: [[B:%.*]] = fmul float [[X]], [[Z:%.*]]
927-
; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[B]], float [[Y:%.*]]
924+
; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[B:%.*]], float [[Y:%.*]]
928925
; CHECK-NEXT: ret float [[C]]
929926
;
930927
%A = fcmp oeq float %x, 1.0
@@ -959,10 +956,10 @@ define float @select_fmul_icmp_bad_2(float %x, float %y, float %z, i32 %k) {
959956
ret float %C
960957
}
961958

962-
define float @select_fdiv_fcmp_bad(float %x, float %y, float %z) {
963-
; CHECK-LABEL: @select_fdiv_fcmp_bad(
959+
define float @select_fdiv_fcmp_equiv(float %x, float %y, float %z) {
960+
; CHECK-LABEL: @select_fdiv_fcmp_equiv(
964961
; CHECK-NEXT: [[A:%.*]] = fcmp oeq float [[X:%.*]], 1.000000e+00
965-
; CHECK-NEXT: [[B:%.*]] = fdiv float [[X]], [[Z:%.*]]
962+
; CHECK-NEXT: [[B:%.*]] = fdiv float 1.000000e+00, [[Z:%.*]]
966963
; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[B]], float [[Y:%.*]]
967964
; CHECK-NEXT: ret float [[C]]
968965
;
@@ -972,10 +969,10 @@ define float @select_fdiv_fcmp_bad(float %x, float %y, float %z) {
972969
ret float %C
973970
}
974971

975-
define float @select_fdiv_fcmp_bad_2(float %x, float %y, float %z) {
976-
; CHECK-LABEL: @select_fdiv_fcmp_bad_2(
972+
define float @select_fdiv_fcmp_equiv2(float %x, float %y, float %z) {
973+
; CHECK-LABEL: @select_fdiv_fcmp_equiv2(
977974
; CHECK-NEXT: [[A:%.*]] = fcmp oeq float [[X:%.*]], 3.000000e+00
978-
; CHECK-NEXT: [[B:%.*]] = fdiv nsz float [[X]], [[Z:%.*]]
975+
; CHECK-NEXT: [[B:%.*]] = fdiv nsz float 3.000000e+00, [[Z:%.*]]
979976
; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[B]], float [[Y:%.*]]
980977
; CHECK-NEXT: ret float [[C]]
981978
;
@@ -1001,10 +998,10 @@ define float @select_fsub_fcmp_bad(float %x, float %y, float %z) {
1001998
ret float %C
1002999
}
10031000

1004-
define float @select_fsub_fcmp_bad_2(float %x, float %y, float %z) {
1005-
; CHECK-LABEL: @select_fsub_fcmp_bad_2(
1001+
define float @select_fsub_fcmp_equiv(float %x, float %y, float %z) {
1002+
; CHECK-LABEL: @select_fsub_fcmp_equiv(
10061003
; CHECK-NEXT: [[A:%.*]] = fcmp oeq float [[X:%.*]], 1.000000e+00
1007-
; CHECK-NEXT: [[B:%.*]] = fsub nsz float [[Z:%.*]], [[X]]
1004+
; CHECK-NEXT: [[B:%.*]] = fadd nsz float [[Z:%.*]], -1.000000e+00
10081005
; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[B]], float [[Y:%.*]]
10091006
; CHECK-NEXT: ret float [[C]]
10101007
;

llvm/test/Transforms/InstCombine/select-value-equivalence.ll

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ define float @select_fcmp_fadd_oeq_not_zero(float %x, float %y) {
9090
; CHECK-LABEL: define float @select_fcmp_fadd_oeq_not_zero(
9191
; CHECK-SAME: float [[X:%.*]], float [[Y:%.*]]) {
9292
; CHECK-NEXT: [[FCMP:%.*]] = fcmp oeq float [[Y]], 2.000000e+00
93-
; CHECK-NEXT: [[FADD:%.*]] = fadd float [[X]], [[Y]]
93+
; CHECK-NEXT: [[FADD:%.*]] = fadd float [[X]], 2.000000e+00
9494
; CHECK-NEXT: [[RETVAL:%.*]] = select i1 [[FCMP]], float [[FADD]], float [[X]]
9595
; CHECK-NEXT: ret float [[RETVAL]]
9696
;
@@ -104,7 +104,7 @@ define float @select_fcmp_fadd_une_not_zero(float %x, float %y) {
104104
; CHECK-LABEL: define float @select_fcmp_fadd_une_not_zero(
105105
; CHECK-SAME: float [[X:%.*]], float [[Y:%.*]]) {
106106
; CHECK-NEXT: [[FCMP:%.*]] = fcmp une float [[Y]], 2.000000e+00
107-
; CHECK-NEXT: [[FADD:%.*]] = fadd float [[X]], [[Y]]
107+
; CHECK-NEXT: [[FADD:%.*]] = fadd float [[X]], 2.000000e+00
108108
; CHECK-NEXT: [[RETVAL:%.*]] = select i1 [[FCMP]], float [[X]], float [[FADD]]
109109
; CHECK-NEXT: ret float [[RETVAL]]
110110
;
@@ -118,7 +118,7 @@ define float @select_fcmp_fadd_ueq_nnan_not_zero(float %x, float %y) {
118118
; CHECK-LABEL: define float @select_fcmp_fadd_ueq_nnan_not_zero(
119119
; CHECK-SAME: float [[X:%.*]], float [[Y:%.*]]) {
120120
; CHECK-NEXT: [[FCMP:%.*]] = fcmp nnan ueq float [[Y]], 2.000000e+00
121-
; CHECK-NEXT: [[FADD:%.*]] = fadd float [[X]], [[Y]]
121+
; CHECK-NEXT: [[FADD:%.*]] = fadd float [[X]], 2.000000e+00
122122
; CHECK-NEXT: [[RETVAL:%.*]] = select i1 [[FCMP]], float [[FADD]], float [[X]]
123123
; CHECK-NEXT: ret float [[RETVAL]]
124124
;
@@ -132,7 +132,7 @@ define float @select_fcmp_fadd_one_nnan_not_zero(float %x, float %y) {
132132
; CHECK-LABEL: define float @select_fcmp_fadd_one_nnan_not_zero(
133133
; CHECK-SAME: float [[X:%.*]], float [[Y:%.*]]) {
134134
; CHECK-NEXT: [[FCMP:%.*]] = fcmp nnan one float [[Y]], 2.000000e+00
135-
; CHECK-NEXT: [[FADD:%.*]] = fadd float [[X]], [[Y]]
135+
; CHECK-NEXT: [[FADD:%.*]] = fadd float [[X]], 2.000000e+00
136136
; CHECK-NEXT: [[RETVAL:%.*]] = select i1 [[FCMP]], float [[X]], float [[FADD]]
137137
; CHECK-NEXT: ret float [[RETVAL]]
138138
;
@@ -202,7 +202,7 @@ define <2 x float> @select_fcmp_fadd_oeq_not_zero_vec(<2 x float> %x, <2 x float
202202
; CHECK-LABEL: define <2 x float> @select_fcmp_fadd_oeq_not_zero_vec(
203203
; CHECK-SAME: <2 x float> [[X:%.*]], <2 x float> [[Y:%.*]]) {
204204
; CHECK-NEXT: [[FCMP:%.*]] = fcmp oeq <2 x float> [[Y]], splat (float 2.000000e+00)
205-
; CHECK-NEXT: [[FADD:%.*]] = fadd <2 x float> [[X]], [[Y]]
205+
; CHECK-NEXT: [[FADD:%.*]] = fadd <2 x float> [[X]], splat (float 2.000000e+00)
206206
; CHECK-NEXT: [[RETVAL:%.*]] = select <2 x i1> [[FCMP]], <2 x float> [[FADD]], <2 x float> [[X]]
207207
; CHECK-NEXT: ret <2 x float> [[RETVAL]]
208208
;
@@ -216,7 +216,7 @@ define <2 x float> @select_fcmp_fadd_une_not_zero_vec(<2 x float> %x, <2 x float
216216
; CHECK-LABEL: define <2 x float> @select_fcmp_fadd_une_not_zero_vec(
217217
; CHECK-SAME: <2 x float> [[X:%.*]], <2 x float> [[Y:%.*]]) {
218218
; CHECK-NEXT: [[FCMP:%.*]] = fcmp une <2 x float> [[Y]], splat (float 2.000000e+00)
219-
; CHECK-NEXT: [[FADD:%.*]] = fadd <2 x float> [[X]], [[Y]]
219+
; CHECK-NEXT: [[FADD:%.*]] = fadd <2 x float> [[X]], splat (float 2.000000e+00)
220220
; CHECK-NEXT: [[RETVAL:%.*]] = select <2 x i1> [[FCMP]], <2 x float> [[X]], <2 x float> [[FADD]]
221221
; CHECK-NEXT: ret <2 x float> [[RETVAL]]
222222
;
@@ -230,7 +230,7 @@ define <2 x float> @select_fcmp_fadd_ueq_nnan_not_zero_vec(<2 x float> %x, <2 x
230230
; CHECK-LABEL: define <2 x float> @select_fcmp_fadd_ueq_nnan_not_zero_vec(
231231
; CHECK-SAME: <2 x float> [[X:%.*]], <2 x float> [[Y:%.*]]) {
232232
; CHECK-NEXT: [[FCMP:%.*]] = fcmp nnan ueq <2 x float> [[Y]], splat (float 2.000000e+00)
233-
; CHECK-NEXT: [[FADD:%.*]] = fadd <2 x float> [[X]], [[Y]]
233+
; CHECK-NEXT: [[FADD:%.*]] = fadd <2 x float> [[X]], splat (float 2.000000e+00)
234234
; CHECK-NEXT: [[RETVAL:%.*]] = select <2 x i1> [[FCMP]], <2 x float> [[FADD]], <2 x float> [[X]]
235235
; CHECK-NEXT: ret <2 x float> [[RETVAL]]
236236
;
@@ -244,7 +244,7 @@ define <2 x float> @select_fcmp_fadd_one_nnan_not_zero_vec(<2 x float> %x, <2 x
244244
; CHECK-LABEL: define <2 x float> @select_fcmp_fadd_one_nnan_not_zero_vec(
245245
; CHECK-SAME: <2 x float> [[X:%.*]], <2 x float> [[Y:%.*]]) {
246246
; CHECK-NEXT: [[FCMP:%.*]] = fcmp nnan one <2 x float> [[Y]], splat (float 2.000000e+00)
247-
; CHECK-NEXT: [[FADD:%.*]] = fadd <2 x float> [[X]], [[Y]]
247+
; CHECK-NEXT: [[FADD:%.*]] = fadd <2 x float> [[X]], splat (float 2.000000e+00)
248248
; CHECK-NEXT: [[RETVAL:%.*]] = select <2 x i1> [[FCMP]], <2 x float> [[X]], <2 x float> [[FADD]]
249249
; CHECK-NEXT: ret <2 x float> [[RETVAL]]
250250
;

0 commit comments

Comments
 (0)