Revert "[mlir][Arith] Add arith.is_nan and arith.is_inf predicates"

This reverts commit 7c349c369847dc2f1736efb9c90d03521cd44a90.

Per discussion at
https://reviews.llvm.org/rG7c349c369847dc2f1736efb9c90d03521cd44a90
and elsewhere, the lowering to LLVM defined here isn't what it should
be and the fastmath flag usage isn't correct, so `arith.is_nan` and
`arith.is_inf` cannot exist in their current form.

It's unclear if those operations should be introduced in the future,
since they make the dialect more complex and don't add any expressive
power. Further discussion may be moved to an RFC (or I'll drop this
patch).

Differential Revision: https://reviews.llvm.org/D157543
This commit is contained in:
Krzysztof Drewniak 2023-08-09 19:30:46 +00:00
parent 3091bdb86d
commit 3fe8ec7906
19 changed files with 66 additions and 294 deletions

View File

@ -10,38 +10,38 @@
real(10) :: x10 = -10.0
real(16) :: x16 = -16.0
! CHECK: "llvm.intr.is.fpclass"(%{{.*}}) <{fastmathFlags = #llvm.fastmath<none>, kinds = 504 : i32}> : (f16) -> i1
! CHECK: "llvm.intr.is.fpclass"(%{{.*}}) <{fastmathFlags = #llvm.fastmath<none>, kinds = 60 : i32}> : (f16) -> i1
! CHECK: "llvm.intr.is.fpclass"(%{{.*}}) <{fastmathFlags = #llvm.fastmath<none>, kinds = 360 : i32}> : (f16) -> i1
! CHECK: "llvm.intr.is.fpclass"(%{{.*}}) <{fastmathFlags = #llvm.fastmath<none>, kinds = 3 : i32}> : (f16) -> i1
! CHECK: "llvm.intr.is.fpclass"(%{{.*}}) <{bit = 504 : i32}> : (f16) -> i1
! CHECK: "llvm.intr.is.fpclass"(%{{.*}}) <{bit = 60 : i32}> : (f16) -> i1
! CHECK: "llvm.intr.is.fpclass"(%{{.*}}) <{bit = 360 : i32}> : (f16) -> i1
! CHECK: "llvm.intr.is.fpclass"(%{{.*}}) <{bit = 3 : i32}> : (f16) -> i1
print*, ieee_is_finite(x2), ieee_is_negative(x2), ieee_is_normal(x2), &
ieee_is_nan(x2)
! CHECK: "llvm.intr.is.fpclass"(%{{.*}}) <{fastmathFlags = #llvm.fastmath<none>, kinds = 504 : i32}> : (bf16) -> i1
! CHECK: "llvm.intr.is.fpclass"(%{{.*}}) <{fastmathFlags = #llvm.fastmath<none>, kinds = 60 : i32}> : (bf16) -> i1
! CHECK: "llvm.intr.is.fpclass"(%{{.*}}) <{fastmathFlags = #llvm.fastmath<none>, kinds = 360 : i32}> : (bf16) -> i1
! CHECK: "llvm.intr.is.fpclass"(%{{.*}}) <{fastmathFlags = #llvm.fastmath<none>, kinds = 3 : i32}> : (bf16) -> i1
! CHECK: "llvm.intr.is.fpclass"(%{{.*}}) <{bit = 504 : i32}> : (bf16) -> i1
! CHECK: "llvm.intr.is.fpclass"(%{{.*}}) <{bit = 60 : i32}> : (bf16) -> i1
! CHECK: "llvm.intr.is.fpclass"(%{{.*}}) <{bit = 360 : i32}> : (bf16) -> i1
! CHECK: "llvm.intr.is.fpclass"(%{{.*}}) <{bit = 3 : i32}> : (bf16) -> i1
print*, ieee_is_finite(x3), ieee_is_negative(x3), ieee_is_normal(x3), &
ieee_is_nan(x3)
! CHECK: "llvm.intr.is.fpclass"(%{{.*}}) <{fastmathFlags = #llvm.fastmath<none>, kinds = 504 : i32}> : (f32) -> i1
! CHECK: "llvm.intr.is.fpclass"(%{{.*}}) <{fastmathFlags = #llvm.fastmath<none>, kinds = 60 : i32}> : (f32) -> i1
! CHECK: "llvm.intr.is.fpclass"(%{{.*}}) <{fastmathFlags = #llvm.fastmath<none>, kinds = 360 : i32}> : (f32) -> i1
! CHECK: "llvm.intr.is.fpclass"(%{{.*}}) <{fastmathFlags = #llvm.fastmath<none>, kinds = 3 : i32}> : (f32) -> i1
! CHECK: "llvm.intr.is.fpclass"(%{{.*}}) <{bit = 504 : i32}> : (f32) -> i1
! CHECK: "llvm.intr.is.fpclass"(%{{.*}}) <{bit = 60 : i32}> : (f32) -> i1
! CHECK: "llvm.intr.is.fpclass"(%{{.*}}) <{bit = 360 : i32}> : (f32) -> i1
! CHECK: "llvm.intr.is.fpclass"(%{{.*}}) <{bit = 3 : i32}> : (f32) -> i1
print*, ieee_is_finite(x4), ieee_is_negative(x4), ieee_is_normal(x4), &
ieee_is_nan(x4)
! CHECK: "llvm.intr.is.fpclass"(%{{.*}}) <{fastmathFlags = #llvm.fastmath<none>, kinds = 504 : i32}> : (f64) -> i1
! CHECK: "llvm.intr.is.fpclass"(%{{.*}}) <{fastmathFlags = #llvm.fastmath<none>, kinds = 60 : i32}> : (f64) -> i1
! CHECK: "llvm.intr.is.fpclass"(%{{.*}}) <{fastmathFlags = #llvm.fastmath<none>, kinds = 360 : i32}> : (f64) -> i1
! CHECK: "llvm.intr.is.fpclass"(%{{.*}}) <{fastmathFlags = #llvm.fastmath<none>, kinds = 3 : i32}> : (f64) -> i1
! CHECK: "llvm.intr.is.fpclass"(%{{.*}}) <{bit = 504 : i32}> : (f64) -> i1
! CHECK: "llvm.intr.is.fpclass"(%{{.*}}) <{bit = 60 : i32}> : (f64) -> i1
! CHECK: "llvm.intr.is.fpclass"(%{{.*}}) <{bit = 360 : i32}> : (f64) -> i1
! CHECK: "llvm.intr.is.fpclass"(%{{.*}}) <{bit = 3 : i32}> : (f64) -> i1
print*, ieee_is_finite(x8), ieee_is_negative(x8), ieee_is_normal(x8), &
ieee_is_nan(x8)
! CHECK: "llvm.intr.is.fpclass"(%{{.*}}) <{fastmathFlags = #llvm.fastmath<none>, kinds = 504 : i32}> : (f128) -> i1
! CHECK: "llvm.intr.is.fpclass"(%{{.*}}) <{fastmathFlags = #llvm.fastmath<none>, kinds = 60 : i32}> : (f128) -> i1
! CHECK: "llvm.intr.is.fpclass"(%{{.*}}) <{fastmathFlags = #llvm.fastmath<none>, kinds = 360 : i32}> : (f128) -> i1
! CHECK: "llvm.intr.is.fpclass"(%{{.*}}) <{fastmathFlags = #llvm.fastmath<none>, kinds = 3 : i32}> : (f128) -> i1
! CHECK: "llvm.intr.is.fpclass"(%{{.*}}) <{bit = 504 : i32}> : (f128) -> i1
! CHECK: "llvm.intr.is.fpclass"(%{{.*}}) <{bit = 60 : i32}> : (f128) -> i1
! CHECK: "llvm.intr.is.fpclass"(%{{.*}}) <{bit = 360 : i32}> : (f128) -> i1
! CHECK: "llvm.intr.is.fpclass"(%{{.*}}) <{bit = 3 : i32}> : (f128) -> i1
print*, ieee_is_finite(x16), ieee_is_negative(x16), ieee_is_normal(x16), &
ieee_is_nan(x16)

View File

@ -7,7 +7,7 @@ subroutine is_finite_test(x, y)
real(8) y
! CHECK: %[[V_3:[0-9]+]] = fir.load %arg0 : !fir.ref<f32>
! CHECK: %[[V_4:[0-9]+]] = "llvm.intr.is.fpclass"(%[[V_3]]) <{fastmathFlags = #llvm.fastmath<none>, kinds = 504 : i32}> : (f32) -> i1
! CHECK: %[[V_4:[0-9]+]] = "llvm.intr.is.fpclass"(%[[V_3]]) <{bit = 504 : i32}> : (f32) -> i1
! CHECK: %[[V_5:[0-9]+]] = fir.convert %[[V_4]] : (i1) -> !fir.logical<4>
! CHECK: %[[V_6:[0-9]+]] = fir.convert %[[V_5]] : (!fir.logical<4>) -> i1
! 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)
! CHECK: %[[V_12:[0-9]+]] = fir.load %arg0 : !fir.ref<f32>
! CHECK: %[[V_13:[0-9]+]] = fir.load %arg0 : !fir.ref<f32>
! CHECK: %[[V_14:[0-9]+]] = arith.addf %[[V_12]], %[[V_13]] {{.*}} : f32
! CHECK: %[[V_15:[0-9]+]] = "llvm.intr.is.fpclass"(%[[V_14]]) <{fastmathFlags = #llvm.fastmath<none>, kinds = 504 : i32}> : (f32) -> i1
! CHECK: %[[V_15:[0-9]+]] = "llvm.intr.is.fpclass"(%[[V_14]]) <{bit = 504 : i32}> : (f32) -> i1
! CHECK: %[[V_16:[0-9]+]] = fir.convert %[[V_15]] : (i1) -> !fir.logical<4>
! CHECK: %[[V_17:[0-9]+]] = fir.convert %[[V_16]] : (!fir.logical<4>) -> i1
! CHECK: %[[V_18:[0-9]+]] = fir.call @_FortranAioOutputLogical(%{{.*}}, %[[V_17]]) {{.*}} : (!fir.ref<i8>, i1) -> i1
print*, ieee_is_finite(x+x)
! CHECK: %[[V_23:[0-9]+]] = fir.load %arg1 : !fir.ref<f64>
! CHECK: %[[V_24:[0-9]+]] = "llvm.intr.is.fpclass"(%[[V_23]]) <{fastmathFlags = #llvm.fastmath<none>, kinds = 504 : i32}> : (f64) -> i1
! CHECK: %[[V_24:[0-9]+]] = "llvm.intr.is.fpclass"(%[[V_23]]) <{bit = 504 : i32}> : (f64) -> i1
! CHECK: %[[V_25:[0-9]+]] = fir.convert %[[V_24]] : (i1) -> !fir.logical<4>
! CHECK: %[[V_26:[0-9]+]] = fir.convert %[[V_25]] : (!fir.logical<4>) -> i1
! 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)
! CHECK: %[[V_32:[0-9]+]] = fir.load %arg1 : !fir.ref<f64>
! CHECK: %[[V_33:[0-9]+]] = fir.load %arg1 : !fir.ref<f64>
! CHECK: %[[V_34:[0-9]+]] = arith.addf %[[V_32]], %[[V_33]] {{.*}} : f64
! CHECK: %[[V_35:[0-9]+]] = "llvm.intr.is.fpclass"(%[[V_34]]) <{fastmathFlags = #llvm.fastmath<none>, kinds = 504 : i32}> : (f64) -> i1
! CHECK: %[[V_35:[0-9]+]] = "llvm.intr.is.fpclass"(%[[V_34]]) <{bit = 504 : i32}> : (f64) -> i1
! CHECK: %[[V_36:[0-9]+]] = fir.convert %[[V_35]] : (i1) -> !fir.logical<4>
! CHECK: %[[V_37:[0-9]+]] = fir.convert %[[V_36]] : (!fir.logical<4>) -> i1
! CHECK: %[[V_38:[0-9]+]] = fir.call @_FortranAioOutputLogical(%{{.*}}, %[[V_37]]) {{.*}} : (!fir.ref<i8>, i1) -> i1

View File

@ -6,7 +6,7 @@ subroutine ieee_is_normal_f16(r)
use ieee_arithmetic
real(KIND=2) :: r
i = ieee_is_normal(r)
! CHECK: %[[l:.*]] = "llvm.intr.is.fpclass"(%{{.*}}) <{fastmathFlags = #llvm.fastmath<none>, kinds = 360 : i32}> : (f16) -> i1
! CHECK: %[[l:.*]] = "llvm.intr.is.fpclass"(%{{.*}}) <{bit = 360 : i32}> : (f16) -> i1
! CHECK: fir.convert %[[l]] : (i1) -> !fir.logical<4>
end subroutine ieee_is_normal_f16
@ -15,7 +15,7 @@ subroutine ieee_is_normal_bf16(r)
use ieee_arithmetic
real(KIND=3) :: r
i = ieee_is_normal(r)
! CHECK: %[[l:.*]] = "llvm.intr.is.fpclass"(%{{.*}}) <{fastmathFlags = #llvm.fastmath<none>, kinds = 360 : i32}> : (bf16) -> i1
! CHECK: %[[l:.*]] = "llvm.intr.is.fpclass"(%{{.*}}) <{bit = 360 : i32}> : (bf16) -> i1
! CHECK: fir.convert %[[l]] : (i1) -> !fir.logical<4>
end subroutine ieee_is_normal_bf16
@ -26,7 +26,7 @@ subroutine ieee_is_normal_f32(r)
use ieee_arithmetic
real :: r
i = ieee_is_normal(r)
! CHECK: %[[l:.*]] = "llvm.intr.is.fpclass"(%{{.*}}) <{fastmathFlags = #llvm.fastmath<none>, kinds = 360 : i32}> : (f32) -> i1
! CHECK: %[[l:.*]] = "llvm.intr.is.fpclass"(%{{.*}}) <{bit = 360 : i32}> : (f32) -> i1
! CHECK: fir.convert %[[l]] : (i1) -> !fir.logical<4>
end subroutine ieee_is_normal_f32
@ -35,7 +35,7 @@ subroutine ieee_is_normal_f64(r)
use ieee_arithmetic
real(KIND=8) :: r
i = ieee_is_normal(r)
! CHECK: %[[l:.*]] = "llvm.intr.is.fpclass"(%{{.*}}) <{fastmathFlags = #llvm.fastmath<none>, kinds = 360 : i32}> : (f64) -> i1
! CHECK: %[[l:.*]] = "llvm.intr.is.fpclass"(%{{.*}}) <{bit = 360 : i32}> : (f64) -> i1
! CHECK: fir.convert %[[l]] : (i1) -> !fir.logical<4>
end subroutine ieee_is_normal_f64
@ -44,7 +44,7 @@ subroutine ieee_is_normal_f80(r)
use ieee_arithmetic
real(KIND=10) :: r
i = ieee_is_normal(r)
! CHECK: %[[l:.*]] = "llvm.intr.is.fpclass"(%{{.*}}) <{fastmathFlags = #llvm.fastmath<none>, kinds = 360 : i32}> : (f80) -> i1
! CHECK: %[[l:.*]] = "llvm.intr.is.fpclass"(%{{.*}}) <{bit = 360 : i32}> : (f80) -> i1
! CHECK: fir.convert %[[l]] : (i1) -> !fir.logical<4>
end subroutine ieee_is_normal_f80
@ -53,6 +53,6 @@ subroutine ieee_is_normal_f128(r)
use ieee_arithmetic
real(KIND=16) :: r
i = ieee_is_normal(r)
! CHECK: %[[l:.*]] = "llvm.intr.is.fpclass"(%{{.*}}) <{fastmathFlags = #llvm.fastmath<none>, kinds = 360 : i32}> : (f128) -> i1
! CHECK: %[[l:.*]] = "llvm.intr.is.fpclass"(%{{.*}}) <{bit = 360 : i32}> : (f128) -> i1
! CHECK: fir.convert %[[l]] : (i1) -> !fir.logical<4>
end subroutine ieee_is_normal_f128

View File

@ -44,8 +44,8 @@ z = ieee_value(z, ieee_quiet_nan)
! CHECK: %[[V_40:[0-9]+]] = fir.load %[[V_2]] : !fir.ref<f128>
! CHECK: %[[V_41:[0-9]+]] = fir.load %[[V_3]] : !fir.ref<f128>
! CHECK: %[[V_42:[0-9]+]] = "llvm.intr.is.fpclass"(%[[V_40]]) <{fastmathFlags = #llvm.fastmath<none>, kinds = 3 : i32}> : (f128) -> i1
! CHECK: %[[V_43:[0-9]+]] = "llvm.intr.is.fpclass"(%[[V_41]]) <{fastmathFlags = #llvm.fastmath<none>, kinds = 3 : i32}> : (f128) -> i1
! CHECK: %[[V_42:[0-9]+]] = "llvm.intr.is.fpclass"(%[[V_40]]) <{bit = 3 : i32}> : (f128) -> i1
! CHECK: %[[V_43:[0-9]+]] = "llvm.intr.is.fpclass"(%[[V_41]]) <{bit = 3 : i32}> : (f128) -> i1
! CHECK: %[[V_44:[0-9]+]] = arith.ori %[[V_42]], %[[V_43]] : i1
! CHECK: %[[V_45:[0-9]+]] = fir.convert %[[V_44]] : (i1) -> !fir.logical<4>
! CHECK: %[[V_46:[0-9]+]] = fir.convert %[[V_45]] : (!fir.logical<4>) -> i1
@ -53,8 +53,8 @@ z = ieee_value(z, ieee_quiet_nan)
! CHECK: %[[V_48:[0-9]+]] = fir.load %[[V_2]] : !fir.ref<f128>
! CHECK: %[[V_49:[0-9]+]] = fir.load %[[V_4]] : !fir.ref<f128>
! CHECK: %[[V_50:[0-9]+]] = "llvm.intr.is.fpclass"(%[[V_48]]) <{fastmathFlags = #llvm.fastmath<none>, kinds = 3 : i32}> : (f128) -> i1
! CHECK: %[[V_51:[0-9]+]] = "llvm.intr.is.fpclass"(%[[V_49]]) <{fastmathFlags = #llvm.fastmath<none>, kinds = 3 : i32}> : (f128) -> i1
! CHECK: %[[V_50:[0-9]+]] = "llvm.intr.is.fpclass"(%[[V_48]]) <{bit = 3 : i32}> : (f128) -> i1
! CHECK: %[[V_51:[0-9]+]] = "llvm.intr.is.fpclass"(%[[V_49]]) <{bit = 3 : i32}> : (f128) -> i1
! CHECK: %[[V_52:[0-9]+]] = arith.ori %[[V_50]], %[[V_51]] : i1
! CHECK: %[[V_53:[0-9]+]] = fir.convert %[[V_52]] : (i1) -> !fir.logical<4>
! CHECK: %[[V_54:[0-9]+]] = fir.convert %[[V_53]] : (!fir.logical<4>) -> i1
@ -62,8 +62,8 @@ z = ieee_value(z, ieee_quiet_nan)
! CHECK: %[[V_56:[0-9]+]] = fir.load %[[V_3]] : !fir.ref<f128>
! CHECK: %[[V_57:[0-9]+]] = fir.load %[[V_4]] : !fir.ref<f128>
! CHECK: %[[V_58:[0-9]+]] = "llvm.intr.is.fpclass"(%[[V_56]]) <{fastmathFlags = #llvm.fastmath<none>, kinds = 3 : i32}> : (f128) -> i1
! CHECK: %[[V_59:[0-9]+]] = "llvm.intr.is.fpclass"(%[[V_57]]) <{fastmathFlags = #llvm.fastmath<none>, kinds = 3 : i32}> : (f128) -> i1
! CHECK: %[[V_58:[0-9]+]] = "llvm.intr.is.fpclass"(%[[V_56]]) <{bit = 3 : i32}> : (f128) -> i1
! CHECK: %[[V_59:[0-9]+]] = "llvm.intr.is.fpclass"(%[[V_57]]) <{bit = 3 : i32}> : (f128) -> i1
! CHECK: %[[V_60:[0-9]+]] = arith.ori %[[V_58]], %[[V_59]] : i1
! CHECK: %[[V_61:[0-9]+]] = fir.convert %[[V_60]] : (i1) -> !fir.logical<4>
! CHECK: %[[V_62:[0-9]+]] = fir.convert %[[V_61]] : (!fir.logical<4>) -> i1

View File

@ -5,7 +5,7 @@
subroutine isnan_f32(r)
real :: r
i = isnan(r)
! CHECK: %[[l:.*]] = "llvm.intr.is.fpclass"(%{{.*}}) <{fastmathFlags = #llvm.fastmath<none>, kinds = 3 : i32}> : (f32) -> i1
! CHECK: %[[l:.*]] = "llvm.intr.is.fpclass"(%{{.*}}) <{bit = 3 : i32}> : (f32) -> i1
! CHECK: fir.convert %[[l]] : (i1) -> !fir.logical<4>
end subroutine isnan_f32
@ -14,7 +14,7 @@ subroutine ieee_is_nan_f32(r)
use ieee_arithmetic
real :: r
i = ieee_is_nan(r)
! CHECK: %[[l:.*]] = "llvm.intr.is.fpclass"(%{{.*}}) <{fastmathFlags = #llvm.fastmath<none>, kinds = 3 : i32}> : (f32) -> i1
! CHECK: %[[l:.*]] = "llvm.intr.is.fpclass"(%{{.*}}) <{bit = 3 : i32}> : (f32) -> i1
! CHECK: fir.convert %[[l]] : (i1) -> !fir.logical<4>
end subroutine ieee_is_nan_f32
@ -22,7 +22,7 @@ end subroutine ieee_is_nan_f32
subroutine isnan_f64(r)
real(KIND=8) :: r
i = isnan(r)
! CHECK: %[[l:.*]] = "llvm.intr.is.fpclass"(%{{.*}}) <{fastmathFlags = #llvm.fastmath<none>, kinds = 3 : i32}> : (f64) -> i1
! CHECK: %[[l:.*]] = "llvm.intr.is.fpclass"(%{{.*}}) <{bit = 3 : i32}> : (f64) -> i1
! CHECK: fir.convert %[[l]] : (i1) -> !fir.logical<4>
end subroutine isnan_f64
@ -31,7 +31,7 @@ subroutine ieee_is_nan_f64(r)
use ieee_arithmetic
real(KIND=8) :: r
i = ieee_is_nan(r)
! CHECK: %[[l:.*]] = "llvm.intr.is.fpclass"(%{{.*}}) <{fastmathFlags = #llvm.fastmath<none>, kinds = 3 : i32}> : (f64) -> i1
! CHECK: %[[l:.*]] = "llvm.intr.is.fpclass"(%{{.*}}) <{bit = 3 : i32}> : (f64) -> i1
! CHECK: fir.convert %[[l]] : (i1) -> !fir.logical<4>
end subroutine ieee_is_nan_f64
@ -39,7 +39,7 @@ end subroutine ieee_is_nan_f64
subroutine isnan_f80(r)
real(KIND=10) :: r
i = isnan(r)
! CHECK: %[[l:.*]] = "llvm.intr.is.fpclass"(%{{.*}}) <{fastmathFlags = #llvm.fastmath<none>, kinds = 3 : i32}> : (f80) -> i1
! CHECK: %[[l:.*]] = "llvm.intr.is.fpclass"(%{{.*}}) <{bit = 3 : i32}> : (f80) -> i1
! CHECK: fir.convert %[[l]] : (i1) -> !fir.logical<4>
end subroutine isnan_f80
@ -48,7 +48,7 @@ subroutine ieee_is_nan_f80(r)
use ieee_arithmetic
real(KIND=10) :: r
i = ieee_is_nan(r)
! CHECK: %[[l:.*]] = "llvm.intr.is.fpclass"(%{{.*}}) <{fastmathFlags = #llvm.fastmath<none>, kinds = 3 : i32}> : (f80) -> i1
! CHECK: %[[l:.*]] = "llvm.intr.is.fpclass"(%{{.*}}) <{bit = 3 : i32}> : (f80) -> i1
! CHECK: fir.convert %[[l]] : (i1) -> !fir.logical<4>
end subroutine ieee_is_nan_f80
@ -56,7 +56,7 @@ end subroutine ieee_is_nan_f80
subroutine isnan_f128(r)
real(KIND=16) :: r
i = isnan(r)
! CHECK: %[[l:.*]] = "llvm.intr.is.fpclass"(%{{.*}}) <{fastmathFlags = #llvm.fastmath<none>, kinds = 3 : i32}> : (f128) -> i1
! CHECK: %[[l:.*]] = "llvm.intr.is.fpclass"(%{{.*}}) <{bit = 3 : i32}> : (f128) -> i1
! CHECK: fir.convert %[[l]] : (i1) -> !fir.logical<4>
end subroutine isnan_f128
@ -65,6 +65,6 @@ subroutine ieee_is_nan_f128(r)
use ieee_arithmetic
real(KIND=16) :: r
i = ieee_is_nan(r)
! CHECK: %[[l:.*]] = "llvm.intr.is.fpclass"(%{{.*}}) <{fastmathFlags = #llvm.fastmath<none>, kinds = 3 : i32}> : (f128) -> i1
! CHECK: %[[l:.*]] = "llvm.intr.is.fpclass"(%{{.*}}) <{bit = 3 : i32}> : (f128) -> i1
! CHECK: fir.convert %[[l]] : (i1) -> !fir.logical<4>
end subroutine ieee_is_nan_f128

View File

@ -49,29 +49,9 @@ public:
ArrayRef<NamedAttribute> getAttrs() const { return convertedAttr.getAttrs(); }
protected:
private:
NamedAttrList convertedAttr;
};
/// Wrapper around AttrConvertFastMathToLLVM that also sets the "kinds"
/// attribute to the bitmask specified in `Kinds`, which is used for converting
/// operations that lower to llvm.is.fpclass.
template <unsigned Kinds, typename SourceOp, typename TargetOp>
class AttrConvertAddFpclassKinds
: public AttrConvertFastMathToLLVM<SourceOp, TargetOp> {
public:
AttrConvertAddFpclassKinds(SourceOp op)
: AttrConvertFastMathToLLVM<SourceOp, TargetOp>(op) {
convertedAttr.set(
"kinds",
IntegerAttr::get(IntegerType::get(op.getContext(), 32), Kinds));
}
ArrayRef<NamedAttribute> getAttrs() const { return convertedAttr.getAttrs(); }
protected:
using AttrConvertFastMathToLLVM<SourceOp, TargetOp>::convertedAttr;
};
} // namespace arith
} // namespace mlir

View File

@ -83,20 +83,6 @@ class Arith_FloatBinaryOp<string mnemonic, list<Trait> traits = []> :
attr-dict `:` type($result) }];
}
// Base class for floating point unary predicate operations.
class Arith_FloatPredicateOp<string mnemonic, list<Trait> traits = []> :
Arith_Op<mnemonic,
!listconcat([DeclareOpInterfaceMethods<ArithFastMathInterface>, Pure,
TypesMatchWith<"result type has i1 element type and same shape as operands",
"operand", "result", "::getI1SameShape($_self)">], traits)>,
Arguments<(ins FloatLike:$operand,
DefaultValuedAttr<
Arith_FastMathAttr, "::mlir::arith::FastMathFlags::none">:$fastmath)>,
Results<(outs BoolLike:$result)> {
let assemblyFormat = [{ $operand (`fastmath` `` $fastmath^)?
attr-dict `:` type($operand) }];
}
// Base class for arithmetic cast operations. Requires a single operand and
// result. If either is a shaped type, then the other must be of the same shape.
class Arith_CastOp<string mnemonic, TypeConstraint From, TypeConstraint To,
@ -985,22 +971,6 @@ def Arith_RemFOp : Arith_FloatBinaryOp<"remf"> {
let hasFolder = 1;
}
//===----------------------------------------------------------------------===//
// IsNanOp
//===----------------------------------------------------------------------===//
def Arith_IsNanOp : Arith_FloatPredicateOp<"is_nan"> {
let summary = "Returns true for IEEE NaN inputs";
let hasFolder = 1;
}
//===----------------------------------------------------------------------===//
// IsInfOp
//===----------------------------------------------------------------------===//
def Arith_IsInfOp : Arith_FloatPredicateOp<"is_inf"> {
let summary = "Returns true for infinite float inputs";
let hasFolder = 1;
}
//===----------------------------------------------------------------------===//
// ExtUIOp
//===----------------------------------------------------------------------===//

View File

@ -120,21 +120,17 @@ def LLVM_AbsOp : LLVM_OneResultIntrOp<"abs", [], [0], [Pure]> {
}];
}
def LLVM_IsFPClass : LLVM_OneResultIntrOp<"is.fpclass", [], [0], [Pure],
/*requiresFastmath=*/1> {
let arguments = (ins LLVM_ScalarOrVectorOf<LLVM_AnyFloat>:$in,
I32Attr:$kinds,
DefaultValuedAttr<LLVM_FastmathFlagsAttr, "{}">:$fastmathFlags);
def LLVM_IsFPClass : LLVM_OneResultIntrOp<"is.fpclass", [], [0], [Pure]> {
let arguments = (ins LLVM_ScalarOrVectorOf<LLVM_AnyFloat>:$in, I32Attr:$bit);
string mlirBuilder = [{
auto op = $_builder.create<$_qualCppClassName>($_location,
$_resultType, $in, $_int_attr($kinds), nullptr);
moduleImport.setFastmathFlagsAttr(inst, op);
$res = op;
$_resultType, $in, $_int_attr($bit));
$res = op;
}];
string llvmBuilder = [{
auto *inst = createIntrinsicCall(
builder, llvm::Intrinsic::}] # llvmEnumName # [{,
{$in, builder.getInt32(op.getKinds())},
{$in, builder.getInt32(op.getBit())},
}] # declTypes # [{);
$res = inst;
}];

View File

@ -54,18 +54,6 @@ using FPToSIOpLowering =
VectorConvertToLLVMPattern<arith::FPToSIOp, LLVM::FPToSIOp>;
using FPToUIOpLowering =
VectorConvertToLLVMPattern<arith::FPToUIOp, LLVM::FPToUIOp>;
template <typename SourceOp, typename TargetOp>
// FPClass bitmask for -inf (bit 2) and +inf (bit 9).
using InfKinds =
arith::AttrConvertAddFpclassKinds<(1 << 2) | (1 << 9), SourceOp, TargetOp>;
using IsInfLowering =
VectorConvertToLLVMPattern<arith::IsInfOp, LLVM::IsFPClass, InfKinds>;
// FPClass bitmask for signalling NaN (bit 0) or quiet NaN (bit 1).
template <typename SourceOp, typename TargetOp>
using NanKinds =
arith::AttrConvertAddFpclassKinds<(1 << 0) | (1 << 1), SourceOp, TargetOp>;
using IsNanLowering =
VectorConvertToLLVMPattern<arith::IsNanOp, LLVM::IsFPClass, NanKinds>;
using MaxFOpLowering =
VectorConvertToLLVMPattern<arith::MaxFOp, LLVM::MaxNumOp,
arith::AttrConvertFastMathToLLVM>;
@ -507,8 +495,6 @@ void mlir::arith::populateArithToLLVMConversionPatterns(
FPToUIOpLowering,
IndexCastOpSILowering,
IndexCastOpUILowering,
IsInfLowering,
IsNanLowering,
MaxFOpLowering,
MaxSIOpLowering,
MaxUIOpLowering,

View File

@ -1094,8 +1094,6 @@ void mlir::arith::populateArithToSPIRVPatterns(
spirv::ElementwiseOpPattern<arith::MulFOp, spirv::FMulOp>,
spirv::ElementwiseOpPattern<arith::DivFOp, spirv::FDivOp>,
spirv::ElementwiseOpPattern<arith::RemFOp, spirv::FRemOp>,
spirv::ElementwiseOpPattern<arith::IsNanOp, spirv::IsNanOp>,
spirv::ElementwiseOpPattern<arith::IsInfOp, spirv::IsInfOp>,
TypeCastingOpPattern<arith::ExtUIOp, spirv::UConvertOp>, ExtUII1Pattern,
TypeCastingOpPattern<arith::ExtSIOp, spirv::SConvertOp>, ExtSII1Pattern,
TypeCastingOpPattern<arith::ExtFOp, spirv::FConvertOp>,

View File

@ -1109,42 +1109,6 @@ OpFoldResult arith::RemFOp::fold(FoldAdaptor adaptor) {
});
}
static Attribute getBoolAttribute(Type type, MLIRContext *ctx, bool value) {
auto boolAttr = BoolAttr::get(ctx, value);
ShapedType shapedType = llvm::dyn_cast_or_null<ShapedType>(type);
if (!shapedType)
return boolAttr;
return DenseElementsAttr::get(shapedType, boolAttr);
}
//===----------------------------------------------------------------------===//
// IsNanOp
//===----------------------------------------------------------------------===//
OpFoldResult IsNanOp::fold(FoldAdaptor adaptor) {
if (bitEnumContainsAll(getFastmath(), FastMathFlags::nnan))
return getBoolAttribute(getType(), getContext(), false);
return constFoldCastOp<FloatAttr, IntegerAttr>(
adaptor.getOperands(), getType(),
[](const APFloat &x, bool &success) -> APInt {
success = true;
return APInt(1, x.isNaN());
});
}
//===----------------------------------------------------------------------===//
// IsInfOp
//===----------------------------------------------------------------------===//
OpFoldResult IsInfOp::fold(FoldAdaptor adaptor) {
if (bitEnumContainsAll(getFastmath(), FastMathFlags::ninf))
return getBoolAttribute(getType(), getContext(), false);
return constFoldCastOp<FloatAttr, IntegerAttr>(
adaptor.getOperands(), getType(),
[](const APFloat &x, bool &success) -> APInt {
success = true;
return APInt(1, x.isInfinity());
});
}
//===----------------------------------------------------------------------===//
// Utility functions for verifying cast ops
//===----------------------------------------------------------------------===//
@ -1695,6 +1659,14 @@ static bool applyCmpPredicateToEqualOperands(arith::CmpIPredicate predicate) {
llvm_unreachable("unknown cmpi predicate kind");
}
static Attribute getBoolAttribute(Type type, MLIRContext *ctx, bool value) {
auto boolAttr = BoolAttr::get(ctx, value);
ShapedType shapedType = llvm::dyn_cast_or_null<ShapedType>(type);
if (!shapedType)
return boolAttr;
return DenseElementsAttr::get(shapedType, boolAttr);
}
static std::optional<int64_t> getIntegerWidth(Type t) {
if (auto intType = llvm::dyn_cast<IntegerType>(t)) {
return intType.getWidth();

View File

@ -179,7 +179,8 @@ public:
Value select = rewriter.create<arith::SelectOp>(loc, cmp, lhs, rhs);
// Handle the case where rhs is NaN: 'isNaN(rhs) ? rhs : select'.
Value isNaN = rewriter.create<arith::IsNanOp>(loc, rhs, op.getFastmath());
Value isNaN = rewriter.create<arith::CmpFOp>(loc, arith::CmpFPredicate::UNO,
rhs, rhs);
rewriter.replaceOpWithNewOp<arith::SelectOp>(op, isNaN, rhs, select);
return success();
}

View File

@ -75,28 +75,6 @@ func.func @ops(f32, f32, i32, i32, f64) -> (f32, i32) {
return %0, %4 : f32, i32
}
// CHECK-LABEL: @float_pred_ops
func.func @float_pred_ops(%arg0: f32) {
// CHECK: "llvm.intr.is.fpclass"(%{{.*}}) <{fastmathFlags = #llvm.fastmath<none>, kinds = 516 : i32}> : (f32) -> i1
arith.is_inf %arg0 : f32
// CHECK-NEXT: "llvm.intr.is.fpclass"(%{{.*}}) <{fastmathFlags = #llvm.fastmath<nnan>, kinds = 516 : i32}> : (f32) -> i1
arith.is_inf %arg0 fastmath <nnan> : f32
// CHECK-NEXT: "llvm.intr.is.fpclass"(%{{.*}}) <{fastmathFlags = #llvm.fastmath<none>, kinds = 3 : i32}> : (f32) -> i1
arith.is_nan %arg0 : f32
// CHECK-NEXT: "llvm.intr.is.fpclass"(%{{.*}}) <{fastmathFlags = #llvm.fastmath<ninf>, kinds = 3 : i32}> : (f32) -> i1
arith.is_nan %arg0 fastmath <ninf> : f32
return
}
// CHECK-LABEL: @vector_float_pred_ops
func.func @vector_float_pred_ops(%arg0: vector<4xf32>) {
// CHECK: "llvm.intr.is.fpclass"(%{{.*}}) <{fastmathFlags = #llvm.fastmath<none>, kinds = 516 : i32}> : (vector<4xf32>) -> vector<4xi1>
arith.is_inf %arg0 : vector<4xf32>
// CHECK: "llvm.intr.is.fpclass"(%{{.*}}) <{fastmathFlags = #llvm.fastmath<none>, kinds = 3 : i32}> : (vector<4xf32>) -> vector<4xi1>
arith.is_nan %arg0 : vector<4xf32>
return
}
// Checking conversion of index types to integers using i1, assuming no target
// system would have a 1-bit address space. Otherwise, we would have had to
// make this test dependent on the pointer size on the target system.

View File

@ -169,16 +169,6 @@ func.func @float32_binary_scalar(%lhs: f32, %rhs: f32) {
return
}
// Check float predicate operation conversions
// CHECK-LABEL: @float32_predicate_scalar
func.func @float32_predicate_scalar(%arg0 : f32) {
// CHECK: spirv.IsNan %{{.*}}: f32
%0 = arith.is_nan %arg0 : f32
// CHECK: spirv.IsInf %{{.*}}: f32
%1 = arith.is_inf %arg0 : f32
return
}
// Check int vector types.
// CHECK-LABEL: @int_vector234
func.func @int_vector234(%arg0: vector<2xi8>, %arg1: vector<4xi64>) {

View File

@ -2567,78 +2567,3 @@ func.func @foldOrXor6(%arg0: index) -> index {
%2 = arith.ori %arg0, %1 : index
return %2 : index
}
// -----
// CHECK-LABEL: @foldIsNanFastmath
// CHECK-SAME: (%[[ARG:.+]]: f32)
// CHECK: %[[FALSE:.+]] = arith.constant false
// CHECK: return %[[FALSE]]
func.func @foldIsNanFastmath(%arg0: f32) -> i1 {
%0 = arith.is_nan %arg0 fastmath <nnan> : f32
func.return %0 : i1
}
// CHECK-LABEL: @foldIsNan
// CHECK: %[[TRUE:.+]] = arith.constant true
// CHECK: return %[[TRUE]]
func.func @foldIsNan() -> i1 {
%cNan = arith.constant 0x7FFFFFFF : f32
%0 = arith.is_nan %cNan : f32
func.return %0 : i1
}
// CHECK-LABEL: @foldNanIsNotNanWithFastmath
// CHECK: %[[FALSE:.+]] = arith.constant false
// CHECK: return %[[FALSE]]
func.func @foldNanIsNotNanWithFastmath() -> i1 {
%cNan = arith.constant 0x7FFFFFFF : f32
%0 = arith.is_nan %cNan fastmath<nnan> : f32
func.return %0 : i1
}
// CHECK-LABEL: @foldIsNotNan
// CHECK: %[[FALSE:.+]] = arith.constant false
// CHECK: return %[[FALSE]]
func.func @foldIsNotNan() -> i1 {
%cNan = arith.constant 1.0 : f32
%0 = arith.is_nan %cNan : f32
func.return %0 : i1
}
// CHECK-LABEL: @foldIsInfFastmath
// CHECK: %[[FALSE:.+]] = arith.constant false
// CHECK: return %[[FALSE]]
func.func @foldIsInfFastmath(%arg0: f32) -> i1 {
%0 = arith.is_inf %arg0 fastmath <ninf> : f32
func.return %0 : i1
}
// CHECK-LABEL: @foldIsInf
// CHECK: %[[TRUE:.+]] = arith.constant true
// CHECK: return %[[TRUE]]
func.func @foldIsInf() -> i1 {
%cInf = arith.constant 0x7F800000 : f32
%0 = arith.is_inf %cInf : f32
func.return %0 : i1
}
// CHECK-LABEL: @foldInfIsNotInfWithFastmath
// CHECK: %[[FALSE:.+]] = arith.constant false
// CHECK: return %[[FALSE]]
func.func @foldInfIsNotInfWithFastmath() -> i1 {
%cInf = arith.constant 0x7F800000 : f32
%0 = arith.is_inf %cInf fastmath<ninf> : f32
func.return %0 : i1
}
// CHECK-LABEL: @foldIsNotInf
// CHECK: %[[FALSE:.+]] = arith.constant false
// CHECK: return %[[FALSE]]
func.func @foldIsNotInf() -> i1 {
%cInf = arith.constant 1.0 : f32
%0 = arith.is_inf %cInf : f32
func.return %0 : i1
}

View File

@ -184,7 +184,7 @@ func.func @maxf(%a: f32, %b: f32) -> f32 {
// CHECK-SAME: %[[LHS:.*]]: f32, %[[RHS:.*]]: f32)
// CHECK-NEXT: %[[CMP:.*]] = arith.cmpf ugt, %[[LHS]], %[[RHS]] : f32
// CHECK-NEXT: %[[SELECT:.*]] = arith.select %[[CMP]], %[[LHS]], %[[RHS]] : f32
// CHECK-NEXT: %[[IS_NAN:.*]] = arith.is_nan %[[RHS]] : f32
// CHECK-NEXT: %[[IS_NAN:.*]] = arith.cmpf uno, %[[RHS]], %[[RHS]] : f32
// CHECK-NEXT: %[[RESULT:.*]] = arith.select %[[IS_NAN]], %[[RHS]], %[[SELECT]] : f32
// CHECK-NEXT: return %[[RESULT]] : f32
@ -198,7 +198,7 @@ func.func @maxf_vector(%a: vector<4xf16>, %b: vector<4xf16>) -> vector<4xf16> {
// CHECK-SAME: %[[LHS:.*]]: vector<4xf16>, %[[RHS:.*]]: vector<4xf16>)
// CHECK-NEXT: %[[CMP:.*]] = arith.cmpf ugt, %[[LHS]], %[[RHS]] : vector<4xf16>
// CHECK-NEXT: %[[SELECT:.*]] = arith.select %[[CMP]], %[[LHS]], %[[RHS]]
// CHECK-NEXT: %[[IS_NAN:.*]] = arith.is_nan %[[RHS]] : vector<4xf16>
// CHECK-NEXT: %[[IS_NAN:.*]] = arith.cmpf uno, %[[RHS]], %[[RHS]] : vector<4xf16>
// CHECK-NEXT: %[[RESULT:.*]] = arith.select %[[IS_NAN]], %[[RHS]], %[[SELECT]]
// CHECK-NEXT: return %[[RESULT]] : vector<4xf16>
@ -213,7 +213,7 @@ func.func @minf(%a: f32, %b: f32) -> f32 {
// CHECK-SAME: %[[LHS:.*]]: f32, %[[RHS:.*]]: f32)
// CHECK-NEXT: %[[CMP:.*]] = arith.cmpf ult, %[[LHS]], %[[RHS]] : f32
// CHECK-NEXT: %[[SELECT:.*]] = arith.select %[[CMP]], %[[LHS]], %[[RHS]] : f32
// CHECK-NEXT: %[[IS_NAN:.*]] = arith.is_nan %[[RHS]] : f32
// CHECK-NEXT: %[[IS_NAN:.*]] = arith.cmpf uno, %[[RHS]], %[[RHS]] : f32
// CHECK-NEXT: %[[RESULT:.*]] = arith.select %[[IS_NAN]], %[[RHS]], %[[SELECT]] : f32
// CHECK-NEXT: return %[[RESULT]] : f32

View File

@ -577,30 +577,6 @@ func.func @test_remf_scalable_vector(%arg0 : vector<[8]xf64>, %arg1 : vector<[8]
return %0 : vector<[8]xf64>
}
// CHECK-LABEL: test_is_nan
func.func @test_is_nan(%arg0 : f32) -> i1 {
%0 = arith.is_nan %arg0 : f32
func.return %0 : i1
}
// CHECK-LABEL: test_is_nan_vector
func.func @test_is_nan_vector(%arg0 : vector<2x2xf32>) -> vector<2x2xi1> {
%0 = arith.is_nan %arg0 : vector<2x2xf32>
func.return %0 : vector<2x2xi1>
}
// CHECK-LABEL: test_is_inf
func.func @test_is_inf(%arg0 : f32) -> i1 {
%0 = arith.is_inf %arg0 : f32
func.return %0 : i1
}
// CHECK-LABEL: test_is_inf_vector
func.func @test_is_inf_vector(%arg0 : vector<2x2xf32>) -> vector<2x2xi1> {
%0 = arith.is_inf %arg0 : vector<2x2xf32>
func.return %0 : vector<2x2xi1>
}
// CHECK-LABEL: test_extui
func.func @test_extui(%arg0 : i32) -> i64 {
%0 = arith.extui %arg0 : i32 to i64

View File

@ -17,9 +17,9 @@ define void @fmuladd_test(float %0, float %1, <8 x float> %2, ptr %3) {
; CHECK-LABEL: llvm.func @fpclass_test
define void @fpclass_test(float %0, <8 x float> %1) {
; CHECK: "llvm.intr.is.fpclass"(%{{.*}}) <{fastmathFlags = #llvm.fastmath<none>, kinds = 0 : i32}> : (f32) -> i1
; CHECK: "llvm.intr.is.fpclass"(%{{.*}}) <{bit = 0 : i32}> : (f32) -> i1
%3 = call i1 @llvm.is.fpclass.f32(float %0, i32 0)
; CHECK: "llvm.intr.is.fpclass"(%{{.*}}) <{fastmathFlags = #llvm.fastmath<none>, kinds = 1 : i32}> : (vector<8xf32>) -> vector<8xi1>
; CHECK: "llvm.intr.is.fpclass"(%{{.*}}) <{bit = 1 : i32}> : (vector<8xf32>) -> vector<8xi1>
%4 = call <8 x i1> @llvm.is.fpclass.v8f32(<8 x float> %1, i32 1)
ret void
}

View File

@ -18,7 +18,7 @@ llvm.func @intrinsics(%arg0: f32, %arg1: f32, %arg2: vector<8xf32>, %arg3: !llvm
// CHECK-LABEL: @fpclass_test
llvm.func @fpclass_test(%arg0: f32) -> i1 {
// CHECK: call i1 @llvm.is.fpclass
%0 = "llvm.intr.is.fpclass"(%arg0) <{fastmathFlags = #llvm.fastmath<nnan>, kinds = 3 : i32 }>: (f32) -> i1
%0 = "llvm.intr.is.fpclass"(%arg0) <{bit = 0 : i32 }>: (f32) -> i1
llvm.return %0 : i1
}