Skip to content

Commit 7c349c3

Browse files
committed
[mlir][Arith] Add arith.is_nan and arith.is_inf predicates
Both LLVM and SPIR-V have some form of "is this float a NaN/Inf" operation (though LLVM's uses the rather opaque "is.fpclass" intrinsic), which is not exposed in MLIR. This has lead to awkward workarounds in -arith-expands-ops where a NaN test was performed by comparing an operation to itself. This commit resolves that issue. Reviewed By: dcaballe, kuhar Differential Revision: https://reviews.llvm.org/D156169
1 parent d6f1880 commit 7c349c3

File tree

19 files changed

+294
-66
lines changed

19 files changed

+294
-66
lines changed

flang/test/Lower/Intrinsics/ieee_class_queries.f90

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -10,38 +10,38 @@
1010
real(10) :: x10 = -10.0
1111
real(16) :: x16 = -16.0
1212

13-
! CHECK: "llvm.intr.is.fpclass"(%{{.*}}) <{bit = 504 : i32}> : (f16) -> i1
14-
! CHECK: "llvm.intr.is.fpclass"(%{{.*}}) <{bit = 60 : i32}> : (f16) -> i1
15-
! CHECK: "llvm.intr.is.fpclass"(%{{.*}}) <{bit = 360 : i32}> : (f16) -> i1
16-
! CHECK: "llvm.intr.is.fpclass"(%{{.*}}) <{bit = 3 : i32}> : (f16) -> i1
13+
! CHECK: "llvm.intr.is.fpclass"(%{{.*}}) <{fastmathFlags = #llvm.fastmath<none>, kinds = 504 : i32}> : (f16) -> i1
14+
! CHECK: "llvm.intr.is.fpclass"(%{{.*}}) <{fastmathFlags = #llvm.fastmath<none>, kinds = 60 : i32}> : (f16) -> i1
15+
! CHECK: "llvm.intr.is.fpclass"(%{{.*}}) <{fastmathFlags = #llvm.fastmath<none>, kinds = 360 : i32}> : (f16) -> i1
16+
! CHECK: "llvm.intr.is.fpclass"(%{{.*}}) <{fastmathFlags = #llvm.fastmath<none>, kinds = 3 : i32}> : (f16) -> i1
1717
print*, ieee_is_finite(x2), ieee_is_negative(x2), ieee_is_normal(x2), &
1818
ieee_is_nan(x2)
1919

20-
! CHECK: "llvm.intr.is.fpclass"(%{{.*}}) <{bit = 504 : i32}> : (bf16) -> i1
21-
! CHECK: "llvm.intr.is.fpclass"(%{{.*}}) <{bit = 60 : i32}> : (bf16) -> i1
22-
! CHECK: "llvm.intr.is.fpclass"(%{{.*}}) <{bit = 360 : i32}> : (bf16) -> i1
23-
! CHECK: "llvm.intr.is.fpclass"(%{{.*}}) <{bit = 3 : i32}> : (bf16) -> i1
20+
! CHECK: "llvm.intr.is.fpclass"(%{{.*}}) <{fastmathFlags = #llvm.fastmath<none>, kinds = 504 : i32}> : (bf16) -> i1
21+
! CHECK: "llvm.intr.is.fpclass"(%{{.*}}) <{fastmathFlags = #llvm.fastmath<none>, kinds = 60 : i32}> : (bf16) -> i1
22+
! CHECK: "llvm.intr.is.fpclass"(%{{.*}}) <{fastmathFlags = #llvm.fastmath<none>, kinds = 360 : i32}> : (bf16) -> i1
23+
! CHECK: "llvm.intr.is.fpclass"(%{{.*}}) <{fastmathFlags = #llvm.fastmath<none>, kinds = 3 : i32}> : (bf16) -> i1
2424
print*, ieee_is_finite(x3), ieee_is_negative(x3), ieee_is_normal(x3), &
2525
ieee_is_nan(x3)
2626

27-
! CHECK: "llvm.intr.is.fpclass"(%{{.*}}) <{bit = 504 : i32}> : (f32) -> i1
28-
! CHECK: "llvm.intr.is.fpclass"(%{{.*}}) <{bit = 60 : i32}> : (f32) -> i1
29-
! CHECK: "llvm.intr.is.fpclass"(%{{.*}}) <{bit = 360 : i32}> : (f32) -> i1
30-
! CHECK: "llvm.intr.is.fpclass"(%{{.*}}) <{bit = 3 : i32}> : (f32) -> i1
27+
! CHECK: "llvm.intr.is.fpclass"(%{{.*}}) <{fastmathFlags = #llvm.fastmath<none>, kinds = 504 : i32}> : (f32) -> i1
28+
! CHECK: "llvm.intr.is.fpclass"(%{{.*}}) <{fastmathFlags = #llvm.fastmath<none>, kinds = 60 : i32}> : (f32) -> i1
29+
! CHECK: "llvm.intr.is.fpclass"(%{{.*}}) <{fastmathFlags = #llvm.fastmath<none>, kinds = 360 : i32}> : (f32) -> i1
30+
! CHECK: "llvm.intr.is.fpclass"(%{{.*}}) <{fastmathFlags = #llvm.fastmath<none>, kinds = 3 : i32}> : (f32) -> i1
3131
print*, ieee_is_finite(x4), ieee_is_negative(x4), ieee_is_normal(x4), &
3232
ieee_is_nan(x4)
3333

34-
! CHECK: "llvm.intr.is.fpclass"(%{{.*}}) <{bit = 504 : i32}> : (f64) -> i1
35-
! CHECK: "llvm.intr.is.fpclass"(%{{.*}}) <{bit = 60 : i32}> : (f64) -> i1
36-
! CHECK: "llvm.intr.is.fpclass"(%{{.*}}) <{bit = 360 : i32}> : (f64) -> i1
37-
! CHECK: "llvm.intr.is.fpclass"(%{{.*}}) <{bit = 3 : i32}> : (f64) -> i1
34+
! CHECK: "llvm.intr.is.fpclass"(%{{.*}}) <{fastmathFlags = #llvm.fastmath<none>, kinds = 504 : i32}> : (f64) -> i1
35+
! CHECK: "llvm.intr.is.fpclass"(%{{.*}}) <{fastmathFlags = #llvm.fastmath<none>, kinds = 60 : i32}> : (f64) -> i1
36+
! CHECK: "llvm.intr.is.fpclass"(%{{.*}}) <{fastmathFlags = #llvm.fastmath<none>, kinds = 360 : i32}> : (f64) -> i1
37+
! CHECK: "llvm.intr.is.fpclass"(%{{.*}}) <{fastmathFlags = #llvm.fastmath<none>, kinds = 3 : i32}> : (f64) -> i1
3838
print*, ieee_is_finite(x8), ieee_is_negative(x8), ieee_is_normal(x8), &
3939
ieee_is_nan(x8)
4040

41-
! CHECK: "llvm.intr.is.fpclass"(%{{.*}}) <{bit = 504 : i32}> : (f128) -> i1
42-
! CHECK: "llvm.intr.is.fpclass"(%{{.*}}) <{bit = 60 : i32}> : (f128) -> i1
43-
! CHECK: "llvm.intr.is.fpclass"(%{{.*}}) <{bit = 360 : i32}> : (f128) -> i1
44-
! CHECK: "llvm.intr.is.fpclass"(%{{.*}}) <{bit = 3 : i32}> : (f128) -> i1
41+
! CHECK: "llvm.intr.is.fpclass"(%{{.*}}) <{fastmathFlags = #llvm.fastmath<none>, kinds = 504 : i32}> : (f128) -> i1
42+
! CHECK: "llvm.intr.is.fpclass"(%{{.*}}) <{fastmathFlags = #llvm.fastmath<none>, kinds = 60 : i32}> : (f128) -> i1
43+
! CHECK: "llvm.intr.is.fpclass"(%{{.*}}) <{fastmathFlags = #llvm.fastmath<none>, kinds = 360 : i32}> : (f128) -> i1
44+
! CHECK: "llvm.intr.is.fpclass"(%{{.*}}) <{fastmathFlags = #llvm.fastmath<none>, kinds = 3 : i32}> : (f128) -> i1
4545
print*, ieee_is_finite(x16), ieee_is_negative(x16), ieee_is_normal(x16), &
4646
ieee_is_nan(x16)
4747

flang/test/Lower/Intrinsics/ieee_is_finite.f90

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ subroutine is_finite_test(x, y)
77
real(8) y
88

99
! CHECK: %[[V_3:[0-9]+]] = fir.load %arg0 : !fir.ref<f32>
10-
! CHECK: %[[V_4:[0-9]+]] = "llvm.intr.is.fpclass"(%[[V_3]]) <{bit = 504 : i32}> : (f32) -> i1
10+
! CHECK: %[[V_4:[0-9]+]] = "llvm.intr.is.fpclass"(%[[V_3]]) <{fastmathFlags = #llvm.fastmath<none>, kinds = 504 : i32}> : (f32) -> i1
1111
! CHECK: %[[V_5:[0-9]+]] = fir.convert %[[V_4]] : (i1) -> !fir.logical<4>
1212
! CHECK: %[[V_6:[0-9]+]] = fir.convert %[[V_5]] : (!fir.logical<4>) -> i1
1313
! CHECK: %[[V_7:[0-9]+]] = fir.call @_FortranAioOutputLogical(%{{.*}}, %[[V_6]]) {{.*}} : (!fir.ref<i8>, i1) -> i1
@@ -16,14 +16,14 @@ subroutine is_finite_test(x, y)
1616
! CHECK: %[[V_12:[0-9]+]] = fir.load %arg0 : !fir.ref<f32>
1717
! CHECK: %[[V_13:[0-9]+]] = fir.load %arg0 : !fir.ref<f32>
1818
! CHECK: %[[V_14:[0-9]+]] = arith.addf %[[V_12]], %[[V_13]] {{.*}} : f32
19-
! CHECK: %[[V_15:[0-9]+]] = "llvm.intr.is.fpclass"(%[[V_14]]) <{bit = 504 : i32}> : (f32) -> i1
19+
! CHECK: %[[V_15:[0-9]+]] = "llvm.intr.is.fpclass"(%[[V_14]]) <{fastmathFlags = #llvm.fastmath<none>, kinds = 504 : i32}> : (f32) -> i1
2020
! CHECK: %[[V_16:[0-9]+]] = fir.convert %[[V_15]] : (i1) -> !fir.logical<4>
2121
! CHECK: %[[V_17:[0-9]+]] = fir.convert %[[V_16]] : (!fir.logical<4>) -> i1
2222
! CHECK: %[[V_18:[0-9]+]] = fir.call @_FortranAioOutputLogical(%{{.*}}, %[[V_17]]) {{.*}} : (!fir.ref<i8>, i1) -> i1
2323
print*, ieee_is_finite(x+x)
2424

2525
! CHECK: %[[V_23:[0-9]+]] = fir.load %arg1 : !fir.ref<f64>
26-
! CHECK: %[[V_24:[0-9]+]] = "llvm.intr.is.fpclass"(%[[V_23]]) <{bit = 504 : i32}> : (f64) -> i1
26+
! CHECK: %[[V_24:[0-9]+]] = "llvm.intr.is.fpclass"(%[[V_23]]) <{fastmathFlags = #llvm.fastmath<none>, kinds = 504 : i32}> : (f64) -> i1
2727
! CHECK: %[[V_25:[0-9]+]] = fir.convert %[[V_24]] : (i1) -> !fir.logical<4>
2828
! CHECK: %[[V_26:[0-9]+]] = fir.convert %[[V_25]] : (!fir.logical<4>) -> i1
2929
! CHECK: %[[V_27:[0-9]+]] = fir.call @_FortranAioOutputLogical(%{{.*}}, %[[V_26]]) {{.*}} : (!fir.ref<i8>, i1) -> i1
@@ -32,7 +32,7 @@ subroutine is_finite_test(x, y)
3232
! CHECK: %[[V_32:[0-9]+]] = fir.load %arg1 : !fir.ref<f64>
3333
! CHECK: %[[V_33:[0-9]+]] = fir.load %arg1 : !fir.ref<f64>
3434
! CHECK: %[[V_34:[0-9]+]] = arith.addf %[[V_32]], %[[V_33]] {{.*}} : f64
35-
! CHECK: %[[V_35:[0-9]+]] = "llvm.intr.is.fpclass"(%[[V_34]]) <{bit = 504 : i32}> : (f64) -> i1
35+
! CHECK: %[[V_35:[0-9]+]] = "llvm.intr.is.fpclass"(%[[V_34]]) <{fastmathFlags = #llvm.fastmath<none>, kinds = 504 : i32}> : (f64) -> i1
3636
! CHECK: %[[V_36:[0-9]+]] = fir.convert %[[V_35]] : (i1) -> !fir.logical<4>
3737
! CHECK: %[[V_37:[0-9]+]] = fir.convert %[[V_36]] : (!fir.logical<4>) -> i1
3838
! CHECK: %[[V_38:[0-9]+]] = fir.call @_FortranAioOutputLogical(%{{.*}}, %[[V_37]]) {{.*}} : (!fir.ref<i8>, i1) -> i1

flang/test/Lower/Intrinsics/ieee_is_normal.f90

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ subroutine ieee_is_normal_f16(r)
66
use ieee_arithmetic
77
real(KIND=2) :: r
88
i = ieee_is_normal(r)
9-
! CHECK: %[[l:.*]] = "llvm.intr.is.fpclass"(%{{.*}}) <{bit = 360 : i32}> : (f16) -> i1
9+
! CHECK: %[[l:.*]] = "llvm.intr.is.fpclass"(%{{.*}}) <{fastmathFlags = #llvm.fastmath<none>, kinds = 360 : i32}> : (f16) -> i1
1010
! CHECK: fir.convert %[[l]] : (i1) -> !fir.logical<4>
1111
end subroutine ieee_is_normal_f16
1212

@@ -15,7 +15,7 @@ subroutine ieee_is_normal_bf16(r)
1515
use ieee_arithmetic
1616
real(KIND=3) :: r
1717
i = ieee_is_normal(r)
18-
! CHECK: %[[l:.*]] = "llvm.intr.is.fpclass"(%{{.*}}) <{bit = 360 : i32}> : (bf16) -> i1
18+
! CHECK: %[[l:.*]] = "llvm.intr.is.fpclass"(%{{.*}}) <{fastmathFlags = #llvm.fastmath<none>, kinds = 360 : i32}> : (bf16) -> i1
1919
! CHECK: fir.convert %[[l]] : (i1) -> !fir.logical<4>
2020
end subroutine ieee_is_normal_bf16
2121

@@ -26,7 +26,7 @@ subroutine ieee_is_normal_f32(r)
2626
use ieee_arithmetic
2727
real :: r
2828
i = ieee_is_normal(r)
29-
! CHECK: %[[l:.*]] = "llvm.intr.is.fpclass"(%{{.*}}) <{bit = 360 : i32}> : (f32) -> i1
29+
! CHECK: %[[l:.*]] = "llvm.intr.is.fpclass"(%{{.*}}) <{fastmathFlags = #llvm.fastmath<none>, kinds = 360 : i32}> : (f32) -> i1
3030
! CHECK: fir.convert %[[l]] : (i1) -> !fir.logical<4>
3131
end subroutine ieee_is_normal_f32
3232

@@ -35,7 +35,7 @@ subroutine ieee_is_normal_f64(r)
3535
use ieee_arithmetic
3636
real(KIND=8) :: r
3737
i = ieee_is_normal(r)
38-
! CHECK: %[[l:.*]] = "llvm.intr.is.fpclass"(%{{.*}}) <{bit = 360 : i32}> : (f64) -> i1
38+
! CHECK: %[[l:.*]] = "llvm.intr.is.fpclass"(%{{.*}}) <{fastmathFlags = #llvm.fastmath<none>, kinds = 360 : i32}> : (f64) -> i1
3939
! CHECK: fir.convert %[[l]] : (i1) -> !fir.logical<4>
4040
end subroutine ieee_is_normal_f64
4141

@@ -44,7 +44,7 @@ subroutine ieee_is_normal_f80(r)
4444
use ieee_arithmetic
4545
real(KIND=10) :: r
4646
i = ieee_is_normal(r)
47-
! CHECK: %[[l:.*]] = "llvm.intr.is.fpclass"(%{{.*}}) <{bit = 360 : i32}> : (f80) -> i1
47+
! CHECK: %[[l:.*]] = "llvm.intr.is.fpclass"(%{{.*}}) <{fastmathFlags = #llvm.fastmath<none>, kinds = 360 : i32}> : (f80) -> i1
4848
! CHECK: fir.convert %[[l]] : (i1) -> !fir.logical<4>
4949
end subroutine ieee_is_normal_f80
5050

@@ -53,6 +53,6 @@ subroutine ieee_is_normal_f128(r)
5353
use ieee_arithmetic
5454
real(KIND=16) :: r
5555
i = ieee_is_normal(r)
56-
! CHECK: %[[l:.*]] = "llvm.intr.is.fpclass"(%{{.*}}) <{bit = 360 : i32}> : (f128) -> i1
56+
! CHECK: %[[l:.*]] = "llvm.intr.is.fpclass"(%{{.*}}) <{fastmathFlags = #llvm.fastmath<none>, kinds = 360 : i32}> : (f128) -> i1
5757
! CHECK: fir.convert %[[l]] : (i1) -> !fir.logical<4>
5858
end subroutine ieee_is_normal_f128

flang/test/Lower/Intrinsics/ieee_unordered.f90

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -44,26 +44,26 @@
4444

4545
! CHECK: %[[V_40:[0-9]+]] = fir.load %[[V_2]] : !fir.ref<f128>
4646
! CHECK: %[[V_41:[0-9]+]] = fir.load %[[V_3]] : !fir.ref<f128>
47-
! CHECK: %[[V_42:[0-9]+]] = "llvm.intr.is.fpclass"(%[[V_40]]) <{bit = 3 : i32}> : (f128) -> i1
48-
! CHECK: %[[V_43:[0-9]+]] = "llvm.intr.is.fpclass"(%[[V_41]]) <{bit = 3 : i32}> : (f128) -> i1
47+
! CHECK: %[[V_42:[0-9]+]] = "llvm.intr.is.fpclass"(%[[V_40]]) <{fastmathFlags = #llvm.fastmath<none>, kinds = 3 : i32}> : (f128) -> i1
48+
! CHECK: %[[V_43:[0-9]+]] = "llvm.intr.is.fpclass"(%[[V_41]]) <{fastmathFlags = #llvm.fastmath<none>, kinds = 3 : i32}> : (f128) -> i1
4949
! CHECK: %[[V_44:[0-9]+]] = arith.ori %[[V_42]], %[[V_43]] : i1
5050
! CHECK: %[[V_45:[0-9]+]] = fir.convert %[[V_44]] : (i1) -> !fir.logical<4>
5151
! CHECK: %[[V_46:[0-9]+]] = fir.convert %[[V_45]] : (!fir.logical<4>) -> i1
5252
! CHECK: %[[V_47:[0-9]+]] = fir.call @_FortranAioOutputLogical(%{{.*}}, %[[V_46]]) {{.*}} : (!fir.ref<i8>, i1) -> i1
5353

5454
! CHECK: %[[V_48:[0-9]+]] = fir.load %[[V_2]] : !fir.ref<f128>
5555
! CHECK: %[[V_49:[0-9]+]] = fir.load %[[V_4]] : !fir.ref<f128>
56-
! CHECK: %[[V_50:[0-9]+]] = "llvm.intr.is.fpclass"(%[[V_48]]) <{bit = 3 : i32}> : (f128) -> i1
57-
! CHECK: %[[V_51:[0-9]+]] = "llvm.intr.is.fpclass"(%[[V_49]]) <{bit = 3 : i32}> : (f128) -> i1
56+
! CHECK: %[[V_50:[0-9]+]] = "llvm.intr.is.fpclass"(%[[V_48]]) <{fastmathFlags = #llvm.fastmath<none>, kinds = 3 : i32}> : (f128) -> i1
57+
! CHECK: %[[V_51:[0-9]+]] = "llvm.intr.is.fpclass"(%[[V_49]]) <{fastmathFlags = #llvm.fastmath<none>, kinds = 3 : i32}> : (f128) -> i1
5858
! CHECK: %[[V_52:[0-9]+]] = arith.ori %[[V_50]], %[[V_51]] : i1
5959
! CHECK: %[[V_53:[0-9]+]] = fir.convert %[[V_52]] : (i1) -> !fir.logical<4>
6060
! CHECK: %[[V_54:[0-9]+]] = fir.convert %[[V_53]] : (!fir.logical<4>) -> i1
6161
! CHECK: %[[V_55:[0-9]+]] = fir.call @_FortranAioOutputLogical(%{{.*}}, %[[V_54]]) {{.*}} : (!fir.ref<i8>, i1) -> i1
6262

6363
! CHECK: %[[V_56:[0-9]+]] = fir.load %[[V_3]] : !fir.ref<f128>
6464
! CHECK: %[[V_57:[0-9]+]] = fir.load %[[V_4]] : !fir.ref<f128>
65-
! CHECK: %[[V_58:[0-9]+]] = "llvm.intr.is.fpclass"(%[[V_56]]) <{bit = 3 : i32}> : (f128) -> i1
66-
! CHECK: %[[V_59:[0-9]+]] = "llvm.intr.is.fpclass"(%[[V_57]]) <{bit = 3 : i32}> : (f128) -> i1
65+
! CHECK: %[[V_58:[0-9]+]] = "llvm.intr.is.fpclass"(%[[V_56]]) <{fastmathFlags = #llvm.fastmath<none>, kinds = 3 : i32}> : (f128) -> i1
66+
! CHECK: %[[V_59:[0-9]+]] = "llvm.intr.is.fpclass"(%[[V_57]]) <{fastmathFlags = #llvm.fastmath<none>, kinds = 3 : i32}> : (f128) -> i1
6767
! CHECK: %[[V_60:[0-9]+]] = arith.ori %[[V_58]], %[[V_59]] : i1
6868
! CHECK: %[[V_61:[0-9]+]] = fir.convert %[[V_60]] : (i1) -> !fir.logical<4>
6969
! CHECK: %[[V_62:[0-9]+]] = fir.convert %[[V_61]] : (!fir.logical<4>) -> i1

flang/test/Lower/Intrinsics/isnan.f90

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
subroutine isnan_f32(r)
66
real :: r
77
i = isnan(r)
8-
! CHECK: %[[l:.*]] = "llvm.intr.is.fpclass"(%{{.*}}) <{bit = 3 : i32}> : (f32) -> i1
8+
! CHECK: %[[l:.*]] = "llvm.intr.is.fpclass"(%{{.*}}) <{fastmathFlags = #llvm.fastmath<none>, kinds = 3 : i32}> : (f32) -> i1
99
! CHECK: fir.convert %[[l]] : (i1) -> !fir.logical<4>
1010
end subroutine isnan_f32
1111

@@ -14,15 +14,15 @@ subroutine ieee_is_nan_f32(r)
1414
use ieee_arithmetic
1515
real :: r
1616
i = ieee_is_nan(r)
17-
! CHECK: %[[l:.*]] = "llvm.intr.is.fpclass"(%{{.*}}) <{bit = 3 : i32}> : (f32) -> i1
17+
! CHECK: %[[l:.*]] = "llvm.intr.is.fpclass"(%{{.*}}) <{fastmathFlags = #llvm.fastmath<none>, kinds = 3 : i32}> : (f32) -> i1
1818
! CHECK: fir.convert %[[l]] : (i1) -> !fir.logical<4>
1919
end subroutine ieee_is_nan_f32
2020

2121
! CHECK-LABEL: isnan_f64
2222
subroutine isnan_f64(r)
2323
real(KIND=8) :: r
2424
i = isnan(r)
25-
! CHECK: %[[l:.*]] = "llvm.intr.is.fpclass"(%{{.*}}) <{bit = 3 : i32}> : (f64) -> i1
25+
! CHECK: %[[l:.*]] = "llvm.intr.is.fpclass"(%{{.*}}) <{fastmathFlags = #llvm.fastmath<none>, kinds = 3 : i32}> : (f64) -> i1
2626
! CHECK: fir.convert %[[l]] : (i1) -> !fir.logical<4>
2727
end subroutine isnan_f64
2828

@@ -31,15 +31,15 @@ subroutine ieee_is_nan_f64(r)
3131
use ieee_arithmetic
3232
real(KIND=8) :: r
3333
i = ieee_is_nan(r)
34-
! CHECK: %[[l:.*]] = "llvm.intr.is.fpclass"(%{{.*}}) <{bit = 3 : i32}> : (f64) -> i1
34+
! CHECK: %[[l:.*]] = "llvm.intr.is.fpclass"(%{{.*}}) <{fastmathFlags = #llvm.fastmath<none>, kinds = 3 : i32}> : (f64) -> i1
3535
! CHECK: fir.convert %[[l]] : (i1) -> !fir.logical<4>
3636
end subroutine ieee_is_nan_f64
3737

3838
! CHECK-LABEL: isnan_f80
3939
subroutine isnan_f80(r)
4040
real(KIND=10) :: r
4141
i = isnan(r)
42-
! CHECK: %[[l:.*]] = "llvm.intr.is.fpclass"(%{{.*}}) <{bit = 3 : i32}> : (f80) -> i1
42+
! CHECK: %[[l:.*]] = "llvm.intr.is.fpclass"(%{{.*}}) <{fastmathFlags = #llvm.fastmath<none>, kinds = 3 : i32}> : (f80) -> i1
4343
! CHECK: fir.convert %[[l]] : (i1) -> !fir.logical<4>
4444
end subroutine isnan_f80
4545

@@ -48,15 +48,15 @@ subroutine ieee_is_nan_f80(r)
4848
use ieee_arithmetic
4949
real(KIND=10) :: r
5050
i = ieee_is_nan(r)
51-
! CHECK: %[[l:.*]] = "llvm.intr.is.fpclass"(%{{.*}}) <{bit = 3 : i32}> : (f80) -> i1
51+
! CHECK: %[[l:.*]] = "llvm.intr.is.fpclass"(%{{.*}}) <{fastmathFlags = #llvm.fastmath<none>, kinds = 3 : i32}> : (f80) -> i1
5252
! CHECK: fir.convert %[[l]] : (i1) -> !fir.logical<4>
5353
end subroutine ieee_is_nan_f80
5454

5555
! CHECK-LABEL: isnan_f128
5656
subroutine isnan_f128(r)
5757
real(KIND=16) :: r
5858
i = isnan(r)
59-
! CHECK: %[[l:.*]] = "llvm.intr.is.fpclass"(%{{.*}}) <{bit = 3 : i32}> : (f128) -> i1
59+
! CHECK: %[[l:.*]] = "llvm.intr.is.fpclass"(%{{.*}}) <{fastmathFlags = #llvm.fastmath<none>, kinds = 3 : i32}> : (f128) -> i1
6060
! CHECK: fir.convert %[[l]] : (i1) -> !fir.logical<4>
6161
end subroutine isnan_f128
6262

@@ -65,6 +65,6 @@ subroutine ieee_is_nan_f128(r)
6565
use ieee_arithmetic
6666
real(KIND=16) :: r
6767
i = ieee_is_nan(r)
68-
! CHECK: %[[l:.*]] = "llvm.intr.is.fpclass"(%{{.*}}) <{bit = 3 : i32}> : (f128) -> i1
68+
! CHECK: %[[l:.*]] = "llvm.intr.is.fpclass"(%{{.*}}) <{fastmathFlags = #llvm.fastmath<none>, kinds = 3 : i32}> : (f128) -> i1
6969
! CHECK: fir.convert %[[l]] : (i1) -> !fir.logical<4>
7070
end subroutine ieee_is_nan_f128

mlir/include/mlir/Conversion/ArithCommon/AttrToLLVMConverter.h

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,29 @@ class AttrConvertFastMathToLLVM {
4949

5050
ArrayRef<NamedAttribute> getAttrs() const { return convertedAttr.getAttrs(); }
5151

52-
private:
52+
protected:
5353
NamedAttrList convertedAttr;
5454
};
55+
56+
/// Wrapper around AttrConvertFastMathToLLVM that also sets the "kinds"
57+
/// attribute to the bitmask specified in `Kinds`, which is used for converting
58+
/// operations that lower to llvm.is.fpclass.
59+
template <unsigned Kinds, typename SourceOp, typename TargetOp>
60+
class AttrConvertAddFpclassKinds
61+
: public AttrConvertFastMathToLLVM<SourceOp, TargetOp> {
62+
public:
63+
AttrConvertAddFpclassKinds(SourceOp op)
64+
: AttrConvertFastMathToLLVM<SourceOp, TargetOp>(op) {
65+
convertedAttr.set(
66+
"kinds",
67+
IntegerAttr::get(IntegerType::get(op.getContext(), 32), Kinds));
68+
}
69+
70+
ArrayRef<NamedAttribute> getAttrs() const { return convertedAttr.getAttrs(); }
71+
72+
protected:
73+
using AttrConvertFastMathToLLVM<SourceOp, TargetOp>::convertedAttr;
74+
};
5575
} // namespace arith
5676
} // namespace mlir
5777

mlir/include/mlir/Dialect/Arith/IR/ArithOps.td

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,20 @@ class Arith_FloatBinaryOp<string mnemonic, list<Trait> traits = []> :
8383
attr-dict `:` type($result) }];
8484
}
8585

86+
// Base class for floating point unary predicate operations.
87+
class Arith_FloatPredicateOp<string mnemonic, list<Trait> traits = []> :
88+
Arith_Op<mnemonic,
89+
!listconcat([DeclareOpInterfaceMethods<ArithFastMathInterface>, Pure,
90+
TypesMatchWith<"result type has i1 element type and same shape as operands",
91+
"operand", "result", "::getI1SameShape($_self)">], traits)>,
92+
Arguments<(ins FloatLike:$operand,
93+
DefaultValuedAttr<
94+
Arith_FastMathAttr, "::mlir::arith::FastMathFlags::none">:$fastmath)>,
95+
Results<(outs BoolLike:$result)> {
96+
let assemblyFormat = [{ $operand (`fastmath` `` $fastmath^)?
97+
attr-dict `:` type($operand) }];
98+
}
99+
86100
// Base class for arithmetic cast operations. Requires a single operand and
87101
// result. If either is a shaped type, then the other must be of the same shape.
88102
class Arith_CastOp<string mnemonic, TypeConstraint From, TypeConstraint To,
@@ -971,6 +985,22 @@ def Arith_RemFOp : Arith_FloatBinaryOp<"remf"> {
971985
let hasFolder = 1;
972986
}
973987

988+
//===----------------------------------------------------------------------===//
989+
// IsNanOp
990+
//===----------------------------------------------------------------------===//
991+
def Arith_IsNanOp : Arith_FloatPredicateOp<"is_nan"> {
992+
let summary = "Returns true for IEEE NaN inputs";
993+
let hasFolder = 1;
994+
}
995+
996+
//===----------------------------------------------------------------------===//
997+
// IsInfOp
998+
//===----------------------------------------------------------------------===//
999+
def Arith_IsInfOp : Arith_FloatPredicateOp<"is_inf"> {
1000+
let summary = "Returns true for infinite float inputs";
1001+
let hasFolder = 1;
1002+
}
1003+
9741004
//===----------------------------------------------------------------------===//
9751005
// ExtUIOp
9761006
//===----------------------------------------------------------------------===//

mlir/include/mlir/Dialect/LLVMIR/LLVMIntrinsicOps.td

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -120,17 +120,21 @@ def LLVM_AbsOp : LLVM_OneResultIntrOp<"abs", [], [0], [Pure]> {
120120
}];
121121
}
122122

123-
def LLVM_IsFPClass : LLVM_OneResultIntrOp<"is.fpclass", [], [0], [Pure]> {
124-
let arguments = (ins LLVM_ScalarOrVectorOf<LLVM_AnyFloat>:$in, I32Attr:$bit);
123+
def LLVM_IsFPClass : LLVM_OneResultIntrOp<"is.fpclass", [], [0], [Pure],
124+
/*requiresFastmath=*/1> {
125+
let arguments = (ins LLVM_ScalarOrVectorOf<LLVM_AnyFloat>:$in,
126+
I32Attr:$kinds,
127+
DefaultValuedAttr<LLVM_FastmathFlagsAttr, "{}">:$fastmathFlags);
125128
string mlirBuilder = [{
126129
auto op = $_builder.create<$_qualCppClassName>($_location,
127-
$_resultType, $in, $_int_attr($bit));
128-
$res = op;
130+
$_resultType, $in, $_int_attr($kinds), nullptr);
131+
moduleImport.setFastmathFlagsAttr(inst, op);
132+
$res = op;
129133
}];
130134
string llvmBuilder = [{
131135
auto *inst = createIntrinsicCall(
132136
builder, llvm::Intrinsic::}] # llvmEnumName # [{,
133-
{$in, builder.getInt32(op.getBit())},
137+
{$in, builder.getInt32(op.getKinds())},
134138
}] # declTypes # [{);
135139
$res = inst;
136140
}];

0 commit comments

Comments
 (0)