Skip to content

Commit

Permalink
ValueTracking: Implement computeKnownFPClass for fdiv for nan handling
Browse files Browse the repository at this point in the history
  • Loading branch information
arsenm committed Apr 20, 2023
1 parent 66a06e2 commit f6d79ad
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 15 deletions.
34 changes: 34 additions & 0 deletions llvm/lib/Analysis/ValueTracking.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4628,6 +4628,40 @@ void computeKnownFPClass(const Value *V, const APInt &DemandedElts,

break;
}
case Instruction::FDiv: {
const bool WantNan = (InterestedClasses & fcNan) != fcNone;
if (!WantNan)
break;

// TODO: FRem
KnownFPClass KnownLHS, KnownRHS;

computeKnownFPClass(Op->getOperand(1), DemandedElts,
fcNan | fcInf | fcZero | fcSubnormal, KnownRHS,
Depth + 1, Q, TLI);

bool KnowSomethingUseful = KnownRHS.isKnownNeverNaN() ||
KnownRHS.isKnownNeverInfinity() ||
KnownRHS.isKnownNeverZero();

if (KnowSomethingUseful) {
computeKnownFPClass(Op->getOperand(0), DemandedElts,
fcNan | fcInf | fcZero, KnownLHS, Depth + 1, Q, TLI);
}

const Function *F = cast<Instruction>(Op)->getFunction();

// Only 0/0, Inf/Inf, Inf REM x and x REM 0 produce NaN.
// TODO: Track sign bit.
if (KnownLHS.isKnownNeverNaN() && KnownRHS.isKnownNeverNaN() &&
(KnownLHS.isKnownNeverInfinity() || KnownRHS.isKnownNeverInfinity()) &&
(KnownLHS.isKnownNeverLogicalZero(*F, Op->getType()) ||
KnownRHS.isKnownNeverLogicalZero(*F, Op->getType()))) {
Known.knownNot(fcNan);
}

break;
}
case Instruction::FPTrunc: {
if ((InterestedClasses & fcNan) == fcNone)
break;
Expand Down
30 changes: 15 additions & 15 deletions llvm/test/Transforms/Attributor/nofpclass-fdiv.ll
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ define float @ret_fdiv_ieee_all__nonan_noinf_nozero(float %arg0, float nofpclass
}

define float @ret_fdiv_ieee_nonan_noinf_nozero__nonan(float nofpclass(nan inf zero) %arg0, float nofpclass(nan) %arg1) #0 {
; CHECK-LABEL: define float @ret_fdiv_ieee_nonan_noinf_nozero__nonan
; CHECK-LABEL: define nofpclass(nan) float @ret_fdiv_ieee_nonan_noinf_nozero__nonan
; CHECK-SAME: (float nofpclass(nan inf zero) [[ARG0:%.*]], float nofpclass(nan) [[ARG1:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: [[FDIV:%.*]] = fdiv float [[ARG0]], [[ARG1]]
; CHECK-NEXT: ret float [[FDIV]]
Expand All @@ -62,7 +62,7 @@ define float @ret_fdiv_ieee_nonan_noinf_nozero__nonan(float nofpclass(nan inf ze
}

define float @ret_fdiv_ieee_nonan__nonan_noinf_nozero(float nofpclass(nan) %arg0, float nofpclass(nan inf zero) %arg1) #0 {
; CHECK-LABEL: define float @ret_fdiv_ieee_nonan__nonan_noinf_nozero
; CHECK-LABEL: define nofpclass(nan) float @ret_fdiv_ieee_nonan__nonan_noinf_nozero
; CHECK-SAME: (float nofpclass(nan) [[ARG0:%.*]], float nofpclass(nan inf zero) [[ARG1:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: [[FDIV:%.*]] = fdiv float [[ARG0]], [[ARG1]]
; CHECK-NEXT: ret float [[FDIV]]
Expand All @@ -72,7 +72,7 @@ define float @ret_fdiv_ieee_nonan__nonan_noinf_nozero(float nofpclass(nan) %arg0
}

define float @ret_fdiv_ieee_nonan_nozero__nonan_noinf(float nofpclass(nan zero) %arg0, float nofpclass(nan inf) %arg1) #0 {
; CHECK-LABEL: define float @ret_fdiv_ieee_nonan_nozero__nonan_noinf
; CHECK-LABEL: define nofpclass(nan) float @ret_fdiv_ieee_nonan_nozero__nonan_noinf
; CHECK-SAME: (float nofpclass(nan zero) [[ARG0:%.*]], float nofpclass(nan inf) [[ARG1:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: [[FDIV:%.*]] = fdiv float [[ARG0]], [[ARG1]]
; CHECK-NEXT: ret float [[FDIV]]
Expand All @@ -82,7 +82,7 @@ define float @ret_fdiv_ieee_nonan_nozero__nonan_noinf(float nofpclass(nan zero)
}

define float @ret_fdiv_ieee_nonan_noinf__nonan_nozero(float nofpclass(nan inf) %arg0, float nofpclass(nan zero) %arg1) #0 {
; CHECK-LABEL: define float @ret_fdiv_ieee_nonan_noinf__nonan_nozero
; CHECK-LABEL: define nofpclass(nan) float @ret_fdiv_ieee_nonan_noinf__nonan_nozero
; CHECK-SAME: (float nofpclass(nan inf) [[ARG0:%.*]], float nofpclass(nan zero) [[ARG1:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: [[FDIV:%.*]] = fdiv float [[ARG0]], [[ARG1]]
; CHECK-NEXT: ret float [[FDIV]]
Expand Down Expand Up @@ -112,7 +112,7 @@ define float @ret_fdiv_daz_nonan_noinf__nonan_nozero(float nofpclass(nan inf) %a
}

define float @ret_fdiv_daz_nonan_nozero_nosub__nonan_noinf(float nofpclass(nan zero sub) %arg0, float nofpclass(nan inf) %arg1) #1 {
; CHECK-LABEL: define float @ret_fdiv_daz_nonan_nozero_nosub__nonan_noinf
; CHECK-LABEL: define nofpclass(nan) float @ret_fdiv_daz_nonan_nozero_nosub__nonan_noinf
; CHECK-SAME: (float nofpclass(nan zero sub) [[ARG0:%.*]], float nofpclass(nan inf) [[ARG1:%.*]]) #[[ATTR1]] {
; CHECK-NEXT: [[FDIV:%.*]] = fdiv float [[ARG0]], [[ARG1]]
; CHECK-NEXT: ret float [[FDIV]]
Expand All @@ -122,7 +122,7 @@ define float @ret_fdiv_daz_nonan_nozero_nosub__nonan_noinf(float nofpclass(nan z
}

define float @ret_fdiv_daz_nonan_noinf__nonan_nozero_nosub(float nofpclass(nan inf) %arg0, float nofpclass(nan zero sub) %arg1) #1 {
; CHECK-LABEL: define float @ret_fdiv_daz_nonan_noinf__nonan_nozero_nosub
; CHECK-LABEL: define nofpclass(nan) float @ret_fdiv_daz_nonan_noinf__nonan_nozero_nosub
; CHECK-SAME: (float nofpclass(nan inf) [[ARG0:%.*]], float nofpclass(nan zero sub) [[ARG1:%.*]]) #[[ATTR1]] {
; CHECK-NEXT: [[FDIV:%.*]] = fdiv float [[ARG0]], [[ARG1]]
; CHECK-NEXT: ret float [[FDIV]]
Expand All @@ -142,7 +142,7 @@ define float @ret_fdiv_ieee_nonan_noinf__nonan_noinf(float nofpclass(nan) %arg0,
}

define float @ret_fdiv_ieee_nonan_noinf_nozero__nonan_noinf_nozero(float nofpclass(nan inf zero) %arg0, float nofpclass(nan inf zero) %arg1) #0 {
; CHECK-LABEL: define float @ret_fdiv_ieee_nonan_noinf_nozero__nonan_noinf_nozero
; CHECK-LABEL: define nofpclass(nan) float @ret_fdiv_ieee_nonan_noinf_nozero__nonan_noinf_nozero
; CHECK-SAME: (float nofpclass(nan inf zero) [[ARG0:%.*]], float nofpclass(nan inf zero) [[ARG1:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: [[FDIV:%.*]] = fdiv float [[ARG0]], [[ARG1]]
; CHECK-NEXT: ret float [[FDIV]]
Expand Down Expand Up @@ -192,7 +192,7 @@ define float @ret_fdiv_ieee_nonan_noinf_noinf__nonan_noinf_noinf(float nofpclass
}

define float @ret_fdiv_ieee_nonan_noinf_nozero__nonan_noinf_noinf(float nofpclass(nan inf zero) %arg0, float nofpclass(nan inf) %arg1) #0 {
; CHECK-LABEL: define float @ret_fdiv_ieee_nonan_noinf_nozero__nonan_noinf_noinf
; CHECK-LABEL: define nofpclass(nan) float @ret_fdiv_ieee_nonan_noinf_nozero__nonan_noinf_noinf
; CHECK-SAME: (float nofpclass(nan inf zero) [[ARG0:%.*]], float nofpclass(nan inf) [[ARG1:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: [[FDIV:%.*]] = fdiv float [[ARG0]], [[ARG1]]
; CHECK-NEXT: ret float [[FDIV]]
Expand All @@ -202,7 +202,7 @@ define float @ret_fdiv_ieee_nonan_noinf_nozero__nonan_noinf_noinf(float nofpclas
}

define float @ret_fdiv_ieee_nonan_noinf_noinf__nonan_noinf_nozero(float nofpclass(nan inf) %arg0, float nofpclass(nan inf zero) %arg1) #0 {
; CHECK-LABEL: define float @ret_fdiv_ieee_nonan_noinf_noinf__nonan_noinf_nozero
; CHECK-LABEL: define nofpclass(nan) float @ret_fdiv_ieee_nonan_noinf_noinf__nonan_noinf_nozero
; CHECK-SAME: (float nofpclass(nan inf) [[ARG0:%.*]], float nofpclass(nan inf zero) [[ARG1:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: [[FDIV:%.*]] = fdiv float [[ARG0]], [[ARG1]]
; CHECK-NEXT: ret float [[FDIV]]
Expand Down Expand Up @@ -232,7 +232,7 @@ define float @ret_fdiv_ieee_nonan_noinf_noposzero__nonan_noinf_noinf(float nofpc
}

define float @ret_fdiv_ieee_nonan_noinf_nozero_nosub__nonan_noinf_nozero_nosub(float nofpclass(nan inf zero sub) %arg0, float nofpclass(nan inf zero sub) %arg1) #0 {
; CHECK-LABEL: define float @ret_fdiv_ieee_nonan_noinf_nozero_nosub__nonan_noinf_nozero_nosub
; CHECK-LABEL: define nofpclass(nan) float @ret_fdiv_ieee_nonan_noinf_nozero_nosub__nonan_noinf_nozero_nosub
; CHECK-SAME: (float nofpclass(nan inf zero sub) [[ARG0:%.*]], float nofpclass(nan inf zero sub) [[ARG1:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: [[FDIV:%.*]] = fdiv float [[ARG0]], [[ARG1]]
; CHECK-NEXT: ret float [[FDIV]]
Expand All @@ -243,7 +243,7 @@ define float @ret_fdiv_ieee_nonan_noinf_nozero_nosub__nonan_noinf_nozero_nosub(f

; Denormal mode doesn't matter because sources are nofpclass(sub)
define float @ret_fdiv_daz_nonan_noinf_nozero_nosub__nonan_noinf_nozero_nosub(float nofpclass(nan inf zero sub) %arg0, float nofpclass(nan inf zero sub) %arg1) #1 {
; CHECK-LABEL: define float @ret_fdiv_daz_nonan_noinf_nozero_nosub__nonan_noinf_nozero_nosub
; CHECK-LABEL: define nofpclass(nan) float @ret_fdiv_daz_nonan_noinf_nozero_nosub__nonan_noinf_nozero_nosub
; CHECK-SAME: (float nofpclass(nan inf zero sub) [[ARG0:%.*]], float nofpclass(nan inf zero sub) [[ARG1:%.*]]) #[[ATTR1]] {
; CHECK-NEXT: [[FDIV:%.*]] = fdiv float [[ARG0]], [[ARG1]]
; CHECK-NEXT: ret float [[FDIV]]
Expand All @@ -253,7 +253,7 @@ define float @ret_fdiv_daz_nonan_noinf_nozero_nosub__nonan_noinf_nozero_nosub(fl
}

define float @ret_fdiv_dapz_nonan_noinf_nozero_nosub__nonan_noinf_nozero_nosub(float nofpclass(nan inf zero sub) %arg0, float nofpclass(nan inf zero sub) %arg1) #2 {
; CHECK-LABEL: define float @ret_fdiv_dapz_nonan_noinf_nozero_nosub__nonan_noinf_nozero_nosub
; CHECK-LABEL: define nofpclass(nan) float @ret_fdiv_dapz_nonan_noinf_nozero_nosub__nonan_noinf_nozero_nosub
; CHECK-SAME: (float nofpclass(nan inf zero sub) [[ARG0:%.*]], float nofpclass(nan inf zero sub) [[ARG1:%.*]]) #[[ATTR2]] {
; CHECK-NEXT: [[FDIV:%.*]] = fdiv float [[ARG0]], [[ARG1]]
; CHECK-NEXT: ret float [[FDIV]]
Expand All @@ -263,7 +263,7 @@ define float @ret_fdiv_dapz_nonan_noinf_nozero_nosub__nonan_noinf_nozero_nosub(f
}

define float @ret_fdiv_dynamic_nonan_noinf_nozero_nosub__nonan_noinf_nozero_nosub(float nofpclass(nan inf zero sub) %arg0, float nofpclass(nan inf zero sub) %arg1) #3 {
; CHECK-LABEL: define float @ret_fdiv_dynamic_nonan_noinf_nozero_nosub__nonan_noinf_nozero_nosub
; CHECK-LABEL: define nofpclass(nan) float @ret_fdiv_dynamic_nonan_noinf_nozero_nosub__nonan_noinf_nozero_nosub
; CHECK-SAME: (float nofpclass(nan inf zero sub) [[ARG0:%.*]], float nofpclass(nan inf zero sub) [[ARG1:%.*]]) #[[ATTR3]] {
; CHECK-NEXT: [[FDIV:%.*]] = fdiv float [[ARG0]], [[ARG1]]
; CHECK-NEXT: ret float [[FDIV]]
Expand All @@ -274,7 +274,7 @@ define float @ret_fdiv_dynamic_nonan_noinf_nozero_nosub__nonan_noinf_nozero_nosu

; Missing no-subnormal on lhs
define float @ret_fdiv_daz_nonan_noinf_nozero__nonan_noinf_nozero_nosub(float nofpclass(nan inf zero) %arg0, float nofpclass(nan inf zero sub) %arg1) #1 {
; CHECK-LABEL: define float @ret_fdiv_daz_nonan_noinf_nozero__nonan_noinf_nozero_nosub
; CHECK-LABEL: define nofpclass(nan) float @ret_fdiv_daz_nonan_noinf_nozero__nonan_noinf_nozero_nosub
; CHECK-SAME: (float nofpclass(nan inf zero) [[ARG0:%.*]], float nofpclass(nan inf zero sub) [[ARG1:%.*]]) #[[ATTR1]] {
; CHECK-NEXT: [[FDIV:%.*]] = fdiv float [[ARG0]], [[ARG1]]
; CHECK-NEXT: ret float [[FDIV]]
Expand All @@ -285,7 +285,7 @@ define float @ret_fdiv_daz_nonan_noinf_nozero__nonan_noinf_nozero_nosub(float no

; Missing no-subnormal on lhs
define float @ret_fdiv_daz_nonan_noinf_nozero_nosub__nonan_noinf_nozero(float nofpclass(nan inf zero sub) %arg0, float nofpclass(nan inf zero) %arg1) #1 {
; CHECK-LABEL: define float @ret_fdiv_daz_nonan_noinf_nozero_nosub__nonan_noinf_nozero
; CHECK-LABEL: define nofpclass(nan) float @ret_fdiv_daz_nonan_noinf_nozero_nosub__nonan_noinf_nozero
; CHECK-SAME: (float nofpclass(nan inf zero sub) [[ARG0:%.*]], float nofpclass(nan inf zero) [[ARG1:%.*]]) #[[ATTR1]] {
; CHECK-NEXT: [[FDIV:%.*]] = fdiv float [[ARG0]], [[ARG1]]
; CHECK-NEXT: ret float [[FDIV]]
Expand Down

0 comments on commit f6d79ad

Please sign in to comment.