xref: /llvm-project/llvm/test/Transforms/InstSimplify/fdiv-strictfp.ll (revision b280ee1dd7e9b36ae7aaa3953556e4b7a7f31a29)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -passes=instsimplify -S | FileCheck %s
3
4define float @fdiv_constant_fold() #0 {
5; CHECK-LABEL: @fdiv_constant_fold(
6; CHECK-NEXT:    ret float 1.500000e+00
7;
8  %f = call float @llvm.experimental.constrained.fdiv.f32(float 3.0, float 2.0, metadata !"round.tonearest", metadata !"fpexcept.ignore") #0
9
10  ret float %f
11}
12
13define float @fdiv_constant_fold_strict() #0 {
14; CHECK-LABEL: @fdiv_constant_fold_strict(
15; CHECK-NEXT:    [[F:%.*]] = call float @llvm.experimental.constrained.fdiv.f32(float 3.000000e+00, float 2.000000e+00, metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR0:[0-9]+]]
16; CHECK-NEXT:    ret float 1.500000e+00
17;
18  %f = call float @llvm.experimental.constrained.fdiv.f32(float 3.0, float 2.0, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
19
20  ret float %f
21}
22
23define float @fdiv_constant_fold_strict2() #0 {
24; CHECK-LABEL: @fdiv_constant_fold_strict2(
25; CHECK-NEXT:    [[F:%.*]] = call float @llvm.experimental.constrained.fdiv.f32(float 2.000000e+00, float 3.000000e+00, metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR0]]
26; CHECK-NEXT:    ret float [[F]]
27;
28  %f = call float @llvm.experimental.constrained.fdiv.f32(float 2.0, float 3.0, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
29
30  ret float %f
31}
32
33define float @frem_constant_fold() #0 {
34; CHECK-LABEL: @frem_constant_fold(
35; CHECK-NEXT:    ret float 1.000000e+00
36;
37  %f = call float @llvm.experimental.constrained.frem.f32(float 3.0, float 2.0, metadata !"round.tonearest", metadata !"fpexcept.ignore") #0
38  ret float %f
39}
40
41define float @frem_constant_fold_strict() #0 {
42; CHECK-LABEL: @frem_constant_fold_strict(
43; CHECK-NEXT:    [[F:%.*]] = call float @llvm.experimental.constrained.frem.f32(float 3.000000e+00, float 2.000000e+00, metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR0]]
44; CHECK-NEXT:    ret float 1.000000e+00
45;
46  %f = call float @llvm.experimental.constrained.frem.f32(float 3.0, float 2.0, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
47  ret float %f
48}
49
50define double @fmul_fdiv_common_operand(double %x, double %y) #0 {
51; CHECK-LABEL: @fmul_fdiv_common_operand(
52; CHECK-NEXT:    [[M:%.*]] = call double @llvm.experimental.constrained.fmul.f64(double [[X:%.*]], double [[Y:%.*]], metadata !"round.tonearest", metadata !"fpexcept.ignore") #[[ATTR0]]
53; CHECK-NEXT:    [[D:%.*]] = call reassoc nnan double @llvm.experimental.constrained.fdiv.f64(double [[M]], double [[Y]], metadata !"round.tonearest", metadata !"fpexcept.ignore") #[[ATTR0]]
54; CHECK-NEXT:    ret double [[D]]
55;
56  %m = call double @llvm.experimental.constrained.fmul.f64(double %x, double %y, metadata !"round.tonearest", metadata !"fpexcept.ignore") #0
57  %d = call reassoc nnan double @llvm.experimental.constrained.fdiv.f64(double %m, double %y, metadata !"round.tonearest", metadata !"fpexcept.ignore") #0
58  ret double %d
59}
60
61; Negative test - the fdiv must be reassociative and not allow NaNs.
62
63define double @fmul_fdiv_common_operand_too_strict(double %x, double %y) #0 {
64; CHECK-LABEL: @fmul_fdiv_common_operand_too_strict(
65; CHECK-NEXT:    [[M:%.*]] = call fast double @llvm.experimental.constrained.fmul.f64(double [[X:%.*]], double [[Y:%.*]], metadata !"round.tonearest", metadata !"fpexcept.ignore") #[[ATTR0]]
66; CHECK-NEXT:    [[D:%.*]] = call reassoc double @llvm.experimental.constrained.fdiv.f64(double [[M]], double [[Y]], metadata !"round.tonearest", metadata !"fpexcept.ignore") #[[ATTR0]]
67; CHECK-NEXT:    ret double [[D]]
68;
69  %m = call fast double @llvm.experimental.constrained.fmul.f64(double %x, double %y, metadata !"round.tonearest", metadata !"fpexcept.ignore") #0
70  %d = call reassoc double @llvm.experimental.constrained.fdiv.f64(double %m, double %y, metadata !"round.tonearest", metadata !"fpexcept.ignore") #0
71  ret double %d
72}
73
74; Commute the fmul operands. Use a vector type to verify that works too.
75
76define <2 x float> @fmul_fdiv_common_operand_commute_vec(<2 x float> %x, <2 x float> %y) #0 {
77; CHECK-LABEL: @fmul_fdiv_common_operand_commute_vec(
78; CHECK-NEXT:    [[M:%.*]] = call <2 x float> @llvm.experimental.constrained.fmul.v2f32(<2 x float> [[Y:%.*]], <2 x float> [[X:%.*]], metadata !"round.tonearest", metadata !"fpexcept.ignore") #[[ATTR0]]
79; CHECK-NEXT:    [[D:%.*]] = call fast <2 x float> @llvm.experimental.constrained.fdiv.v2f32(<2 x float> [[M]], <2 x float> [[Y]], metadata !"round.tonearest", metadata !"fpexcept.ignore") #[[ATTR0]]
80; CHECK-NEXT:    ret <2 x float> [[D]]
81;
82  %m = call <2 x float> @llvm.experimental.constrained.fmul.v2f32(<2 x float> %y, <2 x float> %x, metadata !"round.tonearest", metadata !"fpexcept.ignore") #0
83  %d = call fast <2 x float> @llvm.experimental.constrained.fdiv.v2f32(<2 x float> %m, <2 x float> %y, metadata !"round.tonearest", metadata !"fpexcept.ignore") #0
84  ret <2 x float> %d
85}
86
87declare double @llvm.experimental.constrained.fmul.f64(double, double, metadata, metadata) #0
88declare <2 x float> @llvm.experimental.constrained.fmul.v2f32(<2 x float>, <2 x float>, metadata, metadata) #0
89
90declare float @llvm.experimental.constrained.fdiv.f32(float, float, metadata, metadata) #0
91declare double @llvm.experimental.constrained.fdiv.f64(double, double, metadata, metadata) #0
92declare <2 x float> @llvm.experimental.constrained.fdiv.v2f32(<2 x float>, <2 x float>, metadata, metadata) #0
93
94declare float @llvm.experimental.constrained.frem.f32(float, float, metadata, metadata) #0
95
96attributes #0 = { strictfp }
97
98