Skip to content

Commit 91f886a

Browse files
committed
[FPEnv][TableGen] Add strictfp attribute to constrained intrinsics by default.
In D146869 @arsenm pointed out that the constrained intrinsics aren't getting the strictfp attribute by default. They should be since they are required to have it anyway. TableGen did not know about this attribute until now. This patch adds strictfp to TableGen, and it uses it on all of the constrained intrinsics. Differential Revision: https://reviews.llvm.org/D154991
1 parent 94abecc commit 91f886a

File tree

7 files changed

+349
-16
lines changed

7 files changed

+349
-16
lines changed

clang/test/CodeGenOpenCL/cl20-device-side-enqueue-attributes.cl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ kernel void device_side_enqueue(global float *a, global float *b, int i) {
171171
// STRICTFP: attributes #[[ATTR0]] = { convergent noinline norecurse nounwind optnone strictfp "stack-protector-buffer-size"="8" "uniform-work-group-size"="false" }
172172
// STRICTFP: attributes #[[ATTR1:[0-9]+]] = { nocallback nofree nounwind willreturn memory(argmem: readwrite) }
173173
// STRICTFP: attributes #[[ATTR2]] = { convergent noinline nounwind optnone strictfp "stack-protector-buffer-size"="8" }
174-
// STRICTFP: attributes #[[ATTR3:[0-9]+]] = { nocallback nofree nosync nounwind willreturn memory(inaccessiblemem: readwrite) }
174+
// STRICTFP: attributes #[[ATTR3:[0-9]+]] = { nocallback nofree nosync nounwind strictfp willreturn memory(inaccessiblemem: readwrite) }
175175
// STRICTFP: attributes #[[ATTR4]] = { convergent nounwind "stack-protector-buffer-size"="8" }
176176
// STRICTFP: attributes #[[ATTR5]] = { strictfp }
177177
//.

llvm/include/llvm/IR/Intrinsics.td

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1099,7 +1099,11 @@ def int_is_fpclass
10991099
//===--------------- Constrained Floating Point Intrinsics ----------------===//
11001100
//
11011101

1102-
let IntrProperties = [IntrInaccessibleMemOnly, IntrWillReturn] in {
1102+
/// IntrStrictFP - The intrinsic is allowed to be used in an alternate
1103+
/// floating point environment.
1104+
def IntrStrictFP : IntrinsicProperty;
1105+
1106+
let IntrProperties = [IntrInaccessibleMemOnly, IntrWillReturn, IntrStrictFP] in {
11031107
def int_experimental_constrained_fadd : DefaultAttrsIntrinsic<[ llvm_anyfloat_ty ],
11041108
[ LLVMMatchType<0>,
11051109
LLVMMatchType<0>,
Lines changed: 318 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,318 @@
1+
; RUN: llvm-as < %s | llvm-dis | FileCheck %s
2+
3+
; Test to verify that constrained intrinsics all have the strictfp attribute.
4+
; Ordering is from Intrinsics.td.
5+
6+
define void @func(double %a, double %b, double %c, i32 %i) strictfp {
7+
; CHECK-LABEL: define void @func
8+
; CHECK-SAME: (double [[A:%.*]], double [[B:%.*]], double [[C:%.*]], i32 [[I:%.*]]) #[[ATTR0:[0-9]+]] {
9+
10+
%add = call double @llvm.experimental.constrained.fadd.f64(
11+
double %a, double %b,
12+
metadata !"round.dynamic",
13+
metadata !"fpexcept.strict")
14+
15+
%sub = call double @llvm.experimental.constrained.fsub.f64(
16+
double %a, double %b,
17+
metadata !"round.dynamic",
18+
metadata !"fpexcept.strict")
19+
20+
%mul = call double @llvm.experimental.constrained.fmul.f64(
21+
double %a, double %b,
22+
metadata !"round.dynamic",
23+
metadata !"fpexcept.strict")
24+
25+
%div = call double @llvm.experimental.constrained.fdiv.f64(
26+
double %a, double %b,
27+
metadata !"round.dynamic",
28+
metadata !"fpexcept.strict")
29+
30+
%rem = call double @llvm.experimental.constrained.frem.f64(
31+
double %a, double %b,
32+
metadata !"round.dynamic",
33+
metadata !"fpexcept.strict")
34+
35+
%fma = call double @llvm.experimental.constrained.fma.f64(
36+
double %a, double %b, double %c,
37+
metadata !"round.dynamic",
38+
metadata !"fpexcept.strict")
39+
40+
%fmuladd = call double @llvm.experimental.constrained.fmuladd.f64(
41+
double %a, double %b, double %c,
42+
metadata !"round.dynamic",
43+
metadata !"fpexcept.strict")
44+
45+
%si = call i32 @llvm.experimental.constrained.fptosi.i32.f64(double %a,
46+
metadata !"fpexcept.strict")
47+
48+
%ui = call i32 @llvm.experimental.constrained.fptoui.i32.f64(double %a,
49+
metadata !"fpexcept.strict")
50+
51+
%sfp = call double @llvm.experimental.constrained.sitofp.f64.i32(i32 %i,
52+
metadata !"round.dynamic",
53+
metadata !"fpexcept.strict")
54+
55+
%ufp = call double @llvm.experimental.constrained.uitofp.f64.i32(i32 %i,
56+
metadata !"round.dynamic",
57+
metadata !"fpexcept.strict")
58+
59+
%fptrunc = call float @llvm.experimental.constrained.fptrunc.f32.f64(
60+
double %a,
61+
metadata !"round.dynamic",
62+
metadata !"fpexcept.strict")
63+
64+
%ext = call double @llvm.experimental.constrained.fpext.f64.f32(
65+
float %fptrunc,
66+
metadata !"fpexcept.strict")
67+
68+
%sqrt = call double @llvm.experimental.constrained.sqrt.f64(
69+
double %a,
70+
metadata !"round.dynamic",
71+
metadata !"fpexcept.strict")
72+
73+
%powi = call double @llvm.experimental.constrained.powi.f64(
74+
double %a, i32 %i,
75+
metadata !"round.dynamic",
76+
metadata !"fpexcept.strict")
77+
78+
%sin = call double @llvm.experimental.constrained.sin.f64(
79+
double %a,
80+
metadata !"round.dynamic",
81+
metadata !"fpexcept.strict")
82+
83+
%cos = call double @llvm.experimental.constrained.cos.f64(
84+
double %a,
85+
metadata !"round.dynamic",
86+
metadata !"fpexcept.strict")
87+
88+
%pow = call double @llvm.experimental.constrained.pow.f64(
89+
double %a, double %b,
90+
metadata !"round.dynamic",
91+
metadata !"fpexcept.strict")
92+
93+
%log = call double @llvm.experimental.constrained.log.f64(
94+
double %a,
95+
metadata !"round.dynamic",
96+
metadata !"fpexcept.strict")
97+
98+
%log10 = call double @llvm.experimental.constrained.log10.f64(
99+
double %a,
100+
metadata !"round.dynamic",
101+
metadata !"fpexcept.strict")
102+
103+
%log2 = call double @llvm.experimental.constrained.log2.f64(
104+
double %a,
105+
metadata !"round.dynamic",
106+
metadata !"fpexcept.strict")
107+
108+
%exp = call double @llvm.experimental.constrained.exp.f64(
109+
double %a,
110+
metadata !"round.dynamic",
111+
metadata !"fpexcept.strict")
112+
113+
%exp2 = call double @llvm.experimental.constrained.exp2.f64(
114+
double %a,
115+
metadata !"round.dynamic",
116+
metadata !"fpexcept.strict")
117+
118+
%rint = call double @llvm.experimental.constrained.rint.f64(
119+
double %a,
120+
metadata !"round.dynamic",
121+
metadata !"fpexcept.strict")
122+
123+
%neari = call double @llvm.experimental.constrained.nearbyint.f64(
124+
double %a,
125+
metadata !"round.dynamic",
126+
metadata !"fpexcept.strict")
127+
128+
%x32 = call i32 @llvm.experimental.constrained.lrint.i32.f64(
129+
double %a,
130+
metadata !"round.dynamic",
131+
metadata !"fpexcept.strict")
132+
133+
%x64 = call i64 @llvm.experimental.constrained.llrint.i64.f64(
134+
double %a,
135+
metadata !"round.dynamic",
136+
metadata !"fpexcept.strict")
137+
138+
%maxnum = call double @llvm.experimental.constrained.maxnum.f64(
139+
double %a, double %b,
140+
metadata !"fpexcept.strict")
141+
142+
%minnum = call double @llvm.experimental.constrained.minnum.f64(
143+
double %a, double %b,
144+
metadata !"fpexcept.strict")
145+
146+
%maxmum = call double @llvm.experimental.constrained.maximum.f64(
147+
double %a, double %b,
148+
metadata !"fpexcept.strict")
149+
150+
%minmum = call double @llvm.experimental.constrained.minimum.f64(
151+
double %a, double %b,
152+
metadata !"fpexcept.strict")
153+
154+
%ceil = call double @llvm.experimental.constrained.ceil.f64(
155+
double %a,
156+
metadata !"fpexcept.strict")
157+
158+
%floor = call double @llvm.experimental.constrained.floor.f64(
159+
double %a,
160+
metadata !"fpexcept.strict")
161+
162+
%y32 = call i32 @llvm.experimental.constrained.lround.i32.f64(
163+
double %a,
164+
metadata !"fpexcept.strict")
165+
166+
%y64 = call i64 @llvm.experimental.constrained.llround.i64.f64(
167+
double %a,
168+
metadata !"fpexcept.strict")
169+
170+
%round = call double @llvm.experimental.constrained.round.f64(
171+
double %a,
172+
metadata !"fpexcept.strict")
173+
174+
%roundev = call double @llvm.experimental.constrained.roundeven.f64(
175+
double %a,
176+
metadata !"fpexcept.strict")
177+
178+
%trunc = call double @llvm.experimental.constrained.trunc.f64(
179+
double %a,
180+
metadata !"fpexcept.strict")
181+
182+
%q1 = call i1 @llvm.experimental.constrained.fcmp.f64(
183+
double %a, double %b,
184+
metadata !"oeq",
185+
metadata !"fpexcept.strict")
186+
187+
%s1 = call i1 @llvm.experimental.constrained.fcmps.f64(
188+
double %a, double %b,
189+
metadata !"oeq",
190+
metadata !"fpexcept.strict")
191+
192+
; CHECK: ret void
193+
ret void
194+
}
195+
196+
declare double @llvm.experimental.constrained.fadd.f64(double, double, metadata, metadata)
197+
; CHECK: @llvm.experimental.constrained.fadd.f64({{.*}}) #[[ATTR1:[0-9]+]]
198+
199+
declare double @llvm.experimental.constrained.fsub.f64(double, double, metadata, metadata)
200+
; CHECK: @llvm.experimental.constrained.fsub.f64({{.*}}) #[[ATTR1]]
201+
202+
declare double @llvm.experimental.constrained.fmul.f64(double, double, metadata, metadata)
203+
; CHECK: @llvm.experimental.constrained.fmul.f64({{.*}}) #[[ATTR1]]
204+
205+
declare double @llvm.experimental.constrained.fdiv.f64(double, double, metadata, metadata)
206+
; CHECK: @llvm.experimental.constrained.fdiv.f64({{.*}}) #[[ATTR1]]
207+
208+
declare double @llvm.experimental.constrained.frem.f64(double, double, metadata, metadata)
209+
; CHECK: @llvm.experimental.constrained.frem.f64({{.*}}) #[[ATTR1]]
210+
211+
declare double @llvm.experimental.constrained.fma.f64(double, double, double, metadata, metadata)
212+
; CHECK: @llvm.experimental.constrained.fma.f64({{.*}}) #[[ATTR1]]
213+
214+
declare double @llvm.experimental.constrained.fmuladd.f64(double, double, double, metadata, metadata)
215+
; CHECK: @llvm.experimental.constrained.fmuladd.f64({{.*}}) #[[ATTR1]]
216+
217+
declare i32 @llvm.experimental.constrained.fptosi.i32.f64(double, metadata)
218+
; CHECK: @llvm.experimental.constrained.fptosi.i32.f64({{.*}}) #[[ATTR1]]
219+
220+
declare i32 @llvm.experimental.constrained.fptoui.i32.f64(double, metadata)
221+
; CHECK: @llvm.experimental.constrained.fptoui.i32.f64({{.*}}) #[[ATTR1]]
222+
223+
declare double @llvm.experimental.constrained.sitofp.f64.i32(i32, metadata, metadata)
224+
; CHECK: @llvm.experimental.constrained.sitofp.f64.i32({{.*}}) #[[ATTR1]]
225+
226+
declare double @llvm.experimental.constrained.uitofp.f64.i32(i32, metadata, metadata)
227+
; CHECK: @llvm.experimental.constrained.uitofp.f64.i32({{.*}}) #[[ATTR1]]
228+
229+
declare float @llvm.experimental.constrained.fptrunc.f32.f64(double, metadata, metadata)
230+
; CHECK: @llvm.experimental.constrained.fptrunc.f32.f64({{.*}}) #[[ATTR1]]
231+
232+
declare double @llvm.experimental.constrained.fpext.f64.f32(float, metadata)
233+
; CHECK: @llvm.experimental.constrained.fpext.f64.f32({{.*}}) #[[ATTR1]]
234+
235+
declare double @llvm.experimental.constrained.sqrt.f64(double, metadata, metadata)
236+
; CHECK: @llvm.experimental.constrained.sqrt.f64({{.*}}) #[[ATTR1]]
237+
238+
declare double @llvm.experimental.constrained.powi.f64(double, i32, metadata, metadata)
239+
; CHECK: @llvm.experimental.constrained.powi.f64({{.*}}) #[[ATTR1]]
240+
241+
declare double @llvm.experimental.constrained.sin.f64(double, metadata, metadata)
242+
; CHECK: @llvm.experimental.constrained.sin.f64({{.*}}) #[[ATTR1]]
243+
244+
declare double @llvm.experimental.constrained.cos.f64(double, metadata, metadata)
245+
; CHECK: @llvm.experimental.constrained.cos.f64({{.*}}) #[[ATTR1]]
246+
247+
declare double @llvm.experimental.constrained.pow.f64(double, double, metadata, metadata)
248+
; CHECK: @llvm.experimental.constrained.pow.f64({{.*}}) #[[ATTR1]]
249+
250+
declare double @llvm.experimental.constrained.log.f64(double, metadata, metadata)
251+
; CHECK: @llvm.experimental.constrained.log.f64({{.*}}) #[[ATTR1]]
252+
253+
declare double @llvm.experimental.constrained.log10.f64(double, metadata, metadata)
254+
; CHECK: @llvm.experimental.constrained.log10.f64({{.*}}) #[[ATTR1]]
255+
256+
declare double @llvm.experimental.constrained.log2.f64(double, metadata, metadata)
257+
; CHECK: @llvm.experimental.constrained.log2.f64({{.*}}) #[[ATTR1]]
258+
259+
declare double @llvm.experimental.constrained.exp.f64(double, metadata, metadata)
260+
; CHECK: @llvm.experimental.constrained.exp.f64({{.*}}) #[[ATTR1]]
261+
262+
declare double @llvm.experimental.constrained.exp2.f64(double, metadata, metadata)
263+
; CHECK: @llvm.experimental.constrained.exp2.f64({{.*}}) #[[ATTR1]]
264+
265+
declare double @llvm.experimental.constrained.rint.f64(double, metadata, metadata)
266+
; CHECK: @llvm.experimental.constrained.rint.f64({{.*}}) #[[ATTR1]]
267+
268+
declare double @llvm.experimental.constrained.nearbyint.f64(double, metadata, metadata)
269+
; CHECK: @llvm.experimental.constrained.nearbyint.f64({{.*}}) #[[ATTR1]]
270+
271+
declare i32 @llvm.experimental.constrained.lrint.i32.f64(double, metadata, metadata)
272+
; CHECK: @llvm.experimental.constrained.lrint.i32.f64({{.*}}) #[[ATTR1]]
273+
274+
declare i64 @llvm.experimental.constrained.llrint.i64.f64(double, metadata, metadata)
275+
; CHECK: @llvm.experimental.constrained.llrint.i64.f64({{.*}}) #[[ATTR1]]
276+
277+
declare double @llvm.experimental.constrained.maxnum.f64(double, double, metadata)
278+
; CHECK: @llvm.experimental.constrained.maxnum.f64({{.*}}) #[[ATTR1]]
279+
280+
declare double @llvm.experimental.constrained.minnum.f64(double, double, metadata)
281+
; CHECK: @llvm.experimental.constrained.minnum.f64({{.*}}) #[[ATTR1]]
282+
283+
declare double @llvm.experimental.constrained.maximum.f64(double, double, metadata)
284+
; CHECK: @llvm.experimental.constrained.maximum.f64({{.*}}) #[[ATTR1]]
285+
286+
declare double @llvm.experimental.constrained.minimum.f64(double, double, metadata)
287+
; CHECK: @llvm.experimental.constrained.minimum.f64({{.*}}) #[[ATTR1]]
288+
289+
declare double @llvm.experimental.constrained.ceil.f64(double, metadata)
290+
; CHECK: @llvm.experimental.constrained.ceil.f64({{.*}}) #[[ATTR1]]
291+
292+
declare double @llvm.experimental.constrained.floor.f64(double, metadata)
293+
; CHECK: @llvm.experimental.constrained.floor.f64({{.*}}) #[[ATTR1]]
294+
295+
declare i32 @llvm.experimental.constrained.lround.i32.f64(double, metadata)
296+
; CHECK: @llvm.experimental.constrained.lround.i32.f64({{.*}}) #[[ATTR1]]
297+
298+
declare i64 @llvm.experimental.constrained.llround.i64.f64(double, metadata)
299+
; CHECK: @llvm.experimental.constrained.llround.i64.f64({{.*}}) #[[ATTR1]]
300+
301+
declare double @llvm.experimental.constrained.round.f64(double, metadata)
302+
; CHECK: @llvm.experimental.constrained.round.f64({{.*}}) #[[ATTR1]]
303+
304+
declare double @llvm.experimental.constrained.roundeven.f64(double, metadata)
305+
; CHECK: @llvm.experimental.constrained.roundeven.f64({{.*}}) #[[ATTR1]]
306+
307+
declare double @llvm.experimental.constrained.trunc.f64(double, metadata)
308+
; CHECK: @llvm.experimental.constrained.trunc.f64({{.*}}) #[[ATTR1]]
309+
310+
declare i1 @llvm.experimental.constrained.fcmp.f64(double, double, metadata, metadata)
311+
; CHECK: @llvm.experimental.constrained.fcmp.f64({{.*}}) #[[ATTR1]]
312+
313+
declare i1 @llvm.experimental.constrained.fcmps.f64(double, double, metadata, metadata)
314+
; CHECK: @llvm.experimental.constrained.fcmps.f64({{.*}}) #[[ATTR1]]
315+
316+
; CHECK: attributes #[[ATTR0]] = {{{.*}} strictfp {{.*}}}
317+
; CHECK: attributes #[[ATTR1]] = { {{.*}} strictfp {{.*}} }
318+

0 commit comments

Comments
 (0)