diff --git a/llvm/test/Transforms/InstCombine/is_fpclass.ll b/llvm/test/Transforms/InstCombine/is_fpclass.ll index b0ad07077a543..b95021f6176dd 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)