Skip to content

Commit c30c065

Browse files
committed
[RISCV] Fix crashes with Zfhmin+Zfa.
We were incorrectly making ISD::FMAXIMUM, ISD::FMINIMUM, and ISD::FNEARBYINT legal with Zfhmin+Zfa when we really need Zfh+Zfa.
1 parent 8694353 commit c30c065

File tree

2 files changed

+101
-5
lines changed

2 files changed

+101
-5
lines changed

llvm/lib/Target/RISCV/RISCVISelLowering.cpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -467,8 +467,11 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
467467
setOperationAction(FPRndMode, MVT::f16,
468468
Subtarget.hasStdExtZfa() ? Legal : Custom);
469469
setOperationAction(ISD::IS_FPCLASS, MVT::f16, Custom);
470+
setOperationAction({ISD::FMAXIMUM, ISD::FMINIMUM}, MVT::f16,
471+
Subtarget.hasStdExtZfa() ? Legal : Custom);
470472
} else {
471473
setOperationAction(ZfhminZfbfminPromoteOps, MVT::f16, Promote);
474+
setOperationAction({ISD::FMAXIMUM, ISD::FMINIMUM}, MVT::f16, Promote);
472475
for (auto Op : {ISD::LROUND, ISD::LLROUND, ISD::LRINT, ISD::LLRINT,
473476
ISD::STRICT_LROUND, ISD::STRICT_LLROUND,
474477
ISD::STRICT_LRINT, ISD::STRICT_LLRINT})
@@ -487,8 +490,9 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
487490
setOperationAction(ISD::SELECT, MVT::f16, Custom);
488491
setOperationAction(ISD::BR_CC, MVT::f16, Expand);
489492

490-
setOperationAction(ISD::FNEARBYINT, MVT::f16,
491-
Subtarget.hasStdExtZfa() ? Legal : Promote);
493+
setOperationAction(
494+
ISD::FNEARBYINT, MVT::f16,
495+
Subtarget.hasStdExtZfh() && Subtarget.hasStdExtZfa() ? Legal : Promote);
492496
setOperationAction({ISD::FREM, ISD::FPOW, ISD::FPOWI,
493497
ISD::FCOS, ISD::FSIN, ISD::FSINCOS, ISD::FEXP,
494498
ISD::FEXP2, ISD::FEXP10, ISD::FLOG, ISD::FLOG2,
@@ -506,9 +510,6 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
506510
// We need to custom promote this.
507511
if (Subtarget.is64Bit())
508512
setOperationAction(ISD::FPOWI, MVT::i32, Custom);
509-
510-
setOperationAction({ISD::FMAXIMUM, ISD::FMINIMUM}, MVT::f16,
511-
Subtarget.hasStdExtZfa() ? Legal : Custom);
512513
}
513514

514515
if (Subtarget.hasStdExtFOrZfinx()) {

llvm/test/CodeGen/RISCV/half-zfa.ll

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@
33
; RUN: | FileCheck %s
44
; RUN: llc -mtriple=riscv64 -target-abi lp64f -mattr=+zfa,+zfh < %s \
55
; RUN: | FileCheck %s
6+
; RUN: llc -mtriple=riscv32 -target-abi ilp32f -mattr=+zfa,+zfhmin < %s \
7+
; RUN: | FileCheck %s --check-prefix=ZFHMIN
8+
; RUN: llc -mtriple=riscv64 -target-abi lp64f -mattr=+zfa,+zfhmin < %s \
9+
; RUN: | FileCheck %s --check-prefix=ZFHMIN
610

711
declare half @llvm.minimum.f16(half, half)
812

@@ -11,6 +15,14 @@ define half @fminm_h(half %a, half %b) nounwind {
1115
; CHECK: # %bb.0:
1216
; CHECK-NEXT: fminm.h fa0, fa0, fa1
1317
; CHECK-NEXT: ret
18+
;
19+
; ZFHMIN-LABEL: fminm_h:
20+
; ZFHMIN: # %bb.0:
21+
; ZFHMIN-NEXT: fcvt.s.h fa5, fa1
22+
; ZFHMIN-NEXT: fcvt.s.h fa4, fa0
23+
; ZFHMIN-NEXT: fminm.s fa5, fa4, fa5
24+
; ZFHMIN-NEXT: fcvt.h.s fa0, fa5
25+
; ZFHMIN-NEXT: ret
1426
%1 = call half @llvm.minimum.f16(half %a, half %b)
1527
ret half %1
1628
}
@@ -22,6 +34,14 @@ define half @fmaxm_h(half %a, half %b) nounwind {
2234
; CHECK: # %bb.0:
2335
; CHECK-NEXT: fmaxm.h fa0, fa0, fa1
2436
; CHECK-NEXT: ret
37+
;
38+
; ZFHMIN-LABEL: fmaxm_h:
39+
; ZFHMIN: # %bb.0:
40+
; ZFHMIN-NEXT: fcvt.s.h fa5, fa1
41+
; ZFHMIN-NEXT: fcvt.s.h fa4, fa0
42+
; ZFHMIN-NEXT: fmaxm.s fa5, fa4, fa5
43+
; ZFHMIN-NEXT: fcvt.h.s fa0, fa5
44+
; ZFHMIN-NEXT: ret
2545
%1 = tail call half @llvm.maximum.f16(half %a, half %b)
2646
ret half %1
2747
}
@@ -31,6 +51,13 @@ define half @fround_h_1(half %a) nounwind {
3151
; CHECK: # %bb.0:
3252
; CHECK-NEXT: fround.h fa0, fa0, rmm
3353
; CHECK-NEXT: ret
54+
;
55+
; ZFHMIN-LABEL: fround_h_1:
56+
; ZFHMIN: # %bb.0:
57+
; ZFHMIN-NEXT: fcvt.s.h fa5, fa0
58+
; ZFHMIN-NEXT: fround.s fa5, fa5, rmm
59+
; ZFHMIN-NEXT: fcvt.h.s fa0, fa5
60+
; ZFHMIN-NEXT: ret
3461
%call = tail call half @llvm.round.f16(half %a) nounwind readnone
3562
ret half %call
3663
}
@@ -43,6 +70,13 @@ define half @fround_h_2(half %a) nounwind {
4370
; CHECK: # %bb.0:
4471
; CHECK-NEXT: fround.h fa0, fa0, rdn
4572
; CHECK-NEXT: ret
73+
;
74+
; ZFHMIN-LABEL: fround_h_2:
75+
; ZFHMIN: # %bb.0:
76+
; ZFHMIN-NEXT: fcvt.s.h fa5, fa0
77+
; ZFHMIN-NEXT: fround.s fa5, fa5, rdn
78+
; ZFHMIN-NEXT: fcvt.h.s fa0, fa5
79+
; ZFHMIN-NEXT: ret
4680
%call = tail call half @llvm.floor.f16(half %a) nounwind readnone
4781
ret half %call
4882
}
@@ -55,6 +89,13 @@ define half @fround_h_3(half %a) nounwind {
5589
; CHECK: # %bb.0:
5690
; CHECK-NEXT: fround.h fa0, fa0, rup
5791
; CHECK-NEXT: ret
92+
;
93+
; ZFHMIN-LABEL: fround_h_3:
94+
; ZFHMIN: # %bb.0:
95+
; ZFHMIN-NEXT: fcvt.s.h fa5, fa0
96+
; ZFHMIN-NEXT: fround.s fa5, fa5, rup
97+
; ZFHMIN-NEXT: fcvt.h.s fa0, fa5
98+
; ZFHMIN-NEXT: ret
5899
%call = tail call half @llvm.ceil.f16(half %a) nounwind readnone
59100
ret half %call
60101
}
@@ -67,6 +108,13 @@ define half @fround_h_4(half %a) nounwind {
67108
; CHECK: # %bb.0:
68109
; CHECK-NEXT: fround.h fa0, fa0, rtz
69110
; CHECK-NEXT: ret
111+
;
112+
; ZFHMIN-LABEL: fround_h_4:
113+
; ZFHMIN: # %bb.0:
114+
; ZFHMIN-NEXT: fcvt.s.h fa5, fa0
115+
; ZFHMIN-NEXT: fround.s fa5, fa5, rtz
116+
; ZFHMIN-NEXT: fcvt.h.s fa0, fa5
117+
; ZFHMIN-NEXT: ret
70118
%call = tail call half @llvm.trunc.f16(half %a) nounwind readnone
71119
ret half %call
72120
}
@@ -79,6 +127,13 @@ define half @fround_h_5(half %a) nounwind {
79127
; CHECK: # %bb.0:
80128
; CHECK-NEXT: fround.h fa0, fa0
81129
; CHECK-NEXT: ret
130+
;
131+
; ZFHMIN-LABEL: fround_h_5:
132+
; ZFHMIN: # %bb.0:
133+
; ZFHMIN-NEXT: fcvt.s.h fa5, fa0
134+
; ZFHMIN-NEXT: fround.s fa5, fa5
135+
; ZFHMIN-NEXT: fcvt.h.s fa0, fa5
136+
; ZFHMIN-NEXT: ret
82137
%call = tail call half @llvm.nearbyint.f16(half %a) nounwind readnone
83138
ret half %call
84139
}
@@ -91,6 +146,13 @@ define half @froundnx_h(half %a) nounwind {
91146
; CHECK: # %bb.0:
92147
; CHECK-NEXT: froundnx.h fa0, fa0
93148
; CHECK-NEXT: ret
149+
;
150+
; ZFHMIN-LABEL: froundnx_h:
151+
; ZFHMIN: # %bb.0:
152+
; ZFHMIN-NEXT: fcvt.s.h fa5, fa0
153+
; ZFHMIN-NEXT: froundnx.s fa5, fa5
154+
; ZFHMIN-NEXT: fcvt.h.s fa0, fa5
155+
; ZFHMIN-NEXT: ret
94156
%call = tail call half @llvm.rint.f16(half %a) nounwind readnone
95157
ret half %call
96158
}
@@ -104,6 +166,13 @@ define i32 @fcmp_olt_q(half %a, half %b) nounwind strictfp {
104166
; CHECK: # %bb.0:
105167
; CHECK-NEXT: fltq.h a0, fa0, fa1
106168
; CHECK-NEXT: ret
169+
;
170+
; ZFHMIN-LABEL: fcmp_olt_q:
171+
; ZFHMIN: # %bb.0:
172+
; ZFHMIN-NEXT: fcvt.s.h fa5, fa1
173+
; ZFHMIN-NEXT: fcvt.s.h fa4, fa0
174+
; ZFHMIN-NEXT: fltq.s a0, fa4, fa5
175+
; ZFHMIN-NEXT: ret
107176
%1 = call i1 @llvm.experimental.constrained.fcmp.f16(half %a, half %b, metadata !"olt", metadata !"fpexcept.strict") strictfp
108177
%2 = zext i1 %1 to i32
109178
ret i32 %2
@@ -114,6 +183,13 @@ define i32 @fcmp_ole_q(half %a, half %b) nounwind strictfp {
114183
; CHECK: # %bb.0:
115184
; CHECK-NEXT: fleq.h a0, fa0, fa1
116185
; CHECK-NEXT: ret
186+
;
187+
; ZFHMIN-LABEL: fcmp_ole_q:
188+
; ZFHMIN: # %bb.0:
189+
; ZFHMIN-NEXT: fcvt.s.h fa5, fa1
190+
; ZFHMIN-NEXT: fcvt.s.h fa4, fa0
191+
; ZFHMIN-NEXT: fleq.s a0, fa4, fa5
192+
; ZFHMIN-NEXT: ret
117193
%1 = call i1 @llvm.experimental.constrained.fcmp.f16(half %a, half %b, metadata !"ole", metadata !"fpexcept.strict") strictfp
118194
%2 = zext i1 %1 to i32
119195
ret i32 %2
@@ -126,6 +202,15 @@ define i32 @fcmp_one_q(half %a, half %b) nounwind strictfp {
126202
; CHECK-NEXT: fltq.h a1, fa1, fa0
127203
; CHECK-NEXT: or a0, a1, a0
128204
; CHECK-NEXT: ret
205+
;
206+
; ZFHMIN-LABEL: fcmp_one_q:
207+
; ZFHMIN: # %bb.0:
208+
; ZFHMIN-NEXT: fcvt.s.h fa5, fa1
209+
; ZFHMIN-NEXT: fcvt.s.h fa4, fa0
210+
; ZFHMIN-NEXT: fltq.s a0, fa4, fa5
211+
; ZFHMIN-NEXT: fltq.s a1, fa5, fa4
212+
; ZFHMIN-NEXT: or a0, a1, a0
213+
; ZFHMIN-NEXT: ret
129214
%1 = call i1 @llvm.experimental.constrained.fcmp.f16(half %a, half %b, metadata !"one", metadata !"fpexcept.strict") strictfp
130215
%2 = zext i1 %1 to i32
131216
ret i32 %2
@@ -139,6 +224,16 @@ define i32 @fcmp_ueq_q(half %a, half %b) nounwind strictfp {
139224
; CHECK-NEXT: or a0, a1, a0
140225
; CHECK-NEXT: xori a0, a0, 1
141226
; CHECK-NEXT: ret
227+
;
228+
; ZFHMIN-LABEL: fcmp_ueq_q:
229+
; ZFHMIN: # %bb.0:
230+
; ZFHMIN-NEXT: fcvt.s.h fa5, fa1
231+
; ZFHMIN-NEXT: fcvt.s.h fa4, fa0
232+
; ZFHMIN-NEXT: fltq.s a0, fa4, fa5
233+
; ZFHMIN-NEXT: fltq.s a1, fa5, fa4
234+
; ZFHMIN-NEXT: or a0, a1, a0
235+
; ZFHMIN-NEXT: xori a0, a0, 1
236+
; ZFHMIN-NEXT: ret
142237
%1 = call i1 @llvm.experimental.constrained.fcmp.f16(half %a, half %b, metadata !"ueq", metadata !"fpexcept.strict") strictfp
143238
%2 = zext i1 %1 to i32
144239
ret i32 %2

0 commit comments

Comments
 (0)