Skip to content

Commit d65a025

Browse files
committed
SelectionDAG/expandFMINIMUMNUM_FMAXIMUMNUM: FCANONICALIZE is needed only for sNaN
If we are sure that it is not sNaN, even it may be qNaN, we can use it directly.
1 parent 7020dbc commit d65a025

File tree

3 files changed

+246
-5
lines changed

3 files changed

+246
-5
lines changed

llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7676,6 +7676,9 @@ SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT,
76767676
N2.getOpcode() != ISD::DELETED_NODE &&
76777677
N3.getOpcode() != ISD::DELETED_NODE &&
76787678
"Operand is DELETED_NODE!");
7679+
7680+
SDNodeFlags NewFlags = Flags;
7681+
76797682
// Perform various simplifications.
76807683
switch (Opcode) {
76817684
case ISD::FMA:
@@ -7734,6 +7737,13 @@ SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT,
77347737
}
77357738
case ISD::SELECT:
77367739
case ISD::VSELECT:
7740+
if ((N1->getFlags().hasNoSNaNs() && N2->getFlags().hasNoSNaNs()) ||
7741+
N3->getFlags().hasNoSNaNs())
7742+
NewFlags.setNoSNaNs(true);
7743+
if ((N1->getFlags().hasNoQNaNs() && N2->getFlags().hasNoQNaNs()) ||
7744+
N3->getFlags().hasNoQNaNs())
7745+
NewFlags.setNoQNaNs(true);
7746+
77377747
if (SDValue V = simplifySelect(N1, N2, N3))
77387748
return V;
77397749
break;
@@ -7862,12 +7872,12 @@ SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT,
78627872
AddNodeIDNode(ID, Opcode, VTs, Ops);
78637873
void *IP = nullptr;
78647874
if (SDNode *E = FindNodeOrInsertPos(ID, DL, IP)) {
7865-
E->intersectFlagsWith(Flags);
7875+
E->intersectFlagsWith(NewFlags);
78667876
return SDValue(E, 0);
78677877
}
78687878

78697879
N = newSDNode<SDNode>(Opcode, DL.getIROrder(), DL.getDebugLoc(), VTs);
7870-
N->setFlags(Flags);
7880+
N->setFlags(NewFlags);
78717881
createOperands(N, Ops);
78727882
CSEMap.InsertNode(N, IP);
78737883
} else {
@@ -10325,6 +10335,8 @@ SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT,
1032510335
"Operand is DELETED_NODE!");
1032610336
#endif
1032710337

10338+
SDNodeFlags NewFlags = Flags;
10339+
1032810340
switch (Opcode) {
1032910341
default: break;
1033010342
case ISD::BUILD_VECTOR:
@@ -10349,6 +10361,10 @@ SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT,
1034910361
VT.getVectorElementCount()) &&
1035010362
"Expected select_cc with vector result to have the same sized "
1035110363
"comparison type!");
10364+
if (Ops[2]->getFlags().hasNoSNaNs() && Ops[3]->getFlags().hasNoSNaNs())
10365+
NewFlags.setNoSNaNs(true);
10366+
if (Ops[2]->getFlags().hasNoQNaNs() && Ops[3]->getFlags().hasNoQNaNs())
10367+
NewFlags.setNoQNaNs(true);
1035210368
break;
1035310369
case ISD::BR_CC:
1035410370
assert(NumOps == 5 && "BR_CC takes 5 operands!");
@@ -10415,7 +10431,7 @@ SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT,
1041510431
createOperands(N, Ops);
1041610432
}
1041710433

10418-
N->setFlags(Flags);
10434+
N->setFlags(NewFlags);
1041910435
InsertNode(N);
1042010436
SDValue V(N, 0);
1042110437
NewSDValueDbgMsg(V, "Creating new node: ", this);

llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8664,8 +8664,8 @@ SDValue TargetLowering::expandFMINIMUMNUM_FMAXIMUMNUM(SDNode *Node,
86648664
SDValue MinMax =
86658665
DAG.getSelectCC(DL, LHS, RHS, LHS, RHS, IsMax ? ISD::SETGT : ISD::SETLT);
86668666
// If MinMax is NaN, let's quiet it.
8667-
if (!Flags.hasNoNaNs() && !DAG.isKnownNeverNaN(LHS) &&
8668-
!DAG.isKnownNeverNaN(RHS)) {
8667+
if (!Flags.hasNoNaNs() && !DAG.isKnownNeverSNaN(LHS) &&
8668+
!DAG.isKnownNeverSNaN(RHS)) {
86698669
MinMax = DAG.getNode(ISD::FCANONICALIZE, DL, VT, MinMax, Flags);
86708670
}
86718671

Lines changed: 225 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,225 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2+
; RUN: llc --mtriple=mipsisa64r6 < %s | FileCheck %s --check-prefix=MIPS64R6
3+
; RUN: llc --mtriple=mips64 < %s | FileCheck %s --check-prefix=MIPS64R2
4+
5+
declare float @llvm.maximumnum.f32(float, float)
6+
declare double @llvm.maximumnum.f64(double, double)
7+
declare float @llvm.minimumnum.f32(float, float)
8+
declare double @llvm.minimumnum.f64(double, double)
9+
10+
define float @maximumnum_float_nnan(float nofpclass(nan) %x, float nofpclass(nan) %y) {
11+
; MIPS64R6-LABEL: maximumnum_float_nnan:
12+
; MIPS64R6: # %bb.0:
13+
; MIPS64R6-NEXT: jr $ra
14+
; MIPS64R6-NEXT: max.s $f0, $f12, $f13
15+
;
16+
; MIPS64R2-LABEL: maximumnum_float_nnan:
17+
; MIPS64R2: # %bb.0:
18+
; MIPS64R2-NEXT: c.ule.s $f12, $f13
19+
; MIPS64R2-NEXT: mov.s $f0, $f13
20+
; MIPS64R2-NEXT: movf.s $f0, $f12, $fcc0
21+
; MIPS64R2-NEXT: mfc1 $1, $f12
22+
; MIPS64R2-NEXT: mov.s $f1, $f0
23+
; MIPS64R2-NEXT: movz.s $f1, $f12, $1
24+
; MIPS64R2-NEXT: mfc1 $1, $f13
25+
; MIPS64R2-NEXT: movz.s $f1, $f13, $1
26+
; MIPS64R2-NEXT: mtc1 $zero, $f2
27+
; MIPS64R2-NEXT: c.eq.s $f0, $f2
28+
; MIPS64R2-NEXT: jr $ra
29+
; MIPS64R2-NEXT: movt.s $f0, $f1, $fcc0
30+
%z = call float @llvm.maximumnum.f32(float %x, float %y)
31+
ret float %z
32+
}
33+
34+
define float @maximumnum_float_nsnan(float nofpclass(snan) %x, float nofpclass(snan) %y) {
35+
; MIPS64R6-LABEL: maximumnum_float_nsnan:
36+
; MIPS64R6: # %bb.0:
37+
; MIPS64R6-NEXT: jr $ra
38+
; MIPS64R6-NEXT: max.s $f0, $f12, $f13
39+
;
40+
; MIPS64R2-LABEL: maximumnum_float_nsnan:
41+
; MIPS64R2: # %bb.0:
42+
; MIPS64R2-NEXT: c.un.s $f12, $f12
43+
; MIPS64R2-NEXT: movt.s $f12, $f13, $fcc0
44+
; MIPS64R2-NEXT: c.un.s $f13, $f13
45+
; MIPS64R2-NEXT: movt.s $f13, $f12, $fcc0
46+
; MIPS64R2-NEXT: c.ule.s $f12, $f13
47+
; MIPS64R2-NEXT: mov.s $f0, $f13
48+
; MIPS64R2-NEXT: movf.s $f0, $f12, $fcc0
49+
; MIPS64R2-NEXT: mfc1 $1, $f12
50+
; MIPS64R2-NEXT: mov.s $f1, $f0
51+
; MIPS64R2-NEXT: movz.s $f1, $f12, $1
52+
; MIPS64R2-NEXT: mfc1 $1, $f13
53+
; MIPS64R2-NEXT: movz.s $f1, $f13, $1
54+
; MIPS64R2-NEXT: mtc1 $zero, $f2
55+
; MIPS64R2-NEXT: c.eq.s $f0, $f2
56+
; MIPS64R2-NEXT: jr $ra
57+
; MIPS64R2-NEXT: movt.s $f0, $f1, $fcc0
58+
%z = call float @llvm.maximumnum.f32(float %x, float %y)
59+
ret float %z
60+
}
61+
62+
define float @minimumnum_float_nnan(float nofpclass(nan) %x, float nofpclass(nan) %y) {
63+
; MIPS64R6-LABEL: minimumnum_float_nnan:
64+
; MIPS64R6: # %bb.0:
65+
; MIPS64R6-NEXT: jr $ra
66+
; MIPS64R6-NEXT: min.s $f0, $f12, $f13
67+
;
68+
; MIPS64R2-LABEL: minimumnum_float_nnan:
69+
; MIPS64R2: # %bb.0:
70+
; MIPS64R2-NEXT: c.olt.s $f12, $f13
71+
; MIPS64R2-NEXT: mov.s $f0, $f13
72+
; MIPS64R2-NEXT: movt.s $f0, $f12, $fcc0
73+
; MIPS64R2-NEXT: mfc1 $1, $f12
74+
; MIPS64R2-NEXT: lui $2, 32768
75+
; MIPS64R2-NEXT: xor $1, $1, $2
76+
; MIPS64R2-NEXT: mov.s $f1, $f0
77+
; MIPS64R2-NEXT: movz.s $f1, $f12, $1
78+
; MIPS64R2-NEXT: mfc1 $1, $f13
79+
; MIPS64R2-NEXT: xor $1, $1, $2
80+
; MIPS64R2-NEXT: movz.s $f1, $f13, $1
81+
; MIPS64R2-NEXT: mtc1 $zero, $f2
82+
; MIPS64R2-NEXT: c.eq.s $f0, $f2
83+
; MIPS64R2-NEXT: jr $ra
84+
; MIPS64R2-NEXT: movt.s $f0, $f1, $fcc0
85+
%z = call float @llvm.minimumnum.f32(float %x, float %y)
86+
ret float %z
87+
}
88+
89+
define float @minimumnum_float_nsnan(float nofpclass(snan) %x, float nofpclass(snan) %y) {
90+
; MIPS64R6-LABEL: minimumnum_float_nsnan:
91+
; MIPS64R6: # %bb.0:
92+
; MIPS64R6-NEXT: jr $ra
93+
; MIPS64R6-NEXT: max.s $f0, $f12, $f13
94+
;
95+
; MIPS64R2-LABEL: minimumnum_float_nsnan:
96+
; MIPS64R2: # %bb.0:
97+
; MIPS64R2-NEXT: c.un.s $f12, $f12
98+
; MIPS64R2-NEXT: movt.s $f12, $f13, $fcc0
99+
; MIPS64R2-NEXT: c.un.s $f13, $f13
100+
; MIPS64R2-NEXT: movt.s $f13, $f12, $fcc0
101+
; MIPS64R2-NEXT: c.ule.s $f12, $f13
102+
; MIPS64R2-NEXT: mov.s $f0, $f13
103+
; MIPS64R2-NEXT: movf.s $f0, $f12, $fcc0
104+
; MIPS64R2-NEXT: mfc1 $1, $f12
105+
; MIPS64R2-NEXT: mov.s $f1, $f0
106+
; MIPS64R2-NEXT: movz.s $f1, $f12, $1
107+
; MIPS64R2-NEXT: mfc1 $1, $f13
108+
; MIPS64R2-NEXT: movz.s $f1, $f13, $1
109+
; MIPS64R2-NEXT: mtc1 $zero, $f2
110+
; MIPS64R2-NEXT: c.eq.s $f0, $f2
111+
; MIPS64R2-NEXT: jr $ra
112+
; MIPS64R2-NEXT: movt.s $f0, $f1, $fcc0
113+
%z = call float @llvm.maximumnum.f32(float %x, float %y)
114+
ret float %z
115+
}
116+
117+
118+
119+
define double @maximumnum_double_nnan(double nofpclass(nan) %x, double nofpclass(nan) %y) {
120+
; MIPS64R6-LABEL: maximumnum_double_nnan:
121+
; MIPS64R6: # %bb.0:
122+
; MIPS64R6-NEXT: jr $ra
123+
; MIPS64R6-NEXT: max.d $f0, $f12, $f13
124+
;
125+
; MIPS64R2-LABEL: maximumnum_double_nnan:
126+
; MIPS64R2: # %bb.0:
127+
; MIPS64R2-NEXT: c.ule.d $f12, $f13
128+
; MIPS64R2-NEXT: mov.d $f0, $f13
129+
; MIPS64R2-NEXT: movf.d $f0, $f12, $fcc0
130+
; MIPS64R2-NEXT: dmfc1 $1, $f12
131+
; MIPS64R2-NEXT: mov.d $f1, $f0
132+
; MIPS64R2-NEXT: movz.d $f1, $f12, $1
133+
; MIPS64R2-NEXT: dmfc1 $1, $f13
134+
; MIPS64R2-NEXT: movz.d $f1, $f13, $1
135+
; MIPS64R2-NEXT: dmtc1 $zero, $f2
136+
; MIPS64R2-NEXT: c.eq.d $f0, $f2
137+
; MIPS64R2-NEXT: jr $ra
138+
; MIPS64R2-NEXT: movt.d $f0, $f1, $fcc0
139+
%z = call double @llvm.maximumnum.f64(double %x, double %y)
140+
ret double %z
141+
}
142+
143+
define double @maximumnum_double_nsnan(double nofpclass(snan) %x, double nofpclass(snan) %y) {
144+
; MIPS64R6-LABEL: maximumnum_double_nsnan:
145+
; MIPS64R6: # %bb.0:
146+
; MIPS64R6-NEXT: jr $ra
147+
; MIPS64R6-NEXT: max.d $f0, $f12, $f13
148+
;
149+
; MIPS64R2-LABEL: maximumnum_double_nsnan:
150+
; MIPS64R2: # %bb.0:
151+
; MIPS64R2-NEXT: c.un.d $f12, $f12
152+
; MIPS64R2-NEXT: movt.d $f12, $f13, $fcc0
153+
; MIPS64R2-NEXT: c.un.d $f13, $f13
154+
; MIPS64R2-NEXT: movt.d $f13, $f12, $fcc0
155+
; MIPS64R2-NEXT: c.ule.d $f12, $f13
156+
; MIPS64R2-NEXT: mov.d $f0, $f13
157+
; MIPS64R2-NEXT: movf.d $f0, $f12, $fcc0
158+
; MIPS64R2-NEXT: dmfc1 $1, $f12
159+
; MIPS64R2-NEXT: mov.d $f1, $f0
160+
; MIPS64R2-NEXT: movz.d $f1, $f12, $1
161+
; MIPS64R2-NEXT: dmfc1 $1, $f13
162+
; MIPS64R2-NEXT: movz.d $f1, $f13, $1
163+
; MIPS64R2-NEXT: dmtc1 $zero, $f2
164+
; MIPS64R2-NEXT: c.eq.d $f0, $f2
165+
; MIPS64R2-NEXT: jr $ra
166+
; MIPS64R2-NEXT: movt.d $f0, $f1, $fcc0
167+
%z = call double @llvm.maximumnum.f64(double %x, double %y)
168+
ret double %z
169+
}
170+
171+
define double @minimumnum_double_nnan(double nofpclass(nan) %x, double nofpclass(nan) %y) {
172+
; MIPS64R6-LABEL: minimumnum_double_nnan:
173+
; MIPS64R6: # %bb.0:
174+
; MIPS64R6-NEXT: jr $ra
175+
; MIPS64R6-NEXT: min.d $f0, $f12, $f13
176+
;
177+
; MIPS64R2-LABEL: minimumnum_double_nnan:
178+
; MIPS64R2: # %bb.0:
179+
; MIPS64R2-NEXT: c.olt.d $f12, $f13
180+
; MIPS64R2-NEXT: mov.d $f0, $f13
181+
; MIPS64R2-NEXT: movt.d $f0, $f12, $fcc0
182+
; MIPS64R2-NEXT: daddiu $1, $zero, 1
183+
; MIPS64R2-NEXT: dsll $1, $1, 63
184+
; MIPS64R2-NEXT: dmfc1 $2, $f12
185+
; MIPS64R2-NEXT: xor $2, $2, $1
186+
; MIPS64R2-NEXT: mov.d $f1, $f0
187+
; MIPS64R2-NEXT: movz.d $f1, $f12, $2
188+
; MIPS64R2-NEXT: dmfc1 $2, $f13
189+
; MIPS64R2-NEXT: xor $1, $2, $1
190+
; MIPS64R2-NEXT: movz.d $f1, $f13, $1
191+
; MIPS64R2-NEXT: dmtc1 $zero, $f2
192+
; MIPS64R2-NEXT: c.eq.d $f0, $f2
193+
; MIPS64R2-NEXT: jr $ra
194+
; MIPS64R2-NEXT: movt.d $f0, $f1, $fcc0
195+
%z = call double @llvm.minimumnum.f64(double %x, double %y)
196+
ret double %z
197+
}
198+
199+
define double @minimumnum_double_nsnan(double nofpclass(snan) %x, double nofpclass(snan) %y) {
200+
; MIPS64R6-LABEL: minimumnum_double_nsnan:
201+
; MIPS64R6: # %bb.0:
202+
; MIPS64R6-NEXT: jr $ra
203+
; MIPS64R6-NEXT: max.d $f0, $f12, $f13
204+
;
205+
; MIPS64R2-LABEL: minimumnum_double_nsnan:
206+
; MIPS64R2: # %bb.0:
207+
; MIPS64R2-NEXT: c.un.d $f12, $f12
208+
; MIPS64R2-NEXT: movt.d $f12, $f13, $fcc0
209+
; MIPS64R2-NEXT: c.un.d $f13, $f13
210+
; MIPS64R2-NEXT: movt.d $f13, $f12, $fcc0
211+
; MIPS64R2-NEXT: c.ule.d $f12, $f13
212+
; MIPS64R2-NEXT: mov.d $f0, $f13
213+
; MIPS64R2-NEXT: movf.d $f0, $f12, $fcc0
214+
; MIPS64R2-NEXT: dmfc1 $1, $f12
215+
; MIPS64R2-NEXT: mov.d $f1, $f0
216+
; MIPS64R2-NEXT: movz.d $f1, $f12, $1
217+
; MIPS64R2-NEXT: dmfc1 $1, $f13
218+
; MIPS64R2-NEXT: movz.d $f1, $f13, $1
219+
; MIPS64R2-NEXT: dmtc1 $zero, $f2
220+
; MIPS64R2-NEXT: c.eq.d $f0, $f2
221+
; MIPS64R2-NEXT: jr $ra
222+
; MIPS64R2-NEXT: movt.d $f0, $f1, $fcc0
223+
%z = call double @llvm.maximumnum.f64(double %x, double %y)
224+
ret double %z
225+
}

0 commit comments

Comments
 (0)