1; RUN: opt < %s -instsimplify -S | FileCheck %s
2
3
4; Verify that floor(10.1) is folded to 10.0 when the exception behavior is 'ignore'.
5define double @floor_01() #0 {
6entry:
7  %result = call double @llvm.experimental.constrained.floor.f64(
8                                               double 1.010000e+01,
9                                               metadata !"fpexcept.ignore") #0
10  ret double %result
11  ; CHECK-LABEL: @floor_01
12  ; CHECK: ret double 1.000000e+01
13}
14
15; Verify that floor(-10.1) is folded to -11.0 when the exception behavior is not 'ignore'.
16define double @floor_02() #0 {
17entry:
18  %result = call double @llvm.experimental.constrained.floor.f64(
19                                               double -1.010000e+01,
20                                               metadata !"fpexcept.strict") #0
21  ret double %result
22  ; CHECK-LABEL: @floor_02
23  ; CHECK: ret double -1.100000e+01
24}
25
26; Verify that ceil(10.1) is folded to 11.0 when the exception behavior is 'ignore'.
27define double @ceil_01() #0 {
28entry:
29  %result = call double @llvm.experimental.constrained.ceil.f64(
30                                               double 1.010000e+01,
31                                               metadata !"fpexcept.ignore") #0
32  ret double %result
33  ; CHECK-LABEL: @ceil_01
34  ; CHECK: ret double 1.100000e+01
35}
36
37; Verify that ceil(-10.1) is folded to -10.0 when the exception behavior is not 'ignore'.
38define double @ceil_02() #0 {
39entry:
40  %result = call double @llvm.experimental.constrained.ceil.f64(
41                                               double -1.010000e+01,
42                                               metadata !"fpexcept.strict") #0
43  ret double %result
44  ; CHECK-LABEL: @ceil_02
45  ; CHECK: ret double -1.000000e+01
46}
47
48; Verify that trunc(10.1) is folded to 10.0 when the exception behavior is 'ignore'.
49define double @trunc_01() #0 {
50entry:
51  %result = call double @llvm.experimental.constrained.trunc.f64(
52                                               double 1.010000e+01,
53                                               metadata !"fpexcept.ignore") #0
54  ret double %result
55  ; CHECK-LABEL: @trunc_01
56  ; CHECK: ret double 1.000000e+01
57}
58
59; Verify that trunc(-10.1) is folded to -10.0 when the exception behavior is NOT 'ignore'.
60define double @trunc_02() #0 {
61entry:
62  %result = call double @llvm.experimental.constrained.trunc.f64(
63                                               double -1.010000e+01,
64                                               metadata !"fpexcept.strict") #0
65  ret double %result
66  ; CHECK-LABEL: @trunc_02
67  ; CHECK: ret double -1.000000e+01
68}
69
70; Verify that round(10.5) is folded to 11.0 when the exception behavior is 'ignore'.
71define double @round_01() #0 {
72entry:
73  %result = call double @llvm.experimental.constrained.round.f64(
74                                               double 1.050000e+01,
75                                               metadata !"fpexcept.ignore") #0
76  ret double %result
77  ; CHECK-LABEL: @round_01
78  ; CHECK: ret double 1.100000e+01
79}
80
81; Verify that floor(-10.5) is folded to -11.0 when the exception behavior is NOT 'ignore'.
82define double @round_02() #0 {
83entry:
84  %result = call double @llvm.experimental.constrained.round.f64(
85                                               double -1.050000e+01,
86                                               metadata !"fpexcept.strict") #0
87  ret double %result
88  ; CHECK-LABEL: @round_02
89  ; CHECK: ret double -1.100000e+01
90}
91
92; Verify that nearbyint(10.5) is folded to 11.0 when the rounding mode is 'upward'.
93define double @nearbyint_01() #0 {
94entry:
95  %result = call double @llvm.experimental.constrained.nearbyint.f64(
96                                               double 1.050000e+01,
97                                               metadata !"round.upward",
98                                               metadata !"fpexcept.ignore") #0
99  ret double %result
100  ; CHECK-LABEL: @nearbyint_01
101  ; CHECK: ret double 1.100000e+01
102}
103
104; Verify that nearbyint(10.5) is folded to 10.0 when the rounding mode is 'downward'.
105define double @nearbyint_02() #0 {
106entry:
107  %result = call double @llvm.experimental.constrained.nearbyint.f64(
108                                               double 1.050000e+01,
109                                               metadata !"round.downward",
110                                               metadata !"fpexcept.maytrap") #0
111  ret double %result
112  ; CHECK-LABEL: @nearbyint_02
113  ; CHECK: ret double 1.000000e+01
114}
115
116; Verify that nearbyint(10.5) is folded to 10.0 when the rounding mode is 'towardzero'.
117define double @nearbyint_03() #0 {
118entry:
119  %result = call double @llvm.experimental.constrained.nearbyint.f64(
120                                               double 1.050000e+01,
121                                               metadata !"round.towardzero",
122                                               metadata !"fpexcept.strict") #0
123  ret double %result
124  ; CHECK-LABEL: @nearbyint_03
125  ; CHECK: ret double 1.000000e+01
126}
127
128; Verify that nearbyint(10.5) is folded to 10.0 when the rounding mode is 'tonearest'.
129define double @nearbyint_04() #0 {
130entry:
131  %result = call double @llvm.experimental.constrained.nearbyint.f64(
132                                               double 1.050000e+01,
133                                               metadata !"round.tonearest",
134                                               metadata !"fpexcept.strict") #0
135  ret double %result
136  ; CHECK-LABEL: @nearbyint_04
137  ; CHECK: ret double 1.000000e+01
138}
139
140; Verify that nearbyint(10.5) is NOT folded if the rounding mode is 'dynamic'.
141define double @nearbyint_05() #0 {
142entry:
143  %result = call double @llvm.experimental.constrained.nearbyint.f64(
144                                               double 1.050000e+01,
145                                               metadata !"round.dynamic",
146                                               metadata !"fpexcept.strict") #0
147  ret double %result
148  ; CHECK-LABEL: @nearbyint_05
149  ; CHECK: [[VAL:%.+]] = {{.*}}call double @llvm.experimental.constrained.nearbyint
150  ; CHECK: ret double [[VAL]]
151}
152
153; Verify that trunc(SNAN) is NOT folded if the exception behavior mode is not 'ignore'.
154define double @nonfinite_01() #0 {
155entry:
156  %result = call double @llvm.experimental.constrained.trunc.f64(
157                                               double 0x7ff4000000000000,
158                                               metadata !"fpexcept.strict") #0
159  ret double %result
160  ; CHECK-LABEL: @nonfinite_01
161  ; CHECK: [[VAL:%.+]] = {{.*}}call double @llvm.experimental.constrained.trunc
162  ; CHECK: ret double [[VAL]]
163}
164
165; Verify that trunc(SNAN) is folded to QNAN if the exception behavior mode is 'ignore'.
166define double @nonfinite_02() #0 {
167entry:
168  %result = call double @llvm.experimental.constrained.trunc.f64(
169                                               double 0x7ff4000000000000,
170                                               metadata !"fpexcept.ignore") #0
171  ret double %result
172  ; CHECK-LABEL: @nonfinite_02
173  ; CHECK: ret double 0x7FF8000000000000
174}
175
176; Verify that trunc(QNAN) is folded even if the exception behavior mode is not 'ignore'.
177define double @nonfinite_03() #0 {
178entry:
179  %result = call double @llvm.experimental.constrained.trunc.f64(
180                                               double 0x7ff8000000000000,
181                                               metadata !"fpexcept.strict") #0
182  ret double %result
183  ; CHECK-LABEL: @nonfinite_03
184  ; CHECK: ret double 0x7FF8000000000000
185}
186
187; Verify that trunc(+Inf) is folded even if the exception behavior mode is not 'ignore'.
188define double @nonfinite_04() #0 {
189entry:
190  %result = call double @llvm.experimental.constrained.trunc.f64(
191                                               double 0x7ff0000000000000,
192                                               metadata !"fpexcept.strict") #0
193  ret double %result
194  ; CHECK-LABEL: @nonfinite_04
195  ; CHECK: ret double 0x7FF0000000000000
196}
197
198; Verify that rint(10) is folded to 10.0 when the rounding mode is 'tonearest'.
199define double @rint_01() #0 {
200entry:
201  %result = call double @llvm.experimental.constrained.rint.f64(
202                                               double 1.000000e+01,
203                                               metadata !"round.tonearest",
204                                               metadata !"fpexcept.strict") #0
205  ret double %result
206  ; CHECK-LABEL: @rint_01
207  ; CHECK: ret double 1.000000e+01
208}
209
210; Verify that rint(10.1) is NOT folded to 10.0 when the exception behavior is 'strict'.
211define double @rint_02() #0 {
212entry:
213  %result = call double @llvm.experimental.constrained.rint.f64(
214                                               double 1.010000e+01,
215                                               metadata !"round.tonearest",
216                                               metadata !"fpexcept.strict") #0
217  ret double %result
218  ; CHECK-LABEL: @rint_02
219  ; CHECK: [[VAL:%.+]] = {{.*}}call double @llvm.experimental.constrained.rint
220  ; CHECK: ret double [[VAL]]
221}
222
223; Verify that rint(10.1) is folded to 10.0 when the exception behavior is not 'strict'.
224define double @rint_03() #0 {
225entry:
226  %result = call double @llvm.experimental.constrained.rint.f64(
227                                               double 1.010000e+01,
228                                               metadata !"round.tonearest",
229                                               metadata !"fpexcept.maytrap") #0
230  ret double %result
231  ; CHECK-LABEL: @rint_03
232  ; CHECK: ret double 1.000000e+01
233}
234
235
236attributes #0 = { strictfp }
237
238declare double @llvm.experimental.constrained.nearbyint.f64(double, metadata, metadata)
239declare double @llvm.experimental.constrained.floor.f64(double, metadata)
240declare double @llvm.experimental.constrained.ceil.f64(double, metadata)
241declare double @llvm.experimental.constrained.trunc.f64(double, metadata)
242declare double @llvm.experimental.constrained.round.f64(double, metadata)
243declare double @llvm.experimental.constrained.rint.f64(double, metadata, metadata)
244
245