[clang][modules] Don't prevent translation of FW_Private includes when explicitly...
[llvm-project.git] / llvm / test / Transforms / EarlyCSE / round-dyn-strictfp.ll
blobc33e022f53be2906dbb8dfafe5687c5b866b524c
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
5 ; Test use of constrained floating point intrinsics with dynamic
6 ; rounding mode. Dynamic rounding _must_ disable CSE since EarlyCSE
7 ; will CSE across function calls and we cannot know if the rounding
8 ; mode will be changed by any arbitrary function call.
10 define double @multiple_fadd(double %a, double %b) #0 {
11 ; CHECK-LABEL: @multiple_fadd(
12 ; CHECK-NEXT:    [[TMP1:%.*]] = call double @llvm.experimental.constrained.fadd.f64(double [[A:%.*]], double [[B:%.*]], metadata !"round.dynamic", metadata !"fpexcept.ignore") #[[ATTR0:[0-9]+]]
13 ; CHECK-NEXT:    [[TMP2:%.*]] = call double @llvm.experimental.constrained.fadd.f64(double [[A]], double [[B]], metadata !"round.dynamic", metadata !"fpexcept.ignore") #[[ATTR0]]
14 ; CHECK-NEXT:    [[TMP3:%.*]] = call double @foo.f64(double [[TMP1]], double [[TMP2]]) #[[ATTR0]]
15 ; CHECK-NEXT:    ret double [[TMP2]]
17   %1 = call double @llvm.experimental.constrained.fadd.f64(double %a, double %b, metadata !"round.dynamic", metadata !"fpexcept.ignore") #0
18   %2 = call double @llvm.experimental.constrained.fadd.f64(double %a, double %b, metadata !"round.dynamic", metadata !"fpexcept.ignore") #0
19   %3 = call double @foo.f64(double %1, double %2) #0
20   ret double %2
23 define double @multiple_fadd_split(double %a, double %b) #0 {
24 ; CHECK-LABEL: @multiple_fadd_split(
25 ; CHECK-NEXT:    [[TMP1:%.*]] = call double @llvm.experimental.constrained.fadd.f64(double [[A:%.*]], double [[B:%.*]], metadata !"round.dynamic", metadata !"fpexcept.ignore") #[[ATTR0]]
26 ; CHECK-NEXT:    call void @arbitraryfunc() #[[ATTR0]]
27 ; CHECK-NEXT:    [[TMP2:%.*]] = call double @llvm.experimental.constrained.fadd.f64(double [[A]], double [[B]], metadata !"round.dynamic", metadata !"fpexcept.ignore") #[[ATTR0]]
28 ; CHECK-NEXT:    [[TMP3:%.*]] = call double @foo.f64(double [[TMP1]], double [[TMP2]]) #[[ATTR0]]
29 ; CHECK-NEXT:    ret double [[TMP2]]
31   %1 = call double @llvm.experimental.constrained.fadd.f64(double %a, double %b, metadata !"round.dynamic", metadata !"fpexcept.ignore") #0
32   call void @arbitraryfunc() #0
33   %2 = call double @llvm.experimental.constrained.fadd.f64(double %a, double %b, metadata !"round.dynamic", metadata !"fpexcept.ignore") #0
34   %3 = call double @foo.f64(double %1, double %2) #0
35   ret double %2
38 define double @multiple_fsub(double %a, double %b) #0 {
39 ; CHECK-LABEL: @multiple_fsub(
40 ; CHECK-NEXT:    [[TMP1:%.*]] = call double @llvm.experimental.constrained.fsub.f64(double [[A:%.*]], double [[B:%.*]], metadata !"round.dynamic", metadata !"fpexcept.ignore") #[[ATTR0]]
41 ; CHECK-NEXT:    [[TMP2:%.*]] = call double @llvm.experimental.constrained.fsub.f64(double [[A]], double [[B]], metadata !"round.dynamic", metadata !"fpexcept.ignore") #[[ATTR0]]
42 ; CHECK-NEXT:    [[TMP3:%.*]] = call double @foo.f64(double [[TMP1]], double [[TMP2]]) #[[ATTR0]]
43 ; CHECK-NEXT:    ret double [[TMP2]]
45   %1 = call double @llvm.experimental.constrained.fsub.f64(double %a, double %b, metadata !"round.dynamic", metadata !"fpexcept.ignore") #0
46   %2 = call double @llvm.experimental.constrained.fsub.f64(double %a, double %b, metadata !"round.dynamic", metadata !"fpexcept.ignore") #0
47   %3 = call double @foo.f64(double %1, double %2) #0
48   ret double %2
51 define double @multiple_fsub_split(double %a, double %b) #0 {
52 ; CHECK-LABEL: @multiple_fsub_split(
53 ; CHECK-NEXT:    [[TMP1:%.*]] = call double @llvm.experimental.constrained.fsub.f64(double [[A:%.*]], double [[B:%.*]], metadata !"round.dynamic", metadata !"fpexcept.ignore") #[[ATTR0]]
54 ; CHECK-NEXT:    call void @arbitraryfunc() #[[ATTR0]]
55 ; CHECK-NEXT:    [[TMP2:%.*]] = call double @llvm.experimental.constrained.fsub.f64(double [[A]], double [[B]], metadata !"round.dynamic", metadata !"fpexcept.ignore") #[[ATTR0]]
56 ; CHECK-NEXT:    [[TMP3:%.*]] = call double @foo.f64(double [[TMP1]], double [[TMP2]]) #[[ATTR0]]
57 ; CHECK-NEXT:    ret double [[TMP2]]
59   %1 = call double @llvm.experimental.constrained.fsub.f64(double %a, double %b, metadata !"round.dynamic", metadata !"fpexcept.ignore") #0
60   call void @arbitraryfunc() #0
61   %2 = call double @llvm.experimental.constrained.fsub.f64(double %a, double %b, metadata !"round.dynamic", metadata !"fpexcept.ignore") #0
62   %3 = call double @foo.f64(double %1, double %2) #0
63   ret double %2
66 define double @multiple_fmul(double %a, double %b) #0 {
67 ; CHECK-LABEL: @multiple_fmul(
68 ; CHECK-NEXT:    [[TMP1:%.*]] = call double @llvm.experimental.constrained.fmul.f64(double [[A:%.*]], double [[B:%.*]], metadata !"round.dynamic", metadata !"fpexcept.ignore") #[[ATTR0]]
69 ; CHECK-NEXT:    [[TMP2:%.*]] = call double @llvm.experimental.constrained.fmul.f64(double [[A]], double [[B]], metadata !"round.dynamic", metadata !"fpexcept.ignore") #[[ATTR0]]
70 ; CHECK-NEXT:    [[TMP3:%.*]] = call double @foo.f64(double [[TMP1]], double [[TMP2]]) #[[ATTR0]]
71 ; CHECK-NEXT:    ret double [[TMP2]]
73   %1 = call double @llvm.experimental.constrained.fmul.f64(double %a, double %b, metadata !"round.dynamic", metadata !"fpexcept.ignore") #0
74   %2 = call double @llvm.experimental.constrained.fmul.f64(double %a, double %b, metadata !"round.dynamic", metadata !"fpexcept.ignore") #0
75   %3 = call double @foo.f64(double %1, double %2) #0
76   ret double %2
79 define double @multiple_fmul_split(double %a, double %b) #0 {
80 ; CHECK-LABEL: @multiple_fmul_split(
81 ; CHECK-NEXT:    [[TMP1:%.*]] = call double @llvm.experimental.constrained.fmul.f64(double [[A:%.*]], double [[B:%.*]], metadata !"round.dynamic", metadata !"fpexcept.ignore") #[[ATTR0]]
82 ; CHECK-NEXT:    call void @arbitraryfunc() #[[ATTR0]]
83 ; CHECK-NEXT:    [[TMP2:%.*]] = call double @llvm.experimental.constrained.fmul.f64(double [[A]], double [[B]], metadata !"round.dynamic", metadata !"fpexcept.ignore") #[[ATTR0]]
84 ; CHECK-NEXT:    [[TMP3:%.*]] = call double @foo.f64(double [[TMP1]], double [[TMP2]]) #[[ATTR0]]
85 ; CHECK-NEXT:    ret double [[TMP2]]
87   %1 = call double @llvm.experimental.constrained.fmul.f64(double %a, double %b, metadata !"round.dynamic", metadata !"fpexcept.ignore") #0
88   call void @arbitraryfunc() #0
89   %2 = call double @llvm.experimental.constrained.fmul.f64(double %a, double %b, metadata !"round.dynamic", metadata !"fpexcept.ignore") #0
90   %3 = call double @foo.f64(double %1, double %2) #0
91   ret double %2
94 define double @multiple_fdiv(double %a, double %b) #0 {
95 ; CHECK-LABEL: @multiple_fdiv(
96 ; CHECK-NEXT:    [[TMP1:%.*]] = call double @llvm.experimental.constrained.fdiv.f64(double [[A:%.*]], double [[B:%.*]], metadata !"round.dynamic", metadata !"fpexcept.ignore") #[[ATTR0]]
97 ; CHECK-NEXT:    [[TMP2:%.*]] = call double @llvm.experimental.constrained.fdiv.f64(double [[A]], double [[B]], metadata !"round.dynamic", metadata !"fpexcept.ignore") #[[ATTR0]]
98 ; CHECK-NEXT:    [[TMP3:%.*]] = call double @foo.f64(double [[TMP1]], double [[TMP2]]) #[[ATTR0]]
99 ; CHECK-NEXT:    ret double [[TMP2]]
101   %1 = call double @llvm.experimental.constrained.fdiv.f64(double %a, double %b, metadata !"round.dynamic", metadata !"fpexcept.ignore") #0
102   %2 = call double @llvm.experimental.constrained.fdiv.f64(double %a, double %b, metadata !"round.dynamic", metadata !"fpexcept.ignore") #0
103   %3 = call double @foo.f64(double %1, double %2) #0
104   ret double %2
107 define double @multiple_fdiv_split(double %a, double %b) #0 {
108 ; CHECK-LABEL: @multiple_fdiv_split(
109 ; CHECK-NEXT:    [[TMP1:%.*]] = call double @llvm.experimental.constrained.fdiv.f64(double [[A:%.*]], double [[B:%.*]], metadata !"round.dynamic", metadata !"fpexcept.ignore") #[[ATTR0]]
110 ; CHECK-NEXT:    call void @arbitraryfunc() #[[ATTR0]]
111 ; CHECK-NEXT:    [[TMP2:%.*]] = call double @llvm.experimental.constrained.fdiv.f64(double [[A]], double [[B]], metadata !"round.dynamic", metadata !"fpexcept.ignore") #[[ATTR0]]
112 ; CHECK-NEXT:    [[TMP3:%.*]] = call double @foo.f64(double [[TMP1]], double [[TMP2]]) #[[ATTR0]]
113 ; CHECK-NEXT:    ret double [[TMP2]]
115   %1 = call double @llvm.experimental.constrained.fdiv.f64(double %a, double %b, metadata !"round.dynamic", metadata !"fpexcept.ignore") #0
116   call void @arbitraryfunc() #0
117   %2 = call double @llvm.experimental.constrained.fdiv.f64(double %a, double %b, metadata !"round.dynamic", metadata !"fpexcept.ignore") #0
118   %3 = call double @foo.f64(double %1, double %2) #0
119   ret double %2
122 define double @multiple_frem(double %a, double %b) #0 {
123 ; CHECK-LABEL: @multiple_frem(
124 ; CHECK-NEXT:    [[TMP1:%.*]] = call double @llvm.experimental.constrained.frem.f64(double [[A:%.*]], double [[B:%.*]], metadata !"round.dynamic", metadata !"fpexcept.ignore") #[[ATTR0]]
125 ; CHECK-NEXT:    [[TMP2:%.*]] = call double @llvm.experimental.constrained.frem.f64(double [[A]], double [[B]], metadata !"round.dynamic", metadata !"fpexcept.ignore") #[[ATTR0]]
126 ; CHECK-NEXT:    [[TMP3:%.*]] = call double @foo.f64(double [[TMP1]], double [[TMP2]]) #[[ATTR0]]
127 ; CHECK-NEXT:    ret double [[TMP2]]
129   %1 = call double @llvm.experimental.constrained.frem.f64(double %a, double %b, metadata !"round.dynamic", metadata !"fpexcept.ignore") #0
130   %2 = call double @llvm.experimental.constrained.frem.f64(double %a, double %b, metadata !"round.dynamic", metadata !"fpexcept.ignore") #0
131   %3 = call double @foo.f64(double %1, double %2) #0
132   ret double %2
135 define double @multiple_frem_split(double %a, double %b) #0 {
136 ; CHECK-LABEL: @multiple_frem_split(
137 ; CHECK-NEXT:    [[TMP1:%.*]] = call double @llvm.experimental.constrained.frem.f64(double [[A:%.*]], double [[B:%.*]], metadata !"round.dynamic", metadata !"fpexcept.ignore") #[[ATTR0]]
138 ; CHECK-NEXT:    call void @arbitraryfunc() #[[ATTR0]]
139 ; CHECK-NEXT:    [[TMP2:%.*]] = call double @llvm.experimental.constrained.frem.f64(double [[A]], double [[B]], metadata !"round.dynamic", metadata !"fpexcept.ignore") #[[ATTR0]]
140 ; CHECK-NEXT:    [[TMP3:%.*]] = call double @foo.f64(double [[TMP1]], double [[TMP2]]) #[[ATTR0]]
141 ; CHECK-NEXT:    ret double [[TMP2]]
143   %1 = call double @llvm.experimental.constrained.frem.f64(double %a, double %b, metadata !"round.dynamic", metadata !"fpexcept.ignore") #0
144   call void @arbitraryfunc() #0
145   %2 = call double @llvm.experimental.constrained.frem.f64(double %a, double %b, metadata !"round.dynamic", metadata !"fpexcept.ignore") #0
146   %3 = call double @foo.f64(double %1, double %2) #0
147   ret double %2
150 define double @multiple_uitofp(i32 %a) #0 {
151 ; CHECK-LABEL: @multiple_uitofp(
152 ; CHECK-NEXT:    [[TMP1:%.*]] = call double @llvm.experimental.constrained.uitofp.f64.i32(i32 [[A:%.*]], metadata !"round.dynamic", metadata !"fpexcept.ignore") #[[ATTR0]]
153 ; CHECK-NEXT:    [[TMP2:%.*]] = call double @llvm.experimental.constrained.uitofp.f64.i32(i32 [[A]], metadata !"round.dynamic", metadata !"fpexcept.ignore") #[[ATTR0]]
154 ; CHECK-NEXT:    [[TMP3:%.*]] = call double @foo.f64(double [[TMP1]], double [[TMP1]]) #[[ATTR0]]
155 ; CHECK-NEXT:    ret double [[TMP2]]
157   %1 = call double @llvm.experimental.constrained.uitofp.f64.i32(i32 %a, metadata !"round.dynamic", metadata !"fpexcept.ignore") #0
158   %2 = call double @llvm.experimental.constrained.uitofp.f64.i32(i32 %a, metadata !"round.dynamic", metadata !"fpexcept.ignore") #0
159   %3 = call double @foo.f64(double %1, double %1) #0
160   ret double %2
163 define double @multiple_uitofp_split(i32 %a) #0 {
164 ; CHECK-LABEL: @multiple_uitofp_split(
165 ; CHECK-NEXT:    [[TMP1:%.*]] = call double @llvm.experimental.constrained.uitofp.f64.i32(i32 [[A:%.*]], metadata !"round.dynamic", metadata !"fpexcept.ignore") #[[ATTR0]]
166 ; CHECK-NEXT:    call void @arbitraryfunc() #[[ATTR0]]
167 ; CHECK-NEXT:    [[TMP2:%.*]] = call double @llvm.experimental.constrained.uitofp.f64.i32(i32 [[A]], metadata !"round.dynamic", metadata !"fpexcept.ignore") #[[ATTR0]]
168 ; CHECK-NEXT:    [[TMP3:%.*]] = call double @foo.f64(double [[TMP1]], double [[TMP1]]) #[[ATTR0]]
169 ; CHECK-NEXT:    ret double [[TMP2]]
171   %1 = call double @llvm.experimental.constrained.uitofp.f64.i32(i32 %a, metadata !"round.dynamic", metadata !"fpexcept.ignore") #0
172   call void @arbitraryfunc() #0
173   %2 = call double @llvm.experimental.constrained.uitofp.f64.i32(i32 %a, metadata !"round.dynamic", metadata !"fpexcept.ignore") #0
174   %3 = call double @foo.f64(double %1, double %1) #0
175   ret double %2
178 define double @multiple_sitofp(i32 %a) #0 {
179 ; CHECK-LABEL: @multiple_sitofp(
180 ; CHECK-NEXT:    [[TMP1:%.*]] = call double @llvm.experimental.constrained.sitofp.f64.i32(i32 [[A:%.*]], metadata !"round.dynamic", metadata !"fpexcept.ignore") #[[ATTR0]]
181 ; CHECK-NEXT:    [[TMP2:%.*]] = call double @llvm.experimental.constrained.sitofp.f64.i32(i32 [[A]], metadata !"round.dynamic", metadata !"fpexcept.ignore") #[[ATTR0]]
182 ; CHECK-NEXT:    [[TMP3:%.*]] = call double @foo.f64(double [[TMP1]], double [[TMP1]]) #[[ATTR0]]
183 ; CHECK-NEXT:    ret double [[TMP2]]
185   %1 = call double @llvm.experimental.constrained.sitofp.f64.i32(i32 %a, metadata !"round.dynamic", metadata !"fpexcept.ignore") #0
186   %2 = call double @llvm.experimental.constrained.sitofp.f64.i32(i32 %a, metadata !"round.dynamic", metadata !"fpexcept.ignore") #0
187   %3 = call double @foo.f64(double %1, double %1) #0
188   ret double %2
191 define double @multiple_sitofp_split(i32 %a) #0 {
192 ; CHECK-LABEL: @multiple_sitofp_split(
193 ; CHECK-NEXT:    [[TMP1:%.*]] = call double @llvm.experimental.constrained.sitofp.f64.i32(i32 [[A:%.*]], metadata !"round.dynamic", metadata !"fpexcept.ignore") #[[ATTR0]]
194 ; CHECK-NEXT:    call void @arbitraryfunc() #[[ATTR0]]
195 ; CHECK-NEXT:    [[TMP2:%.*]] = call double @llvm.experimental.constrained.sitofp.f64.i32(i32 [[A]], metadata !"round.dynamic", metadata !"fpexcept.ignore") #[[ATTR0]]
196 ; CHECK-NEXT:    [[TMP3:%.*]] = call double @foo.f64(double [[TMP1]], double [[TMP1]]) #[[ATTR0]]
197 ; CHECK-NEXT:    ret double [[TMP2]]
199   %1 = call double @llvm.experimental.constrained.sitofp.f64.i32(i32 %a, metadata !"round.dynamic", metadata !"fpexcept.ignore") #0
200   call void @arbitraryfunc() #0
201   %2 = call double @llvm.experimental.constrained.sitofp.f64.i32(i32 %a, metadata !"round.dynamic", metadata !"fpexcept.ignore") #0
202   %3 = call double @foo.f64(double %1, double %1) #0
203   ret double %2
206 attributes #0 = { strictfp }
208 declare void @arbitraryfunc() #0
209 declare double @foo.f64(double, double) #0
210 declare i32 @bar.i32(i32, i32) #0
212 declare double @llvm.experimental.constrained.fadd.f64(double, double, metadata, metadata)
213 declare double @llvm.experimental.constrained.fsub.f64(double, double, metadata, metadata)
214 declare double @llvm.experimental.constrained.fmul.f64(double, double, metadata, metadata)
215 declare double @llvm.experimental.constrained.fdiv.f64(double, double, metadata, metadata)
216 declare double @llvm.experimental.constrained.frem.f64(double, double, metadata, metadata)
217 declare i32 @llvm.experimental.constrained.fptoui.i32.f64(double, metadata)
218 declare double @llvm.experimental.constrained.uitofp.f64.i32(i32, metadata, metadata)
219 declare i32 @llvm.experimental.constrained.fptosi.i32.f64(double, metadata)
220 declare double @llvm.experimental.constrained.sitofp.f64.i32(i32, metadata, metadata)
221 declare i1 @llvm.experimental.constrained.fcmp.i1.f64(double, double, metadata, metadata)
222 declare i1 @llvm.experimental.constrained.fcmps.i1.f64(double, double, metadata, metadata)