Skip to content

Commit 84a46c7

Browse files
folkertdevgithub-actions[bot]
authored andcommitted
Automerge: [ARM]: codegen llvm.roundeven.v* (#141786)
fixes llvm/llvm-project#73588 The aarch64 version of `frintn.ll` notes the intention to auto-upgrade `frintn` to `roundeven`. I haven't been able to figure out how to make that happen though (either for arm or aarch64). The original issue came up in rust-lang/stdarch#1807
2 parents ae36193 + 46b3892 commit 84a46c7

File tree

9 files changed

+188
-2
lines changed

9 files changed

+188
-2
lines changed

llvm/lib/Target/ARM/ARMISelLowering.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -905,6 +905,7 @@ ARMTargetLowering::ARMTargetLowering(const TargetMachine &TM,
905905
setOperationAction(ISD::FCEIL, MVT::v2f64, Expand);
906906
setOperationAction(ISD::FTRUNC, MVT::v2f64, Expand);
907907
setOperationAction(ISD::FRINT, MVT::v2f64, Expand);
908+
setOperationAction(ISD::FROUNDEVEN, MVT::v2f64, Expand);
908909
setOperationAction(ISD::FNEARBYINT, MVT::v2f64, Expand);
909910
setOperationAction(ISD::FFLOOR, MVT::v2f64, Expand);
910911
setOperationAction(ISD::FMA, MVT::v2f64, Expand);
@@ -927,6 +928,7 @@ ARMTargetLowering::ARMTargetLowering(const TargetMachine &TM,
927928
setOperationAction(ISD::FCEIL, MVT::v4f32, Expand);
928929
setOperationAction(ISD::FTRUNC, MVT::v4f32, Expand);
929930
setOperationAction(ISD::FRINT, MVT::v4f32, Expand);
931+
setOperationAction(ISD::FROUNDEVEN, MVT::v4f32, Expand);
930932
setOperationAction(ISD::FNEARBYINT, MVT::v4f32, Expand);
931933
setOperationAction(ISD::FFLOOR, MVT::v4f32, Expand);
932934

@@ -945,6 +947,7 @@ ARMTargetLowering::ARMTargetLowering(const TargetMachine &TM,
945947
setOperationAction(ISD::FCEIL, MVT::v2f32, Expand);
946948
setOperationAction(ISD::FTRUNC, MVT::v2f32, Expand);
947949
setOperationAction(ISD::FRINT, MVT::v2f32, Expand);
950+
setOperationAction(ISD::FROUNDEVEN, MVT::v2f32, Expand);
948951
setOperationAction(ISD::FNEARBYINT, MVT::v2f32, Expand);
949952
setOperationAction(ISD::FFLOOR, MVT::v2f32, Expand);
950953

@@ -1087,6 +1090,7 @@ ARMTargetLowering::ARMTargetLowering(const TargetMachine &TM,
10871090
setOperationAction(ISD::FCEIL, MVT::f64, Expand);
10881091
setOperationAction(ISD::FTRUNC, MVT::f64, Expand);
10891092
setOperationAction(ISD::FRINT, MVT::f64, Expand);
1093+
setOperationAction(ISD::FROUNDEVEN, MVT::f64, Expand);
10901094
setOperationAction(ISD::FNEARBYINT, MVT::f64, Expand);
10911095
setOperationAction(ISD::FFLOOR, MVT::f64, Expand);
10921096
setOperationAction(ISD::SINT_TO_FP, MVT::i32, Custom);
@@ -1534,6 +1538,7 @@ ARMTargetLowering::ARMTargetLowering(const TargetMachine &TM,
15341538
setOperationAction(ISD::FTRUNC, MVT::f32, Legal);
15351539
setOperationAction(ISD::FNEARBYINT, MVT::f32, Legal);
15361540
setOperationAction(ISD::FRINT, MVT::f32, Legal);
1541+
setOperationAction(ISD::FROUNDEVEN, MVT::f32, Legal);
15371542
setOperationAction(ISD::FMINNUM, MVT::f32, Legal);
15381543
setOperationAction(ISD::FMAXNUM, MVT::f32, Legal);
15391544
if (Subtarget->hasNEON()) {
@@ -1550,6 +1555,7 @@ ARMTargetLowering::ARMTargetLowering(const TargetMachine &TM,
15501555
setOperationAction(ISD::FTRUNC, MVT::f64, Legal);
15511556
setOperationAction(ISD::FNEARBYINT, MVT::f64, Legal);
15521557
setOperationAction(ISD::FRINT, MVT::f64, Legal);
1558+
setOperationAction(ISD::FROUNDEVEN, MVT::f64, Legal);
15531559
setOperationAction(ISD::FMINNUM, MVT::f64, Legal);
15541560
setOperationAction(ISD::FMAXNUM, MVT::f64, Legal);
15551561
}

llvm/lib/Target/ARM/ARMInstrVFP.td

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1135,8 +1135,13 @@ multiclass vrint_inst_anpm<string opc, bits<2> rm,
11351135
Requires<[HasFPARMv8,HasDPVFP]>;
11361136
}
11371137

1138+
// Match either froundeven or int_arm_neon_vrintn
1139+
def vrintn_or_froundeven : PatFrags<(ops node:$src),
1140+
[(int_arm_neon_vrintn node:$src),
1141+
(froundeven node:$src)]>;
1142+
11381143
defm VRINTA : vrint_inst_anpm<"a", 0b00, fround>;
1139-
defm VRINTN : vrint_inst_anpm<"n", 0b01, int_arm_neon_vrintn>;
1144+
defm VRINTN : vrint_inst_anpm<"n", 0b01, vrintn_or_froundeven>;
11401145
defm VRINTP : vrint_inst_anpm<"p", 0b10, fceil>;
11411146
defm VRINTM : vrint_inst_anpm<"m", 0b11, ffloor>;
11421147

llvm/test/CodeGen/ARM/arm32-rounding.ll

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,22 @@ entry:
104104
ret double %call
105105
}
106106

107+
; CHECK-LABEL: test13
108+
; CHECK: vrintn.f32
109+
define float @test13(float %a) {
110+
entry:
111+
%round = call float @llvm.roundeven.f32(float %a)
112+
ret float %round
113+
}
114+
115+
; CHECK-LABEL: test14
116+
; CHECK: vrintn.f64
117+
define double @test14(double %a) {
118+
entry:
119+
%round = call double @llvm.roundeven.f64(double %a)
120+
ret double %round
121+
}
122+
107123
declare float @floorf(float) nounwind readnone
108124
declare double @floor(double) nounwind readnone
109125
declare float @ceilf(float) nounwind readnone
@@ -116,3 +132,5 @@ declare float @nearbyintf(float) nounwind readnone
116132
declare double @nearbyint(double) nounwind readnone
117133
declare float @rintf(float) nounwind readnone
118134
declare double @rint(double) nounwind readnone
135+
declare float @llvm.roundeven.f32(float)
136+
declare double @llvm.roundeven.f64(double)

llvm/test/CodeGen/ARM/fp16-fullfp16.ll

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -585,6 +585,18 @@ define void @test_round(ptr %p) {
585585
ret void
586586
}
587587

588+
define void @test_roundeven(ptr %p) {
589+
; CHECK-LABEL: test_roundeven:
590+
; CHECK: vldr.16 s0, [r0]
591+
; CHECK-NEXT: vrintn.f16 s0, s0
592+
; CHECK-NEXT: vstr.16 s0, [r0]
593+
; CHECK-NEXT: bx lr
594+
%a = load half, ptr %p, align 2
595+
%r = call half @llvm.roundeven.f16(half %a)
596+
store half %r, ptr %p
597+
ret void
598+
}
599+
588600
define void @test_fmuladd(ptr %p, ptr %q, ptr %r) {
589601
; CHECK-LABEL: test_fmuladd:
590602
; CHECK: vldr.16 s0, [r1]
@@ -623,4 +635,5 @@ declare half @llvm.trunc.f16(half %a)
623635
declare half @llvm.rint.f16(half %a)
624636
declare half @llvm.nearbyint.f16(half %a)
625637
declare half @llvm.round.f16(half %a)
638+
declare half @llvm.roundeven.f16(half %a)
626639
declare half @llvm.fmuladd.f16(half %a, half %b, half %c)

llvm/test/CodeGen/ARM/fp16-promote.ll

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -411,6 +411,7 @@ declare half @llvm.trunc.f16(half %a) #0
411411
declare half @llvm.rint.f16(half %a) #0
412412
declare half @llvm.nearbyint.f16(half %a) #0
413413
declare half @llvm.round.f16(half %a) #0
414+
declare half @llvm.roundeven.f16(half %a) #0
414415
declare half @llvm.fmuladd.f16(half %a, half %b, half %c) #0
415416

416417
; CHECK-ALL-LABEL: test_sqrt:
@@ -811,6 +812,21 @@ define void @test_round(ptr %p) {
811812
ret void
812813
}
813814

815+
; CHECK-FP16-LABEL: test_roundeven:
816+
; CHECK-FP16: vcvtb.f32.f16
817+
; CHECK-FP16: bl roundevenf
818+
; CHECK-FP16: vcvtb.f16.f32
819+
; CHECK-LIBCALL-LABEL: test_roundeven:
820+
; CHECK-LIBCALL: bl __aeabi_h2f
821+
; CHECK-LIBCALL: bl roundevenf
822+
; CHECK-LIBCALL: bl __aeabi_f2h
823+
define void @test_roundeven(ptr %p) {
824+
%a = load half, ptr %p, align 2
825+
%r = call half @llvm.roundeven.f16(half %a)
826+
store half %r, ptr %p
827+
ret void
828+
}
829+
814830
; CHECK-FP16-LABEL: test_fmuladd:
815831
; CHECK-FP16: vcvtb.f32.f16
816832
; CHECK-FP16: vcvtb.f32.f16

llvm/test/CodeGen/ARM/vrint.ll

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
; RUN: llc -mtriple=armv8 -mattr=+neon %s -o - | FileCheck %s
22

33
declare float @llvm.arm.neon.vrintn.f32(float) nounwind readnone
4+
declare <2 x float> @llvm.arm.neon.vrintn.v2f32(<2 x float>) nounwind readnone
5+
declare <4 x float> @llvm.arm.neon.vrintn.v4f32(<4 x float>) nounwind readnone
46

57
; CHECK-LABEL: vrintn_f32:
68
; CHECK: vrintn.f32
@@ -9,3 +11,109 @@ define float @vrintn_f32(ptr %A) nounwind {
911
%tmp2 = call float @llvm.arm.neon.vrintn.f32(float %tmp1)
1012
ret float %tmp2
1113
}
14+
15+
define <2 x float> @frintn_2s(<2 x float> %A) nounwind {
16+
; CHECK-LABEL: frintn_2s:
17+
; CHECK: @ %bb.0:
18+
; CHECK-NEXT: vmov d16, r0, r1
19+
; CHECK-NEXT: vrintn.f32 d16, d16
20+
; CHECK-NEXT: vmov r0, r1, d16
21+
; CHECK-NEXT: bx lr
22+
%tmp3 = call <2 x float> @llvm.arm.neon.vrintn.v2f32(<2 x float> %A)
23+
ret <2 x float> %tmp3
24+
}
25+
26+
define <4 x float> @frintn_4s(<4 x float> %A) nounwind {
27+
; CHECK-LABEL: frintn_4s:
28+
; CHECK: @ %bb.0:
29+
; CHECK-NEXT: vmov d17, r2, r3
30+
; CHECK-NEXT: vmov d16, r0, r1
31+
; CHECK-NEXT: vrintn.f32 q8, q8
32+
; CHECK-NEXT: vmov r0, r1, d16
33+
; CHECK-NEXT: vmov r2, r3, d17
34+
; CHECK-NEXT: bx lr
35+
%tmp3 = call <4 x float> @llvm.arm.neon.vrintn.v4f32(<4 x float> %A)
36+
ret <4 x float> %tmp3
37+
}
38+
39+
define <4 x half> @roundeven_4h(<4 x half> %A) nounwind {
40+
; CHECK-LABEL: roundeven_4h:
41+
; CHECK: @ %bb.0:
42+
; CHECK-NEXT: vmov s0, r3
43+
; CHECK-NEXT: vcvtb.f32.f16 s0, s0
44+
; CHECK-NEXT: vmov s2, r2
45+
; CHECK-NEXT: vrintn.f32 s0, s0
46+
; CHECK-NEXT: vcvtb.f32.f16 s2, s2
47+
; CHECK-NEXT: vrintn.f32 s2, s2
48+
; CHECK-NEXT: vcvtb.f16.f32 s0, s0
49+
; CHECK-NEXT: vcvtb.f16.f32 s2, s2
50+
; CHECK-NEXT: vmov r2, s0
51+
; CHECK-NEXT: vmov s0, r1
52+
; CHECK-NEXT: vmov r3, s2
53+
; CHECK-NEXT: vcvtb.f32.f16 s0, s0
54+
; CHECK-NEXT: vmov s2, r0
55+
; CHECK-NEXT: vrintn.f32 s0, s0
56+
; CHECK-NEXT: vcvtb.f32.f16 s2, s2
57+
; CHECK-NEXT: vcvtb.f16.f32 s0, s0
58+
; CHECK-NEXT: vrintn.f32 s2, s2
59+
; CHECK-NEXT: vmov r0, s0
60+
; CHECK-NEXT: vcvtb.f16.f32 s2, s2
61+
; CHECK-NEXT: vmov r1, s2
62+
; CHECK-NEXT: pkhbt r2, r3, r2, lsl #16
63+
; CHECK-NEXT: pkhbt r0, r1, r0, lsl #16
64+
; CHECK-NEXT: vmov d16, r0, r2
65+
; CHECK-NEXT: vmov.u16 r0, d16[0]
66+
; CHECK-NEXT: vmov.u16 r1, d16[1]
67+
; CHECK-NEXT: vmov.u16 r2, d16[2]
68+
; CHECK-NEXT: vmov.u16 r3, d16[3]
69+
; CHECK-NEXT: bx lr
70+
%tmp3 = call <4 x half> @llvm.roundeven.v4f16(<4 x half> %A)
71+
ret <4 x half> %tmp3
72+
}
73+
74+
define <2 x float> @roundeven_2s(<2 x float> %A) nounwind {
75+
; CHECK-LABEL: roundeven_2s:
76+
; CHECK: @ %bb.0:
77+
; CHECK-NEXT: vmov d0, r0, r1
78+
; CHECK-NEXT: vrintn.f32 s3, s1
79+
; CHECK-NEXT: vrintn.f32 s2, s0
80+
; CHECK-NEXT: vmov r0, r1, d1
81+
; CHECK-NEXT: bx lr
82+
%tmp3 = call <2 x float> @llvm.roundeven.v2f32(<2 x float> %A)
83+
ret <2 x float> %tmp3
84+
}
85+
86+
define <4 x float> @roundeven_4s(<4 x float> %A) nounwind {
87+
; CHECK-LABEL: roundeven_4s:
88+
; CHECK: @ %bb.0:
89+
; CHECK-NEXT: vmov d1, r2, r3
90+
; CHECK-NEXT: vmov d0, r0, r1
91+
; CHECK-NEXT: vrintn.f32 s7, s3
92+
; CHECK-NEXT: vrintn.f32 s6, s2
93+
; CHECK-NEXT: vrintn.f32 s5, s1
94+
; CHECK-NEXT: vrintn.f32 s4, s0
95+
; CHECK-NEXT: vmov r2, r3, d3
96+
; CHECK-NEXT: vmov r0, r1, d2
97+
; CHECK-NEXT: bx lr
98+
%tmp3 = call <4 x float> @llvm.roundeven.v4f32(<4 x float> %A)
99+
ret <4 x float> %tmp3
100+
}
101+
102+
define <2 x double> @roundeven_2d(<2 x double> %A) nounwind {
103+
; CHECK-LABEL: roundeven_2d:
104+
; CHECK: @ %bb.0:
105+
; CHECK-NEXT: vmov d16, r2, r3
106+
; CHECK-NEXT: vmov d17, r0, r1
107+
; CHECK-NEXT: vrintn.f64 d16, d16
108+
; CHECK-NEXT: vrintn.f64 d17, d17
109+
; CHECK-NEXT: vmov r2, r3, d16
110+
; CHECK-NEXT: vmov r0, r1, d17
111+
; CHECK-NEXT: bx lr
112+
%tmp3 = call <2 x double> @llvm.roundeven.v2f64(<2 x double> %A)
113+
ret <2 x double> %tmp3
114+
}
115+
116+
declare <4 x half> @llvm.roundeven.v4f16(<4 x half>) nounwind readnone
117+
declare <2 x float> @llvm.roundeven.v2f32(<2 x float>) nounwind readnone
118+
declare <4 x float> @llvm.roundeven.v4f32(<4 x float>) nounwind readnone
119+
declare <2 x double> @llvm.roundeven.v2f64(<2 x double>) nounwind readnone

llvm/test/CodeGen/Thumb2/bf16-instructions.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2373,7 +2373,7 @@ define bfloat @test_roundeven(bfloat %a) {
23732373
; CHECK-FP-NEXT: vmov r0, s0
23742374
; CHECK-FP-NEXT: lsls r0, r0, #16
23752375
; CHECK-FP-NEXT: vmov s0, r0
2376-
; CHECK-FP-NEXT: bl roundevenf
2376+
; CHECK-FP-NEXT: vrintn.f32 s0, s0
23772377
; CHECK-FP-NEXT: bl __truncsfbf2
23782378
; CHECK-FP-NEXT: vmov.f16 r0, s0
23792379
; CHECK-FP-NEXT: vmov s0, r0

llvm/test/CodeGen/Thumb2/float-intrinsics-double.ll

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,16 @@ define double @round_d(double %a) {
204204
ret double %1
205205
}
206206

207+
declare double @llvm.roundeven.f64(double %Val)
208+
define double @roundeven_d(double %a) {
209+
; CHECK-LABEL: roundeven_d:
210+
; SOFT: {{(bl|b)}} roundeven
211+
; VFP4: b roundeven
212+
; FP-ARMv8: vrintn.f64
213+
%1 = call double @llvm.roundeven.f64(double %a)
214+
ret double %1
215+
}
216+
207217
declare double @llvm.fmuladd.f64(double %a, double %b, double %c)
208218
define double @fmuladd_d(double %a, double %b, double %c) {
209219
; CHECK-LABEL: fmuladd_d:

llvm/test/CodeGen/Thumb2/float-intrinsics-float.ll

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,16 @@ define float @round_f(float %a) {
210210
ret float %1
211211
}
212212

213+
declare float @llvm.roundeven.f32(float %Val)
214+
define float @roundeven_f(float %a) {
215+
; CHECK-LABEL: roundeven_f:
216+
; SOFT: bl roundevenf
217+
; VFP4: b roundevenf
218+
; FP-ARMv8: vrintn.f32
219+
%1 = call float @llvm.roundeven.f32(float %a)
220+
ret float %1
221+
}
222+
213223
declare float @llvm.fmuladd.f32(float %a, float %b, float %c)
214224
define float @fmuladd_f(float %a, float %b, float %c) {
215225
; CHECK-LABEL: fmuladd_f:

0 commit comments

Comments
 (0)