[llvm] 40ef625 - InstCombine: Add baseline test for and/or/xor of is.fpclass

Matt Arsenault via llvm-commits llvm-commits at lists.llvm.org
Tue Dec 13 06:58:21 PST 2022


Author: Matt Arsenault
Date: 2022-12-13T09:58:01-05:00
New Revision: 40ef6256172311158ff564152c8afb1afbbdcadc

URL: https://github.com/llvm/llvm-project/commit/40ef6256172311158ff564152c8afb1afbbdcadc
DIFF: https://github.com/llvm/llvm-project/commit/40ef6256172311158ff564152c8afb1afbbdcadc.diff

LOG: InstCombine: Add baseline test for and/or/xor of is.fpclass

Added: 
    

Modified: 
    llvm/test/Transforms/InstCombine/is_fpclass.ll

Removed: 
    


################################################################################
diff  --git a/llvm/test/Transforms/InstCombine/is_fpclass.ll b/llvm/test/Transforms/InstCombine/is_fpclass.ll
index b0ad07077a54..b95021f6176d 100644
--- a/llvm/test/Transforms/InstCombine/is_fpclass.ll
+++ b/llvm/test/Transforms/InstCombine/is_fpclass.ll
@@ -773,6 +773,399 @@ define <2 x i1> @test_fold_or_class_v2f32(<2 x float> %a) {
   ret <2 x i1> %or
 }
 
+; --------------------------------------------------------------------
+; and llvm.is.fpclass, llvm.is.fpclass
+; --------------------------------------------------------------------
+
+define i1 @test_fold_and_class_f32_0(float %a) {
+; CHECK-LABEL: @test_fold_and_class_f32_0(
+; CHECK-NEXT:    [[CLASS0:%.*]] = call i1 @llvm.is.fpclass.f32(float [[A:%.*]], i32 1)
+; CHECK-NEXT:    [[CLASS1:%.*]] = fcmp uno float [[A]], 0.000000e+00
+; CHECK-NEXT:    [[AND:%.*]] = and i1 [[CLASS0]], [[CLASS1]]
+; CHECK-NEXT:    ret i1 [[AND]]
+;
+  %class0 = call i1 @llvm.is.fpclass.f32(float %a, i32 1)
+  %class1 = fcmp uno float %a, 0.000000e+00
+  %and = and i1 %class0, %class1
+  ret i1 %and
+}
+
+define i1 @test_fold_and3_class_f32_0(float %a) {
+; CHECK-LABEL: @test_fold_and3_class_f32_0(
+; CHECK-NEXT:    [[CLASS0:%.*]] = call i1 @llvm.is.fpclass.f32(float [[A:%.*]], i32 3)
+; CHECK-NEXT:    [[CLASS1:%.*]] = call i1 @llvm.is.fpclass.f32(float [[A]], i32 2)
+; CHECK-NEXT:    [[CLASS2:%.*]] = call i1 @llvm.is.fpclass.f32(float [[A]], i32 7)
+; CHECK-NEXT:    [[AND_0:%.*]] = and i1 [[CLASS0]], [[CLASS1]]
+; CHECK-NEXT:    [[AND_1:%.*]] = and i1 [[AND_0]], [[CLASS2]]
+; CHECK-NEXT:    ret i1 [[AND_1]]
+;
+  %class0 = call i1 @llvm.is.fpclass.f32(float %a, i32 3)
+  %class1 = call i1 @llvm.is.fpclass.f32(float %a, i32 2)
+  %class2 = call i1 @llvm.is.fpclass.f32(float %a, i32 7)
+  %and.0 = and i1 %class0, %class1
+  %and.1 = and i1 %and.0, %class2
+  ret i1 %and.1
+}
+
+define i1 @test_fold_and_all_tests_class_f32_0(float %a) {
+; CHECK-LABEL: @test_fold_and_all_tests_class_f32_0(
+; CHECK-NEXT:    [[CLASS0:%.*]] = call i1 @llvm.is.fpclass.f32(float [[A:%.*]], i32 1)
+; CHECK-NEXT:    [[CLASS1:%.*]] = call i1 @llvm.is.fpclass.f32(float [[A]], i32 2)
+; CHECK-NEXT:    [[CLASS2:%.*]] = call i1 @llvm.is.fpclass.f32(float [[A]], i32 4)
+; CHECK-NEXT:    [[CLASS3:%.*]] = call i1 @llvm.is.fpclass.f32(float [[A]], i32 8)
+; CHECK-NEXT:    [[CLASS4:%.*]] = call i1 @llvm.is.fpclass.f32(float [[A]], i32 16)
+; CHECK-NEXT:    [[CLASS5:%.*]] = call i1 @llvm.is.fpclass.f32(float [[A]], i32 32)
+; CHECK-NEXT:    [[CLASS6:%.*]] = call i1 @llvm.is.fpclass.f32(float [[A]], i32 64)
+; CHECK-NEXT:    [[CLASS7:%.*]] = call i1 @llvm.is.fpclass.f32(float [[A]], i32 128)
+; CHECK-NEXT:    [[CLASS8:%.*]] = call i1 @llvm.is.fpclass.f32(float [[A]], i32 256)
+; CHECK-NEXT:    [[CLASS9:%.*]] = call i1 @llvm.is.fpclass.f32(float [[A]], i32 512)
+; CHECK-NEXT:    [[AND_0:%.*]] = and i1 [[CLASS0]], [[CLASS1]]
+; CHECK-NEXT:    [[AND_1:%.*]] = and i1 [[AND_0]], [[CLASS2]]
+; CHECK-NEXT:    [[AND_2:%.*]] = and i1 [[AND_1]], [[CLASS3]]
+; CHECK-NEXT:    [[AND_3:%.*]] = and i1 [[AND_2]], [[CLASS4]]
+; CHECK-NEXT:    [[AND_4:%.*]] = and i1 [[AND_3]], [[CLASS5]]
+; CHECK-NEXT:    [[AND_5:%.*]] = and i1 [[AND_4]], [[CLASS6]]
+; CHECK-NEXT:    [[AND_6:%.*]] = and i1 [[AND_5]], [[CLASS7]]
+; CHECK-NEXT:    [[AND_7:%.*]] = and i1 [[AND_6]], [[CLASS8]]
+; CHECK-NEXT:    [[AND_8:%.*]] = and i1 [[AND_7]], [[CLASS9]]
+; CHECK-NEXT:    ret i1 [[AND_8]]
+;
+  %class0 = call i1 @llvm.is.fpclass.f32(float %a, i32 1)
+  %class1 = call i1 @llvm.is.fpclass.f32(float %a, i32 2)
+  %class2 = call i1 @llvm.is.fpclass.f32(float %a, i32 4)
+  %class3 = call i1 @llvm.is.fpclass.f32(float %a, i32 8)
+  %class4 = call i1 @llvm.is.fpclass.f32(float %a, i32 16)
+  %class5 = call i1 @llvm.is.fpclass.f32(float %a, i32 32)
+  %class6 = call i1 @llvm.is.fpclass.f32(float %a, i32 64)
+  %class7 = call i1 @llvm.is.fpclass.f32(float %a, i32 128)
+  %class8 = call i1 @llvm.is.fpclass.f32(float %a, i32 256)
+  %class9 = call i1 @llvm.is.fpclass.f32(float %a, i32 512)
+  %and.0 = and i1 %class0, %class1
+  %and.1 = and i1 %and.0, %class2
+  %and.2 = and i1 %and.1, %class3
+  %and.3 = and i1 %and.2, %class4
+  %and.4 = and i1 %and.3, %class5
+  %and.5 = and i1 %and.4, %class6
+  %and.6 = and i1 %and.5, %class7
+  %and.7 = and i1 %and.6, %class8
+  %and.8 = and i1 %and.7, %class9
+  ret i1 %and.8
+}
+
+define i1 @test_fold_and_not_all_tests_class_f32_0(float %a) {
+; CHECK-LABEL: @test_fold_and_not_all_tests_class_f32_0(
+; CHECK-NEXT:    [[CLASS0:%.*]] = call i1 @llvm.is.fpclass.f32(float [[A:%.*]], i32 1022)
+; CHECK-NEXT:    [[CLASS1:%.*]] = call i1 @llvm.is.fpclass.f32(float [[A]], i32 1021)
+; CHECK-NEXT:    [[CLASS2:%.*]] = call i1 @llvm.is.fpclass.f32(float [[A]], i32 1019)
+; CHECK-NEXT:    [[CLASS3:%.*]] = call i1 @llvm.is.fpclass.f32(float [[A]], i32 1015)
+; CHECK-NEXT:    [[CLASS4:%.*]] = call i1 @llvm.is.fpclass.f32(float [[A]], i32 1007)
+; CHECK-NEXT:    [[CLASS5:%.*]] = call i1 @llvm.is.fpclass.f32(float [[A]], i32 991)
+; CHECK-NEXT:    [[CLASS6:%.*]] = call i1 @llvm.is.fpclass.f32(float [[A]], i32 959)
+; CHECK-NEXT:    [[CLASS7:%.*]] = call i1 @llvm.is.fpclass.f32(float [[A]], i32 895)
+; CHECK-NEXT:    [[CLASS8:%.*]] = call i1 @llvm.is.fpclass.f32(float [[A]], i32 767)
+; CHECK-NEXT:    [[CLASS9:%.*]] = call i1 @llvm.is.fpclass.f32(float [[A]], i32 511)
+; CHECK-NEXT:    [[AND_0:%.*]] = and i1 [[CLASS0]], [[CLASS1]]
+; CHECK-NEXT:    [[AND_1:%.*]] = and i1 [[AND_0]], [[CLASS2]]
+; CHECK-NEXT:    [[AND_2:%.*]] = and i1 [[AND_1]], [[CLASS3]]
+; CHECK-NEXT:    [[AND_3:%.*]] = and i1 [[AND_2]], [[CLASS4]]
+; CHECK-NEXT:    [[AND_4:%.*]] = and i1 [[AND_3]], [[CLASS5]]
+; CHECK-NEXT:    [[AND_5:%.*]] = and i1 [[AND_4]], [[CLASS6]]
+; CHECK-NEXT:    [[AND_6:%.*]] = and i1 [[AND_5]], [[CLASS7]]
+; CHECK-NEXT:    [[AND_7:%.*]] = and i1 [[AND_6]], [[CLASS8]]
+; CHECK-NEXT:    [[AND_8:%.*]] = and i1 [[AND_7]], [[CLASS9]]
+; CHECK-NEXT:    ret i1 [[AND_8]]
+;
+  %class0 = call i1 @llvm.is.fpclass.f32(float %a, i32 1022)
+  %class1 = call i1 @llvm.is.fpclass.f32(float %a, i32 1021)
+  %class2 = call i1 @llvm.is.fpclass.f32(float %a, i32 1019)
+  %class3 = call i1 @llvm.is.fpclass.f32(float %a, i32 1015)
+  %class4 = call i1 @llvm.is.fpclass.f32(float %a, i32 1007)
+  %class5 = call i1 @llvm.is.fpclass.f32(float %a, i32 991)
+  %class6 = call i1 @llvm.is.fpclass.f32(float %a, i32 959)
+  %class7 = call i1 @llvm.is.fpclass.f32(float %a, i32 895)
+  %class8 = call i1 @llvm.is.fpclass.f32(float %a, i32 767)
+  %class9 = call i1 @llvm.is.fpclass.f32(float %a, i32 511)
+  %and.0 = and i1 %class0, %class1
+  %and.1 = and i1 %and.0, %class2
+  %and.2 = and i1 %and.1, %class3
+  %and.3 = and i1 %and.2, %class4
+  %and.4 = and i1 %and.3, %class5
+  %and.5 = and i1 %and.4, %class6
+  %and.6 = and i1 %and.5, %class7
+  %and.7 = and i1 %and.6, %class8
+  %and.8 = and i1 %and.7, %class9
+  ret i1 %and.8
+}
+
+define i1 @test_fold_and_class_f32_1(float %a) {
+; CHECK-LABEL: @test_fold_and_class_f32_1(
+; CHECK-NEXT:    [[CLASS0:%.*]] = call i1 @llvm.is.fpclass.f32(float [[A:%.*]], i32 48)
+; CHECK-NEXT:    [[CLASS1:%.*]] = call i1 @llvm.is.fpclass.f32(float [[A]], i32 11)
+; CHECK-NEXT:    [[AND:%.*]] = and i1 [[CLASS0]], [[CLASS1]]
+; CHECK-NEXT:    ret i1 [[AND]]
+;
+  %class0 = call i1 @llvm.is.fpclass.f32(float %a, i32 48)
+  %class1 = call i1 @llvm.is.fpclass.f32(float %a, i32 11)
+  %and = and i1 %class0, %class1
+  ret i1 %and
+}
+
+define i1 @test_no_fold_and_class_f32_multi_use0(float %a, ptr %ptr) {
+; CHECK-LABEL: @test_no_fold_and_class_f32_multi_use0(
+; CHECK-NEXT:    [[CLASS0:%.*]] = call i1 @llvm.is.fpclass.f32(float [[A:%.*]], i32 15)
+; CHECK-NEXT:    store i1 [[CLASS0]], ptr [[PTR:%.*]], align 1
+; CHECK-NEXT:    [[CLASS1:%.*]] = call i1 @llvm.is.fpclass.f32(float [[A]], i32 8)
+; CHECK-NEXT:    [[AND:%.*]] = and i1 [[CLASS0]], [[CLASS1]]
+; CHECK-NEXT:    ret i1 [[AND]]
+;
+  %class0 = call i1 @llvm.is.fpclass.f32(float %a, i32 15)
+  store i1 %class0, ptr %ptr
+  %class1 = call i1 @llvm.is.fpclass.f32(float %a, i32 8)
+  %and = and i1 %class0, %class1
+  ret i1 %and
+}
+
+define i1 @test_no_fold_and_class_f32_multi_use1(float %a, ptr %ptr) {
+; CHECK-LABEL: @test_no_fold_and_class_f32_multi_use1(
+; CHECK-NEXT:    [[CLASS0:%.*]] = call i1 @llvm.is.fpclass.f32(float [[A:%.*]], i32 15)
+; CHECK-NEXT:    [[CLASS1:%.*]] = call i1 @llvm.is.fpclass.f32(float [[A]], i32 8)
+; CHECK-NEXT:    store i1 [[CLASS1]], ptr [[PTR:%.*]], align 1
+; CHECK-NEXT:    [[AND:%.*]] = and i1 [[CLASS0]], [[CLASS1]]
+; CHECK-NEXT:    ret i1 [[AND]]
+;
+  %class0 = call i1 @llvm.is.fpclass.f32(float %a, i32 15)
+  %class1 = call i1 @llvm.is.fpclass.f32(float %a, i32 8)
+  store i1 %class1, ptr %ptr
+  %and = and i1 %class0, %class1
+  ret i1 %and
+}
+
+define i1 @test_fold_and_class_f32_2(float %a) {
+; CHECK-LABEL: @test_fold_and_class_f32_2(
+; CHECK-NEXT:    [[CLASS0:%.*]] = call i1 @llvm.is.fpclass.f32(float [[A:%.*]], i32 7)
+; CHECK-NEXT:    [[CLASS1:%.*]] = call i1 @llvm.is.fpclass.f32(float [[A]], i32 7)
+; CHECK-NEXT:    [[AND:%.*]] = and i1 [[CLASS0]], [[CLASS1]]
+; CHECK-NEXT:    ret i1 [[AND]]
+;
+  %class0 = call i1 @llvm.is.fpclass.f32(float %a, i32 7)
+  %class1 = call i1 @llvm.is.fpclass.f32(float %a, i32 7)
+  %and = and i1 %class0, %class1
+  ret i1 %and
+}
+
+define i1 @test_fold_and_class_f32_3(float %a) {
+; CHECK-LABEL: @test_fold_and_class_f32_3(
+; CHECK-NEXT:    [[CLASS0:%.*]] = call i1 @llvm.is.fpclass.f32(float [[A:%.*]], i32 37)
+; CHECK-NEXT:    [[CLASS1:%.*]] = call i1 @llvm.is.fpclass.f32(float [[A]], i32 393)
+; CHECK-NEXT:    [[AND:%.*]] = and i1 [[CLASS0]], [[CLASS1]]
+; CHECK-NEXT:    ret i1 [[AND]]
+;
+  %class0 = call i1 @llvm.is.fpclass.f32(float %a, i32 37)
+  %class1 = call i1 @llvm.is.fpclass.f32(float %a, i32 393)
+  %and = and i1 %class0, %class1
+  ret i1 %and
+}
+
+define i1 @test_fold_and_class_f32_4(float %a) {
+; CHECK-LABEL: @test_fold_and_class_f32_4(
+; CHECK-NEXT:    [[CLASS0:%.*]] = call i1 @llvm.is.fpclass.f32(float [[A:%.*]], i32 393)
+; CHECK-NEXT:    [[CLASS1:%.*]] = call i1 @llvm.is.fpclass.f32(float [[A]], i32 37)
+; CHECK-NEXT:    [[AND:%.*]] = and i1 [[CLASS0]], [[CLASS1]]
+; CHECK-NEXT:    ret i1 [[AND]]
+;
+  %class0 = call i1 @llvm.is.fpclass.f32(float %a, i32 393)
+  %class1 = call i1 @llvm.is.fpclass.f32(float %a, i32 37)
+  %and = and i1 %class0, %class1
+  ret i1 %and
+}
+
+define i1 @test_no_fold_and_class_f32_0(float %a, float %b) {
+; CHECK-LABEL: @test_no_fold_and_class_f32_0(
+; CHECK-NEXT:    [[CLASS0:%.*]] = call i1 @llvm.is.fpclass.f32(float [[A:%.*]], i32 7)
+; CHECK-NEXT:    [[CLASS1:%.*]] = call i1 @llvm.is.fpclass.f32(float [[B:%.*]], i32 15)
+; CHECK-NEXT:    [[AND:%.*]] = and i1 [[CLASS0]], [[CLASS1]]
+; CHECK-NEXT:    ret i1 [[AND]]
+;
+  %class0 = call i1 @llvm.is.fpclass.f32(float %a, i32 7)
+  %class1 = call i1 @llvm.is.fpclass.f32(float %b, i32 15)
+  %and = and i1 %class0, %class1
+  ret i1 %and
+}
+
+define <2 x i1> @test_fold_and_class_v2f32(<2 x float> %a) {
+; CHECK-LABEL: @test_fold_and_class_v2f32(
+; CHECK-NEXT:    [[CLASS0:%.*]] = call <2 x i1> @llvm.is.fpclass.v2f32(<2 x float> [[A:%.*]], i32 7)
+; CHECK-NEXT:    [[CLASS1:%.*]] = call <2 x i1> @llvm.is.fpclass.v2f32(<2 x float> [[A]], i32 15)
+; CHECK-NEXT:    [[AND:%.*]] = and <2 x i1> [[CLASS0]], [[CLASS1]]
+; CHECK-NEXT:    ret <2 x i1> [[AND]]
+;
+  %class0 = call <2 x i1> @llvm.is.fpclass.v2f32(<2 x float> %a, i32 7)
+  %class1 = call <2 x i1> @llvm.is.fpclass.v2f32(<2 x float> %a, i32 15)
+  %and = and <2 x i1> %class0, %class1
+  ret <2 x i1> %and
+}
+
+; --------------------------------------------------------------------
+; xor llvm.is.fpclass, llvm.is.fpclass
+; --------------------------------------------------------------------
+
+define i1 @test_fold_xor_class_f32_0(float %a) {
+; CHECK-LABEL: @test_fold_xor_class_f32_0(
+; CHECK-NEXT:    [[CLASS0:%.*]] = call i1 @llvm.is.fpclass.f32(float [[A:%.*]], i32 1)
+; CHECK-NEXT:    [[CLASS1:%.*]] = fcmp uno float [[A]], 0.000000e+00
+; CHECK-NEXT:    [[XOR:%.*]] = xor i1 [[CLASS0]], [[CLASS1]]
+; CHECK-NEXT:    ret i1 [[XOR]]
+;
+  %class0 = call i1 @llvm.is.fpclass.f32(float %a, i32 1)
+  %class1 = fcmp uno float %a, 0.000000e+00
+  %xor = xor i1 %class0, %class1
+  ret i1 %xor
+}
+
+define i1 @test_fold_xor3_class_f32_0(float %a) {
+; CHECK-LABEL: @test_fold_xor3_class_f32_0(
+; CHECK-NEXT:    [[CLASS0:%.*]] = call i1 @llvm.is.fpclass.f32(float [[A:%.*]], i32 1)
+; CHECK-NEXT:    [[CLASS1:%.*]] = call i1 @llvm.is.fpclass.f32(float [[A]], i32 2)
+; CHECK-NEXT:    [[CLASS2:%.*]] = call i1 @llvm.is.fpclass.f32(float [[A]], i32 4)
+; CHECK-NEXT:    [[XOR_0:%.*]] = xor i1 [[CLASS0]], [[CLASS1]]
+; CHECK-NEXT:    [[XOR_1:%.*]] = xor i1 [[XOR_0]], [[CLASS2]]
+; CHECK-NEXT:    ret i1 [[XOR_1]]
+;
+  %class0 = call i1 @llvm.is.fpclass.f32(float %a, i32 1)
+  %class1 = call i1 @llvm.is.fpclass.f32(float %a, i32 2)
+  %class2 = call i1 @llvm.is.fpclass.f32(float %a, i32 4)
+  %xor.0 = xor i1 %class0, %class1
+  %xor.1 = xor i1 %xor.0, %class2
+  ret i1 %xor.1
+}
+
+define i1 @test_fold_xor_all_tests_class_f32_0(float %a) {
+; CHECK-LABEL: @test_fold_xor_all_tests_class_f32_0(
+; CHECK-NEXT:    [[CLASS0:%.*]] = call i1 @llvm.is.fpclass.f32(float [[A:%.*]], i32 1)
+; CHECK-NEXT:    [[CLASS1:%.*]] = call i1 @llvm.is.fpclass.f32(float [[A]], i32 2)
+; CHECK-NEXT:    [[CLASS2:%.*]] = call i1 @llvm.is.fpclass.f32(float [[A]], i32 4)
+; CHECK-NEXT:    [[CLASS3:%.*]] = call i1 @llvm.is.fpclass.f32(float [[A]], i32 8)
+; CHECK-NEXT:    [[CLASS4:%.*]] = call i1 @llvm.is.fpclass.f32(float [[A]], i32 16)
+; CHECK-NEXT:    [[CLASS5:%.*]] = call i1 @llvm.is.fpclass.f32(float [[A]], i32 32)
+; CHECK-NEXT:    [[CLASS6:%.*]] = call i1 @llvm.is.fpclass.f32(float [[A]], i32 64)
+; CHECK-NEXT:    [[CLASS7:%.*]] = call i1 @llvm.is.fpclass.f32(float [[A]], i32 128)
+; CHECK-NEXT:    [[CLASS8:%.*]] = call i1 @llvm.is.fpclass.f32(float [[A]], i32 256)
+; CHECK-NEXT:    [[CLASS9:%.*]] = call i1 @llvm.is.fpclass.f32(float [[A]], i32 512)
+; CHECK-NEXT:    [[XOR_0:%.*]] = xor i1 [[CLASS0]], [[CLASS1]]
+; CHECK-NEXT:    [[XOR_1:%.*]] = xor i1 [[XOR_0]], [[CLASS2]]
+; CHECK-NEXT:    [[XOR_2:%.*]] = xor i1 [[XOR_1]], [[CLASS3]]
+; CHECK-NEXT:    [[XOR_3:%.*]] = xor i1 [[XOR_2]], [[CLASS4]]
+; CHECK-NEXT:    [[XOR_4:%.*]] = xor i1 [[XOR_3]], [[CLASS5]]
+; CHECK-NEXT:    [[XOR_5:%.*]] = xor i1 [[XOR_4]], [[CLASS6]]
+; CHECK-NEXT:    [[XOR_6:%.*]] = xor i1 [[XOR_5]], [[CLASS7]]
+; CHECK-NEXT:    [[XOR_7:%.*]] = xor i1 [[XOR_6]], [[CLASS8]]
+; CHECK-NEXT:    [[XOR_8:%.*]] = xor i1 [[XOR_7]], [[CLASS9]]
+; CHECK-NEXT:    ret i1 [[XOR_8]]
+;
+  %class0 = call i1 @llvm.is.fpclass.f32(float %a, i32 1)
+  %class1 = call i1 @llvm.is.fpclass.f32(float %a, i32 2)
+  %class2 = call i1 @llvm.is.fpclass.f32(float %a, i32 4)
+  %class3 = call i1 @llvm.is.fpclass.f32(float %a, i32 8)
+  %class4 = call i1 @llvm.is.fpclass.f32(float %a, i32 16)
+  %class5 = call i1 @llvm.is.fpclass.f32(float %a, i32 32)
+  %class6 = call i1 @llvm.is.fpclass.f32(float %a, i32 64)
+  %class7 = call i1 @llvm.is.fpclass.f32(float %a, i32 128)
+  %class8 = call i1 @llvm.is.fpclass.f32(float %a, i32 256)
+  %class9 = call i1 @llvm.is.fpclass.f32(float %a, i32 512)
+  %xor.0 = xor i1 %class0, %class1
+  %xor.1 = xor i1 %xor.0, %class2
+  %xor.2 = xor i1 %xor.1, %class3
+  %xor.3 = xor i1 %xor.2, %class4
+  %xor.4 = xor i1 %xor.3, %class5
+  %xor.5 = xor i1 %xor.4, %class6
+  %xor.6 = xor i1 %xor.5, %class7
+  %xor.7 = xor i1 %xor.6, %class8
+  %xor.8 = xor i1 %xor.7, %class9
+  ret i1 %xor.8
+}
+
+define i1 @test_fold_xor_class_f32_1(float %a) {
+; CHECK-LABEL: @test_fold_xor_class_f32_1(
+; CHECK-NEXT:    [[CLASS0:%.*]] = call i1 @llvm.is.fpclass.f32(float [[A:%.*]], i32 4)
+; CHECK-NEXT:    [[CLASS1:%.*]] = call i1 @llvm.is.fpclass.f32(float [[A]], i32 8)
+; CHECK-NEXT:    [[XOR:%.*]] = xor i1 [[CLASS0]], [[CLASS1]]
+; CHECK-NEXT:    ret i1 [[XOR]]
+;
+  %class0 = call i1 @llvm.is.fpclass.f32(float %a, i32 4)
+  %class1 = call i1 @llvm.is.fpclass.f32(float %a, i32 8)
+  %xor = xor i1 %class0, %class1
+  ret i1 %xor
+}
+
+define i1 @test_no_fold_xor_class_f32_multi_use0(float %a, ptr %ptr) {
+; CHECK-LABEL: @test_no_fold_xor_class_f32_multi_use0(
+; CHECK-NEXT:    [[CLASS0:%.*]] = call i1 @llvm.is.fpclass.f32(float [[A:%.*]], i32 4)
+; CHECK-NEXT:    store i1 [[CLASS0]], ptr [[PTR:%.*]], align 1
+; CHECK-NEXT:    [[CLASS1:%.*]] = call i1 @llvm.is.fpclass.f32(float [[A]], i32 8)
+; CHECK-NEXT:    [[XOR:%.*]] = xor i1 [[CLASS0]], [[CLASS1]]
+; CHECK-NEXT:    ret i1 [[XOR]]
+;
+  %class0 = call i1 @llvm.is.fpclass.f32(float %a, i32 4)
+  store i1 %class0, ptr %ptr
+  %class1 = call i1 @llvm.is.fpclass.f32(float %a, i32 8)
+  %xor = xor i1 %class0, %class1
+  ret i1 %xor
+}
+
+define i1 @test_no_fold_xor_class_f32_multi_use1(float %a, ptr %ptr) {
+; CHECK-LABEL: @test_no_fold_xor_class_f32_multi_use1(
+; CHECK-NEXT:    [[CLASS0:%.*]] = call i1 @llvm.is.fpclass.f32(float [[A:%.*]], i32 4)
+; CHECK-NEXT:    [[CLASS1:%.*]] = call i1 @llvm.is.fpclass.f32(float [[A]], i32 8)
+; CHECK-NEXT:    store i1 [[CLASS1]], ptr [[PTR:%.*]], align 1
+; CHECK-NEXT:    [[XOR:%.*]] = xor i1 [[CLASS0]], [[CLASS1]]
+; CHECK-NEXT:    ret i1 [[XOR]]
+;
+  %class0 = call i1 @llvm.is.fpclass.f32(float %a, i32 4)
+  %class1 = call i1 @llvm.is.fpclass.f32(float %a, i32 8)
+  store i1 %class1, ptr %ptr
+  %xor = xor i1 %class0, %class1
+  ret i1 %xor
+}
+
+define i1 @test_fold_xor_class_f32_2(float %a) {
+; CHECK-LABEL: @test_fold_xor_class_f32_2(
+; CHECK-NEXT:    [[CLASS0:%.*]] = call i1 @llvm.is.fpclass.f32(float [[A:%.*]], i32 7)
+; CHECK-NEXT:    [[CLASS1:%.*]] = call i1 @llvm.is.fpclass.f32(float [[A]], i32 7)
+; CHECK-NEXT:    [[XOR:%.*]] = xor i1 [[CLASS0]], [[CLASS1]]
+; CHECK-NEXT:    ret i1 [[XOR]]
+;
+  %class0 = call i1 @llvm.is.fpclass.f32(float %a, i32 7)
+  %class1 = call i1 @llvm.is.fpclass.f32(float %a, i32 7)
+  %xor = xor i1 %class0, %class1
+  ret i1 %xor
+}
+
+define i1 @test_no_fold_xor_class_f32_0(float %a, float %b) {
+; CHECK-LABEL: @test_no_fold_xor_class_f32_0(
+; CHECK-NEXT:    [[CLASS0:%.*]] = call i1 @llvm.is.fpclass.f32(float [[A:%.*]], i32 4)
+; CHECK-NEXT:    [[CLASS1:%.*]] = call i1 @llvm.is.fpclass.f32(float [[B:%.*]], i32 8)
+; CHECK-NEXT:    [[XOR:%.*]] = xor i1 [[CLASS0]], [[CLASS1]]
+; CHECK-NEXT:    ret i1 [[XOR]]
+;
+  %class0 = call i1 @llvm.is.fpclass.f32(float %a, i32 4)
+  %class1 = call i1 @llvm.is.fpclass.f32(float %b, i32 8)
+  %xor = xor i1 %class0, %class1
+  ret i1 %xor
+}
+
+define <2 x i1> @test_fold_xor_class_v2f32(<2 x float> %a) {
+; CHECK-LABEL: @test_fold_xor_class_v2f32(
+; CHECK-NEXT:    [[CLASS0:%.*]] = call <2 x i1> @llvm.is.fpclass.v2f32(<2 x float> [[A:%.*]], i32 4)
+; CHECK-NEXT:    [[CLASS1:%.*]] = call <2 x i1> @llvm.is.fpclass.v2f32(<2 x float> [[A]], i32 8)
+; CHECK-NEXT:    [[XOR:%.*]] = or <2 x i1> [[CLASS0]], [[CLASS1]]
+; CHECK-NEXT:    ret <2 x i1> [[XOR]]
+;
+  %class0 = call <2 x i1> @llvm.is.fpclass.v2f32(<2 x float> %a, i32 4)
+  %class1 = call <2 x i1> @llvm.is.fpclass.v2f32(<2 x float> %a, i32 8)
+  %xor = or <2 x i1> %class0, %class1
+  ret <2 x i1> %xor
+}
+
 declare i1 @llvm.is.fpclass.f32(float, i32 immarg)
 declare i1 @llvm.is.fpclass.f64(double, i32 immarg)
 declare <2 x i1> @llvm.is.fpclass.v2f32(<2 x float>, i32 immarg)


        


More information about the llvm-commits mailing list