Skip to content

Commit 1872cb7

Browse files
committed
InstSimplify: support floating-point equivalences
Since cd16b07 (IR: introduce CmpInst::isEquivalence), there is now an isEquivalence routine in CmpInst that we can use to determine equivalence in simplifySelectWithICmpEq. Implement this, extending the code from integer-equalities to integer and floating-point equivalences.
1 parent eacce99 commit 1872cb7

File tree

2 files changed

+38
-72
lines changed

2 files changed

+38
-72
lines changed

llvm/lib/Analysis/InstructionSimplify.cpp

Lines changed: 28 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -4617,10 +4617,10 @@ static Value *simplifySelectWithFakeICmpEq(Value *CmpLHS, Value *CmpRHS,
46174617

46184618
/// Try to simplify a select instruction when its condition operand is an
46194619
/// integer equality comparison.
4620-
static Value *simplifySelectWithICmpEq(Value *CmpLHS, Value *CmpRHS,
4621-
Value *TrueVal, Value *FalseVal,
4622-
const SimplifyQuery &Q,
4623-
unsigned MaxRecurse) {
4620+
static Value *simplifySelectWithEquivalence(Value *CmpLHS, Value *CmpRHS,
4621+
Value *TrueVal, Value *FalseVal,
4622+
const SimplifyQuery &Q,
4623+
unsigned MaxRecurse) {
46244624
if (simplifyWithOpReplaced(FalseVal, CmpLHS, CmpRHS, Q.getWithoutUndef(),
46254625
/* AllowRefinement */ false,
46264626
/* DropFlags */ nullptr, MaxRecurse) == TrueVal)
@@ -4635,33 +4635,29 @@ static Value *simplifySelectWithICmpEq(Value *CmpLHS, Value *CmpRHS,
46354635

46364636
/// Try to simplify a select instruction when its condition operand is an
46374637
/// integer comparison.
4638-
static Value *simplifySelectWithICmpCond(Value *CondVal, Value *TrueVal,
4639-
Value *FalseVal,
4640-
const SimplifyQuery &Q,
4641-
unsigned MaxRecurse) {
4638+
static Value *simplifySelectWithCmpCond(Value *CondVal, Value *TrueVal,
4639+
Value *FalseVal, const SimplifyQuery &Q,
4640+
unsigned MaxRecurse) {
46424641
ICmpInst::Predicate Pred;
46434642
Value *CmpLHS, *CmpRHS;
4644-
if (!match(CondVal, m_ICmp(Pred, m_Value(CmpLHS), m_Value(CmpRHS))))
4643+
if (!match(CondVal, m_Cmp(Pred, m_Value(CmpLHS), m_Value(CmpRHS))))
46454644
return nullptr;
4645+
auto *CI = cast<CmpInst>(CondVal);
46464646

46474647
if (Value *V = simplifyCmpSelOfMaxMin(CmpLHS, CmpRHS, Pred, TrueVal, FalseVal))
46484648
return V;
46494649

4650-
// Canonicalize ne to eq predicate.
4651-
if (Pred == ICmpInst::ICMP_NE) {
4652-
Pred = ICmpInst::ICMP_EQ;
4650+
// Canonicalize the equivalence, of which equality is a subset.
4651+
if (CI->isEquivalence(/*Invert=*/true))
46534652
std::swap(TrueVal, FalseVal);
4654-
}
46554653

46564654
// Check for integer min/max with a limit constant:
46574655
// X > MIN_INT ? X : MIN_INT --> X
46584656
// X < MAX_INT ? X : MAX_INT --> X
46594657
if (TrueVal->getType()->isIntOrIntVectorTy()) {
46604658
Value *X, *Y;
46614659
SelectPatternFlavor SPF =
4662-
matchDecomposedSelectPattern(cast<ICmpInst>(CondVal), TrueVal, FalseVal,
4663-
X, Y)
4664-
.Flavor;
4660+
matchDecomposedSelectPattern(CI, TrueVal, FalseVal, X, Y).Flavor;
46654661
if (SelectPatternResult::isMinOrMax(SPF) && Pred == getMinMaxPred(SPF)) {
46664662
APInt LimitC = getMinMaxLimit(getInverseMinMaxFlavor(SPF),
46674663
X->getType()->getScalarSizeInBits());
@@ -4670,7 +4666,7 @@ static Value *simplifySelectWithICmpCond(Value *CondVal, Value *TrueVal,
46704666
}
46714667
}
46724668

4673-
if (Pred == ICmpInst::ICMP_EQ && match(CmpRHS, m_Zero())) {
4669+
if (CI->isEquality() && match(CmpRHS, m_Zero())) {
46744670
Value *X;
46754671
const APInt *Y;
46764672
if (match(CmpLHS, m_And(m_Value(X), m_APInt(Y))))
@@ -4698,7 +4694,7 @@ static Value *simplifySelectWithICmpCond(Value *CondVal, Value *TrueVal,
46984694
// (ShAmt == 0) ? X : fshl(X, X, ShAmt) --> fshl(X, X, ShAmt)
46994695
// (ShAmt == 0) ? X : fshr(X, X, ShAmt) --> fshr(X, X, ShAmt)
47004696
if (match(FalseVal, isRotate) && TrueVal == X && CmpLHS == ShAmt &&
4701-
Pred == ICmpInst::ICMP_EQ)
4697+
CI->isEquality())
47024698
return FalseVal;
47034699

47044700
// X == 0 ? abs(X) : -abs(X) --> -abs(X)
@@ -4720,12 +4716,12 @@ static Value *simplifySelectWithICmpCond(Value *CondVal, Value *TrueVal,
47204716
// If we have a scalar equality comparison, then we know the value in one of
47214717
// the arms of the select. See if substituting this value into the arm and
47224718
// simplifying the result yields the same value as the other arm.
4723-
if (Pred == ICmpInst::ICMP_EQ) {
4724-
if (Value *V = simplifySelectWithICmpEq(CmpLHS, CmpRHS, TrueVal, FalseVal,
4725-
Q, MaxRecurse))
4719+
if (CI->isEquivalence() || CI->isEquivalence(/*Invert=*/true)) {
4720+
if (Value *V = simplifySelectWithEquivalence(CmpLHS, CmpRHS, TrueVal,
4721+
FalseVal, Q, MaxRecurse))
47264722
return V;
4727-
if (Value *V = simplifySelectWithICmpEq(CmpRHS, CmpLHS, TrueVal, FalseVal,
4728-
Q, MaxRecurse))
4723+
if (Value *V = simplifySelectWithEquivalence(CmpRHS, CmpLHS, TrueVal,
4724+
FalseVal, Q, MaxRecurse))
47294725
return V;
47304726

47314727
Value *X;
@@ -4734,23 +4730,23 @@ static Value *simplifySelectWithICmpCond(Value *CondVal, Value *TrueVal,
47344730
if (match(CmpLHS, m_Or(m_Value(X), m_Value(Y))) &&
47354731
match(CmpRHS, m_Zero())) {
47364732
// (X | Y) == 0 implies X == 0 and Y == 0.
4737-
if (Value *V = simplifySelectWithICmpEq(X, CmpRHS, TrueVal, FalseVal, Q,
4738-
MaxRecurse))
4733+
if (Value *V = simplifySelectWithEquivalence(X, CmpRHS, TrueVal, FalseVal,
4734+
Q, MaxRecurse))
47394735
return V;
4740-
if (Value *V = simplifySelectWithICmpEq(Y, CmpRHS, TrueVal, FalseVal, Q,
4741-
MaxRecurse))
4736+
if (Value *V = simplifySelectWithEquivalence(Y, CmpRHS, TrueVal, FalseVal,
4737+
Q, MaxRecurse))
47424738
return V;
47434739
}
47444740

47454741
// select((X & Y) == -1 ? X : -1) --> -1 (commuted 2 ways)
47464742
if (match(CmpLHS, m_And(m_Value(X), m_Value(Y))) &&
47474743
match(CmpRHS, m_AllOnes())) {
47484744
// (X & Y) == -1 implies X == -1 and Y == -1.
4749-
if (Value *V = simplifySelectWithICmpEq(X, CmpRHS, TrueVal, FalseVal, Q,
4750-
MaxRecurse))
4745+
if (Value *V = simplifySelectWithEquivalence(X, CmpRHS, TrueVal, FalseVal,
4746+
Q, MaxRecurse))
47514747
return V;
4752-
if (Value *V = simplifySelectWithICmpEq(Y, CmpRHS, TrueVal, FalseVal, Q,
4753-
MaxRecurse))
4748+
if (Value *V = simplifySelectWithEquivalence(Y, CmpRHS, TrueVal, FalseVal,
4749+
Q, MaxRecurse))
47544750
return V;
47554751
}
47564752
}
@@ -4952,7 +4948,7 @@ static Value *simplifySelectInst(Value *Cond, Value *TrueVal, Value *FalseVal,
49524948
}
49534949

49544950
if (Value *V =
4955-
simplifySelectWithICmpCond(Cond, TrueVal, FalseVal, Q, MaxRecurse))
4951+
simplifySelectWithCmpCond(Cond, TrueVal, FalseVal, Q, MaxRecurse))
49564952
return V;
49574953

49584954
if (Value *V = simplifySelectWithFCmp(Cond, TrueVal, FalseVal, Q))

llvm/test/Transforms/InstSimplify/select-equivalence-fp.ll

Lines changed: 10 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,7 @@
33

44
define float @select_fcmp_fsub_oeq(float %x, float %y) {
55
; CHECK-LABEL: @select_fcmp_fsub_oeq(
6-
; CHECK-NEXT: [[FCMP:%.*]] = fcmp oeq float [[Y:%.*]], 2.000000e+00
7-
; CHECK-NEXT: [[FADD:%.*]] = fsub float [[Y]], 2.000000e+00
8-
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[FCMP]], float [[FADD]], float 0.000000e+00
9-
; CHECK-NEXT: ret float [[SEL]]
6+
; CHECK-NEXT: ret float 0.000000e+00
107
;
118
%fcmp = fcmp oeq float %y, 2.
129
%fadd = fsub float %y, 2.
@@ -42,10 +39,7 @@ define float @select_fcmp_fsub_ueq(float %x, float %y) {
4239

4340
define float @select_fcmp_fsub_ueq_nnan(float %x, float %y) {
4441
; CHECK-LABEL: @select_fcmp_fsub_ueq_nnan(
45-
; CHECK-NEXT: [[FCMP:%.*]] = fcmp nnan ueq float [[Y:%.*]], 2.000000e+00
46-
; CHECK-NEXT: [[FADD:%.*]] = fsub float [[Y]], 2.000000e+00
47-
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[FCMP]], float [[FADD]], float 0.000000e+00
48-
; CHECK-NEXT: ret float [[SEL]]
42+
; CHECK-NEXT: ret float 0.000000e+00
4943
;
5044
%fcmp = fcmp nnan ueq float %y, 2.
5145
%fadd = fsub float %y, 2.
@@ -55,10 +49,7 @@ define float @select_fcmp_fsub_ueq_nnan(float %x, float %y) {
5549

5650
define float @select_fcmp_fsub_une(float %x, float %y) {
5751
; CHECK-LABEL: @select_fcmp_fsub_une(
58-
; CHECK-NEXT: [[FCMP:%.*]] = fcmp une float [[Y:%.*]], 2.000000e+00
59-
; CHECK-NEXT: [[FADD:%.*]] = fsub float [[Y]], 2.000000e+00
60-
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[FCMP]], float 0.000000e+00, float [[FADD]]
61-
; CHECK-NEXT: ret float [[SEL]]
52+
; CHECK-NEXT: ret float 0.000000e+00
6253
;
6354
%fcmp = fcmp une float %y, 2.
6455
%fadd = fsub float %y, 2.
@@ -94,10 +85,7 @@ define float @select_fcmp_fsub_one(float %x, float %y) {
9485

9586
define float @select_fcmp_fsub_one_nnan(float %x, float %y) {
9687
; CHECK-LABEL: @select_fcmp_fsub_one_nnan(
97-
; CHECK-NEXT: [[FCMP:%.*]] = fcmp nnan one float [[Y:%.*]], 2.000000e+00
98-
; CHECK-NEXT: [[FADD:%.*]] = fsub float [[Y]], 2.000000e+00
99-
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[FCMP]], float 0.000000e+00, float [[FADD]]
100-
; CHECK-NEXT: ret float [[SEL]]
88+
; CHECK-NEXT: ret float 0.000000e+00
10189
;
10290
%fcmp = fcmp nnan one float %y, 2.
10391
%fadd = fsub float %y, 2.
@@ -107,10 +95,7 @@ define float @select_fcmp_fsub_one_nnan(float %x, float %y) {
10795

10896
define float @select_fcmp_fadd(float %x, float %y) {
10997
; CHECK-LABEL: @select_fcmp_fadd(
110-
; CHECK-NEXT: [[FCMP:%.*]] = fcmp oeq float [[Y:%.*]], 2.000000e+00
111-
; CHECK-NEXT: [[FADD:%.*]] = fadd float [[Y]], 2.000000e+00
112-
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[FCMP]], float [[FADD]], float 4.000000e+00
113-
; CHECK-NEXT: ret float [[SEL]]
98+
; CHECK-NEXT: ret float 4.000000e+00
11499
;
115100
%fcmp = fcmp oeq float %y, 2.
116101
%fadd = fadd float %y, 2.
@@ -120,10 +105,7 @@ define float @select_fcmp_fadd(float %x, float %y) {
120105

121106
define <2 x float> @select_fcmp_fadd_vec(<2 x float> %x, <2 x float> %y) {
122107
; CHECK-LABEL: @select_fcmp_fadd_vec(
123-
; CHECK-NEXT: [[FCMP:%.*]] = fcmp oeq <2 x float> [[Y:%.*]], <float 2.000000e+00, float 2.000000e+00>
124-
; CHECK-NEXT: [[FADD:%.*]] = fadd <2 x float> [[Y]], <float 2.000000e+00, float 2.000000e+00>
125-
; CHECK-NEXT: [[SEL:%.*]] = select <2 x i1> [[FCMP]], <2 x float> [[FADD]], <2 x float> <float 4.000000e+00, float 4.000000e+00>
126-
; CHECK-NEXT: ret <2 x float> [[SEL]]
108+
; CHECK-NEXT: ret <2 x float> <float 4.000000e+00, float 4.000000e+00>
127109
;
128110
%fcmp = fcmp oeq <2 x float> %y, <float 2., float 2.>
129111
%fadd = fadd <2 x float> %y, <float 2., float 2.>
@@ -134,10 +116,7 @@ define <2 x float> @select_fcmp_fadd_vec(<2 x float> %x, <2 x float> %y) {
134116

135117
define float @select_fcmp_fdiv(float %x, float %y) {
136118
; CHECK-LABEL: @select_fcmp_fdiv(
137-
; CHECK-NEXT: [[FCMP:%.*]] = fcmp oeq float [[Y:%.*]], 2.000000e+00
138-
; CHECK-NEXT: [[FDIV:%.*]] = fdiv float [[Y]], 2.000000e+00
139-
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[FCMP]], float [[FDIV]], float 1.000000e+00
140-
; CHECK-NEXT: ret float [[SEL]]
119+
; CHECK-NEXT: ret float 1.000000e+00
141120
;
142121
%fcmp = fcmp oeq float %y, 2.
143122
%fdiv = fdiv float %y, 2.
@@ -147,10 +126,7 @@ define float @select_fcmp_fdiv(float %x, float %y) {
147126

148127
define float @select_fcmp_frem(float %x, float %y) {
149128
; CHECK-LABEL: @select_fcmp_frem(
150-
; CHECK-NEXT: [[FCMP:%.*]] = fcmp oeq float [[Y:%.*]], 3.000000e+00
151-
; CHECK-NEXT: [[FREM:%.*]] = frem float [[Y]], 2.000000e+00
152-
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[FCMP]], float [[FREM]], float 1.000000e+00
153-
; CHECK-NEXT: ret float [[SEL]]
129+
; CHECK-NEXT: ret float 1.000000e+00
154130
;
155131
%fcmp = fcmp oeq float %y, 3.
156132
%frem = frem float %y, 2.
@@ -160,10 +136,7 @@ define float @select_fcmp_frem(float %x, float %y) {
160136

161137
define <2 x float> @select_fcmp_insertelement(<2 x float> %x, <2 x float> %y) {
162138
; CHECK-LABEL: @select_fcmp_insertelement(
163-
; CHECK-NEXT: [[CMP:%.*]] = fcmp oeq <2 x float> [[Y:%.*]], <float 2.000000e+00, float 2.000000e+00>
164-
; CHECK-NEXT: [[INSERT:%.*]] = insertelement <2 x float> [[Y]], float 4.000000e+00, i64 0
165-
; CHECK-NEXT: [[RETVAL:%.*]] = select <2 x i1> [[CMP]], <2 x float> [[INSERT]], <2 x float> <float 4.000000e+00, float 2.000000e+00>
166-
; CHECK-NEXT: ret <2 x float> [[RETVAL]]
139+
; CHECK-NEXT: ret <2 x float> <float 4.000000e+00, float 2.000000e+00>
167140
;
168141
%fcmp = fcmp oeq <2 x float> %y, <float 2., float 2.>
169142
%insert = insertelement <2 x float> %y, float 4., i64 0
@@ -173,10 +146,7 @@ define <2 x float> @select_fcmp_insertelement(<2 x float> %x, <2 x float> %y) {
173146

174147
define <4 x float> @select_fcmp_shufflevector_select(<4 x float> %x, <4 x float> %y) {
175148
; CHECK-LABEL: @select_fcmp_shufflevector_select(
176-
; CHECK-NEXT: [[FCMP:%.*]] = fcmp oeq <4 x float> [[Y:%.*]], <float 2.000000e+00, float 2.000000e+00, float 2.000000e+00, float 2.000000e+00>
177-
; CHECK-NEXT: [[SHUFFLE:%.*]] = shufflevector <4 x float> [[Y]], <4 x float> poison, <4 x i32> <i32 4, i32 1, i32 6, i32 3>
178-
; CHECK-NEXT: [[SEL:%.*]] = select <4 x i1> [[FCMP]], <4 x float> [[SHUFFLE]], <4 x float> <float poison, float 2.000000e+00, float poison, float 2.000000e+00>
179-
; CHECK-NEXT: ret <4 x float> [[SEL]]
149+
; CHECK-NEXT: ret <4 x float> <float poison, float 2.000000e+00, float poison, float 2.000000e+00>
180150
;
181151
%fcmp = fcmp oeq <4 x float> %y, <float 2., float 2., float 2., float 2.>
182152
%shuffle = shufflevector <4 x float> %y, <4 x float> poison, <4 x i32> <i32 4, i32 1, i32 6, i32 3>

0 commit comments

Comments
 (0)