@@ -40,13 +40,11 @@ define i1 @f64_fcnan_fcinf(double %a) {
40
40
ret i1 %cmp
41
41
}
42
42
43
- ; TODO: handle more fpclass check idioms
44
43
define i1 @f32_fcinf (float %a ) {
45
44
; CHECK-LABEL: define i1 @f32_fcinf(
46
45
; CHECK-SAME: float [[A:%.*]]) {
47
46
; CHECK-NEXT: [[TMP1:%.*]] = call float @llvm.fabs.f32(float [[A]])
48
- ; CHECK-NEXT: [[AND:%.*]] = bitcast float [[TMP1]] to i32
49
- ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 2139095040
47
+ ; CHECK-NEXT: [[CMP:%.*]] = fcmp oeq float [[TMP1]], 0x7FF0000000000000
50
48
; CHECK-NEXT: ret i1 [[CMP]]
51
49
;
52
50
%i32 = bitcast float %a to i32
@@ -55,6 +53,63 @@ define i1 @f32_fcinf(float %a) {
55
53
ret i1 %cmp
56
54
}
57
55
56
+ define i1 @f32_fcposinf (float %a ) {
57
+ ; CHECK-LABEL: define i1 @f32_fcposinf(
58
+ ; CHECK-SAME: float [[A:%.*]]) {
59
+ ; CHECK-NEXT: [[CMP:%.*]] = fcmp oeq float [[A]], 0x7FF0000000000000
60
+ ; CHECK-NEXT: ret i1 [[CMP]]
61
+ ;
62
+ %i32 = bitcast float %a to i32
63
+ %cmp = icmp eq i32 %i32 , 2139095040
64
+ ret i1 %cmp
65
+ }
66
+
67
+ define i1 @f32_fcneginf (float %a ) {
68
+ ; CHECK-LABEL: define i1 @f32_fcneginf(
69
+ ; CHECK-SAME: float [[A:%.*]]) {
70
+ ; CHECK-NEXT: [[CMP:%.*]] = fcmp oeq float [[A]], 0xFFF0000000000000
71
+ ; CHECK-NEXT: ret i1 [[CMP]]
72
+ ;
73
+ %i32 = bitcast float %a to i32
74
+ %cmp = icmp eq i32 %i32 , 4286578688
75
+ ret i1 %cmp
76
+ }
77
+
78
+ define i1 @f32_fcposzero (float %a ) {
79
+ ; CHECK-LABEL: define i1 @f32_fcposzero(
80
+ ; CHECK-SAME: float [[A:%.*]]) {
81
+ ; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.is.fpclass.f32(float [[A]], i32 64)
82
+ ; CHECK-NEXT: ret i1 [[CMP]]
83
+ ;
84
+ %i32 = bitcast float %a to i32
85
+ %cmp = icmp eq i32 %i32 , 0
86
+ ret i1 %cmp
87
+ }
88
+
89
+ define i1 @f32_fcnegzero (float %a ) {
90
+ ; CHECK-LABEL: define i1 @f32_fcnegzero(
91
+ ; CHECK-SAME: float [[A:%.*]]) {
92
+ ; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.is.fpclass.f32(float [[A]], i32 32)
93
+ ; CHECK-NEXT: ret i1 [[CMP]]
94
+ ;
95
+ %i32 = bitcast float %a to i32
96
+ %cmp = icmp eq i32 %i32 , 2147483648
97
+ ret i1 %cmp
98
+ }
99
+
100
+ define i1 @f32_fczero (float %a ) {
101
+ ; CHECK-LABEL: define i1 @f32_fczero(
102
+ ; CHECK-SAME: float [[A:%.*]]) {
103
+ ; CHECK-NEXT: [[CMP:%.*]] = fcmp oeq float [[A]], 0.000000e+00
104
+ ; CHECK-NEXT: ret i1 [[CMP]]
105
+ ;
106
+ %i32 = bitcast float %a to i32
107
+ %and = and i32 %i32 , 2147483647
108
+ %cmp = icmp eq i32 %and , 0
109
+ ret i1 %cmp
110
+ }
111
+
112
+ ; TODO: handle more fpclass check idioms
58
113
define i1 @f32_fcnan (float %a ) {
59
114
; CHECK-LABEL: define i1 @f32_fcnan(
60
115
; CHECK-SAME: float [[A:%.*]]) {
@@ -101,6 +156,19 @@ define <2 x i1> @f32_fcnan_fcinf_vec(<2 x float> %a) {
101
156
ret <2 x i1 > %cmp
102
157
}
103
158
159
+ define <2 x i1 > @f32_fcinf_vec (<2 x float > %a ) {
160
+ ; CHECK-LABEL: define <2 x i1> @f32_fcinf_vec(
161
+ ; CHECK-SAME: <2 x float> [[A:%.*]]) {
162
+ ; CHECK-NEXT: [[TMP1:%.*]] = call <2 x float> @llvm.fabs.v2f32(<2 x float> [[A]])
163
+ ; CHECK-NEXT: [[CMP:%.*]] = fcmp oeq <2 x float> [[TMP1]], <float 0x7FF0000000000000, float 0x7FF0000000000000>
164
+ ; CHECK-NEXT: ret <2 x i1> [[CMP]]
165
+ ;
166
+ %i32 = bitcast <2 x float > %a to <2 x i32 >
167
+ %and = and <2 x i32 > %i32 , <i32 2147483647 , i32 2147483647 >
168
+ %cmp = icmp eq <2 x i32 > %and , <i32 2139095040 , i32 2139095040 >
169
+ ret <2 x i1 > %cmp
170
+ }
171
+
104
172
; Negative tests
105
173
106
174
define i1 @f32_fcnan_fcinf_wrong_mask1 (float %a ) {
@@ -158,6 +226,18 @@ define i1 @f32_fcnan_fcinf_wrong_pred(float %a) {
158
226
ret i1 %cmp
159
227
}
160
228
229
+ define i1 @f32_fcposzero_wrong_pred (float %a ) {
230
+ ; CHECK-LABEL: define i1 @f32_fcposzero_wrong_pred(
231
+ ; CHECK-SAME: float [[A:%.*]]) {
232
+ ; CHECK-NEXT: [[I32:%.*]] = bitcast float [[A]] to i32
233
+ ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[I32]], 0
234
+ ; CHECK-NEXT: ret i1 [[CMP]]
235
+ ;
236
+ %i32 = bitcast float %a to i32
237
+ %cmp = icmp slt i32 %i32 , 0
238
+ ret i1 %cmp
239
+ }
240
+
161
241
define i1 @f32_fcnan_fcinf_wrong_type1 (<2 x float > %a ) {
162
242
; CHECK-LABEL: define i1 @f32_fcnan_fcinf_wrong_type1(
163
243
; CHECK-SAME: <2 x float> [[A:%.*]]) {
@@ -172,6 +252,18 @@ define i1 @f32_fcnan_fcinf_wrong_type1(<2 x float> %a) {
172
252
ret i1 %cmp
173
253
}
174
254
255
+ define i1 @f32_fcposinf_wrong_type1 (<2 x float > %a ) {
256
+ ; CHECK-LABEL: define i1 @f32_fcposinf_wrong_type1(
257
+ ; CHECK-SAME: <2 x float> [[A:%.*]]) {
258
+ ; CHECK-NEXT: [[I64:%.*]] = bitcast <2 x float> [[A]] to i64
259
+ ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[I64]], 2139095040
260
+ ; CHECK-NEXT: ret i1 [[CMP]]
261
+ ;
262
+ %i64 = bitcast <2 x float > %a to i64
263
+ %cmp = icmp eq i64 %i64 , 2139095040
264
+ ret i1 %cmp
265
+ }
266
+
175
267
define i1 @f32_fcnan_fcinf_wrong_type2 (x86_fp80 %a ) {
176
268
; CHECK-LABEL: define i1 @f32_fcnan_fcinf_wrong_type2(
177
269
; CHECK-SAME: x86_fp80 [[A:%.*]]) {
@@ -186,6 +278,18 @@ define i1 @f32_fcnan_fcinf_wrong_type2(x86_fp80 %a) {
186
278
ret i1 %cmp
187
279
}
188
280
281
+ define i1 @f32_fcposzero_wrong_type2 (x86_fp80 %a ) {
282
+ ; CHECK-LABEL: define i1 @f32_fcposzero_wrong_type2(
283
+ ; CHECK-SAME: x86_fp80 [[A:%.*]]) {
284
+ ; CHECK-NEXT: [[I80:%.*]] = bitcast x86_fp80 [[A]] to i80
285
+ ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i80 [[I80]], 0
286
+ ; CHECK-NEXT: ret i1 [[CMP]]
287
+ ;
288
+ %i80 = bitcast x86_fp80 %a to i80
289
+ %cmp = icmp eq i80 %i80 , 0
290
+ ret i1 %cmp
291
+ }
292
+
189
293
define i1 @f32_fcnan_fcinf_noimplicitfloat (float %a ) #0 {
190
294
; CHECK-LABEL: define i1 @f32_fcnan_fcinf_noimplicitfloat(
191
295
; CHECK-SAME: float [[A:%.*]]) #[[ATTR1:[0-9]+]] {
@@ -200,4 +304,44 @@ define i1 @f32_fcnan_fcinf_noimplicitfloat(float %a) #0 {
200
304
ret i1 %cmp
201
305
}
202
306
307
+ define i1 @f32_fcposinf_noimplicitfloat (float %a ) #0 {
308
+ ; CHECK-LABEL: define i1 @f32_fcposinf_noimplicitfloat(
309
+ ; CHECK-SAME: float [[A:%.*]]) #[[ATTR1]] {
310
+ ; CHECK-NEXT: [[I32:%.*]] = bitcast float [[A]] to i32
311
+ ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[I32]], 2139095040
312
+ ; CHECK-NEXT: ret i1 [[CMP]]
313
+ ;
314
+ %i32 = bitcast float %a to i32
315
+ %cmp = icmp eq i32 %i32 , 2139095040
316
+ ret i1 %cmp
317
+ }
318
+
319
+ define i1 @f32_fcposnan (float %a ) {
320
+ ; CHECK-LABEL: define i1 @f32_fcposnan(
321
+ ; CHECK-SAME: float [[A:%.*]]) {
322
+ ; CHECK-NEXT: [[I32:%.*]] = bitcast float [[A]] to i32
323
+ ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[I32]], 2139095041
324
+ ; CHECK-NEXT: ret i1 [[CMP]]
325
+ ;
326
+ %i32 = bitcast float %a to i32
327
+ %cmp = icmp eq i32 %i32 , 2139095041
328
+ ret i1 %cmp
329
+ }
330
+
331
+ define i1 @f32_fcposinf_multiuse (float %a ) {
332
+ ; CHECK-LABEL: define i1 @f32_fcposinf_multiuse(
333
+ ; CHECK-SAME: float [[A:%.*]]) {
334
+ ; CHECK-NEXT: [[I32:%.*]] = bitcast float [[A]] to i32
335
+ ; CHECK-NEXT: call void @usei32(i32 [[I32]])
336
+ ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[I32]], 2139095040
337
+ ; CHECK-NEXT: ret i1 [[CMP]]
338
+ ;
339
+ %i32 = bitcast float %a to i32
340
+ call void @usei32 (i32 %i32 )
341
+ %cmp = icmp eq i32 %i32 , 2139095040
342
+ ret i1 %cmp
343
+ }
344
+
345
+ declare void @usei32 (i32 )
346
+
203
347
attributes #0 = { noimplicitfloat }
0 commit comments