Skip to content

Commit 85e2487

Browse files
committed
[InstCombine] Handle isSubnormalOrZero idiom
1 parent 2634222 commit 85e2487

File tree

2 files changed

+13
-15
lines changed

2 files changed

+13
-15
lines changed

llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1884,17 +1884,23 @@ Instruction *InstCombinerImpl::foldICmpAndConstConst(ICmpInst &Cmp,
18841884
// llvm.is.fpclass(X, fcInf|fcNan)
18851885
// (icmp ne (and (bitcast X to int), ExponentMask), ExponentMask) -->
18861886
// llvm.is.fpclass(X, ~(fcInf|fcNan))
1887+
// (icmp eq (and (bitcast X to int), ExponentMask), 0) -->
1888+
// llvm.is.fpclass(X, fcSubnormal|fcZero)
1889+
// (icmp ne (and (bitcast X to int), ExponentMask), 0) -->
1890+
// llvm.is.fpclass(X, ~(fcSubnormal|fcZero))
18871891
Value *V;
18881892
if (!Cmp.getParent()->getParent()->hasFnAttribute(
18891893
Attribute::NoImplicitFloat) &&
18901894
Cmp.isEquality() &&
18911895
match(X, m_OneUse(m_ElementWiseBitCast(m_Value(V))))) {
18921896
Type *FPType = V->getType()->getScalarType();
1893-
if (FPType->isIEEELikeFPTy() && C1 == *C2) {
1897+
if (FPType->isIEEELikeFPTy() && (C1.isZero() || C1 == *C2)) {
18941898
APInt ExponentMask =
18951899
APFloat::getInf(FPType->getFltSemantics()).bitcastToAPInt();
1896-
if (C1 == ExponentMask) {
1897-
unsigned Mask = FPClassTest::fcNan | FPClassTest::fcInf;
1900+
if (*C2 == ExponentMask) {
1901+
unsigned Mask = C1.isZero()
1902+
? FPClassTest::fcZero | FPClassTest::fcSubnormal
1903+
: FPClassTest::fcNan | FPClassTest::fcInf;
18981904
if (isICMP_NE)
18991905
Mask = ~Mask & fcAllFlags;
19001906
return replaceInstUsesWith(Cmp, Builder.createIsFPClass(V, Mask));

llvm/test/Transforms/InstCombine/fpclass-check-idioms.ll

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -569,9 +569,7 @@ define i1 @f32_fcnan_fcinf_noimplicitfloat_strictfp(float %a) strictfp #0 {
569569
define i1 @f32_fcsubnormal_fczero(float %a) {
570570
; CHECK-LABEL: define i1 @f32_fcsubnormal_fczero(
571571
; CHECK-SAME: float [[A:%.*]]) {
572-
; CHECK-NEXT: [[I32:%.*]] = bitcast float [[A]] to i32
573-
; CHECK-NEXT: [[AND:%.*]] = and i32 [[I32]], 2139095040
574-
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0
572+
; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.is.fpclass.f32(float [[A]], i32 240)
575573
; CHECK-NEXT: ret i1 [[CMP]]
576574
;
577575
%i32 = bitcast float %a to i32
@@ -583,9 +581,7 @@ define i1 @f32_fcsubnormal_fczero(float %a) {
583581
define i1 @f32_not_fcsubnormal_fczero(float %a) {
584582
; CHECK-LABEL: define i1 @f32_not_fcsubnormal_fczero(
585583
; CHECK-SAME: float [[A:%.*]]) {
586-
; CHECK-NEXT: [[I32:%.*]] = bitcast float [[A]] to i32
587-
; CHECK-NEXT: [[AND:%.*]] = and i32 [[I32]], 2139095040
588-
; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[AND]], 0
584+
; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.is.fpclass.f32(float [[A]], i32 783)
589585
; CHECK-NEXT: ret i1 [[CMP]]
590586
;
591587
%i32 = bitcast float %a to i32
@@ -597,9 +593,7 @@ define i1 @f32_not_fcsubnormal_fczero(float %a) {
597593
define <2 x i1> @f64_fcsubnormal_fczero_vec(<2 x double> %a) {
598594
; CHECK-LABEL: define <2 x i1> @f64_fcsubnormal_fczero_vec(
599595
; CHECK-SAME: <2 x double> [[A:%.*]]) {
600-
; CHECK-NEXT: [[I64:%.*]] = bitcast <2 x double> [[A]] to <2 x i64>
601-
; CHECK-NEXT: [[AND:%.*]] = and <2 x i64> [[I64]], splat (i64 9218868437227405312)
602-
; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i64> [[AND]], zeroinitializer
596+
; CHECK-NEXT: [[CMP:%.*]] = call <2 x i1> @llvm.is.fpclass.v2f64(<2 x double> [[A]], i32 240)
603597
; CHECK-NEXT: ret <2 x i1> [[CMP]]
604598
;
605599
%i64 = bitcast <2 x double> %a to <2 x i64>
@@ -611,9 +605,7 @@ define <2 x i1> @f64_fcsubnormal_fczero_vec(<2 x double> %a) {
611605
define <2 x i1> @f64_no_fcsubnormal_fczero_vec(<2 x double> %a) {
612606
; CHECK-LABEL: define <2 x i1> @f64_no_fcsubnormal_fczero_vec(
613607
; CHECK-SAME: <2 x double> [[A:%.*]]) {
614-
; CHECK-NEXT: [[I64:%.*]] = bitcast <2 x double> [[A]] to <2 x i64>
615-
; CHECK-NEXT: [[AND:%.*]] = and <2 x i64> [[I64]], splat (i64 9218868437227405312)
616-
; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i64> [[AND]], zeroinitializer
608+
; CHECK-NEXT: [[CMP:%.*]] = call <2 x i1> @llvm.is.fpclass.v2f64(<2 x double> [[A]], i32 783)
617609
; CHECK-NEXT: ret <2 x i1> [[CMP]]
618610
;
619611
%i64 = bitcast <2 x double> %a to <2 x i64>

0 commit comments

Comments
 (0)