[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