Skip to content

Commit 62aaa96

Browse files
[SDAG[[X86] Added method to scalarize STRICT_FSETCC (llvm#154486)
Fixes llvm#154485
1 parent 3baddbb commit 62aaa96

File tree

3 files changed

+335
-0
lines changed

3 files changed

+335
-0
lines changed

llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -909,6 +909,7 @@ class LLVM_LIBRARY_VISIBILITY DAGTypeLegalizer {
909909
SDValue ScalarizeVecOp_EXTRACT_VECTOR_ELT(SDNode *N);
910910
SDValue ScalarizeVecOp_VSELECT(SDNode *N);
911911
SDValue ScalarizeVecOp_VSETCC(SDNode *N);
912+
SDValue ScalarizeVecOp_VSTRICT_FSETCC(SDNode *N, unsigned OpNo);
912913
SDValue ScalarizeVecOp_STORE(StoreSDNode *N, unsigned OpNo);
913914
SDValue ScalarizeVecOp_FP_ROUND(SDNode *N, unsigned OpNo);
914915
SDValue ScalarizeVecOp_STRICT_FP_ROUND(SDNode *N, unsigned OpNo);

llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -789,6 +789,10 @@ bool DAGTypeLegalizer::ScalarizeVectorOperand(SDNode *N, unsigned OpNo) {
789789
case ISD::SETCC:
790790
Res = ScalarizeVecOp_VSETCC(N);
791791
break;
792+
case ISD::STRICT_FSETCC:
793+
case ISD::STRICT_FSETCCS:
794+
Res = ScalarizeVecOp_VSTRICT_FSETCC(N, OpNo);
795+
break;
792796
case ISD::STORE:
793797
Res = ScalarizeVecOp_STORE(cast<StoreSDNode>(N), OpNo);
794798
break;
@@ -985,6 +989,43 @@ SDValue DAGTypeLegalizer::ScalarizeVecOp_VSETCC(SDNode *N) {
985989
return DAG.getNode(ISD::SCALAR_TO_VECTOR, DL, VT, Res);
986990
}
987991

992+
// Similiar to ScalarizeVecOp_VSETCC, with added logic to update chains.
993+
SDValue DAGTypeLegalizer::ScalarizeVecOp_VSTRICT_FSETCC(SDNode *N,
994+
unsigned OpNo) {
995+
assert(OpNo == 1 && "Wrong operand for scalarization!");
996+
assert(N->getValueType(0).isVector() &&
997+
N->getOperand(1).getValueType().isVector() &&
998+
"Operand types must be vectors");
999+
assert(N->getValueType(0) == MVT::v1i1 && "Expected v1i1 type");
1000+
1001+
EVT VT = N->getValueType(0);
1002+
SDValue Ch = N->getOperand(0);
1003+
SDValue LHS = GetScalarizedVector(N->getOperand(1));
1004+
SDValue RHS = GetScalarizedVector(N->getOperand(2));
1005+
SDValue CC = N->getOperand(3);
1006+
1007+
EVT OpVT = N->getOperand(1).getValueType();
1008+
EVT NVT = VT.getVectorElementType();
1009+
SDLoc DL(N);
1010+
SDValue Res = DAG.getNode(N->getOpcode(), DL, {MVT::i1, MVT::Other},
1011+
{Ch, LHS, RHS, CC});
1012+
1013+
// Legalize the chain result - switch anything that used the old chain to
1014+
// use the new one.
1015+
ReplaceValueWith(SDValue(N, 1), Res.getValue(1));
1016+
1017+
ISD::NodeType ExtendCode =
1018+
TargetLowering::getExtendForContent(TLI.getBooleanContents(OpVT));
1019+
1020+
Res = DAG.getNode(ExtendCode, DL, NVT, Res);
1021+
Res = DAG.getNode(ISD::SCALAR_TO_VECTOR, DL, VT, Res);
1022+
1023+
// Do our own replacement and return SDValue() to tell the caller that we
1024+
// handled all replacements since caller can only handle a single result.
1025+
ReplaceValueWith(SDValue(N, 0), Res);
1026+
return SDValue();
1027+
}
1028+
9881029
/// If the value to store is a vector that needs to be scalarized, it must be
9891030
/// <1 x ty>. Just store the element.
9901031
SDValue DAGTypeLegalizer::ScalarizeVecOp_STORE(StoreSDNode *N, unsigned OpNo){
Lines changed: 293 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,293 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
2+
; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx512f | FileCheck %s
3+
4+
define <1 x i1> @test_oeq_q_v1f64(<1 x double> %a, <1 x double> %b) {
5+
; CHECK-LABEL: test_oeq_q_v1f64:
6+
; CHECK: # %bb.0:
7+
; CHECK-NEXT: vucomisd %xmm1, %xmm0
8+
; CHECK-NEXT: setnp %cl
9+
; CHECK-NEXT: sete %al
10+
; CHECK-NEXT: andb %cl, %al
11+
; CHECK-NEXT: retq
12+
%cond = tail call <1 x i1> @llvm.experimental.constrained.fcmp.v1f64(<1 x double> %a, <1 x double> %b, metadata !"oeq", metadata !"fpexcept.strict")
13+
ret <1 x i1> %cond
14+
}
15+
16+
define <1 x i1> @test_ogt_q_v1f64(<1 x double> %a, <1 x double> %b) {
17+
; CHECK-LABEL: test_ogt_q_v1f64:
18+
; CHECK: # %bb.0:
19+
; CHECK-NEXT: vucomisd %xmm1, %xmm0
20+
; CHECK-NEXT: seta %al
21+
; CHECK-NEXT: retq
22+
%cond = tail call <1 x i1> @llvm.experimental.constrained.fcmp.v1f64(<1 x double> %a, <1 x double> %b, metadata !"ogt", metadata !"fpexcept.strict")
23+
ret <1 x i1> %cond
24+
}
25+
26+
define <1 x i1> @test_oge_q_v1f64(<1 x double> %a, <1 x double> %b) {
27+
; CHECK-LABEL: test_oge_q_v1f64:
28+
; CHECK: # %bb.0:
29+
; CHECK-NEXT: vucomisd %xmm1, %xmm0
30+
; CHECK-NEXT: setae %al
31+
; CHECK-NEXT: retq
32+
%cond = tail call <1 x i1> @llvm.experimental.constrained.fcmp.v1f64(<1 x double> %a, <1 x double> %b, metadata !"oge", metadata !"fpexcept.strict")
33+
ret <1 x i1> %cond
34+
}
35+
36+
define <1 x i1> @test_olt_q_v1f64(<1 x double> %a, <1 x double> %b) {
37+
; CHECK-LABEL: test_olt_q_v1f64:
38+
; CHECK: # %bb.0:
39+
; CHECK-NEXT: vucomisd %xmm0, %xmm1
40+
; CHECK-NEXT: seta %al
41+
; CHECK-NEXT: retq
42+
%cond = tail call <1 x i1> @llvm.experimental.constrained.fcmp.v1f64(<1 x double> %a, <1 x double> %b, metadata !"olt", metadata !"fpexcept.strict")
43+
ret <1 x i1> %cond
44+
}
45+
46+
define <1 x i1> @test_ole_q_v1f64(<1 x double> %a, <1 x double> %b) {
47+
; CHECK-LABEL: test_ole_q_v1f64:
48+
; CHECK: # %bb.0:
49+
; CHECK-NEXT: vucomisd %xmm0, %xmm1
50+
; CHECK-NEXT: setae %al
51+
; CHECK-NEXT: retq
52+
%cond = tail call <1 x i1> @llvm.experimental.constrained.fcmp.v1f64(<1 x double> %a, <1 x double> %b, metadata !"ole", metadata !"fpexcept.strict")
53+
ret <1 x i1> %cond
54+
}
55+
56+
define <1 x i1> @test_one_q_v1f64(<1 x double> %a, <1 x double> %b) {
57+
; CHECK-LABEL: test_one_q_v1f64:
58+
; CHECK: # %bb.0:
59+
; CHECK-NEXT: vucomisd %xmm1, %xmm0
60+
; CHECK-NEXT: setne %al
61+
; CHECK-NEXT: retq
62+
%cond = tail call <1 x i1> @llvm.experimental.constrained.fcmp.v1f64(<1 x double> %a, <1 x double> %b, metadata !"one", metadata !"fpexcept.strict")
63+
ret <1 x i1> %cond
64+
}
65+
66+
define <1 x i1> @test_ord_q_v1f64(<1 x double> %a, <1 x double> %b) {
67+
; CHECK-LABEL: test_ord_q_v1f64:
68+
; CHECK: # %bb.0:
69+
; CHECK-NEXT: vucomisd %xmm1, %xmm0
70+
; CHECK-NEXT: setnp %al
71+
; CHECK-NEXT: retq
72+
%cond = tail call <1 x i1> @llvm.experimental.constrained.fcmp.v1f64(<1 x double> %a, <1 x double> %b, metadata !"ord", metadata !"fpexcept.strict")
73+
ret <1 x i1> %cond
74+
}
75+
76+
define <1 x i1> @test_ueq_q_v1f64(<1 x double> %a, <1 x double> %b) {
77+
; CHECK-LABEL: test_ueq_q_v1f64:
78+
; CHECK: # %bb.0:
79+
; CHECK-NEXT: vucomisd %xmm1, %xmm0
80+
; CHECK-NEXT: setnp %al
81+
; CHECK-NEXT: retq
82+
%cond = tail call <1 x i1> @llvm.experimental.constrained.fcmp.v1f64(<1 x double> %a, <1 x double> %b, metadata !"ord", metadata !"fpexcept.strict")
83+
ret <1 x i1> %cond
84+
}
85+
86+
define <1 x i1> @test_ugt_q_v1f64(<1 x double> %a, <1 x double> %b) {
87+
; CHECK-LABEL: test_ugt_q_v1f64:
88+
; CHECK: # %bb.0:
89+
; CHECK-NEXT: vucomisd %xmm0, %xmm1
90+
; CHECK-NEXT: setb %al
91+
; CHECK-NEXT: retq
92+
%cond = tail call <1 x i1> @llvm.experimental.constrained.fcmp.v1f64(<1 x double> %a, <1 x double> %b, metadata !"ugt", metadata !"fpexcept.strict")
93+
ret <1 x i1> %cond
94+
}
95+
96+
define <1 x i1> @test_uge_q_v1f64(<1 x double> %a, <1 x double> %b) {
97+
; CHECK-LABEL: test_uge_q_v1f64:
98+
; CHECK: # %bb.0:
99+
; CHECK-NEXT: vucomisd %xmm0, %xmm1
100+
; CHECK-NEXT: setbe %al
101+
; CHECK-NEXT: retq
102+
%cond = tail call <1 x i1> @llvm.experimental.constrained.fcmp.v1f64(<1 x double> %a, <1 x double> %b, metadata !"uge", metadata !"fpexcept.strict")
103+
ret <1 x i1> %cond
104+
}
105+
106+
define <1 x i1> @test_ult_q_v1f64(<1 x double> %a, <1 x double> %b) {
107+
; CHECK-LABEL: test_ult_q_v1f64:
108+
; CHECK: # %bb.0:
109+
; CHECK-NEXT: vucomisd %xmm1, %xmm0
110+
; CHECK-NEXT: setb %al
111+
; CHECK-NEXT: retq
112+
%cond = tail call <1 x i1> @llvm.experimental.constrained.fcmp.v1f64(<1 x double> %a, <1 x double> %b, metadata !"ult", metadata !"fpexcept.strict")
113+
ret <1 x i1> %cond
114+
}
115+
116+
define <1 x i1> @test_ule_q_v1f64(<1 x double> %a, <1 x double> %b) {
117+
; CHECK-LABEL: test_ule_q_v1f64:
118+
; CHECK: # %bb.0:
119+
; CHECK-NEXT: vucomisd %xmm1, %xmm0
120+
; CHECK-NEXT: setbe %al
121+
; CHECK-NEXT: retq
122+
%cond = tail call <1 x i1> @llvm.experimental.constrained.fcmp.v1f64(<1 x double> %a, <1 x double> %b, metadata !"ule", metadata !"fpexcept.strict")
123+
ret <1 x i1> %cond
124+
}
125+
126+
define <1 x i1> @test_une_q_v1f64(<1 x double> %a, <1 x double> %b) {
127+
; CHECK-LABEL: test_une_q_v1f64:
128+
; CHECK: # %bb.0:
129+
; CHECK-NEXT: vucomisd %xmm1, %xmm0
130+
; CHECK-NEXT: setp %cl
131+
; CHECK-NEXT: setne %al
132+
; CHECK-NEXT: orb %cl, %al
133+
; CHECK-NEXT: retq
134+
%cond = tail call <1 x i1> @llvm.experimental.constrained.fcmp.v1f64(<1 x double> %a, <1 x double> %b, metadata !"une", metadata !"fpexcept.strict")
135+
ret <1 x i1> %cond
136+
}
137+
138+
define <1 x i1> @test_uno_q_v1f64(<1 x double> %a, <1 x double> %b) {
139+
; CHECK-LABEL: test_uno_q_v1f64:
140+
; CHECK: # %bb.0:
141+
; CHECK-NEXT: vucomisd %xmm1, %xmm0
142+
; CHECK-NEXT: setp %al
143+
; CHECK-NEXT: retq
144+
%cond = tail call <1 x i1> @llvm.experimental.constrained.fcmp.v1f64(<1 x double> %a, <1 x double> %b, metadata !"uno", metadata !"fpexcept.strict")
145+
ret <1 x i1> %cond
146+
}
147+
148+
define <1 x i1> @test_oeq_s_v1f64(<1 x double> %a, <1 x double> %b) {
149+
; CHECK-LABEL: test_oeq_s_v1f64:
150+
; CHECK: # %bb.0:
151+
; CHECK-NEXT: vcomisd %xmm1, %xmm0
152+
; CHECK-NEXT: setnp %cl
153+
; CHECK-NEXT: sete %al
154+
; CHECK-NEXT: andb %cl, %al
155+
; CHECK-NEXT: retq
156+
%cond = tail call <1 x i1> @llvm.experimental.constrained.fcmps.v1f64(<1 x double> %a, <1 x double> %b, metadata !"oeq", metadata !"fpexcept.strict")
157+
ret <1 x i1> %cond
158+
}
159+
160+
define <1 x i1> @test_ogt_s_v1f64(<1 x double> %a, <1 x double> %b) {
161+
; CHECK-LABEL: test_ogt_s_v1f64:
162+
; CHECK: # %bb.0:
163+
; CHECK-NEXT: vcomisd %xmm1, %xmm0
164+
; CHECK-NEXT: seta %al
165+
; CHECK-NEXT: retq
166+
%cond = tail call <1 x i1> @llvm.experimental.constrained.fcmps.v1f64(<1 x double> %a, <1 x double> %b, metadata !"ogt", metadata !"fpexcept.strict")
167+
ret <1 x i1> %cond
168+
}
169+
170+
define <1 x i1> @test_oge_s_v1f64(<1 x double> %a, <1 x double> %b) {
171+
; CHECK-LABEL: test_oge_s_v1f64:
172+
; CHECK: # %bb.0:
173+
; CHECK-NEXT: vcomisd %xmm1, %xmm0
174+
; CHECK-NEXT: setae %al
175+
; CHECK-NEXT: retq
176+
%cond = tail call <1 x i1> @llvm.experimental.constrained.fcmps.v1f64(<1 x double> %a, <1 x double> %b, metadata !"oge", metadata !"fpexcept.strict")
177+
ret <1 x i1> %cond
178+
}
179+
180+
define <1 x i1> @test_olt_s_v1f64(<1 x double> %a, <1 x double> %b) {
181+
; CHECK-LABEL: test_olt_s_v1f64:
182+
; CHECK: # %bb.0:
183+
; CHECK-NEXT: vcomisd %xmm0, %xmm1
184+
; CHECK-NEXT: seta %al
185+
; CHECK-NEXT: retq
186+
%cond = tail call <1 x i1> @llvm.experimental.constrained.fcmps.v1f64(<1 x double> %a, <1 x double> %b, metadata !"olt", metadata !"fpexcept.strict")
187+
ret <1 x i1> %cond
188+
}
189+
190+
define <1 x i1> @test_ole_s_v1f64(<1 x double> %a, <1 x double> %b) {
191+
; CHECK-LABEL: test_ole_s_v1f64:
192+
; CHECK: # %bb.0:
193+
; CHECK-NEXT: vcomisd %xmm0, %xmm1
194+
; CHECK-NEXT: setae %al
195+
; CHECK-NEXT: retq
196+
%cond = tail call <1 x i1> @llvm.experimental.constrained.fcmps.v1f64(<1 x double> %a, <1 x double> %b, metadata !"ole", metadata !"fpexcept.strict")
197+
ret <1 x i1> %cond
198+
}
199+
200+
define <1 x i1> @test_one_s_v1f64(<1 x double> %a, <1 x double> %b) {
201+
; CHECK-LABEL: test_one_s_v1f64:
202+
; CHECK: # %bb.0:
203+
; CHECK-NEXT: vcomisd %xmm1, %xmm0
204+
; CHECK-NEXT: setne %al
205+
; CHECK-NEXT: retq
206+
%cond = tail call <1 x i1> @llvm.experimental.constrained.fcmps.v1f64(<1 x double> %a, <1 x double> %b, metadata !"one", metadata !"fpexcept.strict")
207+
ret <1 x i1> %cond
208+
}
209+
210+
define <1 x i1> @test_ord_s_v1f64(<1 x double> %a, <1 x double> %b) {
211+
; CHECK-LABEL: test_ord_s_v1f64:
212+
; CHECK: # %bb.0:
213+
; CHECK-NEXT: vcomisd %xmm1, %xmm0
214+
; CHECK-NEXT: setnp %al
215+
; CHECK-NEXT: retq
216+
%cond = tail call <1 x i1> @llvm.experimental.constrained.fcmps.v1f64(<1 x double> %a, <1 x double> %b, metadata !"ord", metadata !"fpexcept.strict")
217+
ret <1 x i1> %cond
218+
}
219+
220+
define <1 x i1> @test_ueq_s_v1f64(<1 x double> %a, <1 x double> %b) {
221+
; CHECK-LABEL: test_ueq_s_v1f64:
222+
; CHECK: # %bb.0:
223+
; CHECK-NEXT: vcomisd %xmm1, %xmm0
224+
; CHECK-NEXT: setnp %al
225+
; CHECK-NEXT: retq
226+
%cond = tail call <1 x i1> @llvm.experimental.constrained.fcmps.v1f64(<1 x double> %a, <1 x double> %b, metadata !"ord", metadata !"fpexcept.strict")
227+
ret <1 x i1> %cond
228+
}
229+
230+
define <1 x i1> @test_ugt_s_v1f64(<1 x double> %a, <1 x double> %b) {
231+
; CHECK-LABEL: test_ugt_s_v1f64:
232+
; CHECK: # %bb.0:
233+
; CHECK-NEXT: vcomisd %xmm0, %xmm1
234+
; CHECK-NEXT: setb %al
235+
; CHECK-NEXT: retq
236+
%cond = tail call <1 x i1> @llvm.experimental.constrained.fcmps.v1f64(<1 x double> %a, <1 x double> %b, metadata !"ugt", metadata !"fpexcept.strict")
237+
ret <1 x i1> %cond
238+
}
239+
240+
define <1 x i1> @test_uge_s_v1f64(<1 x double> %a, <1 x double> %b) {
241+
; CHECK-LABEL: test_uge_s_v1f64:
242+
; CHECK: # %bb.0:
243+
; CHECK-NEXT: vcomisd %xmm0, %xmm1
244+
; CHECK-NEXT: setbe %al
245+
; CHECK-NEXT: retq
246+
%cond = tail call <1 x i1> @llvm.experimental.constrained.fcmps.v1f64(<1 x double> %a, <1 x double> %b, metadata !"uge", metadata !"fpexcept.strict")
247+
ret <1 x i1> %cond
248+
}
249+
250+
define <1 x i1> @test_ult_s_v1f64(<1 x double> %a, <1 x double> %b) {
251+
; CHECK-LABEL: test_ult_s_v1f64:
252+
; CHECK: # %bb.0:
253+
; CHECK-NEXT: vcomisd %xmm1, %xmm0
254+
; CHECK-NEXT: setb %al
255+
; CHECK-NEXT: retq
256+
%cond = tail call <1 x i1> @llvm.experimental.constrained.fcmps.v1f64(<1 x double> %a, <1 x double> %b, metadata !"ult", metadata !"fpexcept.strict")
257+
ret <1 x i1> %cond
258+
}
259+
260+
define <1 x i1> @test_ule_s_v1f64(<1 x double> %a, <1 x double> %b) {
261+
; CHECK-LABEL: test_ule_s_v1f64:
262+
; CHECK: # %bb.0:
263+
; CHECK-NEXT: vcomisd %xmm1, %xmm0
264+
; CHECK-NEXT: setbe %al
265+
; CHECK-NEXT: retq
266+
%cond = tail call <1 x i1> @llvm.experimental.constrained.fcmps.v1f64(<1 x double> %a, <1 x double> %b, metadata !"ule", metadata !"fpexcept.strict")
267+
ret <1 x i1> %cond
268+
}
269+
270+
define <1 x i1> @test_une_s_v1f64(<1 x double> %a, <1 x double> %b) {
271+
; CHECK-LABEL: test_une_s_v1f64:
272+
; CHECK: # %bb.0:
273+
; CHECK-NEXT: vcomisd %xmm1, %xmm0
274+
; CHECK-NEXT: setp %cl
275+
; CHECK-NEXT: setne %al
276+
; CHECK-NEXT: orb %cl, %al
277+
; CHECK-NEXT: retq
278+
%cond = tail call <1 x i1> @llvm.experimental.constrained.fcmps.v1f64(<1 x double> %a, <1 x double> %b, metadata !"une", metadata !"fpexcept.strict")
279+
ret <1 x i1> %cond
280+
}
281+
282+
define <1 x i1> @test_uno_s_v1f64(<1 x double> %a, <1 x double> %b) {
283+
; CHECK-LABEL: test_uno_s_v1f64:
284+
; CHECK: # %bb.0:
285+
; CHECK-NEXT: vcomisd %xmm1, %xmm0
286+
; CHECK-NEXT: setp %al
287+
; CHECK-NEXT: retq
288+
%cond = tail call <1 x i1> @llvm.experimental.constrained.fcmps.v1f64(<1 x double> %a, <1 x double> %b, metadata !"uno", metadata !"fpexcept.strict")
289+
ret <1 x i1> %cond
290+
}
291+
292+
declare <1 x i1> @llvm.experimental.constrained.fcmp.v1f64(<1 x double>, <1 x double>, metadata, metadata)
293+
declare <1 x i1> @llvm.experimental.constrained.fcmps.v1f64(<1 x double>, <1 x double>, metadata, metadata)

0 commit comments

Comments
 (0)