Skip to content

Commit

Permalink
InstCombine: Fold negations of is_fpclass intrinsics
Browse files Browse the repository at this point in the history
Can invert the result by inverting the test mask.
  • Loading branch information
arsenm committed Dec 13, 2022
1 parent b7232da commit 19d428f
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 12 deletions.
8 changes: 8 additions & 0 deletions llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
Expand Up @@ -3743,6 +3743,14 @@ Instruction *InstCombinerImpl::foldNot(BinaryOperator &I) {
Value *InvMaxMin = Builder.CreateBinaryIntrinsic(InvID, X, NotY);
return replaceInstUsesWith(I, InvMaxMin);
}

if (II->getIntrinsicID() == Intrinsic::is_fpclass) {
ConstantInt *ClassMask = cast<ConstantInt>(II->getArgOperand(1));
II->setArgOperand(
1, ConstantInt::get(ClassMask->getType(),
~ClassMask->getZExtValue() & fcAllFlags));
return replaceInstUsesWith(I, II);
}
}

if (NotOp->hasOneUse()) {
Expand Down
20 changes: 8 additions & 12 deletions llvm/test/Transforms/InstCombine/is_fpclass.ll
Expand Up @@ -357,9 +357,8 @@ define i1 @test_class_is_nan_other_nnan_src(float %x) {

define i1 @test_class_not_is_nan(float %x) {
; CHECK-LABEL: define {{[^@]+}}@test_class_not_is_nan(
; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[X:%.*]], i32 3)
; CHECK-NEXT: [[NOT:%.*]] = xor i1 [[CLASS]], true
; CHECK-NEXT: ret i1 [[NOT]]
; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[X:%.*]], i32 1020)
; CHECK-NEXT: ret i1 [[CLASS]]
;
%class = call i1 @llvm.is.fpclass.f32(float %x, i32 3)
%not = xor i1 %class, true
Expand All @@ -381,9 +380,8 @@ define i1 @test_class_not_is_nan_multi_use(float %x, ptr %ptr) {

define i1 @test_class_not_is_inf_nan(float %x) {
; CHECK-LABEL: define {{[^@]+}}@test_class_not_is_inf_nan(
; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[X:%.*]], i32 519)
; CHECK-NEXT: [[NOT:%.*]] = xor i1 [[CLASS]], true
; CHECK-NEXT: ret i1 [[NOT]]
; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[X:%.*]], i32 504)
; CHECK-NEXT: ret i1 [[CLASS]]
;
%class = call i1 @llvm.is.fpclass.f32(float %x, i32 519)
%not = xor i1 %class, true
Expand All @@ -392,9 +390,8 @@ define i1 @test_class_not_is_inf_nan(float %x) {

define i1 @test_class_not_is_normal(float %x) {
; CHECK-LABEL: define {{[^@]+}}@test_class_not_is_normal(
; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[X:%.*]], i32 264)
; CHECK-NEXT: [[NOT:%.*]] = xor i1 [[CLASS]], true
; CHECK-NEXT: ret i1 [[NOT]]
; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[X:%.*]], i32 759)
; CHECK-NEXT: ret i1 [[CLASS]]
;
%class = call i1 @llvm.is.fpclass.f32(float %x, i32 264)
%not = xor i1 %class, true
Expand All @@ -413,9 +410,8 @@ define i1 @test_class_xor_false(float %x) {

define <2 x i1> @test_class_not_vector(<2 x float> %x) {
; CHECK-LABEL: define {{[^@]+}}@test_class_not_vector(
; CHECK-NEXT: [[CLASS:%.*]] = call <2 x i1> @llvm.is.fpclass.v2f32(<2 x float> [[X:%.*]], i32 33)
; CHECK-NEXT: [[NOT:%.*]] = xor <2 x i1> [[CLASS]], <i1 true, i1 true>
; CHECK-NEXT: ret <2 x i1> [[NOT]]
; CHECK-NEXT: [[CLASS:%.*]] = call <2 x i1> @llvm.is.fpclass.v2f32(<2 x float> [[X:%.*]], i32 990)
; CHECK-NEXT: ret <2 x i1> [[CLASS]]
;
%class = call <2 x i1> @llvm.is.fpclass.v2f32(<2 x float> %x, i32 33)
%not = xor <2 x i1> %class, <i1 true, i1 true>
Expand Down

0 comments on commit 19d428f

Please sign in to comment.