Skip to content

Commit adacbf6

Browse files
committed
[SystemZ] Add codegen support for llvm.roundeven
This is straightforward as we already had all the necessary instructions, they simply were not wired up. Also allows implementing the vec_round intrinsic via the standard llvm.roundeven IR instead of a platform intrinsic now.
1 parent dbbdc7e commit adacbf6

23 files changed

+619
-117
lines changed

Diff for: clang/lib/CodeGen/CGBuiltin.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -21011,6 +21011,8 @@ Value *CodeGenFunction::EmitSystemZBuiltinExpr(unsigned BuiltinID,
2101121011
CI = Intrinsic::experimental_constrained_nearbyint; break;
2101221012
case 1: ID = Intrinsic::round;
2101321013
CI = Intrinsic::experimental_constrained_round; break;
21014+
case 4: ID = Intrinsic::roundeven;
21015+
CI = Intrinsic::experimental_constrained_roundeven; break;
2101421016
case 5: ID = Intrinsic::trunc;
2101521017
CI = Intrinsic::experimental_constrained_trunc; break;
2101621018
case 6: ID = Intrinsic::ceil;

Diff for: clang/test/CodeGen/SystemZ/builtins-systemz-vector-constrained.c

+4-2
Original file line numberDiff line numberDiff line change
@@ -44,12 +44,14 @@ void test_float(void) {
4444
// CHECK: call <2 x double> @llvm.experimental.constrained.nearbyint.v2f64(<2 x double> %{{.*}})
4545
vd = __builtin_s390_vfidb(vd, 4, 1);
4646
// CHECK: call <2 x double> @llvm.experimental.constrained.round.v2f64(<2 x double> %{{.*}})
47+
vd = __builtin_s390_vfidb(vd, 4, 4);
48+
// CHECK: call <2 x double> @llvm.experimental.constrained.roundeven.v2f64(<2 x double> %{{.*}})
4749
vd = __builtin_s390_vfidb(vd, 4, 5);
4850
// CHECK: call <2 x double> @llvm.experimental.constrained.trunc.v2f64(<2 x double> %{{.*}})
4951
vd = __builtin_s390_vfidb(vd, 4, 6);
5052
// CHECK: call <2 x double> @llvm.experimental.constrained.ceil.v2f64(<2 x double> %{{.*}})
5153
vd = __builtin_s390_vfidb(vd, 4, 7);
5254
// CHECK: call <2 x double> @llvm.experimental.constrained.floor.v2f64(<2 x double> %{{.*}})
53-
vd = __builtin_s390_vfidb(vd, 4, 4);
54-
// CHECK: call <2 x double> @llvm.s390.vfidb(<2 x double> %{{.*}}, i32 4, i32 4)
55+
vd = __builtin_s390_vfidb(vd, 4, 3);
56+
// CHECK: call <2 x double> @llvm.s390.vfidb(<2 x double> %{{.*}}, i32 4, i32 3)
5557
}

Diff for: clang/test/CodeGen/SystemZ/builtins-systemz-vector.c

+4-2
Original file line numberDiff line numberDiff line change
@@ -593,12 +593,14 @@ void test_float(void) {
593593
// CHECK: call <2 x double> @llvm.nearbyint.v2f64(<2 x double> %{{.*}})
594594
vd = __builtin_s390_vfidb(vd, 4, 1);
595595
// CHECK: call <2 x double> @llvm.round.v2f64(<2 x double> %{{.*}})
596+
vd = __builtin_s390_vfidb(vd, 4, 4);
597+
// CHECK: call <2 x double> @llvm.roundeven.v2f64(<2 x double> %{{.*}})
596598
vd = __builtin_s390_vfidb(vd, 4, 5);
597599
// CHECK: call <2 x double> @llvm.trunc.v2f64(<2 x double> %{{.*}})
598600
vd = __builtin_s390_vfidb(vd, 4, 6);
599601
// CHECK: call <2 x double> @llvm.ceil.v2f64(<2 x double> %{{.*}})
600602
vd = __builtin_s390_vfidb(vd, 4, 7);
601603
// CHECK: call <2 x double> @llvm.floor.v2f64(<2 x double> %{{.*}})
602-
vd = __builtin_s390_vfidb(vd, 4, 4);
603-
// CHECK: call <2 x double> @llvm.s390.vfidb(<2 x double> %{{.*}}, i32 4, i32 4)
604+
vd = __builtin_s390_vfidb(vd, 4, 3);
605+
// CHECK: call <2 x double> @llvm.s390.vfidb(<2 x double> %{{.*}}, i32 4, i32 3)
604606
}

Diff for: clang/test/CodeGen/SystemZ/builtins-systemz-vector2-constrained.c

+4
Original file line numberDiff line numberDiff line change
@@ -59,11 +59,15 @@ void test_float(void) {
5959
// CHECK: call <4 x float> @llvm.experimental.constrained.nearbyint.v4f32(<4 x float> %{{.*}}, metadata !{{.*}})
6060
vf = __builtin_s390_vfisb(vf, 4, 1);
6161
// CHECK: call <4 x float> @llvm.experimental.constrained.round.v4f32(<4 x float> %{{.*}}, metadata !{{.*}})
62+
vf = __builtin_s390_vfisb(vf, 4, 4);
63+
// CHECK: call <4 x float> @llvm.experimental.constrained.roundeven.v4f32(<4 x float> %{{.*}}, metadata !{{.*}})
6264
vf = __builtin_s390_vfisb(vf, 4, 5);
6365
// CHECK: call <4 x float> @llvm.experimental.constrained.trunc.v4f32(<4 x float> %{{.*}}, metadata !{{.*}})
6466
vf = __builtin_s390_vfisb(vf, 4, 6);
6567
// CHECK: call <4 x float> @llvm.experimental.constrained.ceil.v4f32(<4 x float> %{{.*}}, metadata !{{.*}})
6668
vf = __builtin_s390_vfisb(vf, 4, 7);
6769
// CHECK: call <4 x float> @llvm.experimental.constrained.floor.v4f32(<4 x float> %{{.*}}, metadata !{{.*}})
70+
vf = __builtin_s390_vfisb(vf, 4, 3);
71+
// CHECK: call <4 x float> @llvm.s390.vfisb(<4 x float> %{{.*}}, i32 4, i32 3)
6872
}
6973

Diff for: clang/test/CodeGen/SystemZ/builtins-systemz-vector2.c

+4-2
Original file line numberDiff line numberDiff line change
@@ -125,13 +125,15 @@ void test_float(void) {
125125
// CHECK: call <4 x float> @llvm.nearbyint.v4f32(<4 x float> %{{.*}})
126126
vf = __builtin_s390_vfisb(vf, 4, 1);
127127
// CHECK: call <4 x float> @llvm.round.v4f32(<4 x float> %{{.*}})
128+
vf = __builtin_s390_vfisb(vf, 4, 4);
129+
// CHECK: call <4 x float> @llvm.roundeven.v4f32(<4 x float> %{{.*}})
128130
vf = __builtin_s390_vfisb(vf, 4, 5);
129131
// CHECK: call <4 x float> @llvm.trunc.v4f32(<4 x float> %{{.*}})
130132
vf = __builtin_s390_vfisb(vf, 4, 6);
131133
// CHECK: call <4 x float> @llvm.ceil.v4f32(<4 x float> %{{.*}})
132134
vf = __builtin_s390_vfisb(vf, 4, 7);
133135
// CHECK: call <4 x float> @llvm.floor.v4f32(<4 x float> %{{.*}})
134-
vf = __builtin_s390_vfisb(vf, 4, 4);
135-
// CHECK: call <4 x float> @llvm.s390.vfisb(<4 x float> %{{.*}}, i32 4, i32 4)
136+
vf = __builtin_s390_vfisb(vf, 4, 3);
137+
// CHECK: call <4 x float> @llvm.s390.vfisb(<4 x float> %{{.*}}, i32 4, i32 3)
136138
}
137139

Diff for: clang/test/CodeGen/SystemZ/builtins-systemz-zvector-constrained.c

+2
Original file line numberDiff line numberDiff line change
@@ -315,4 +315,6 @@ void test_float(void) {
315315
// CHECK: call <2 x double> @llvm.experimental.constrained.rint.v2f64(<2 x double> %{{.*}}, metadata !{{.*}})
316316
// CHECK-ASM: vfidb %{{.*}}, %{{.*}}, 0, 0
317317
vd = vec_round(vd);
318+
// CHECK: call <2 x double> @llvm.experimental.constrained.roundeven.v2f64(<2 x double> %{{.*}}, metadata !{{.*}})
319+
// CHECK-ASM: vfidb %{{.*}}, %{{.*}}, 4, 4
318320
}

Diff for: clang/test/CodeGen/SystemZ/builtins-systemz-zvector.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -4889,7 +4889,7 @@ void test_float(void) {
48894889
// CHECK: call <2 x double> @llvm.rint.v2f64(<2 x double> %{{.*}})
48904890
// CHECK-ASM: vfidb %{{.*}}, %{{.*}}, 0, 0
48914891
vd = vec_round(vd);
4892-
// CHECK: call <2 x double> @llvm.s390.vfidb(<2 x double> %{{.*}}, i32 4, i32 4)
4892+
// CHECK: call <2 x double> @llvm.roundeven.v2f64(<2 x double> %{{.*}})
48934893
// CHECK-ASM: vfidb %{{.*}}, %{{.*}}, 4, 4
48944894

48954895
vbl = vec_fp_test_data_class(vd, 0, &cc);

Diff for: clang/test/CodeGen/SystemZ/builtins-systemz-zvector2-constrained.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -522,10 +522,10 @@ void test_float(void) {
522522
// CHECK-ASM: vfidb %{{.*}}, %{{.*}}, 0, 0
523523

524524
vf = vec_round(vf);
525-
// CHECK: call <4 x float> @llvm.s390.vfisb(<4 x float> %{{.*}}, i32 4, i32 4)
525+
// CHECK: call <4 x float> @llvm.experimental.constrained.roundeven.v4f32(<4 x float> %{{.*}}, metadata !{{.*}})
526526
// CHECK-ASM: vfisb %{{.*}}, %{{.*}}, 4, 4
527527
vd = vec_round(vd);
528-
// CHECK: call <2 x double> @llvm.s390.vfidb(<2 x double> %{{.*}}, i32 4, i32 4)
528+
// CHECK: call <2 x double> @llvm.experimental.constrained.roundeven.v2f64(<2 x double> %{{.*}}, metadata !{{.*}})
529529
// CHECK-ASM: vfidb %{{.*}}, %{{.*}}, 4, 4
530530

531531
vbi = vec_fp_test_data_class(vf, 0, &cc);

Diff for: clang/test/CodeGen/SystemZ/builtins-systemz-zvector2.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -908,10 +908,10 @@ void test_float(void) {
908908
// CHECK-ASM: vfidb %{{.*}}, %{{.*}}, 0, 0
909909

910910
vf = vec_round(vf);
911-
// CHECK: call <4 x float> @llvm.s390.vfisb(<4 x float> %{{.*}}, i32 4, i32 4)
911+
// CHECK: call <4 x float> @llvm.roundeven.v4f32(<4 x float> %{{.*}})
912912
// CHECK-ASM: vfisb %{{.*}}, %{{.*}}, 4, 4
913913
vd = vec_round(vd);
914-
// CHECK: call <2 x double> @llvm.s390.vfidb(<2 x double> %{{.*}}, i32 4, i32 4)
914+
// CHECK: call <2 x double> @llvm.roundeven.v2f64(<2 x double> %{{.*}})
915915
// CHECK-ASM: vfidb %{{.*}}, %{{.*}}, 4, 4
916916

917917
vbi = vec_fp_test_data_class(vf, 0, &cc);

Diff for: llvm/lib/Target/SystemZ/SystemZISelLowering.cpp

+8-2
Original file line numberDiff line numberDiff line change
@@ -556,6 +556,7 @@ SystemZTargetLowering::SystemZTargetLowering(const TargetMachine &TM,
556556
setOperationAction(ISD::FCEIL, VT, Legal);
557557
setOperationAction(ISD::FTRUNC, VT, Legal);
558558
setOperationAction(ISD::FROUND, VT, Legal);
559+
setOperationAction(ISD::FROUNDEVEN, VT, Legal);
559560
}
560561

561562
// No special instructions for these.
@@ -582,8 +583,9 @@ SystemZTargetLowering::SystemZTargetLowering(const TargetMachine &TM,
582583
setOperationAction(ISD::STRICT_FNEARBYINT, VT, Legal);
583584
setOperationAction(ISD::STRICT_FFLOOR, VT, Legal);
584585
setOperationAction(ISD::STRICT_FCEIL, VT, Legal);
585-
setOperationAction(ISD::STRICT_FROUND, VT, Legal);
586586
setOperationAction(ISD::STRICT_FTRUNC, VT, Legal);
587+
setOperationAction(ISD::STRICT_FROUND, VT, Legal);
588+
setOperationAction(ISD::STRICT_FROUNDEVEN, VT, Legal);
587589
}
588590
}
589591
}
@@ -616,6 +618,7 @@ SystemZTargetLowering::SystemZTargetLowering(const TargetMachine &TM,
616618
setOperationAction(ISD::FCEIL, MVT::v2f64, Legal);
617619
setOperationAction(ISD::FTRUNC, MVT::v2f64, Legal);
618620
setOperationAction(ISD::FROUND, MVT::v2f64, Legal);
621+
setOperationAction(ISD::FROUNDEVEN, MVT::v2f64, Legal);
619622

620623
// Handle constrained floating-point operations.
621624
setOperationAction(ISD::STRICT_FADD, MVT::v2f64, Legal);
@@ -630,6 +633,7 @@ SystemZTargetLowering::SystemZTargetLowering(const TargetMachine &TM,
630633
setOperationAction(ISD::STRICT_FCEIL, MVT::v2f64, Legal);
631634
setOperationAction(ISD::STRICT_FTRUNC, MVT::v2f64, Legal);
632635
setOperationAction(ISD::STRICT_FROUND, MVT::v2f64, Legal);
636+
setOperationAction(ISD::STRICT_FROUNDEVEN, MVT::v2f64, Legal);
633637

634638
setOperationAction(ISD::SETCC, MVT::v2f64, Custom);
635639
setOperationAction(ISD::SETCC, MVT::v4f32, Custom);
@@ -657,6 +661,7 @@ SystemZTargetLowering::SystemZTargetLowering(const TargetMachine &TM,
657661
setOperationAction(ISD::FCEIL, MVT::v4f32, Legal);
658662
setOperationAction(ISD::FTRUNC, MVT::v4f32, Legal);
659663
setOperationAction(ISD::FROUND, MVT::v4f32, Legal);
664+
setOperationAction(ISD::FROUNDEVEN, MVT::v4f32, Legal);
660665

661666
setOperationAction(ISD::FMAXNUM, MVT::f64, Legal);
662667
setOperationAction(ISD::FMAXIMUM, MVT::f64, Legal);
@@ -694,8 +699,9 @@ SystemZTargetLowering::SystemZTargetLowering(const TargetMachine &TM,
694699
setOperationAction(ISD::STRICT_FNEARBYINT, MVT::v4f32, Legal);
695700
setOperationAction(ISD::STRICT_FFLOOR, MVT::v4f32, Legal);
696701
setOperationAction(ISD::STRICT_FCEIL, MVT::v4f32, Legal);
697-
setOperationAction(ISD::STRICT_FROUND, MVT::v4f32, Legal);
698702
setOperationAction(ISD::STRICT_FTRUNC, MVT::v4f32, Legal);
703+
setOperationAction(ISD::STRICT_FROUND, MVT::v4f32, Legal);
704+
setOperationAction(ISD::STRICT_FROUNDEVEN, MVT::v4f32, Legal);
699705
for (auto VT : { MVT::f32, MVT::f64, MVT::f128,
700706
MVT::v4f32, MVT::v2f64 }) {
701707
setOperationAction(ISD::STRICT_FMAXNUM, VT, Legal);

Diff for: llvm/lib/Target/SystemZ/SystemZInstrFP.td

+6
Original file line numberDiff line numberDiff line change
@@ -411,6 +411,12 @@ let Predicates = [FeatureFPExtension] in {
411411
def : Pat<(any_ftrunc FP64:$src), (FIDBRA 5, FP64:$src, 4)>;
412412
def : Pat<(any_ftrunc FP128:$src), (FIXBRA 5, FP128:$src, 4)>;
413413

414+
// Same idea for roundeven, where mode 4 is round towards nearest
415+
// with ties to even.
416+
def : Pat<(any_froundeven FP32:$src), (FIEBRA 4, FP32:$src, 4)>;
417+
def : Pat<(any_froundeven FP64:$src), (FIDBRA 4, FP64:$src, 4)>;
418+
def : Pat<(any_froundeven FP128:$src), (FIXBRA 4, FP128:$src, 4)>;
419+
414420
// Same idea for round, where mode 1 is round towards nearest with
415421
// ties away from zero.
416422
def : Pat<(any_fround FP32:$src), (FIEBRA 1, FP32:$src, 4)>;

Diff for: llvm/lib/Target/SystemZ/SystemZInstrVector.td

+1
Original file line numberDiff line numberDiff line change
@@ -1397,6 +1397,7 @@ multiclass VectorRounding<Instruction insn, TypedReg tr> {
13971397
def : FPConversion<insn, any_ffloor, tr, tr, 4, 7>;
13981398
def : FPConversion<insn, any_fceil, tr, tr, 4, 6>;
13991399
def : FPConversion<insn, any_ftrunc, tr, tr, 4, 5>;
1400+
def : FPConversion<insn, any_froundeven, tr, tr, 4, 4>;
14001401
def : FPConversion<insn, any_fround, tr, tr, 4, 1>;
14011402
}
14021403

Diff for: llvm/test/CodeGen/SystemZ/fp-round-01.ll

+32
Original file line numberDiff line numberDiff line change
@@ -193,3 +193,35 @@ define void @f18(ptr %ptr) {
193193
store fp128 %res, ptr %ptr
194194
ret void
195195
}
196+
197+
; Test roundeven for f32.
198+
declare float @llvm.roundeven.f32(float %f)
199+
define float @f19(float %f) {
200+
; CHECK-LABEL: f19:
201+
; CHECK: brasl %r14, roundevenf@PLT
202+
; CHECK: br %r14
203+
%res = call float @llvm.roundeven.f32(float %f)
204+
ret float %res
205+
}
206+
207+
; Test roundeven for f64.
208+
declare double @llvm.roundeven.f64(double %f)
209+
define double @f20(double %f) {
210+
; CHECK-LABEL: f20:
211+
; CHECK: brasl %r14, roundeven@PLT
212+
; CHECK: br %r14
213+
%res = call double @llvm.roundeven.f64(double %f)
214+
ret double %res
215+
}
216+
217+
; Test roundeven for f128.
218+
declare fp128 @llvm.roundeven.f128(fp128 %f)
219+
define void @f21(ptr %ptr) {
220+
; CHECK-LABEL: f21:
221+
; CHECK: brasl %r14, roundevenl@PLT
222+
; CHECK: br %r14
223+
%src = load fp128, ptr %ptr
224+
%res = call fp128 @llvm.roundeven.f128(fp128 %src)
225+
store fp128 %res, ptr %ptr
226+
ret void
227+
}

Diff for: llvm/test/CodeGen/SystemZ/fp-round-02.ll

+32
Original file line numberDiff line numberDiff line change
@@ -197,3 +197,35 @@ define void @f18(ptr %ptr) {
197197
store fp128 %res, ptr %ptr
198198
ret void
199199
}
200+
201+
; Test roundeven for f32.
202+
declare float @llvm.roundeven.f32(float %f)
203+
define float @f19(float %f) {
204+
; CHECK-LABEL: f19:
205+
; CHECK: fiebra %f0, 4, %f0, 4
206+
; CHECK: br %r14
207+
%res = call float @llvm.roundeven.f32(float %f)
208+
ret float %res
209+
}
210+
211+
; Test roundeven for f64.
212+
declare double @llvm.roundeven.f64(double %f)
213+
define double @f20(double %f) {
214+
; CHECK-LABEL: f20:
215+
; CHECK: fidbra %f0, 4, %f0, 4
216+
; CHECK: br %r14
217+
%res = call double @llvm.roundeven.f64(double %f)
218+
ret double %res
219+
}
220+
221+
; Test roundeven for f128.
222+
declare fp128 @llvm.roundeven.f128(fp128 %f)
223+
define void @f21(ptr %ptr) {
224+
; CHECK-LABEL: f21:
225+
; CHECK: fixbra %f0, 4, %f0, 4
226+
; CHECK: br %r14
227+
%src = load fp128, ptr %ptr
228+
%res = call fp128 @llvm.roundeven.f128(fp128 %src)
229+
store fp128 %res, ptr %ptr
230+
ret void
231+
}

Diff for: llvm/test/CodeGen/SystemZ/fp-round-03.ll

+34
Original file line numberDiff line numberDiff line change
@@ -205,3 +205,37 @@ define void @f18(ptr %ptr) {
205205
store fp128 %res, ptr %ptr
206206
ret void
207207
}
208+
209+
; Test roundeven for f32.
210+
declare float @llvm.roundeven.f32(float %f)
211+
define float @f19(float %f) {
212+
; CHECK-LABEL: f19:
213+
; CHECK: fiebra %f0, 4, %f0, 4
214+
; CHECK: br %r14
215+
%res = call float @llvm.roundeven.f32(float %f)
216+
ret float %res
217+
}
218+
219+
; Test roundeven for f64.
220+
declare double @llvm.roundeven.f64(double %f)
221+
define double @f20(double %f) {
222+
; CHECK-LABEL: f20:
223+
; CHECK: fidbra %f0, 4, %f0, 4
224+
; CHECK: br %r14
225+
%res = call double @llvm.roundeven.f64(double %f)
226+
ret double %res
227+
}
228+
229+
; Test roundeven for f128.
230+
declare fp128 @llvm.roundeven.f128(fp128 %f)
231+
define void @f21(ptr %ptr) {
232+
; CHECK-LABEL: f21:
233+
; CHECK: vl [[REG:%v[0-9]+]], 0(%r2)
234+
; CHECK: wfixb [[RES:%v[0-9]+]], [[REG]], 4, 4
235+
; CHECK: vst [[RES]], 0(%r2)
236+
; CHECK: br %r14
237+
%src = load fp128, ptr %ptr
238+
%res = call fp128 @llvm.roundeven.f128(fp128 %src)
239+
store fp128 %res, ptr %ptr
240+
ret void
241+
}

Diff for: llvm/test/CodeGen/SystemZ/fp-strict-round-01.ll

+38
Original file line numberDiff line numberDiff line change
@@ -236,4 +236,42 @@ define void @f18(ptr %ptr) #0 {
236236
ret void
237237
}
238238

239+
; Test roundeven for f32.
240+
declare float @llvm.experimental.constrained.roundeven.f32(float, metadata)
241+
define float @f19(float %f) #0 {
242+
; CHECK-LABEL: f19:
243+
; CHECK: brasl %r14, roundevenf@PLT
244+
; CHECK: br %r14
245+
%res = call float @llvm.experimental.constrained.roundeven.f32(
246+
float %f,
247+
metadata !"fpexcept.strict") #0
248+
ret float %res
249+
}
250+
251+
; Test roundeven for f64.
252+
declare double @llvm.experimental.constrained.roundeven.f64(double, metadata)
253+
define double @f20(double %f) #0 {
254+
; CHECK-LABEL: f20:
255+
; CHECK: brasl %r14, roundeven@PLT
256+
; CHECK: br %r14
257+
%res = call double @llvm.experimental.constrained.roundeven.f64(
258+
double %f,
259+
metadata !"fpexcept.strict") #0
260+
ret double %res
261+
}
262+
263+
; Test roundeven for f128.
264+
declare fp128 @llvm.experimental.constrained.roundeven.f128(fp128, metadata)
265+
define void @f21(ptr %ptr) #0 {
266+
; CHECK-LABEL: f21:
267+
; CHECK: brasl %r14, roundevenl@PLT
268+
; CHECK: br %r14
269+
%src = load fp128, ptr %ptr
270+
%res = call fp128 @llvm.experimental.constrained.roundeven.f128(
271+
fp128 %src,
272+
metadata !"fpexcept.strict") #0
273+
store fp128 %res, ptr %ptr
274+
ret void
275+
}
276+
239277
attributes #0 = { strictfp }

Diff for: llvm/test/CodeGen/SystemZ/fp-strict-round-02.ll

+38
Original file line numberDiff line numberDiff line change
@@ -240,4 +240,42 @@ define void @f18(ptr %ptr) #0 {
240240
ret void
241241
}
242242

243+
; Test roundeven for f32.
244+
declare float @llvm.experimental.constrained.roundeven.f32(float, metadata)
245+
define float @f19(float %f) #0 {
246+
; CHECK-LABEL: f19:
247+
; CHECK: fiebra %f0, 4, %f0, 4
248+
; CHECK: br %r14
249+
%res = call float @llvm.experimental.constrained.roundeven.f32(
250+
float %f,
251+
metadata !"fpexcept.strict") #0
252+
ret float %res
253+
}
254+
255+
; Test roundeven for f64.
256+
declare double @llvm.experimental.constrained.roundeven.f64(double, metadata)
257+
define double @f20(double %f) #0 {
258+
; CHECK-LABEL: f20:
259+
; CHECK: fidbra %f0, 4, %f0, 4
260+
; CHECK: br %r14
261+
%res = call double @llvm.experimental.constrained.roundeven.f64(
262+
double %f,
263+
metadata !"fpexcept.strict") #0
264+
ret double %res
265+
}
266+
267+
; Test roundeven for f128.
268+
declare fp128 @llvm.experimental.constrained.roundeven.f128(fp128, metadata)
269+
define void @f21(ptr %ptr) #0 {
270+
; CHECK-LABEL: f21:
271+
; CHECK: fixbra %f0, 4, %f0, 4
272+
; CHECK: br %r14
273+
%src = load fp128, ptr %ptr
274+
%res = call fp128 @llvm.experimental.constrained.roundeven.f128(
275+
fp128 %src,
276+
metadata !"fpexcept.strict") #0
277+
store fp128 %res, ptr %ptr
278+
ret void
279+
}
280+
243281
attributes #0 = { strictfp }

0 commit comments

Comments
 (0)