[llvm] 0b5c51b - InstCombine: Add some additional is.fpclass tests
Matt Arsenault via llvm-commits
llvm-commits at lists.llvm.org
Wed Feb 8 18:19:34 PST 2023
Author: Matt Arsenault
Date: 2023-02-08T22:19:20-04:00
New Revision: 0b5c51b04050c4542f317c1ebcf850b5c27489fb
URL: https://github.com/llvm/llvm-project/commit/0b5c51b04050c4542f317c1ebcf850b5c27489fb
DIFF: https://github.com/llvm/llvm-project/commit/0b5c51b04050c4542f317c1ebcf850b5c27489fb.diff
LOG: InstCombine: Add some additional is.fpclass tests
Test some more cases related to compare with 0 and inf.
Added:
Modified:
llvm/test/Transforms/InstCombine/combine-is.fpclass-and-fcmp.ll
llvm/test/Transforms/InstCombine/create-class-from-logic-fcmp.ll
llvm/test/Transforms/InstCombine/is_fpclass.ll
Removed:
################################################################################
diff --git a/llvm/test/Transforms/InstCombine/combine-is.fpclass-and-fcmp.ll b/llvm/test/Transforms/InstCombine/combine-is.fpclass-and-fcmp.ll
index 35e0e1396ac9..a4ec83661c66 100644
--- a/llvm/test/Transforms/InstCombine/combine-is.fpclass-and-fcmp.ll
+++ b/llvm/test/Transforms/InstCombine/combine-is.fpclass-and-fcmp.ll
@@ -222,6 +222,58 @@ define i1 @fcmp_oeq_zero_or_class_normal(half %x) {
ret i1 %or
}
+define i1 @fcmp_oeq_zero_or_class_normal_daz(half %x) #1 {
+; CHECK-LABEL: @fcmp_oeq_zero_or_class_normal_daz(
+; CHECK-NEXT: [[OEQ_INF:%.*]] = fcmp oeq half [[X:%.*]], 0xH0000
+; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X]], i32 264)
+; CHECK-NEXT: [[OR:%.*]] = or i1 [[OEQ_INF]], [[CLASS]]
+; CHECK-NEXT: ret i1 [[OR]]
+;
+ %oeq.inf = fcmp oeq half %x, 0.0
+ %class = call i1 @llvm.is.fpclass.f16(half %x, i32 264)
+ %or = or i1 %oeq.inf, %class
+ ret i1 %or
+}
+
+define <2 x i1> @fcmp_oeq_zero_or_class_normal_daz_v2f16(<2 x half> %x) #1 {
+; CHECK-LABEL: @fcmp_oeq_zero_or_class_normal_daz_v2f16(
+; CHECK-NEXT: [[OEQ_INF:%.*]] = fcmp oeq <2 x half> [[X:%.*]], zeroinitializer
+; CHECK-NEXT: [[CLASS:%.*]] = call <2 x i1> @llvm.is.fpclass.v2f16(<2 x half> [[X]], i32 264)
+; CHECK-NEXT: [[OR:%.*]] = or <2 x i1> [[OEQ_INF]], [[CLASS]]
+; CHECK-NEXT: ret <2 x i1> [[OR]]
+;
+ %oeq.inf = fcmp oeq <2 x half> %x, zeroinitializer
+ %class = call <2 x i1> @llvm.is.fpclass.v2f16(<2 x half> %x, i32 264)
+ %or = or <2 x i1> %oeq.inf, %class
+ ret <2 x i1> %or
+}
+
+define i1 @fcmp_oeq_zero_or_class_normal_dynamic(half %x) #2 {
+; CHECK-LABEL: @fcmp_oeq_zero_or_class_normal_dynamic(
+; CHECK-NEXT: [[OEQ_INF:%.*]] = fcmp oeq half [[X:%.*]], 0xH0000
+; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X]], i32 264)
+; CHECK-NEXT: [[OR:%.*]] = or i1 [[OEQ_INF]], [[CLASS]]
+; CHECK-NEXT: ret i1 [[OR]]
+;
+ %oeq.inf = fcmp oeq half %x, 0.0
+ %class = call i1 @llvm.is.fpclass.f16(half %x, i32 264)
+ %or = or i1 %oeq.inf, %class
+ ret i1 %or
+}
+
+define <2 x i1> @fcmp_oeq_zero_or_class_normal_dynamic_v2f16(<2 x half> %x) #2 {
+; CHECK-LABEL: @fcmp_oeq_zero_or_class_normal_dynamic_v2f16(
+; CHECK-NEXT: [[OEQ_INF:%.*]] = fcmp oeq <2 x half> [[X:%.*]], zeroinitializer
+; CHECK-NEXT: [[CLASS:%.*]] = call <2 x i1> @llvm.is.fpclass.v2f16(<2 x half> [[X]], i32 264)
+; CHECK-NEXT: [[OR:%.*]] = or <2 x i1> [[OEQ_INF]], [[CLASS]]
+; CHECK-NEXT: ret <2 x i1> [[OR]]
+;
+ %oeq.inf = fcmp oeq <2 x half> %x, zeroinitializer
+ %class = call <2 x i1> @llvm.is.fpclass.v2f16(<2 x half> %x, i32 264)
+ %or = or <2 x i1> %oeq.inf, %class
+ ret <2 x i1> %or
+}
+
define i1 @class_normal_or_fcmp_oeq_zero(half %x) {
; CHECK-LABEL: @class_normal_or_fcmp_oeq_zero(
; CHECK-NEXT: [[OEQ_INF:%.*]] = fcmp oeq half [[X:%.*]], 0xH0000
@@ -274,6 +326,32 @@ define i1 @fcmp_one_zero_or_class_normal(half %x) {
ret i1 %or
}
+define i1 @fcmp_one_zero_or_class_normal_daz(half %x) #1 {
+; CHECK-LABEL: @fcmp_one_zero_or_class_normal_daz(
+; CHECK-NEXT: [[ONE_INF:%.*]] = fcmp one half [[X:%.*]], 0xH0000
+; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X]], i32 264)
+; CHECK-NEXT: [[OR:%.*]] = or i1 [[ONE_INF]], [[CLASS]]
+; CHECK-NEXT: ret i1 [[OR]]
+;
+ %one.inf = fcmp one half %x, 0.0
+ %class = call i1 @llvm.is.fpclass.f16(half %x, i32 264)
+ %or = or i1 %one.inf, %class
+ ret i1 %or
+}
+
+define i1 @fcmp_one_zero_or_class_normal_dynamic(half %x) #2 {
+; CHECK-LABEL: @fcmp_one_zero_or_class_normal_dynamic(
+; CHECK-NEXT: [[ONE_INF:%.*]] = fcmp one half [[X:%.*]], 0xH0000
+; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X]], i32 264)
+; CHECK-NEXT: [[OR:%.*]] = or i1 [[ONE_INF]], [[CLASS]]
+; CHECK-NEXT: ret i1 [[OR]]
+;
+ %one.inf = fcmp one half %x, 0.0
+ %class = call i1 @llvm.is.fpclass.f16(half %x, i32 264)
+ %or = or i1 %one.inf, %class
+ ret i1 %or
+}
+
define i1 @class_normal_or_fcmp_one_zero(half %x) {
; CHECK-LABEL: @class_normal_or_fcmp_one_zero(
; CHECK-NEXT: [[ONE_INF:%.*]] = fcmp one half [[X:%.*]], 0xH0000
@@ -313,6 +391,32 @@ define i1 @class_normal_or_fcmp_une_zero(half %x) {
ret i1 %or
}
+define i1 @class_normal_or_fcmp_une_zero_daz(half %x) #1 {
+; CHECK-LABEL: @class_normal_or_fcmp_une_zero_daz(
+; CHECK-NEXT: [[UNE_INF:%.*]] = fcmp une half [[X:%.*]], 0xH0000
+; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X]], i32 264)
+; CHECK-NEXT: [[OR:%.*]] = or i1 [[UNE_INF]], [[CLASS]]
+; CHECK-NEXT: ret i1 [[OR]]
+;
+ %une.inf = fcmp une half %x, 0.0
+ %class = call i1 @llvm.is.fpclass.f16(half %x, i32 264)
+ %or = or i1 %une.inf, %class
+ ret i1 %or
+}
+
+define i1 @class_normal_or_fcmp_une_zero_dynamic(half %x) #2 {
+; CHECK-LABEL: @class_normal_or_fcmp_une_zero_dynamic(
+; CHECK-NEXT: [[UNE_INF:%.*]] = fcmp une half [[X:%.*]], 0xH0000
+; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X]], i32 264)
+; CHECK-NEXT: [[OR:%.*]] = or i1 [[UNE_INF]], [[CLASS]]
+; CHECK-NEXT: ret i1 [[OR]]
+;
+ %une.inf = fcmp une half %x, 0.0
+ %class = call i1 @llvm.is.fpclass.f16(half %x, i32 264)
+ %or = or i1 %une.inf, %class
+ ret i1 %or
+}
+
define i1 @fcmp_oeq_inf_xor_class_normal(half %x) {
; CHECK-LABEL: @fcmp_oeq_inf_xor_class_normal(
; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 776)
@@ -343,3 +447,5 @@ declare i1 @llvm.is.fpclass.f16(half, i32 immarg) #0
declare <2 x i1> @llvm.is.fpclass.v2f16(<2 x half>, i32 immarg) #0
attributes #0 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }
+attributes #1 = { "denormal-fp-math"="ieee,preserve-sign" }
+attributes #2 = { "denormal-fp-math"="ieee,dynamic" }
diff --git a/llvm/test/Transforms/InstCombine/create-class-from-logic-fcmp.ll b/llvm/test/Transforms/InstCombine/create-class-from-logic-fcmp.ll
index 15e48ae4185b..0e8fd2fb13ea 100644
--- a/llvm/test/Transforms/InstCombine/create-class-from-logic-fcmp.ll
+++ b/llvm/test/Transforms/InstCombine/create-class-from-logic-fcmp.ll
@@ -2049,8 +2049,146 @@ define i1 @fabs_ueq_neginfinity_or_fabs_uge_smallest_normal(half %x) #0 {
ret i1 %class
}
+; --------------------------------------------------------------------
+; Test denormal mode handling with x == 0
+; --------------------------------------------------------------------
+
+; Base pattern !isfinite(x) || x == 0.0, with input denormals flushed to 0
+define i1 @not_isfinite_or_zero_f16_daz(half %x) #1 {
+; CHECK-LABEL: @not_isfinite_or_zero_f16_daz(
+; CHECK-NEXT: [[FABS:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
+; CHECK-NEXT: [[CMPINF:%.*]] = fcmp ueq half [[FABS]], 0xH7C00
+; CHECK-NEXT: [[CMPZERO:%.*]] = fcmp oeq half [[X]], 0xH0000
+; CHECK-NEXT: [[CLASS:%.*]] = or i1 [[CMPZERO]], [[CMPINF]]
+; CHECK-NEXT: ret i1 [[CLASS]]
+;
+ %fabs = call half @llvm.fabs.f16(half %x)
+ %cmpinf = fcmp ueq half %fabs, 0xH7C00
+ %cmpzero = fcmp oeq half %x, 0xH0000
+ %class = or i1 %cmpzero, %cmpinf
+ ret i1 %class
+}
+
+define <2 x i1> @not_isfinite_or_zero_v2f16_daz(<2 x half> %x) #1 {
+; CHECK-LABEL: @not_isfinite_or_zero_v2f16_daz(
+; CHECK-NEXT: [[FABS:%.*]] = call <2 x half> @llvm.fabs.v2f16(<2 x half> [[X:%.*]])
+; CHECK-NEXT: [[CMPINF:%.*]] = fcmp ueq <2 x half> [[FABS]], <half 0xH7C00, half 0xH7C00>
+; CHECK-NEXT: [[CMPZERO:%.*]] = fcmp oeq <2 x half> [[X]], zeroinitializer
+; CHECK-NEXT: [[CLASS:%.*]] = or <2 x i1> [[CMPZERO]], [[CMPINF]]
+; CHECK-NEXT: ret <2 x i1> [[CLASS]]
+;
+ %fabs = call <2 x half> @llvm.fabs.v2f16(<2 x half> %x)
+ %cmpinf = fcmp ueq <2 x half> %fabs, <half 0xH7C00, half 0xH7C00>
+ %cmpzero = fcmp oeq <2 x half> %x, zeroinitializer
+ %class = or <2 x i1> %cmpzero, %cmpinf
+ ret <2 x i1> %class
+}
+
+; Base pattern !isfinite(x) || x == 0.0, with unknown input denormal treatment
+define i1 @not_isfinite_or_zero_f16_dynamic(half %x) #2 {
+; CHECK-LABEL: @not_isfinite_or_zero_f16_dynamic(
+; CHECK-NEXT: [[FABS:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
+; CHECK-NEXT: [[CMPINF:%.*]] = fcmp ueq half [[FABS]], 0xH7C00
+; CHECK-NEXT: [[CMPZERO:%.*]] = fcmp oeq half [[X]], 0xH0000
+; CHECK-NEXT: [[CLASS:%.*]] = or i1 [[CMPZERO]], [[CMPINF]]
+; CHECK-NEXT: ret i1 [[CLASS]]
+;
+ %fabs = call half @llvm.fabs.f16(half %x)
+ %cmpinf = fcmp ueq half %fabs, 0xH7C00
+ %cmpzero = fcmp oeq half %x, 0xH0000
+ %class = or i1 %cmpzero, %cmpinf
+ ret i1 %class
+}
+
+define <2 x i1> @not_isfinite_or_zero_v2f16_dynamic(<2 x half> %x) #2 {
+; CHECK-LABEL: @not_isfinite_or_zero_v2f16_dynamic(
+; CHECK-NEXT: [[FABS:%.*]] = call <2 x half> @llvm.fabs.v2f16(<2 x half> [[X:%.*]])
+; CHECK-NEXT: [[CMPINF:%.*]] = fcmp ueq <2 x half> [[FABS]], <half 0xH7C00, half 0xH7C00>
+; CHECK-NEXT: [[CMPZERO:%.*]] = fcmp oeq <2 x half> [[X]], zeroinitializer
+; CHECK-NEXT: [[CLASS:%.*]] = or <2 x i1> [[CMPZERO]], [[CMPINF]]
+; CHECK-NEXT: ret <2 x i1> [[CLASS]]
+;
+ %fabs = call <2 x half> @llvm.fabs.v2f16(<2 x half> %x)
+ %cmpinf = fcmp ueq <2 x half> %fabs, <half 0xH7C00, half 0xH7C00>
+ %cmpzero = fcmp oeq <2 x half> %x, zeroinitializer
+ %class = or <2 x i1> %cmpzero, %cmpinf
+ ret <2 x i1> %class
+}
+
+define i1 @not_zero_and_subnormal_daz(half %x) #1 {
+; CHECK-LABEL: @not_zero_and_subnormal_daz(
+; CHECK-NEXT: [[OR:%.*]] = fcmp ord half [[X:%.*]], 0xH0000
+; CHECK-NEXT: ret i1 [[OR]]
+;
+ %fabs = call half @llvm.fabs.f16(half %x)
+ %cmp.zero = fcmp one half %fabs, 0.0
+ %cmp.smallest.normal = fcmp olt half %fabs, 0xH0400
+ %or = or i1 %cmp.smallest.normal, %cmp.zero
+ ret i1 %or
+}
+
+define i1 @not_zero_and_subnormal_dynamic(half %x) #2 {
+; CHECK-LABEL: @not_zero_and_subnormal_dynamic(
+; CHECK-NEXT: [[FABS:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
+; CHECK-NEXT: [[CMP_ZERO:%.*]] = fcmp one half [[X]], 0xH0000
+; CHECK-NEXT: [[CMP_SMALLEST_NORMAL:%.*]] = fcmp olt half [[FABS]], 0xH0400
+; CHECK-NEXT: [[OR:%.*]] = or i1 [[CMP_SMALLEST_NORMAL]], [[CMP_ZERO]]
+; CHECK-NEXT: ret i1 [[OR]]
+;
+ %fabs = call half @llvm.fabs.f16(half %x)
+ %cmp.zero = fcmp one half %fabs, 0.0
+ %cmp.smallest.normal = fcmp olt half %fabs, 0xH0400
+ %or = or i1 %cmp.smallest.normal, %cmp.zero
+ ret i1 %or
+}
+
+; TODO: This could fold to just fcmp olt half %fabs, 0xH0400
+define i1 @subnormal_or_zero_ieee(half %x) #0 {
+; CHECK-LABEL: @subnormal_or_zero_ieee(
+; CHECK-NEXT: [[FABS:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
+; CHECK-NEXT: [[IS_SUBNORMAL:%.*]] = fcmp olt half [[FABS]], 0xH0400
+; CHECK-NEXT: [[IS_ZERO:%.*]] = fcmp oeq half [[X]], 0xH0000
+; CHECK-NEXT: [[AND:%.*]] = or i1 [[IS_SUBNORMAL]], [[IS_ZERO]]
+; CHECK-NEXT: ret i1 [[AND]]
+;
+ %fabs = call half @llvm.fabs.f16(half %x)
+ %is.subnormal = fcmp olt half %fabs, 0xH0400
+ %is.zero = fcmp oeq half %x, 0xH0000
+ %and = or i1 %is.subnormal, %is.zero
+ ret i1 %and
+}
+
+define i1 @subnormal_or_zero_daz(half %x) #1 {
+; CHECK-LABEL: @subnormal_or_zero_daz(
+; CHECK-NEXT: [[AND:%.*]] = fcmp oeq half [[X:%.*]], 0xH0000
+; CHECK-NEXT: ret i1 [[AND]]
+;
+ %fabs = call half @llvm.fabs.f16(half %x)
+ %is.subnormal = fcmp olt half %fabs, 0xH0400
+ %is.zero = fcmp oeq half %x, 0xH0000
+ %and = or i1 %is.subnormal, %is.zero
+ ret i1 %and
+}
+
+define i1 @subnormal_or_zero_dynamic(half %x) #2 {
+; CHECK-LABEL: @subnormal_or_zero_dynamic(
+; CHECK-NEXT: [[FABS:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
+; CHECK-NEXT: [[IS_SUBNORMAL:%.*]] = fcmp olt half [[FABS]], 0xH0400
+; CHECK-NEXT: [[IS_ZERO:%.*]] = fcmp oeq half [[X]], 0xH0000
+; CHECK-NEXT: [[AND:%.*]] = or i1 [[IS_SUBNORMAL]], [[IS_ZERO]]
+; CHECK-NEXT: ret i1 [[AND]]
+;
+ %fabs = call half @llvm.fabs.f16(half %x)
+ %is.subnormal = fcmp olt half %fabs, 0xH0400
+ %is.zero = fcmp oeq half %x, 0xH0000
+ %and = or i1 %is.subnormal, %is.zero
+ ret i1 %and
+}
+
declare half @llvm.fabs.f16(half) #0
declare half @llvm.canonicalize.f16(half) #0
declare <2 x half> @llvm.fabs.v2f16(<2 x half>) #0
attributes #0 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }
+attributes #1 = { "denormal-fp-math"="ieee,preserve-sign" }
+attributes #2 = { "denormal-fp-math"="ieee,dynamic" }
diff --git a/llvm/test/Transforms/InstCombine/is_fpclass.ll b/llvm/test/Transforms/InstCombine/is_fpclass.ll
index 0d9a3b958cca..f746215dbbdf 100644
--- a/llvm/test/Transforms/InstCombine/is_fpclass.ll
+++ b/llvm/test/Transforms/InstCombine/is_fpclass.ll
@@ -107,7 +107,7 @@ define <2 x i1> @test_class_isnan_v2f32(<2 x float> %x) {
define i1 @test_class_isnan_f32_strict(float %x) {
; CHECK-LABEL: @test_class_isnan_f32_strict(
-; CHECK-NEXT: [[VAL:%.*]] = call i1 @llvm.is.fpclass.f32(float [[X:%.*]], i32 3) #[[ATTR2:[0-9]+]]
+; CHECK-NEXT: [[VAL:%.*]] = call i1 @llvm.is.fpclass.f32(float [[X:%.*]], i32 3) #[[ATTR6:[0-9]+]]
; CHECK-NEXT: ret i1 [[VAL]]
;
%val = call i1 @llvm.is.fpclass.f32(float %x, i32 3) strictfp
@@ -123,6 +123,51 @@ define i1 @test_class_is_p0_n0_f32(float %x) {
ret i1 %val
}
+define <2 x i1> @test_class_is_p0_n0_v2f32(<2 x float> %x) {
+; CHECK-LABEL: @test_class_is_p0_n0_v2f32(
+; CHECK-NEXT: [[VAL:%.*]] = call <2 x i1> @llvm.is.fpclass.v2f32(<2 x float> [[X:%.*]], i32 96)
+; CHECK-NEXT: ret <2 x i1> [[VAL]]
+;
+ %val = call <2 x i1> @llvm.is.fpclass.v2f32(<2 x float> %x, i32 96) ; fcZero
+ ret <2 x i1> %val
+}
+
+define <2 x i1> @test_class_is_p0_n0_v2f32_daz(<2 x float> %x) "denormal-fp-math-f32"="ieee,preserve-sign" {
+; CHECK-LABEL: @test_class_is_p0_n0_v2f32_daz(
+; CHECK-NEXT: [[VAL:%.*]] = call <2 x i1> @llvm.is.fpclass.v2f32(<2 x float> [[X:%.*]], i32 96)
+; CHECK-NEXT: ret <2 x i1> [[VAL]]
+;
+ %val = call <2 x i1> @llvm.is.fpclass.v2f32(<2 x float> %x, i32 96) ; fcZero
+ ret <2 x i1> %val
+}
+
+define <2 x i1> @test_class_is_p0_n0_v2f32_dynamic(<2 x float> %x) "denormal-fp-math-f32"="ieee,dynamic" {
+; CHECK-LABEL: @test_class_is_p0_n0_v2f32_dynamic(
+; CHECK-NEXT: [[VAL:%.*]] = call <2 x i1> @llvm.is.fpclass.v2f32(<2 x float> [[X:%.*]], i32 96)
+; CHECK-NEXT: ret <2 x i1> [[VAL]]
+;
+ %val = call <2 x i1> @llvm.is.fpclass.v2f32(<2 x float> %x, i32 96) ; fcZero
+ ret <2 x i1> %val
+}
+
+define i1 @test_class_is_p0_n0_or_nan_f32(float %x) {
+; CHECK-LABEL: @test_class_is_p0_n0_or_nan_f32(
+; CHECK-NEXT: [[VAL:%.*]] = call i1 @llvm.is.fpclass.f32(float [[X:%.*]], i32 99)
+; CHECK-NEXT: ret i1 [[VAL]]
+;
+ %val = call i1 @llvm.is.fpclass.f32(float %x, i32 99) ; fcZero|fcNan
+ ret i1 %val
+}
+
+define <2 x i1> @test_class_is_p0_n0_or_nan_v2f32(<2 x float> %x) {
+; CHECK-LABEL: @test_class_is_p0_n0_or_nan_v2f32(
+; CHECK-NEXT: [[VAL:%.*]] = call <2 x i1> @llvm.is.fpclass.v2f32(<2 x float> [[X:%.*]], i32 99)
+; CHECK-NEXT: ret <2 x i1> [[VAL]]
+;
+ %val = call <2 x i1> @llvm.is.fpclass.v2f32(<2 x float> %x, i32 99) ; fcZero|fcNan
+ ret <2 x i1> %val
+}
+
define i1 @test_class_is_not_p0_n0_f32(float %x) {
; CHECK-LABEL: @test_class_is_not_p0_n0_f32(
; CHECK-NEXT: [[VAL:%.*]] = call i1 @llvm.is.fpclass.f32(float [[X:%.*]], i32 927)
@@ -132,9 +177,18 @@ define i1 @test_class_is_not_p0_n0_f32(float %x) {
ret i1 %val
}
+define <2 x i1> @test_class_is_not_p0_n0_v2f32(<2 x float> %x) {
+; CHECK-LABEL: @test_class_is_not_p0_n0_v2f32(
+; CHECK-NEXT: [[VAL:%.*]] = call <2 x i1> @llvm.is.fpclass.v2f32(<2 x float> [[X:%.*]], i32 927)
+; CHECK-NEXT: ret <2 x i1> [[VAL]]
+;
+ %val = call <2 x i1> @llvm.is.fpclass.v2f32(<2 x float> %x, i32 927) ; ~fcZero & fcAllFlags
+ ret <2 x i1> %val
+}
+
define i1 @test_class_is_not_p0_n0_f32_strict(float %x) {
; CHECK-LABEL: @test_class_is_not_p0_n0_f32_strict(
-; CHECK-NEXT: [[VAL:%.*]] = call i1 @llvm.is.fpclass.f32(float [[X:%.*]], i32 927) #[[ATTR2]]
+; CHECK-NEXT: [[VAL:%.*]] = call i1 @llvm.is.fpclass.f32(float [[X:%.*]], i32 927) #[[ATTR6]]
; CHECK-NEXT: ret i1 [[VAL]]
;
%val = call i1 @llvm.is.fpclass.f32(float %x, i32 927) strictfp ; ~fcZero & fcAllFlags
@@ -150,6 +204,15 @@ define i1 @test_class_is_not_p0_n0_f32_daz(float %x) "denormal-fp-math"="ieee,pr
ret i1 %val
}
+define i1 @test_class_is_not_p0_n0_f32_dynamic(float %x) "denormal-fp-math"="ieee,dynamic" {
+; CHECK-LABEL: @test_class_is_not_p0_n0_f32_dynamic(
+; CHECK-NEXT: [[VAL:%.*]] = call i1 @llvm.is.fpclass.f32(float [[X:%.*]], i32 927)
+; CHECK-NEXT: ret i1 [[VAL]]
+;
+ %val = call i1 @llvm.is.fpclass.f32(float %x, i32 927) ; ~fcZero & fcAllFlags
+ ret i1 %val
+}
+
define i1 @test_class_is_not_p0_n0_psub_nsub_f32_daz(float %x) "denormal-fp-math"="ieee,preserve-sign" {
; CHECK-LABEL: @test_class_is_not_p0_n0_psub_nsub_f32_daz(
; CHECK-NEXT: [[VAL:%.*]] = call i1 @llvm.is.fpclass.f32(float [[X:%.*]], i32 783)
@@ -168,9 +231,18 @@ define i1 @test_class_is_not_p0_n0_psub_nsub_f32_dapz(float %x) "denormal-fp-mat
ret i1 %val
}
+define i1 @test_class_is_not_p0_n0_psub_nsub_f32_dynamic(float %x) "denormal-fp-math"="ieee,dynamiz" {
+; CHECK-LABEL: @test_class_is_not_p0_n0_psub_nsub_f32_dynamic(
+; CHECK-NEXT: [[VAL:%.*]] = call i1 @llvm.is.fpclass.f32(float [[X:%.*]], i32 783)
+; CHECK-NEXT: ret i1 [[VAL]]
+;
+ %val = call i1 @llvm.is.fpclass.f32(float %x, i32 783) ; ~(fcZero|fcSubnormal) & fcAllFlags
+ ret i1 %val
+}
+
define i1 @test_class_is_p0_n0_f32_strict(float %x) {
; CHECK-LABEL: @test_class_is_p0_n0_f32_strict(
-; CHECK-NEXT: [[VAL:%.*]] = call i1 @llvm.is.fpclass.f32(float [[X:%.*]], i32 96) #[[ATTR2]]
+; CHECK-NEXT: [[VAL:%.*]] = call i1 @llvm.is.fpclass.f32(float [[X:%.*]], i32 96) #[[ATTR6]]
; CHECK-NEXT: ret i1 [[VAL]]
;
%val = call i1 @llvm.is.fpclass.f32(float %x, i32 96) strictfp
@@ -222,6 +294,186 @@ define i1 @test_class_is_p0_n0_psub_nsub_f32_dapz(float %x) "denormal-fp-math"="
ret i1 %val
}
+define i1 @test_class_is_p0_n0_psub_nsub_f32_dynamic(float %x) "denormal-fp-math"="ieee,dynamic" {
+; CHECK-LABEL: @test_class_is_p0_n0_psub_nsub_f32_dynamic(
+; CHECK-NEXT: [[VAL:%.*]] = call i1 @llvm.is.fpclass.f32(float [[X:%.*]], i32 240)
+; CHECK-NEXT: ret i1 [[VAL]]
+;
+ %val = call i1 @llvm.is.fpclass.f32(float %x, i32 240) ; fcZero | fcSubnormal
+ ret i1 %val
+}
+
+define <2 x i1> @test_class_is_p0_n0_psub_nsub_v2f32(<2 x float> %x) {
+; CHECK-LABEL: @test_class_is_p0_n0_psub_nsub_v2f32(
+; CHECK-NEXT: [[VAL:%.*]] = call <2 x i1> @llvm.is.fpclass.v2f32(<2 x float> [[X:%.*]], i32 240)
+; CHECK-NEXT: ret <2 x i1> [[VAL]]
+;
+ %val = call <2 x i1> @llvm.is.fpclass.v2f32(<2 x float> %x, i32 240) ; fcZero | fcSubnormal
+ ret <2 x i1> %val
+}
+
+define <2 x i1> @test_class_is_p0_n0_psub_nsub_v2f32_daz(<2 x float> %x) "denormal-fp-math"="ieee,preserve-sign" {
+; CHECK-LABEL: @test_class_is_p0_n0_psub_nsub_v2f32_daz(
+; CHECK-NEXT: [[VAL:%.*]] = call <2 x i1> @llvm.is.fpclass.v2f32(<2 x float> [[X:%.*]], i32 240)
+; CHECK-NEXT: ret <2 x i1> [[VAL]]
+;
+ %val = call <2 x i1> @llvm.is.fpclass.v2f32(<2 x float> %x, i32 240) ; fcZero | fcSubnormal
+ ret <2 x i1> %val
+}
+
+define <2 x i1> @test_class_is_p0_n0_psub_nsub_v2f32_dapz(<2 x float> %x) "denormal-fp-math"="ieee,positive-zero" {
+; CHECK-LABEL: @test_class_is_p0_n0_psub_nsub_v2f32_dapz(
+; CHECK-NEXT: [[VAL:%.*]] = call <2 x i1> @llvm.is.fpclass.v2f32(<2 x float> [[X:%.*]], i32 240)
+; CHECK-NEXT: ret <2 x i1> [[VAL]]
+;
+ %val = call <2 x i1> @llvm.is.fpclass.v2f32(<2 x float> %x, i32 240) ; fcZero | fcSubnormal
+ ret <2 x i1> %val
+}
+
+define <2 x i1> @test_class_is_p0_n0_psub_nsub_v2f32_dynamic(<2 x float> %x) "denormal-fp-math"="ieee,dynamic" {
+; CHECK-LABEL: @test_class_is_p0_n0_psub_nsub_v2f32_dynamic(
+; CHECK-NEXT: [[VAL:%.*]] = call <2 x i1> @llvm.is.fpclass.v2f32(<2 x float> [[X:%.*]], i32 240)
+; CHECK-NEXT: ret <2 x i1> [[VAL]]
+;
+ %val = call <2 x i1> @llvm.is.fpclass.v2f32(<2 x float> %x, i32 240) ; fcZero | fcSubnormal
+ ret <2 x i1> %val
+}
+
+define i1 @test_class_is_pinf_f32(float %x) {
+; CHECK-LABEL: @test_class_is_pinf_f32(
+; CHECK-NEXT: [[VAL:%.*]] = call i1 @llvm.is.fpclass.f32(float [[X:%.*]], i32 512)
+; CHECK-NEXT: ret i1 [[VAL]]
+;
+ %val = call i1 @llvm.is.fpclass.f32(float %x, i32 512) ; fcPosInf
+ ret i1 %val
+}
+
+define i1 @test_class_is_pinf_or_nan_f32(float %x) {
+; CHECK-LABEL: @test_class_is_pinf_or_nan_f32(
+; CHECK-NEXT: [[VAL:%.*]] = call i1 @llvm.is.fpclass.f32(float [[X:%.*]], i32 515)
+; CHECK-NEXT: ret i1 [[VAL]]
+;
+ %val = call i1 @llvm.is.fpclass.f32(float %x, i32 515) ; fcPosInf|fcNan
+ ret i1 %val
+}
+
+define <2 x i1> @test_class_is_pinf_v2f32(<2 x float> %x) {
+; CHECK-LABEL: @test_class_is_pinf_v2f32(
+; CHECK-NEXT: [[VAL:%.*]] = call <2 x i1> @llvm.is.fpclass.v2f32(<2 x float> [[X:%.*]], i32 512)
+; CHECK-NEXT: ret <2 x i1> [[VAL]]
+;
+ %val = call <2 x i1> @llvm.is.fpclass.v2f32(<2 x float> %x, i32 512) ; fcPosInf
+ ret <2 x i1> %val
+}
+
+define i1 @test_class_is_ninf_f32(float %x) {
+; CHECK-LABEL: @test_class_is_ninf_f32(
+; CHECK-NEXT: [[VAL:%.*]] = call i1 @llvm.is.fpclass.f32(float [[X:%.*]], i32 4)
+; CHECK-NEXT: ret i1 [[VAL]]
+;
+ %val = call i1 @llvm.is.fpclass.f32(float %x, i32 4) ; fcNegInf
+ ret i1 %val
+}
+
+define i1 @test_class_is_ninf_or_nan_f32(float %x) {
+; CHECK-LABEL: @test_class_is_ninf_or_nan_f32(
+; CHECK-NEXT: [[VAL:%.*]] = call i1 @llvm.is.fpclass.f32(float [[X:%.*]], i32 7)
+; CHECK-NEXT: ret i1 [[VAL]]
+;
+ %val = call i1 @llvm.is.fpclass.f32(float %x, i32 7) ; fcNegInf|fcNan
+ ret i1 %val
+}
+
+define <2 x i1> @test_class_is_ninf_v2f32(<2 x float> %x) {
+; CHECK-LABEL: @test_class_is_ninf_v2f32(
+; CHECK-NEXT: [[VAL:%.*]] = call <2 x i1> @llvm.is.fpclass.v2f32(<2 x float> [[X:%.*]], i32 4)
+; CHECK-NEXT: ret <2 x i1> [[VAL]]
+;
+ %val = call <2 x i1> @llvm.is.fpclass.v2f32(<2 x float> %x, i32 4) ; fcNegInf
+ ret <2 x i1> %val
+}
+
+define i1 @test_class_is_inf_f32(float %x) {
+; CHECK-LABEL: @test_class_is_inf_f32(
+; CHECK-NEXT: [[VAL:%.*]] = call i1 @llvm.is.fpclass.f32(float [[X:%.*]], i32 516)
+; CHECK-NEXT: ret i1 [[VAL]]
+;
+ %val = call i1 @llvm.is.fpclass.f32(float %x, i32 516) ; fcInf
+ ret i1 %val
+}
+
+define <2 x i1> @test_class_is_inf_v2f32(<2 x float> %x) {
+; CHECK-LABEL: @test_class_is_inf_v2f32(
+; CHECK-NEXT: [[VAL:%.*]] = call <2 x i1> @llvm.is.fpclass.v2f32(<2 x float> [[X:%.*]], i32 516)
+; CHECK-NEXT: ret <2 x i1> [[VAL]]
+;
+ %val = call <2 x i1> @llvm.is.fpclass.v2f32(<2 x float> %x, i32 516) ; fcInf
+ ret <2 x i1> %val
+}
+
+define i1 @test_class_is_inf_or_nan_f32(float %x) {
+; CHECK-LABEL: @test_class_is_inf_or_nan_f32(
+; CHECK-NEXT: [[VAL:%.*]] = call i1 @llvm.is.fpclass.f32(float [[X:%.*]], i32 519)
+; CHECK-NEXT: ret i1 [[VAL]]
+;
+ %val = call i1 @llvm.is.fpclass.f32(float %x, i32 519) ; fcInf|fcNan
+ ret i1 %val
+}
+
+define i1 @test_class_is_pinf_f32_strict(float %x) {
+; CHECK-LABEL: @test_class_is_pinf_f32_strict(
+; CHECK-NEXT: [[VAL:%.*]] = call i1 @llvm.is.fpclass.f32(float [[X:%.*]], i32 512) #[[ATTR6]]
+; CHECK-NEXT: ret i1 [[VAL]]
+;
+ %val = call i1 @llvm.is.fpclass.f32(float %x, i32 512) strictfp ; fcPosInf
+ ret i1 %val
+}
+
+define i1 @test_class_is_ninf_f32_strict(float %x) {
+; CHECK-LABEL: @test_class_is_ninf_f32_strict(
+; CHECK-NEXT: [[VAL:%.*]] = call i1 @llvm.is.fpclass.f32(float [[X:%.*]], i32 4) #[[ATTR6]]
+; CHECK-NEXT: ret i1 [[VAL]]
+;
+ %val = call i1 @llvm.is.fpclass.f32(float %x, i32 4) strictfp ; fcNegInf
+ ret i1 %val
+}
+
+define i1 @test_class_is_inf_f32_strict(float %x) {
+; CHECK-LABEL: @test_class_is_inf_f32_strict(
+; CHECK-NEXT: [[VAL:%.*]] = call i1 @llvm.is.fpclass.f32(float [[X:%.*]], i32 516) #[[ATTR6]]
+; CHECK-NEXT: ret i1 [[VAL]]
+;
+ %val = call i1 @llvm.is.fpclass.f32(float %x, i32 516) strictfp ; fcInf
+ ret i1 %val
+}
+
+define i1 @test_class_is_pinf_or_nan_f32_strict(float %x) {
+; CHECK-LABEL: @test_class_is_pinf_or_nan_f32_strict(
+; CHECK-NEXT: [[VAL:%.*]] = call i1 @llvm.is.fpclass.f32(float [[X:%.*]], i32 515) #[[ATTR6]]
+; CHECK-NEXT: ret i1 [[VAL]]
+;
+ %val = call i1 @llvm.is.fpclass.f32(float %x, i32 515) strictfp ; fcPosInf|fcNan
+ ret i1 %val
+}
+
+define i1 @test_class_is_ninf_or_nan_f32_strict(float %x) {
+; CHECK-LABEL: @test_class_is_ninf_or_nan_f32_strict(
+; CHECK-NEXT: [[VAL:%.*]] = call i1 @llvm.is.fpclass.f32(float [[X:%.*]], i32 7) #[[ATTR6]]
+; CHECK-NEXT: ret i1 [[VAL]]
+;
+ %val = call i1 @llvm.is.fpclass.f32(float %x, i32 7) strictfp ; fcNegInf|fcNan
+ ret i1 %val
+}
+
+define i1 @test_class_is_inf_or_nan_f32_strict(float %x) {
+; CHECK-LABEL: @test_class_is_inf_or_nan_f32_strict(
+; CHECK-NEXT: [[VAL:%.*]] = call i1 @llvm.is.fpclass.f32(float [[X:%.*]], i32 519) #[[ATTR6]]
+; CHECK-NEXT: ret i1 [[VAL]]
+;
+ %val = call i1 @llvm.is.fpclass.f32(float %x, i32 519) strictfp ; fcInf|fcNan
+ ret i1 %val
+}
+
define i1 @test_constant_class_snan_test_snan_f64() {
; CHECK-LABEL: @test_constant_class_snan_test_snan_f64(
; CHECK-NEXT: ret i1 true
@@ -1342,7 +1594,7 @@ define i1 @test_class_fneg_posinf_negnormal_possubnormal_negzero_nan(float %arg)
; -> ninf|pnormal|negsubnormal|pzero|snan
define i1 @test_class_fneg_posinf_negnormal_possubnormal_negzero_snan_strictfp(float %arg) strictfp {
; CHECK-LABEL: @test_class_fneg_posinf_negnormal_possubnormal_negzero_snan_strictfp(
-; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[ARG:%.*]], i32 341) #[[ATTR2]]
+; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[ARG:%.*]], i32 341) #[[ATTR6]]
; CHECK-NEXT: ret i1 [[CLASS]]
;
%fneg = fneg float %arg
@@ -1673,7 +1925,7 @@ define i1 @test_class_fabs_posinf_negnormal_possubnormal_negzero_nan(float %arg)
; -> pinf|psubnormal|snan
define i1 @test_class_fabs_posinf_negnormal_possubnormal_negzero_snan_strictfp(float %arg) strictfp {
; CHECK-LABEL: @test_class_fabs_posinf_negnormal_possubnormal_negzero_snan_strictfp(
-; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[ARG:%.*]], i32 661) #[[ATTR2]]
+; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[ARG:%.*]], i32 661) #[[ATTR6]]
; CHECK-NEXT: ret i1 [[CLASS]]
;
%fabs = call float @llvm.fabs.f32(float %arg)
@@ -2003,7 +2255,7 @@ define i1 @test_class_fneg_fabs_posinf_negnormal_possubnormal_negzero_nan(float
; strictfp doesn't matter
define i1 @test_class_fneg_fabs_posinf_negnormal_possubnormal_negzero_snan_strictfp(float %arg) strictfp {
; CHECK-LABEL: @test_class_fneg_fabs_posinf_negnormal_possubnormal_negzero_snan_strictfp(
-; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[ARG:%.*]], i32 361) #[[ATTR2]]
+; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[ARG:%.*]], i32 361) #[[ATTR6]]
; CHECK-NEXT: ret i1 [[CLASS]]
;
%fabs = call float @llvm.fabs.f32(float %arg)
More information about the llvm-commits
mailing list