[flang-commits] [flang] 7c349c3 - [mlir][Arith] Add arith.is_nan and arith.is_inf predicates
Krzysztof Drewniak via flang-commits
flang-commits at lists.llvm.org
Wed Aug 2 07:42:31 PDT 2023
Author: Krzysztof Drewniak
Date: 2023-08-02T14:42:25Z
New Revision: 7c349c369847dc2f1736efb9c90d03521cd44a90
URL: https://github.com/llvm/llvm-project/commit/7c349c369847dc2f1736efb9c90d03521cd44a90
DIFF: https://github.com/llvm/llvm-project/commit/7c349c369847dc2f1736efb9c90d03521cd44a90.diff
LOG: [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
Added:
Modified:
flang/test/Lower/Intrinsics/ieee_class_queries.f90
flang/test/Lower/Intrinsics/ieee_is_finite.f90
flang/test/Lower/Intrinsics/ieee_is_normal.f90
flang/test/Lower/Intrinsics/ieee_unordered.f90
flang/test/Lower/Intrinsics/isnan.f90
mlir/include/mlir/Conversion/ArithCommon/AttrToLLVMConverter.h
mlir/include/mlir/Dialect/Arith/IR/ArithOps.td
mlir/include/mlir/Dialect/LLVMIR/LLVMIntrinsicOps.td
mlir/lib/Conversion/ArithToLLVM/ArithToLLVM.cpp
mlir/lib/Conversion/ArithToSPIRV/ArithToSPIRV.cpp
mlir/lib/Dialect/Arith/IR/ArithOps.cpp
mlir/lib/Dialect/Arith/Transforms/ExpandOps.cpp
mlir/test/Conversion/ArithToLLVM/arith-to-llvm.mlir
mlir/test/Conversion/ArithToSPIRV/arith-to-spirv.mlir
mlir/test/Dialect/Arith/canonicalize.mlir
mlir/test/Dialect/Arith/expand-ops.mlir
mlir/test/Dialect/Arith/ops.mlir
mlir/test/Target/LLVMIR/Import/intrinsic.ll
mlir/test/Target/LLVMIR/llvmir-intrinsics.mlir
Removed:
################################################################################
diff --git a/flang/test/Lower/Intrinsics/ieee_class_queries.f90 b/flang/test/Lower/Intrinsics/ieee_class_queries.f90
index bb7787ea903e23..137ab23e5de37a 100644
--- a/flang/test/Lower/Intrinsics/ieee_class_queries.f90
+++ b/flang/test/Lower/Intrinsics/ieee_class_queries.f90
@@ -10,38 +10,38 @@
real(10) :: x10 = -10.0
real(16) :: x16 = -16.0
- ! 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
+ ! 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
print*, ieee_is_finite(x2), ieee_is_negative(x2), ieee_is_normal(x2), &
ieee_is_nan(x2)
- ! 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
+ ! 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
print*, ieee_is_finite(x3), ieee_is_negative(x3), ieee_is_normal(x3), &
ieee_is_nan(x3)
- ! 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
+ ! 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
print*, ieee_is_finite(x4), ieee_is_negative(x4), ieee_is_normal(x4), &
ieee_is_nan(x4)
- ! 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
+ ! 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
print*, ieee_is_finite(x8), ieee_is_negative(x8), ieee_is_normal(x8), &
ieee_is_nan(x8)
- ! 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
+ ! 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
print*, ieee_is_finite(x16), ieee_is_negative(x16), ieee_is_normal(x16), &
ieee_is_nan(x16)
diff --git a/flang/test/Lower/Intrinsics/ieee_is_finite.f90 b/flang/test/Lower/Intrinsics/ieee_is_finite.f90
index db226c0d0a5ce7..19b5980c0956d2 100644
--- a/flang/test/Lower/Intrinsics/ieee_is_finite.f90
+++ b/flang/test/Lower/Intrinsics/ieee_is_finite.f90
@@ -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]]) <{bit = 504 : i32}> : (f32) -> i1
+ ! CHECK: %[[V_4:[0-9]+]] = "llvm.intr.is.fpclass"(%[[V_3]]) <{fastmathFlags = #llvm.fastmath<none>, kinds = 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]]) <{bit = 504 : i32}> : (f32) -> i1
+ ! CHECK: %[[V_15:[0-9]+]] = "llvm.intr.is.fpclass"(%[[V_14]]) <{fastmathFlags = #llvm.fastmath<none>, kinds = 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]]) <{bit = 504 : i32}> : (f64) -> i1
+ ! CHECK: %[[V_24:[0-9]+]] = "llvm.intr.is.fpclass"(%[[V_23]]) <{fastmathFlags = #llvm.fastmath<none>, kinds = 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]]) <{bit = 504 : i32}> : (f64) -> i1
+ ! CHECK: %[[V_35:[0-9]+]] = "llvm.intr.is.fpclass"(%[[V_34]]) <{fastmathFlags = #llvm.fastmath<none>, kinds = 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
diff --git a/flang/test/Lower/Intrinsics/ieee_is_normal.f90 b/flang/test/Lower/Intrinsics/ieee_is_normal.f90
index f9ab01881d250d..fef5b361448577 100644
--- a/flang/test/Lower/Intrinsics/ieee_is_normal.f90
+++ b/flang/test/Lower/Intrinsics/ieee_is_normal.f90
@@ -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"(%{{.*}}) <{bit = 360 : i32}> : (f16) -> i1
+ ! CHECK: %[[l:.*]] = "llvm.intr.is.fpclass"(%{{.*}}) <{fastmathFlags = #llvm.fastmath<none>, kinds = 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"(%{{.*}}) <{bit = 360 : i32}> : (bf16) -> i1
+ ! CHECK: %[[l:.*]] = "llvm.intr.is.fpclass"(%{{.*}}) <{fastmathFlags = #llvm.fastmath<none>, kinds = 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"(%{{.*}}) <{bit = 360 : i32}> : (f32) -> i1
+ ! CHECK: %[[l:.*]] = "llvm.intr.is.fpclass"(%{{.*}}) <{fastmathFlags = #llvm.fastmath<none>, kinds = 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"(%{{.*}}) <{bit = 360 : i32}> : (f64) -> i1
+ ! CHECK: %[[l:.*]] = "llvm.intr.is.fpclass"(%{{.*}}) <{fastmathFlags = #llvm.fastmath<none>, kinds = 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"(%{{.*}}) <{bit = 360 : i32}> : (f80) -> i1
+ ! CHECK: %[[l:.*]] = "llvm.intr.is.fpclass"(%{{.*}}) <{fastmathFlags = #llvm.fastmath<none>, kinds = 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"(%{{.*}}) <{bit = 360 : i32}> : (f128) -> i1
+ ! CHECK: %[[l:.*]] = "llvm.intr.is.fpclass"(%{{.*}}) <{fastmathFlags = #llvm.fastmath<none>, kinds = 360 : i32}> : (f128) -> i1
! CHECK: fir.convert %[[l]] : (i1) -> !fir.logical<4>
end subroutine ieee_is_normal_f128
diff --git a/flang/test/Lower/Intrinsics/ieee_unordered.f90 b/flang/test/Lower/Intrinsics/ieee_unordered.f90
index 58b827348bfe03..e84738e2356099 100644
--- a/flang/test/Lower/Intrinsics/ieee_unordered.f90
+++ b/flang/test/Lower/Intrinsics/ieee_unordered.f90
@@ -44,8 +44,8 @@
! 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]]) <{bit = 3 : i32}> : (f128) -> i1
-! CHECK: %[[V_43:[0-9]+]] = "llvm.intr.is.fpclass"(%[[V_41]]) <{bit = 3 : i32}> : (f128) -> i1
+! 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_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 @@
! 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]]) <{bit = 3 : i32}> : (f128) -> i1
-! CHECK: %[[V_51:[0-9]+]] = "llvm.intr.is.fpclass"(%[[V_49]]) <{bit = 3 : i32}> : (f128) -> i1
+! 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_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 @@
! 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]]) <{bit = 3 : i32}> : (f128) -> i1
-! CHECK: %[[V_59:[0-9]+]] = "llvm.intr.is.fpclass"(%[[V_57]]) <{bit = 3 : i32}> : (f128) -> i1
+! 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_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
diff --git a/flang/test/Lower/Intrinsics/isnan.f90 b/flang/test/Lower/Intrinsics/isnan.f90
index 700b2d1a67c656..10af98e7aa9186 100644
--- a/flang/test/Lower/Intrinsics/isnan.f90
+++ b/flang/test/Lower/Intrinsics/isnan.f90
@@ -5,7 +5,7 @@
subroutine isnan_f32(r)
real :: r
i = isnan(r)
- ! CHECK: %[[l:.*]] = "llvm.intr.is.fpclass"(%{{.*}}) <{bit = 3 : i32}> : (f32) -> i1
+ ! CHECK: %[[l:.*]] = "llvm.intr.is.fpclass"(%{{.*}}) <{fastmathFlags = #llvm.fastmath<none>, kinds = 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"(%{{.*}}) <{bit = 3 : i32}> : (f32) -> i1
+ ! CHECK: %[[l:.*]] = "llvm.intr.is.fpclass"(%{{.*}}) <{fastmathFlags = #llvm.fastmath<none>, kinds = 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"(%{{.*}}) <{bit = 3 : i32}> : (f64) -> i1
+ ! CHECK: %[[l:.*]] = "llvm.intr.is.fpclass"(%{{.*}}) <{fastmathFlags = #llvm.fastmath<none>, kinds = 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"(%{{.*}}) <{bit = 3 : i32}> : (f64) -> i1
+ ! CHECK: %[[l:.*]] = "llvm.intr.is.fpclass"(%{{.*}}) <{fastmathFlags = #llvm.fastmath<none>, kinds = 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"(%{{.*}}) <{bit = 3 : i32}> : (f80) -> i1
+ ! CHECK: %[[l:.*]] = "llvm.intr.is.fpclass"(%{{.*}}) <{fastmathFlags = #llvm.fastmath<none>, kinds = 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"(%{{.*}}) <{bit = 3 : i32}> : (f80) -> i1
+ ! CHECK: %[[l:.*]] = "llvm.intr.is.fpclass"(%{{.*}}) <{fastmathFlags = #llvm.fastmath<none>, kinds = 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"(%{{.*}}) <{bit = 3 : i32}> : (f128) -> i1
+ ! CHECK: %[[l:.*]] = "llvm.intr.is.fpclass"(%{{.*}}) <{fastmathFlags = #llvm.fastmath<none>, kinds = 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"(%{{.*}}) <{bit = 3 : i32}> : (f128) -> i1
+ ! CHECK: %[[l:.*]] = "llvm.intr.is.fpclass"(%{{.*}}) <{fastmathFlags = #llvm.fastmath<none>, kinds = 3 : i32}> : (f128) -> i1
! CHECK: fir.convert %[[l]] : (i1) -> !fir.logical<4>
end subroutine ieee_is_nan_f128
diff --git a/mlir/include/mlir/Conversion/ArithCommon/AttrToLLVMConverter.h b/mlir/include/mlir/Conversion/ArithCommon/AttrToLLVMConverter.h
index eea16b4da6a690..b924f05e39f7ed 100644
--- a/mlir/include/mlir/Conversion/ArithCommon/AttrToLLVMConverter.h
+++ b/mlir/include/mlir/Conversion/ArithCommon/AttrToLLVMConverter.h
@@ -49,9 +49,29 @@ class AttrConvertFastMathToLLVM {
ArrayRef<NamedAttribute> getAttrs() const { return convertedAttr.getAttrs(); }
-private:
+protected:
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
diff --git a/mlir/include/mlir/Dialect/Arith/IR/ArithOps.td b/mlir/include/mlir/Dialect/Arith/IR/ArithOps.td
index 2ffd49c5034e69..d7d297ce81c185 100644
--- a/mlir/include/mlir/Dialect/Arith/IR/ArithOps.td
+++ b/mlir/include/mlir/Dialect/Arith/IR/ArithOps.td
@@ -83,6 +83,20 @@ 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,
@@ -971,6 +985,22 @@ 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
//===----------------------------------------------------------------------===//
diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMIntrinsicOps.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMIntrinsicOps.td
index 990af1d3d61fe0..88316bedcce8fc 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/LLVMIntrinsicOps.td
+++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMIntrinsicOps.td
@@ -120,17 +120,21 @@ def LLVM_AbsOp : LLVM_OneResultIntrOp<"abs", [], [0], [Pure]> {
}];
}
-def LLVM_IsFPClass : LLVM_OneResultIntrOp<"is.fpclass", [], [0], [Pure]> {
- let arguments = (ins LLVM_ScalarOrVectorOf<LLVM_AnyFloat>:$in, I32Attr:$bit);
+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);
string mlirBuilder = [{
auto op = $_builder.create<$_qualCppClassName>($_location,
- $_resultType, $in, $_int_attr($bit));
- $res = op;
+ $_resultType, $in, $_int_attr($kinds), nullptr);
+ moduleImport.setFastmathFlagsAttr(inst, op);
+ $res = op;
}];
string llvmBuilder = [{
auto *inst = createIntrinsicCall(
builder, llvm::Intrinsic::}] # llvmEnumName # [{,
- {$in, builder.getInt32(op.getBit())},
+ {$in, builder.getInt32(op.getKinds())},
}] # declTypes # [{);
$res = inst;
}];
diff --git a/mlir/lib/Conversion/ArithToLLVM/ArithToLLVM.cpp b/mlir/lib/Conversion/ArithToLLVM/ArithToLLVM.cpp
index 3b4b6452a8ec31..d12fee3552dcf2 100644
--- a/mlir/lib/Conversion/ArithToLLVM/ArithToLLVM.cpp
+++ b/mlir/lib/Conversion/ArithToLLVM/ArithToLLVM.cpp
@@ -53,6 +53,18 @@ 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>;
@@ -465,6 +477,8 @@ void mlir::arith::populateArithToLLVMConversionPatterns(
FPToUIOpLowering,
IndexCastOpSILowering,
IndexCastOpUILowering,
+ IsInfLowering,
+ IsNanLowering,
MaxFOpLowering,
MaxSIOpLowering,
MaxUIOpLowering,
diff --git a/mlir/lib/Conversion/ArithToSPIRV/ArithToSPIRV.cpp b/mlir/lib/Conversion/ArithToSPIRV/ArithToSPIRV.cpp
index f74c7e3490cd80..fe6e9de75c248c 100644
--- a/mlir/lib/Conversion/ArithToSPIRV/ArithToSPIRV.cpp
+++ b/mlir/lib/Conversion/ArithToSPIRV/ArithToSPIRV.cpp
@@ -1094,6 +1094,8 @@ 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>,
diff --git a/mlir/lib/Dialect/Arith/IR/ArithOps.cpp b/mlir/lib/Dialect/Arith/IR/ArithOps.cpp
index eb73787b354778..482198771c3f6a 100644
--- a/mlir/lib/Dialect/Arith/IR/ArithOps.cpp
+++ b/mlir/lib/Dialect/Arith/IR/ArithOps.cpp
@@ -1109,6 +1109,42 @@ 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
//===----------------------------------------------------------------------===//
@@ -1659,14 +1695,6 @@ 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();
diff --git a/mlir/lib/Dialect/Arith/Transforms/ExpandOps.cpp b/mlir/lib/Dialect/Arith/Transforms/ExpandOps.cpp
index 9810d2923da40a..092ff52319a98e 100644
--- a/mlir/lib/Dialect/Arith/Transforms/ExpandOps.cpp
+++ b/mlir/lib/Dialect/Arith/Transforms/ExpandOps.cpp
@@ -179,8 +179,7 @@ struct MaxMinFOpConverter : public OpRewritePattern<OpTy> {
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::CmpFOp>(loc, arith::CmpFPredicate::UNO,
- rhs, rhs);
+ Value isNaN = rewriter.create<arith::IsNanOp>(loc, rhs, op.getFastmath());
rewriter.replaceOpWithNewOp<arith::SelectOp>(op, isNaN, rhs, select);
return success();
}
diff --git a/mlir/test/Conversion/ArithToLLVM/arith-to-llvm.mlir b/mlir/test/Conversion/ArithToLLVM/arith-to-llvm.mlir
index 1788232aee40c8..db9df579820d69 100644
--- a/mlir/test/Conversion/ArithToLLVM/arith-to-llvm.mlir
+++ b/mlir/test/Conversion/ArithToLLVM/arith-to-llvm.mlir
@@ -71,6 +71,28 @@ 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.
diff --git a/mlir/test/Conversion/ArithToSPIRV/arith-to-spirv.mlir b/mlir/test/Conversion/ArithToSPIRV/arith-to-spirv.mlir
index d70df982c366ad..06b5cccd5f41e1 100644
--- a/mlir/test/Conversion/ArithToSPIRV/arith-to-spirv.mlir
+++ b/mlir/test/Conversion/ArithToSPIRV/arith-to-spirv.mlir
@@ -169,6 +169,16 @@ 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>) {
diff --git a/mlir/test/Dialect/Arith/canonicalize.mlir b/mlir/test/Dialect/Arith/canonicalize.mlir
index 5b392fe9cf58a0..b65f8d3b0e01e4 100644
--- a/mlir/test/Dialect/Arith/canonicalize.mlir
+++ b/mlir/test/Dialect/Arith/canonicalize.mlir
@@ -2567,3 +2567,78 @@ 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
+}
diff --git a/mlir/test/Dialect/Arith/expand-ops.mlir b/mlir/test/Dialect/Arith/expand-ops.mlir
index 9f63c941353631..e8d98a0736e8ed 100644
--- a/mlir/test/Dialect/Arith/expand-ops.mlir
+++ b/mlir/test/Dialect/Arith/expand-ops.mlir
@@ -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.cmpf uno, %[[RHS]], %[[RHS]] : f32
+// CHECK-NEXT: %[[IS_NAN:.*]] = arith.is_nan %[[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.cmpf uno, %[[RHS]], %[[RHS]] : vector<4xf16>
+// CHECK-NEXT: %[[IS_NAN:.*]] = arith.is_nan %[[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.cmpf uno, %[[RHS]], %[[RHS]] : f32
+// CHECK-NEXT: %[[IS_NAN:.*]] = arith.is_nan %[[RHS]] : f32
// CHECK-NEXT: %[[RESULT:.*]] = arith.select %[[IS_NAN]], %[[RHS]], %[[SELECT]] : f32
// CHECK-NEXT: return %[[RESULT]] : f32
diff --git a/mlir/test/Dialect/Arith/ops.mlir b/mlir/test/Dialect/Arith/ops.mlir
index faa138a170ddfa..2e3af34169b85e 100644
--- a/mlir/test/Dialect/Arith/ops.mlir
+++ b/mlir/test/Dialect/Arith/ops.mlir
@@ -577,6 +577,30 @@ 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
diff --git a/mlir/test/Target/LLVMIR/Import/intrinsic.ll b/mlir/test/Target/LLVMIR/Import/intrinsic.ll
index 543de93f2f44c0..5ebe98991687a8 100644
--- a/mlir/test/Target/LLVMIR/Import/intrinsic.ll
+++ b/mlir/test/Target/LLVMIR/Import/intrinsic.ll
@@ -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"(%{{.*}}) <{bit = 0 : i32}> : (f32) -> i1
+ ; CHECK: "llvm.intr.is.fpclass"(%{{.*}}) <{fastmathFlags = #llvm.fastmath<none>, kinds = 0 : i32}> : (f32) -> i1
%3 = call i1 @llvm.is.fpclass.f32(float %0, i32 0)
- ; CHECK: "llvm.intr.is.fpclass"(%{{.*}}) <{bit = 1 : i32}> : (vector<8xf32>) -> vector<8xi1>
+ ; CHECK: "llvm.intr.is.fpclass"(%{{.*}}) <{fastmathFlags = #llvm.fastmath<none>, kinds = 1 : i32}> : (vector<8xf32>) -> vector<8xi1>
%4 = call <8 x i1> @llvm.is.fpclass.v8f32(<8 x float> %1, i32 1)
ret void
}
diff --git a/mlir/test/Target/LLVMIR/llvmir-intrinsics.mlir b/mlir/test/Target/LLVMIR/llvmir-intrinsics.mlir
index d666017f6aa248..9dfcacd7dedd38 100644
--- a/mlir/test/Target/LLVMIR/llvmir-intrinsics.mlir
+++ b/mlir/test/Target/LLVMIR/llvmir-intrinsics.mlir
@@ -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) <{bit = 0 : i32 }>: (f32) -> i1
+ %0 = "llvm.intr.is.fpclass"(%arg0) <{fastmathFlags = #llvm.fastmath<nnan>, kinds = 3 : i32 }>: (f32) -> i1
llvm.return %0 : i1
}
More information about the flang-commits
mailing list