xref: /llvm-project/llvm/test/Transforms/EarlyCSE/mixed-strictfp.ll (revision 819abe412dd554303cb932d6ec2200b9b9ebdd78)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -S -passes=early-cse -earlycse-debug-hash | FileCheck %s
3; RUN: opt < %s -S -passes='early-cse<memssa>' | FileCheck %s
4
5; Test use of constrained floating point intrinsics mixing the default
6; floating point environment with alternate modes. None of the tests
7; should trigger CSE.
8
9define double @mixed_fadd_neginf(double %a, double %b) #0 {
10; CHECK-LABEL: @mixed_fadd_neginf(
11; CHECK-NEXT:    [[TMP1:%.*]] = call double @llvm.experimental.constrained.fadd.f64(double [[A:%.*]], double [[B:%.*]], metadata !"round.tonearest", metadata !"fpexcept.ignore") #[[ATTR0:[0-9]+]]
12; CHECK-NEXT:    [[TMP2:%.*]] = call double @llvm.experimental.constrained.fadd.f64(double [[A]], double [[B]], metadata !"round.downward", metadata !"fpexcept.ignore") #[[ATTR0]]
13; CHECK-NEXT:    [[TMP3:%.*]] = call double @foo.f64(double [[TMP1]], double [[TMP2]]) #[[ATTR0]]
14; CHECK-NEXT:    ret double [[TMP2]]
15;
16  %1 = call double @llvm.experimental.constrained.fadd.f64(double %a, double %b, metadata !"round.tonearest", metadata !"fpexcept.ignore") #0
17  %2 = call double @llvm.experimental.constrained.fadd.f64(double %a, double %b, metadata !"round.downward", metadata !"fpexcept.ignore") #0
18  %3 = call double @foo.f64(double %1, double %2) #0
19  ret double %2
20}
21
22define double @mixed_fadd_maytrap(double %a, double %b) #0 {
23; CHECK-LABEL: @mixed_fadd_maytrap(
24; CHECK-NEXT:    [[TMP1:%.*]] = call double @llvm.experimental.constrained.fadd.f64(double [[A:%.*]], double [[B:%.*]], metadata !"round.tonearest", metadata !"fpexcept.ignore") #[[ATTR0]]
25; CHECK-NEXT:    [[TMP2:%.*]] = call double @llvm.experimental.constrained.fadd.f64(double [[A]], double [[B]], metadata !"round.tonearest", metadata !"fpexcept.maytrap") #[[ATTR0]]
26; CHECK-NEXT:    [[TMP3:%.*]] = call double @foo.f64(double [[TMP1]], double [[TMP2]]) #[[ATTR0]]
27; CHECK-NEXT:    ret double [[TMP2]]
28;
29  %1 = call double @llvm.experimental.constrained.fadd.f64(double %a, double %b, metadata !"round.tonearest", metadata !"fpexcept.ignore") #0
30  %2 = call double @llvm.experimental.constrained.fadd.f64(double %a, double %b, metadata !"round.tonearest", metadata !"fpexcept.maytrap") #0
31  %3 = call double @foo.f64(double %1, double %2) #0
32  ret double %2
33}
34
35define double @mixed_fadd_strict(double %a, double %b) #0 {
36; CHECK-LABEL: @mixed_fadd_strict(
37; CHECK-NEXT:    [[TMP1:%.*]] = call double @llvm.experimental.constrained.fadd.f64(double [[A:%.*]], double [[B:%.*]], metadata !"round.tonearest", metadata !"fpexcept.ignore") #[[ATTR0]]
38; CHECK-NEXT:    [[TMP2:%.*]] = call double @llvm.experimental.constrained.fadd.f64(double [[A]], double [[B]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR0]]
39; CHECK-NEXT:    [[TMP3:%.*]] = call double @foo.f64(double [[TMP1]], double [[TMP2]]) #[[ATTR0]]
40; CHECK-NEXT:    ret double [[TMP2]]
41;
42  %1 = call double @llvm.experimental.constrained.fadd.f64(double %a, double %b, metadata !"round.tonearest", metadata !"fpexcept.ignore") #0
43  %2 = call double @llvm.experimental.constrained.fadd.f64(double %a, double %b, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
44  %3 = call double @foo.f64(double %1, double %2) #0
45  ret double %2
46}
47
48define double @mixed_fsub_neginf(double %a, double %b) #0 {
49; CHECK-LABEL: @mixed_fsub_neginf(
50; CHECK-NEXT:    [[TMP1:%.*]] = call double @llvm.experimental.constrained.fsub.f64(double [[A:%.*]], double [[B:%.*]], metadata !"round.tonearest", metadata !"fpexcept.ignore") #[[ATTR0]]
51; CHECK-NEXT:    [[TMP2:%.*]] = call double @llvm.experimental.constrained.fsub.f64(double [[A]], double [[B]], metadata !"round.downward", metadata !"fpexcept.ignore") #[[ATTR0]]
52; CHECK-NEXT:    [[TMP3:%.*]] = call double @foo.f64(double [[TMP1]], double [[TMP2]]) #[[ATTR0]]
53; CHECK-NEXT:    ret double [[TMP2]]
54;
55  %1 = call double @llvm.experimental.constrained.fsub.f64(double %a, double %b, metadata !"round.tonearest", metadata !"fpexcept.ignore") #0
56  %2 = call double @llvm.experimental.constrained.fsub.f64(double %a, double %b, metadata !"round.downward", metadata !"fpexcept.ignore") #0
57  %3 = call double @foo.f64(double %1, double %2) #0
58  ret double %2
59}
60
61define double @mixed_fsub_maytrap(double %a, double %b) #0 {
62; CHECK-LABEL: @mixed_fsub_maytrap(
63; CHECK-NEXT:    [[TMP1:%.*]] = call double @llvm.experimental.constrained.fsub.f64(double [[A:%.*]], double [[B:%.*]], metadata !"round.tonearest", metadata !"fpexcept.ignore") #[[ATTR0]]
64; CHECK-NEXT:    [[TMP2:%.*]] = call double @llvm.experimental.constrained.fsub.f64(double [[A]], double [[B]], metadata !"round.tonearest", metadata !"fpexcept.maytrap") #[[ATTR0]]
65; CHECK-NEXT:    [[TMP3:%.*]] = call double @foo.f64(double [[TMP1]], double [[TMP2]]) #[[ATTR0]]
66; CHECK-NEXT:    ret double [[TMP2]]
67;
68  %1 = call double @llvm.experimental.constrained.fsub.f64(double %a, double %b, metadata !"round.tonearest", metadata !"fpexcept.ignore") #0
69  %2 = call double @llvm.experimental.constrained.fsub.f64(double %a, double %b, metadata !"round.tonearest", metadata !"fpexcept.maytrap") #0
70  %3 = call double @foo.f64(double %1, double %2) #0
71  ret double %2
72}
73
74define double @mixed_fsub_strict(double %a, double %b) #0 {
75; CHECK-LABEL: @mixed_fsub_strict(
76; CHECK-NEXT:    [[TMP1:%.*]] = call double @llvm.experimental.constrained.fsub.f64(double [[A:%.*]], double [[B:%.*]], metadata !"round.tonearest", metadata !"fpexcept.ignore") #[[ATTR0]]
77; CHECK-NEXT:    [[TMP2:%.*]] = call double @llvm.experimental.constrained.fsub.f64(double [[A]], double [[B]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR0]]
78; CHECK-NEXT:    [[TMP3:%.*]] = call double @foo.f64(double [[TMP1]], double [[TMP2]]) #[[ATTR0]]
79; CHECK-NEXT:    ret double [[TMP2]]
80;
81  %1 = call double @llvm.experimental.constrained.fsub.f64(double %a, double %b, metadata !"round.tonearest", metadata !"fpexcept.ignore") #0
82  %2 = call double @llvm.experimental.constrained.fsub.f64(double %a, double %b, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
83  %3 = call double @foo.f64(double %1, double %2) #0
84  ret double %2
85}
86
87define double @mixed_fmul_neginf(double %a, double %b) #0 {
88; CHECK-LABEL: @mixed_fmul_neginf(
89; CHECK-NEXT:    [[TMP1:%.*]] = call double @llvm.experimental.constrained.fmul.f64(double [[A:%.*]], double [[B:%.*]], metadata !"round.tonearest", metadata !"fpexcept.ignore") #[[ATTR0]]
90; CHECK-NEXT:    [[TMP2:%.*]] = call double @llvm.experimental.constrained.fmul.f64(double [[A]], double [[B]], metadata !"round.downward", metadata !"fpexcept.ignore") #[[ATTR0]]
91; CHECK-NEXT:    [[TMP3:%.*]] = call double @foo.f64(double [[TMP1]], double [[TMP2]]) #[[ATTR0]]
92; CHECK-NEXT:    ret double [[TMP2]]
93;
94  %1 = call double @llvm.experimental.constrained.fmul.f64(double %a, double %b, metadata !"round.tonearest", metadata !"fpexcept.ignore") #0
95  %2 = call double @llvm.experimental.constrained.fmul.f64(double %a, double %b, metadata !"round.downward", metadata !"fpexcept.ignore") #0
96  %3 = call double @foo.f64(double %1, double %2) #0
97  ret double %2
98}
99define double @mixed_fmul_maytrap(double %a, double %b) #0 {
100; CHECK-LABEL: @mixed_fmul_maytrap(
101; CHECK-NEXT:    [[TMP1:%.*]] = call double @llvm.experimental.constrained.fmul.f64(double [[A:%.*]], double [[B:%.*]], metadata !"round.tonearest", metadata !"fpexcept.ignore") #[[ATTR0]]
102; CHECK-NEXT:    [[TMP2:%.*]] = call double @llvm.experimental.constrained.fmul.f64(double [[A]], double [[B]], metadata !"round.tonearest", metadata !"fpexcept.maytrap") #[[ATTR0]]
103; CHECK-NEXT:    [[TMP3:%.*]] = call double @foo.f64(double [[TMP1]], double [[TMP2]]) #[[ATTR0]]
104; CHECK-NEXT:    ret double [[TMP2]]
105;
106  %1 = call double @llvm.experimental.constrained.fmul.f64(double %a, double %b, metadata !"round.tonearest", metadata !"fpexcept.ignore") #0
107  %2 = call double @llvm.experimental.constrained.fmul.f64(double %a, double %b, metadata !"round.tonearest", metadata !"fpexcept.maytrap") #0
108  %3 = call double @foo.f64(double %1, double %2) #0
109  ret double %2
110}
111
112define double @mixed_fmul_strict(double %a, double %b) #0 {
113; CHECK-LABEL: @mixed_fmul_strict(
114; CHECK-NEXT:    [[TMP1:%.*]] = call double @llvm.experimental.constrained.fmul.f64(double [[A:%.*]], double [[B:%.*]], metadata !"round.tonearest", metadata !"fpexcept.ignore") #[[ATTR0]]
115; CHECK-NEXT:    [[TMP2:%.*]] = call double @llvm.experimental.constrained.fmul.f64(double [[A]], double [[B]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR0]]
116; CHECK-NEXT:    [[TMP3:%.*]] = call double @foo.f64(double [[TMP1]], double [[TMP2]]) #[[ATTR0]]
117; CHECK-NEXT:    ret double [[TMP2]]
118;
119  %1 = call double @llvm.experimental.constrained.fmul.f64(double %a, double %b, metadata !"round.tonearest", metadata !"fpexcept.ignore") #0
120  %2 = call double @llvm.experimental.constrained.fmul.f64(double %a, double %b, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
121  %3 = call double @foo.f64(double %1, double %2) #0
122  ret double %2
123}
124
125define double @mixed_fdiv_neginf(double %a, double %b) #0 {
126; CHECK-LABEL: @mixed_fdiv_neginf(
127; CHECK-NEXT:    [[TMP1:%.*]] = call double @llvm.experimental.constrained.fdiv.f64(double [[A:%.*]], double [[B:%.*]], metadata !"round.tonearest", metadata !"fpexcept.ignore") #[[ATTR0]]
128; CHECK-NEXT:    [[TMP2:%.*]] = call double @llvm.experimental.constrained.fdiv.f64(double [[A]], double [[B]], metadata !"round.downward", metadata !"fpexcept.ignore") #[[ATTR0]]
129; CHECK-NEXT:    [[TMP3:%.*]] = call double @foo.f64(double [[TMP1]], double [[TMP2]]) #[[ATTR0]]
130; CHECK-NEXT:    ret double [[TMP2]]
131;
132  %1 = call double @llvm.experimental.constrained.fdiv.f64(double %a, double %b, metadata !"round.tonearest", metadata !"fpexcept.ignore") #0
133  %2 = call double @llvm.experimental.constrained.fdiv.f64(double %a, double %b, metadata !"round.downward", metadata !"fpexcept.ignore") #0
134  %3 = call double @foo.f64(double %1, double %2) #0
135  ret double %2
136}
137
138define double @mixed_fdiv_maytrap(double %a, double %b) #0 {
139; CHECK-LABEL: @mixed_fdiv_maytrap(
140; CHECK-NEXT:    [[TMP1:%.*]] = call double @llvm.experimental.constrained.fdiv.f64(double [[A:%.*]], double [[B:%.*]], metadata !"round.tonearest", metadata !"fpexcept.ignore") #[[ATTR0]]
141; CHECK-NEXT:    [[TMP2:%.*]] = call double @llvm.experimental.constrained.fdiv.f64(double [[A]], double [[B]], metadata !"round.tonearest", metadata !"fpexcept.maytrap") #[[ATTR0]]
142; CHECK-NEXT:    [[TMP3:%.*]] = call double @foo.f64(double [[TMP1]], double [[TMP2]]) #[[ATTR0]]
143; CHECK-NEXT:    ret double [[TMP2]]
144;
145  %1 = call double @llvm.experimental.constrained.fdiv.f64(double %a, double %b, metadata !"round.tonearest", metadata !"fpexcept.ignore") #0
146  %2 = call double @llvm.experimental.constrained.fdiv.f64(double %a, double %b, metadata !"round.tonearest", metadata !"fpexcept.maytrap") #0
147  %3 = call double @foo.f64(double %1, double %2) #0
148  ret double %2
149}
150
151define double @mixed_fdiv_strict(double %a, double %b) #0 {
152; CHECK-LABEL: @mixed_fdiv_strict(
153; CHECK-NEXT:    [[TMP1:%.*]] = call double @llvm.experimental.constrained.fdiv.f64(double [[A:%.*]], double [[B:%.*]], metadata !"round.tonearest", metadata !"fpexcept.ignore") #[[ATTR0]]
154; CHECK-NEXT:    [[TMP2:%.*]] = call double @llvm.experimental.constrained.fdiv.f64(double [[A]], double [[B]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR0]]
155; CHECK-NEXT:    [[TMP3:%.*]] = call double @foo.f64(double [[TMP1]], double [[TMP2]]) #[[ATTR0]]
156; CHECK-NEXT:    ret double [[TMP2]]
157;
158  %1 = call double @llvm.experimental.constrained.fdiv.f64(double %a, double %b, metadata !"round.tonearest", metadata !"fpexcept.ignore") #0
159  %2 = call double @llvm.experimental.constrained.fdiv.f64(double %a, double %b, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
160  %3 = call double @foo.f64(double %1, double %2) #0
161  ret double %2
162}
163
164define double @mixed_frem_neginf(double %a, double %b) #0 {
165; CHECK-LABEL: @mixed_frem_neginf(
166; CHECK-NEXT:    [[TMP1:%.*]] = call double @llvm.experimental.constrained.frem.f64(double [[A:%.*]], double [[B:%.*]], metadata !"round.tonearest", metadata !"fpexcept.ignore") #[[ATTR0]]
167; CHECK-NEXT:    [[TMP2:%.*]] = call double @llvm.experimental.constrained.frem.f64(double [[A]], double [[B]], metadata !"round.downward", metadata !"fpexcept.ignore") #[[ATTR0]]
168; CHECK-NEXT:    [[TMP3:%.*]] = call double @foo.f64(double [[TMP1]], double [[TMP2]]) #[[ATTR0]]
169; CHECK-NEXT:    ret double [[TMP2]]
170;
171  %1 = call double @llvm.experimental.constrained.frem.f64(double %a, double %b, metadata !"round.tonearest", metadata !"fpexcept.ignore") #0
172  %2 = call double @llvm.experimental.constrained.frem.f64(double %a, double %b, metadata !"round.downward", metadata !"fpexcept.ignore") #0
173  %3 = call double @foo.f64(double %1, double %2) #0
174  ret double %2
175}
176
177define double @mixed_frem_maytrap(double %a, double %b) #0 {
178; CHECK-LABEL: @mixed_frem_maytrap(
179; CHECK-NEXT:    [[TMP1:%.*]] = call double @llvm.experimental.constrained.frem.f64(double [[A:%.*]], double [[B:%.*]], metadata !"round.tonearest", metadata !"fpexcept.ignore") #[[ATTR0]]
180; CHECK-NEXT:    [[TMP2:%.*]] = call double @llvm.experimental.constrained.frem.f64(double [[A]], double [[B]], metadata !"round.tonearest", metadata !"fpexcept.maytrap") #[[ATTR0]]
181; CHECK-NEXT:    [[TMP3:%.*]] = call double @foo.f64(double [[TMP1]], double [[TMP2]]) #[[ATTR0]]
182; CHECK-NEXT:    ret double [[TMP2]]
183;
184  %1 = call double @llvm.experimental.constrained.frem.f64(double %a, double %b, metadata !"round.tonearest", metadata !"fpexcept.ignore") #0
185  %2 = call double @llvm.experimental.constrained.frem.f64(double %a, double %b, metadata !"round.tonearest", metadata !"fpexcept.maytrap") #0
186  %3 = call double @foo.f64(double %1, double %2) #0
187  ret double %2
188}
189
190define double @mixed_frem_strict(double %a, double %b) #0 {
191; CHECK-LABEL: @mixed_frem_strict(
192; CHECK-NEXT:    [[TMP1:%.*]] = call double @llvm.experimental.constrained.frem.f64(double [[A:%.*]], double [[B:%.*]], metadata !"round.tonearest", metadata !"fpexcept.ignore") #[[ATTR0]]
193; CHECK-NEXT:    [[TMP2:%.*]] = call double @llvm.experimental.constrained.frem.f64(double [[A]], double [[B]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR0]]
194; CHECK-NEXT:    [[TMP3:%.*]] = call double @foo.f64(double [[TMP1]], double [[TMP2]]) #[[ATTR0]]
195; CHECK-NEXT:    ret double [[TMP2]]
196;
197  %1 = call double @llvm.experimental.constrained.frem.f64(double %a, double %b, metadata !"round.tonearest", metadata !"fpexcept.ignore") #0
198  %2 = call double @llvm.experimental.constrained.frem.f64(double %a, double %b, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
199  %3 = call double @foo.f64(double %1, double %2) #0
200  ret double %2
201}
202
203define i32 @mixed_fptoui_maytrap(double %a) #0 {
204; CHECK-LABEL: @mixed_fptoui_maytrap(
205; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.experimental.constrained.fptoui.i32.f64(double [[A:%.*]], metadata !"fpexcept.ignore") #[[ATTR0]]
206; CHECK-NEXT:    [[TMP2:%.*]] = call i32 @llvm.experimental.constrained.fptoui.i32.f64(double [[A]], metadata !"fpexcept.maytrap") #[[ATTR0]]
207; CHECK-NEXT:    [[TMP3:%.*]] = call i32 @bar.i32(i32 [[TMP1]], i32 [[TMP1]]) #[[ATTR0]]
208; CHECK-NEXT:    ret i32 [[TMP2]]
209;
210  %1 = call i32 @llvm.experimental.constrained.fptoui.i32.f64(double %a, metadata !"fpexcept.ignore") #0
211  %2 = call i32 @llvm.experimental.constrained.fptoui.i32.f64(double %a, metadata !"fpexcept.maytrap") #0
212  %3 = call i32 @bar.i32(i32 %1, i32 %1) #0
213  ret i32 %2
214}
215
216define i32 @mixed_fptoui_strict(double %a) #0 {
217; CHECK-LABEL: @mixed_fptoui_strict(
218; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.experimental.constrained.fptoui.i32.f64(double [[A:%.*]], metadata !"fpexcept.ignore") #[[ATTR0]]
219; CHECK-NEXT:    [[TMP2:%.*]] = call i32 @llvm.experimental.constrained.fptoui.i32.f64(double [[A]], metadata !"fpexcept.strict") #[[ATTR0]]
220; CHECK-NEXT:    [[TMP3:%.*]] = call i32 @bar.i32(i32 [[TMP1]], i32 [[TMP1]]) #[[ATTR0]]
221; CHECK-NEXT:    ret i32 [[TMP2]]
222;
223  %1 = call i32 @llvm.experimental.constrained.fptoui.i32.f64(double %a, metadata !"fpexcept.ignore") #0
224  %2 = call i32 @llvm.experimental.constrained.fptoui.i32.f64(double %a, metadata !"fpexcept.strict") #0
225  %3 = call i32 @bar.i32(i32 %1, i32 %1) #0
226  ret i32 %2
227}
228
229define double @mixed_uitofp_neginf(i32 %a) #0 {
230; CHECK-LABEL: @mixed_uitofp_neginf(
231; CHECK-NEXT:    [[TMP1:%.*]] = call double @llvm.experimental.constrained.uitofp.f64.i32(i32 [[A:%.*]], metadata !"round.tonearest", metadata !"fpexcept.ignore") #[[ATTR0]]
232; CHECK-NEXT:    [[TMP2:%.*]] = call double @llvm.experimental.constrained.uitofp.f64.i32(i32 [[A]], metadata !"round.downward", metadata !"fpexcept.ignore") #[[ATTR0]]
233; CHECK-NEXT:    [[TMP3:%.*]] = call double @foo.f64(double [[TMP1]], double [[TMP1]]) #[[ATTR0]]
234; CHECK-NEXT:    ret double [[TMP2]]
235;
236  %1 = call double @llvm.experimental.constrained.uitofp.f64.i32(i32 %a, metadata !"round.tonearest", metadata !"fpexcept.ignore") #0
237  %2 = call double @llvm.experimental.constrained.uitofp.f64.i32(i32 %a, metadata !"round.downward", metadata !"fpexcept.ignore") #0
238  %3 = call double @foo.f64(double %1, double %1) #0
239  ret double %2
240}
241
242define double @mixed_uitofp_maytrap(i32 %a) #0 {
243; CHECK-LABEL: @mixed_uitofp_maytrap(
244; CHECK-NEXT:    [[TMP1:%.*]] = call double @llvm.experimental.constrained.uitofp.f64.i32(i32 [[A:%.*]], metadata !"round.tonearest", metadata !"fpexcept.ignore") #[[ATTR0]]
245; CHECK-NEXT:    [[TMP2:%.*]] = call double @llvm.experimental.constrained.uitofp.f64.i32(i32 [[A]], metadata !"round.tonearest", metadata !"fpexcept.maytrap") #[[ATTR0]]
246; CHECK-NEXT:    [[TMP3:%.*]] = call double @foo.f64(double [[TMP1]], double [[TMP1]]) #[[ATTR0]]
247; CHECK-NEXT:    ret double [[TMP2]]
248;
249  %1 = call double @llvm.experimental.constrained.uitofp.f64.i32(i32 %a, metadata !"round.tonearest", metadata !"fpexcept.ignore") #0
250  %2 = call double @llvm.experimental.constrained.uitofp.f64.i32(i32 %a, metadata !"round.tonearest", metadata !"fpexcept.maytrap") #0
251  %3 = call double @foo.f64(double %1, double %1) #0
252  ret double %2
253}
254
255define double @mixed_uitofp_strict(i32 %a) #0 {
256; CHECK-LABEL: @mixed_uitofp_strict(
257; CHECK-NEXT:    [[TMP1:%.*]] = call double @llvm.experimental.constrained.uitofp.f64.i32(i32 [[A:%.*]], metadata !"round.tonearest", metadata !"fpexcept.ignore") #[[ATTR0]]
258; CHECK-NEXT:    [[TMP2:%.*]] = call double @llvm.experimental.constrained.uitofp.f64.i32(i32 [[A]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR0]]
259; CHECK-NEXT:    [[TMP3:%.*]] = call double @foo.f64(double [[TMP1]], double [[TMP1]]) #[[ATTR0]]
260; CHECK-NEXT:    ret double [[TMP2]]
261;
262  %1 = call double @llvm.experimental.constrained.uitofp.f64.i32(i32 %a, metadata !"round.tonearest", metadata !"fpexcept.ignore") #0
263  %2 = call double @llvm.experimental.constrained.uitofp.f64.i32(i32 %a, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
264  %3 = call double @foo.f64(double %1, double %1) #0
265  ret double %2
266}
267
268define i32 @mixed_fptosi_maytrap(double %a) #0 {
269; CHECK-LABEL: @mixed_fptosi_maytrap(
270; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.experimental.constrained.fptosi.i32.f64(double [[A:%.*]], metadata !"fpexcept.ignore") #[[ATTR0]]
271; CHECK-NEXT:    [[TMP2:%.*]] = call i32 @llvm.experimental.constrained.fptosi.i32.f64(double [[A]], metadata !"fpexcept.maytrap") #[[ATTR0]]
272; CHECK-NEXT:    [[TMP3:%.*]] = call i32 @bar.i32(i32 [[TMP1]], i32 [[TMP1]]) #[[ATTR0]]
273; CHECK-NEXT:    ret i32 [[TMP2]]
274;
275  %1 = call i32 @llvm.experimental.constrained.fptosi.i32.f64(double %a, metadata !"fpexcept.ignore") #0
276  %2 = call i32 @llvm.experimental.constrained.fptosi.i32.f64(double %a, metadata !"fpexcept.maytrap") #0
277  %3 = call i32 @bar.i32(i32 %1, i32 %1) #0
278  ret i32 %2
279}
280
281define i32 @mixed_fptosi_strict(double %a) #0 {
282; CHECK-LABEL: @mixed_fptosi_strict(
283; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.experimental.constrained.fptosi.i32.f64(double [[A:%.*]], metadata !"fpexcept.ignore") #[[ATTR0]]
284; CHECK-NEXT:    [[TMP2:%.*]] = call i32 @llvm.experimental.constrained.fptosi.i32.f64(double [[A]], metadata !"fpexcept.strict") #[[ATTR0]]
285; CHECK-NEXT:    [[TMP3:%.*]] = call i32 @bar.i32(i32 [[TMP1]], i32 [[TMP1]]) #[[ATTR0]]
286; CHECK-NEXT:    ret i32 [[TMP2]]
287;
288  %1 = call i32 @llvm.experimental.constrained.fptosi.i32.f64(double %a, metadata !"fpexcept.ignore") #0
289  %2 = call i32 @llvm.experimental.constrained.fptosi.i32.f64(double %a, metadata !"fpexcept.strict") #0
290  %3 = call i32 @bar.i32(i32 %1, i32 %1) #0
291  ret i32 %2
292}
293
294define double @mixed_sitofp_neginf(i32 %a) #0 {
295; CHECK-LABEL: @mixed_sitofp_neginf(
296; CHECK-NEXT:    [[TMP1:%.*]] = call double @llvm.experimental.constrained.sitofp.f64.i32(i32 [[A:%.*]], metadata !"round.tonearest", metadata !"fpexcept.ignore") #[[ATTR0]]
297; CHECK-NEXT:    [[TMP2:%.*]] = call double @llvm.experimental.constrained.sitofp.f64.i32(i32 [[A]], metadata !"round.downward", metadata !"fpexcept.ignore") #[[ATTR0]]
298; CHECK-NEXT:    [[TMP3:%.*]] = call double @foo.f64(double [[TMP1]], double [[TMP1]]) #[[ATTR0]]
299; CHECK-NEXT:    ret double [[TMP2]]
300;
301  %1 = call double @llvm.experimental.constrained.sitofp.f64.i32(i32 %a, metadata !"round.tonearest", metadata !"fpexcept.ignore") #0
302  %2 = call double @llvm.experimental.constrained.sitofp.f64.i32(i32 %a, metadata !"round.downward", metadata !"fpexcept.ignore") #0
303  %3 = call double @foo.f64(double %1, double %1) #0
304  ret double %2
305}
306
307define double @mixed_sitofp_maytrap(i32 %a) #0 {
308; CHECK-LABEL: @mixed_sitofp_maytrap(
309; CHECK-NEXT:    [[TMP1:%.*]] = call double @llvm.experimental.constrained.sitofp.f64.i32(i32 [[A:%.*]], metadata !"round.tonearest", metadata !"fpexcept.ignore") #[[ATTR0]]
310; CHECK-NEXT:    [[TMP2:%.*]] = call double @llvm.experimental.constrained.sitofp.f64.i32(i32 [[A]], metadata !"round.tonearest", metadata !"fpexcept.maytrap") #[[ATTR0]]
311; CHECK-NEXT:    [[TMP3:%.*]] = call double @foo.f64(double [[TMP1]], double [[TMP1]]) #[[ATTR0]]
312; CHECK-NEXT:    ret double [[TMP2]]
313;
314  %1 = call double @llvm.experimental.constrained.sitofp.f64.i32(i32 %a, metadata !"round.tonearest", metadata !"fpexcept.ignore") #0
315  %2 = call double @llvm.experimental.constrained.sitofp.f64.i32(i32 %a, metadata !"round.tonearest", metadata !"fpexcept.maytrap") #0
316  %3 = call double @foo.f64(double %1, double %1) #0
317  ret double %2
318}
319
320define double @mixed_sitofp_strict(i32 %a) #0 {
321; CHECK-LABEL: @mixed_sitofp_strict(
322; CHECK-NEXT:    [[TMP1:%.*]] = call double @llvm.experimental.constrained.sitofp.f64.i32(i32 [[A:%.*]], metadata !"round.tonearest", metadata !"fpexcept.ignore") #[[ATTR0]]
323; CHECK-NEXT:    [[TMP2:%.*]] = call double @llvm.experimental.constrained.sitofp.f64.i32(i32 [[A]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR0]]
324; CHECK-NEXT:    [[TMP3:%.*]] = call double @foo.f64(double [[TMP1]], double [[TMP1]]) #[[ATTR0]]
325; CHECK-NEXT:    ret double [[TMP2]]
326;
327  %1 = call double @llvm.experimental.constrained.sitofp.f64.i32(i32 %a, metadata !"round.tonearest", metadata !"fpexcept.ignore") #0
328  %2 = call double @llvm.experimental.constrained.sitofp.f64.i32(i32 %a, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
329  %3 = call double @foo.f64(double %1, double %1) #0
330  ret double %2
331}
332
333define i1 @mixed_fcmp_maytrap(double %a, double %b) #0 {
334; CHECK-LABEL: @mixed_fcmp_maytrap(
335; CHECK-NEXT:    [[TMP1:%.*]] = call i1 @llvm.experimental.constrained.fcmp.f64(double [[A:%.*]], double [[B:%.*]], metadata !"oeq", metadata !"fpexcept.ignore") #[[ATTR0]]
336; CHECK-NEXT:    [[TMP2:%.*]] = call i1 @llvm.experimental.constrained.fcmp.f64(double [[A]], double [[B]], metadata !"oeq", metadata !"fpexcept.maytrap") #[[ATTR0]]
337; CHECK-NEXT:    [[TMP3:%.*]] = zext i1 [[TMP1]] to i32
338; CHECK-NEXT:    [[TMP4:%.*]] = zext i1 [[TMP2]] to i32
339; CHECK-NEXT:    [[TMP5:%.*]] = call i32 @bar.i32(i32 [[TMP3]], i32 [[TMP4]]) #[[ATTR0]]
340; CHECK-NEXT:    ret i1 [[TMP2]]
341;
342  %1 = call i1 @llvm.experimental.constrained.fcmp.f64(double %a, double %b, metadata !"oeq", metadata !"fpexcept.ignore") #0
343  %2 = call i1 @llvm.experimental.constrained.fcmp.f64(double %a, double %b, metadata !"oeq", metadata !"fpexcept.maytrap") #0
344  %3 = zext i1 %1 to i32
345  %4 = zext i1 %2 to i32
346  %5 = call i32 @bar.i32(i32 %3, i32 %4) #0
347  ret i1 %2
348}
349
350define i1 @mixed_fcmp_strict(double %a, double %b) #0 {
351; CHECK-LABEL: @mixed_fcmp_strict(
352; CHECK-NEXT:    [[TMP1:%.*]] = call i1 @llvm.experimental.constrained.fcmp.f64(double [[A:%.*]], double [[B:%.*]], metadata !"oeq", metadata !"fpexcept.ignore") #[[ATTR0]]
353; CHECK-NEXT:    [[TMP2:%.*]] = call i1 @llvm.experimental.constrained.fcmp.f64(double [[A]], double [[B]], metadata !"oeq", metadata !"fpexcept.strict") #[[ATTR0]]
354; CHECK-NEXT:    [[TMP3:%.*]] = zext i1 [[TMP1]] to i32
355; CHECK-NEXT:    [[TMP4:%.*]] = zext i1 [[TMP2]] to i32
356; CHECK-NEXT:    [[TMP5:%.*]] = call i32 @bar.i32(i32 [[TMP3]], i32 [[TMP4]]) #[[ATTR0]]
357; CHECK-NEXT:    ret i1 [[TMP2]]
358;
359  %1 = call i1 @llvm.experimental.constrained.fcmp.f64(double %a, double %b, metadata !"oeq", metadata !"fpexcept.ignore") #0
360  %2 = call i1 @llvm.experimental.constrained.fcmp.f64(double %a, double %b, metadata !"oeq", metadata !"fpexcept.strict") #0
361  %3 = zext i1 %1 to i32
362  %4 = zext i1 %2 to i32
363  %5 = call i32 @bar.i32(i32 %3, i32 %4) #0
364  ret i1 %2
365}
366
367define i1 @mixed_fcmps_maytrap(double %a, double %b) #0 {
368; CHECK-LABEL: @mixed_fcmps_maytrap(
369; CHECK-NEXT:    [[TMP1:%.*]] = call i1 @llvm.experimental.constrained.fcmps.f64(double [[A:%.*]], double [[B:%.*]], metadata !"oeq", metadata !"fpexcept.ignore") #[[ATTR0]]
370; CHECK-NEXT:    [[TMP2:%.*]] = call i1 @llvm.experimental.constrained.fcmps.f64(double [[A]], double [[B]], metadata !"oeq", metadata !"fpexcept.maytrap") #[[ATTR0]]
371; CHECK-NEXT:    [[TMP3:%.*]] = zext i1 [[TMP1]] to i32
372; CHECK-NEXT:    [[TMP4:%.*]] = zext i1 [[TMP2]] to i32
373; CHECK-NEXT:    [[TMP5:%.*]] = call i32 @bar.i32(i32 [[TMP3]], i32 [[TMP4]]) #[[ATTR0]]
374; CHECK-NEXT:    ret i1 [[TMP2]]
375;
376  %1 = call i1 @llvm.experimental.constrained.fcmps.f64(double %a, double %b, metadata !"oeq", metadata !"fpexcept.ignore") #0
377  %2 = call i1 @llvm.experimental.constrained.fcmps.f64(double %a, double %b, metadata !"oeq", metadata !"fpexcept.maytrap") #0
378  %3 = zext i1 %1 to i32
379  %4 = zext i1 %2 to i32
380  %5 = call i32 @bar.i32(i32 %3, i32 %4) #0
381  ret i1 %2
382}
383
384define i1 @mixed_fcmps_strict(double %a, double %b) #0 {
385; CHECK-LABEL: @mixed_fcmps_strict(
386; CHECK-NEXT:    [[TMP1:%.*]] = call i1 @llvm.experimental.constrained.fcmps.f64(double [[A:%.*]], double [[B:%.*]], metadata !"oeq", metadata !"fpexcept.ignore") #[[ATTR0]]
387; CHECK-NEXT:    [[TMP2:%.*]] = call i1 @llvm.experimental.constrained.fcmps.f64(double [[A]], double [[B]], metadata !"oeq", metadata !"fpexcept.strict") #[[ATTR0]]
388; CHECK-NEXT:    [[TMP3:%.*]] = zext i1 [[TMP1]] to i32
389; CHECK-NEXT:    [[TMP4:%.*]] = zext i1 [[TMP2]] to i32
390; CHECK-NEXT:    [[TMP5:%.*]] = call i32 @bar.i32(i32 [[TMP3]], i32 [[TMP4]]) #[[ATTR0]]
391; CHECK-NEXT:    ret i1 [[TMP2]]
392;
393  %1 = call i1 @llvm.experimental.constrained.fcmps.f64(double %a, double %b, metadata !"oeq", metadata !"fpexcept.ignore") #0
394  %2 = call i1 @llvm.experimental.constrained.fcmps.f64(double %a, double %b, metadata !"oeq", metadata !"fpexcept.strict") #0
395  %3 = zext i1 %1 to i32
396  %4 = zext i1 %2 to i32
397  %5 = call i32 @bar.i32(i32 %3, i32 %4) #0
398  ret i1 %2
399}
400
401attributes #0 = { strictfp }
402
403declare void @arbitraryfunc() #0
404declare double @foo.f64(double, double) #0
405declare i32 @bar.i32(i32, i32) #0
406
407declare double @llvm.experimental.constrained.fadd.f64(double, double, metadata, metadata)
408declare double @llvm.experimental.constrained.fsub.f64(double, double, metadata, metadata)
409declare double @llvm.experimental.constrained.fmul.f64(double, double, metadata, metadata)
410declare double @llvm.experimental.constrained.fdiv.f64(double, double, metadata, metadata)
411declare double @llvm.experimental.constrained.frem.f64(double, double, metadata, metadata)
412declare i32 @llvm.experimental.constrained.fptoui.i32.f64(double, metadata)
413declare double @llvm.experimental.constrained.uitofp.f64.i32(i32, metadata, metadata)
414declare i32 @llvm.experimental.constrained.fptosi.i32.f64(double, metadata)
415declare double @llvm.experimental.constrained.sitofp.f64.i32(i32, metadata, metadata)
416declare i1 @llvm.experimental.constrained.fcmp.f64(double, double, metadata, metadata)
417declare i1 @llvm.experimental.constrained.fcmps.f64(double, double, metadata, metadata)
418