Repository navigation
[KnownFPClass] Improve fadd/fsub deductions around infinity classes - #239064
ZERICO2005 wants to merge 3 commits into
Conversation
|
@llvm/pr-subscribers-llvm-transforms @llvm/pr-subscribers-llvm-support Author: Eric Ross (ZERICO2005) ChangesImprove Also adds test coverage for Patch is 57.90 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/239064.diff 5 Files Affected:
diff --git a/llvm/lib/Support/KnownFPClass.cpp b/llvm/lib/Support/KnownFPClass.cpp
index f9d8dd1ec20b9..5b0097774fb94 100644
--- a/llvm/lib/Support/KnownFPClass.cpp
+++ b/llvm/lib/Support/KnownFPClass.cpp
@@ -498,19 +498,32 @@ static KnownFPClass fadd_impl(const KnownFPClass &KnownLHS,
const KnownFPClass &KnownRHS, bool IsFMA) {
KnownFPClass Known;
- if (KnownLHS.cannotBeOrderedLessThanZero() &&
- KnownRHS.cannotBeOrderedLessThanZero()) {
- Known.knownNot(KnownFPClass::OrderedLessThanZeroMask);
+ // Rule out infinity.
+ if (KnownLHS.isKnownNever(fcPosInf) && KnownRHS.isKnownNever(fcPosInf) &&
+ (KnownLHS.isKnownNever(fcPosSubnormal | fcPosNormal) ||
+ KnownRHS.isKnownNever(fcPosSubnormal | fcPosNormal)))
+ Known.knownNot(fcPosInf);
+ if (KnownLHS.isKnownNever(fcNegInf) && KnownRHS.isKnownNever(fcNegInf) &&
+ (KnownLHS.isKnownNever(fcNegSubnormal | fcNegNormal) ||
+ KnownRHS.isKnownNever(fcNegSubnormal | fcNegNormal)))
+ Known.knownNot(fcNegInf);
+
+ // Rule out finite.
+ // The only reason this is valid for fma is because fmul will never report a
+ // result where normal is ruled out but overflow is possible (different from
+ // exact infinity).
+ if (KnownLHS.isKnownNever(fcNegSubnormal | fcNegNormal) &&
+ KnownRHS.isKnownNever(fcNegSubnormal | fcNegNormal)) {
+ Known.knownNot(fcNegSubnormal | fcNegNormal);
// This can't underflow if one of the operands is known normal.
if (KnownLHS.isKnownNever(fcZero | fcPosSubnormal) ||
KnownRHS.isKnownNever(fcZero | fcPosSubnormal))
Known.knownNot(fcZero | fcPosSubnormal);
}
-
- if (KnownLHS.cannotBeOrderedGreaterThanZero() &&
- KnownRHS.cannotBeOrderedGreaterThanZero()) {
- Known.knownNot(KnownFPClass::OrderedGreaterThanZeroMask);
+ if (KnownLHS.isKnownNever(fcPosSubnormal | fcPosNormal) &&
+ KnownRHS.isKnownNever(fcPosSubnormal | fcPosNormal)) {
+ Known.knownNot(fcPosSubnormal | fcPosNormal);
// This can't underflow if one of the operands is known normal.
if (KnownLHS.isKnownNever(fcZero | fcNegSubnormal) ||
diff --git a/llvm/test/Transforms/Attributor/nofpclass-fadd-fsub.ll b/llvm/test/Transforms/Attributor/nofpclass-fadd-fsub.ll
index 2385e189c1130..0d83ec12ff151 100644
--- a/llvm/test/Transforms/Attributor/nofpclass-fadd-fsub.ll
+++ b/llvm/test/Transforms/Attributor/nofpclass-fadd-fsub.ll
@@ -631,8 +631,6 @@ define float @fadd_known_positive_normal_dapz(float nofpclass(ninf nnorm nzero)
ret float %add
}
-
-
define float @fadd_self(float noundef %arg) {
; CHECK-LABEL: define noundef float @fadd_self(
; CHECK-SAME: float noundef [[ARG:%.*]]) #[[ATTR0]] {
@@ -774,7 +772,7 @@ define float @fadd_self_no_noninf_nnorm(float noundef nofpclass(ninf nnorm) %arg
}
define float @fadd_self_no_pnorm_psub(float noundef nofpclass(pnorm psub) %arg) {
-; CHECK-LABEL: define noundef nofpclass(psub) float @fadd_self_no_pnorm_psub(
+; CHECK-LABEL: define noundef nofpclass(psub pnorm) float @fadd_self_no_pnorm_psub(
; CHECK-SAME: float noundef nofpclass(psub pnorm) [[ARG:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: [[ADD:%.*]] = fadd float [[ARG]], [[ARG]]
; CHECK-NEXT: ret float [[ADD]]
@@ -784,7 +782,7 @@ define float @fadd_self_no_pnorm_psub(float noundef nofpclass(pnorm psub) %arg)
}
define float @fadd_self_no_nnorm_nsub(float noundef nofpclass(nnorm nsub) %arg) {
-; CHECK-LABEL: define noundef nofpclass(nsub) float @fadd_self_no_nnorm_nsub(
+; CHECK-LABEL: define noundef nofpclass(nsub nnorm) float @fadd_self_no_nnorm_nsub(
; CHECK-SAME: float noundef nofpclass(nsub nnorm) [[ARG:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: [[ADD:%.*]] = fadd float [[ARG]], [[ARG]]
; CHECK-NEXT: ret float [[ADD]]
@@ -1208,8 +1206,6 @@ define float @fadd_self_no_zero__output_only_is_dynamic(float noundef nofpclass(
ret float %add
}
-
-
define float @fadd_self_no_zero__output_only_is_ftpz(float noundef nofpclass(zero) %arg) #4 {
; CHECK-LABEL: define noundef nofpclass(nzero) float @fadd_self_no_zero__output_only_is_ftpz(
; CHECK-SAME: float noundef nofpclass(zero) [[ARG:%.*]]) #[[ATTR5]] {
@@ -1295,7 +1291,7 @@ define half @known_negative_normal_or_inf__fadd__known_negative_or_nan(half nofp
}
define float @fsub__lhs_nzero__rhs_psub(float nofpclass(nan inf pzero sub norm) %lhs, float nofpclass(nan inf zero nsub norm) %rhs) {
-; CHECK-LABEL: define nofpclass(nan pinf nzero psub pnorm) float @fsub__lhs_nzero__rhs_psub(
+; CHECK-LABEL: define nofpclass(nan inf nzero psub pnorm) float @fsub__lhs_nzero__rhs_psub(
; CHECK-SAME: float nofpclass(nan inf pzero sub norm) [[LHS:%.*]], float nofpclass(nan inf zero nsub norm) [[RHS:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: [[SUB:%.*]] = fsub float [[LHS]], [[RHS]]
; CHECK-NEXT: ret float [[SUB]]
@@ -1306,7 +1302,7 @@ define float @fsub__lhs_nzero__rhs_psub(float nofpclass(nan inf pzero sub norm)
; We shall not rule out negative zero: -0.0 - dapz(psub) == -0.0 - +0.0 == -0.0
define float @fsub__lhs_nzero__rhs_psub__mode_ieee_dapz(float nofpclass(nan inf pzero sub norm) %lhs, float nofpclass(nan inf zero nsub norm) %rhs) #5 {
-; CHECK-LABEL: define nofpclass(nan pinf psub pnorm) float @fsub__lhs_nzero__rhs_psub__mode_ieee_dapz(
+; CHECK-LABEL: define nofpclass(nan inf psub pnorm) float @fsub__lhs_nzero__rhs_psub__mode_ieee_dapz(
; CHECK-SAME: float nofpclass(nan inf pzero sub norm) [[LHS:%.*]], float nofpclass(nan inf zero nsub norm) [[RHS:%.*]]) #[[ATTR7]] {
; CHECK-NEXT: [[SUB:%.*]] = fsub float [[LHS]], [[RHS]]
; CHECK-NEXT: ret float [[SUB]]
@@ -1317,7 +1313,7 @@ define float @fsub__lhs_nzero__rhs_psub__mode_ieee_dapz(float nofpclass(nan inf
; We shall not rule out negative zero: -0.0 - daz(psub) == -0.0 - +0.0 == -0.0
define float @fsub__lhs_nzero__rhs_psub__mode_ieee_daz(float nofpclass(nan inf pzero sub norm) %lhs, float nofpclass(nan inf zero nsub norm) %rhs) #2 {
-; CHECK-LABEL: define nofpclass(nan pinf psub pnorm) float @fsub__lhs_nzero__rhs_psub__mode_ieee_daz(
+; CHECK-LABEL: define nofpclass(nan inf psub pnorm) float @fsub__lhs_nzero__rhs_psub__mode_ieee_daz(
; CHECK-SAME: float nofpclass(nan inf pzero sub norm) [[LHS:%.*]], float nofpclass(nan inf zero nsub norm) [[RHS:%.*]]) #[[ATTR4]] {
; CHECK-NEXT: [[SUB:%.*]] = fsub float [[LHS]], [[RHS]]
; CHECK-NEXT: ret float [[SUB]]
@@ -1327,7 +1323,7 @@ define float @fsub__lhs_nzero__rhs_psub__mode_ieee_daz(float nofpclass(nan inf p
}
define float @fsub__lhs_nzero__rhs_psub__mode_ftpz_dapz(float nofpclass(nan inf pzero sub norm) %lhs, float nofpclass(nan inf zero nsub norm) %rhs) #3 {
-; CHECK-LABEL: define nofpclass(nan pinf psub pnorm) float @fsub__lhs_nzero__rhs_psub__mode_ftpz_dapz(
+; CHECK-LABEL: define nofpclass(nan inf psub pnorm) float @fsub__lhs_nzero__rhs_psub__mode_ftpz_dapz(
; CHECK-SAME: float nofpclass(nan inf pzero sub norm) [[LHS:%.*]], float nofpclass(nan inf zero nsub norm) [[RHS:%.*]]) #[[ATTR2]] {
; CHECK-NEXT: [[SUB:%.*]] = fsub float [[LHS]], [[RHS]]
; CHECK-NEXT: ret float [[SUB]]
@@ -1337,7 +1333,7 @@ define float @fsub__lhs_nzero__rhs_psub__mode_ftpz_dapz(float nofpclass(nan inf
}
define float @fsub__lhs_nzero__rhs_psub__mode_dynamic_dapz(float nofpclass(nan inf pzero sub norm) %lhs, float nofpclass(nan inf zero nsub norm) %rhs) #7 {
-; CHECK-LABEL: define nofpclass(nan pinf psub pnorm) float @fsub__lhs_nzero__rhs_psub__mode_dynamic_dapz(
+; CHECK-LABEL: define nofpclass(nan inf psub pnorm) float @fsub__lhs_nzero__rhs_psub__mode_dynamic_dapz(
; CHECK-SAME: float nofpclass(nan inf pzero sub norm) [[LHS:%.*]], float nofpclass(nan inf zero nsub norm) [[RHS:%.*]]) #[[ATTR10:[0-9]+]] {
; CHECK-NEXT: [[SUB:%.*]] = fsub float [[LHS]], [[RHS]]
; CHECK-NEXT: ret float [[SUB]]
@@ -1347,7 +1343,7 @@ define float @fsub__lhs_nzero__rhs_psub__mode_dynamic_dapz(float nofpclass(nan i
}
define float @fsub__lhs_nzero__rhs_psub__mode_dynamic_dynamic(float nofpclass(nan inf pzero sub norm) %lhs, float nofpclass(nan inf zero nsub norm) %rhs) #6 {
-; CHECK-LABEL: define nofpclass(nan pinf psub pnorm) float @fsub__lhs_nzero__rhs_psub__mode_dynamic_dynamic(
+; CHECK-LABEL: define nofpclass(nan inf psub pnorm) float @fsub__lhs_nzero__rhs_psub__mode_dynamic_dynamic(
; CHECK-SAME: float nofpclass(nan inf pzero sub norm) [[LHS:%.*]], float nofpclass(nan inf zero nsub norm) [[RHS:%.*]]) #[[ATTR3]] {
; CHECK-NEXT: [[SUB:%.*]] = fsub float [[LHS]], [[RHS]]
; CHECK-NEXT: ret float [[SUB]]
@@ -1356,6 +1352,340 @@ define float @fsub__lhs_nzero__rhs_psub__mode_dynamic_dynamic(float nofpclass(na
ret float %sub
}
+;-------------------------------------------------------------------------------
+
+; Rule out NaN.
+
+define float @fadd__no_nan_ninf__no_nan_ninf(float nofpclass(nan ninf) %lhs, float nofpclass(nan ninf) %rhs) {
+; CHECK-LABEL: define nofpclass(nan) float @fadd__no_nan_ninf__no_nan_ninf(
+; CHECK-SAME: float nofpclass(nan ninf) [[LHS:%.*]], float nofpclass(nan ninf) [[RHS:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT: [[ADD:%.*]] = fadd float [[LHS]], [[RHS]]
+; CHECK-NEXT: ret float [[ADD]]
+;
+ %add = fadd float %lhs, %rhs
+ ret float %add
+}
+
+define float @fadd__no_nan_pinf__no_nan_ninf(float nofpclass(nan pinf) %lhs, float nofpclass(nan ninf) %rhs) {
+; CHECK-LABEL: define nofpclass(snan) float @fadd__no_nan_pinf__no_nan_ninf(
+; CHECK-SAME: float nofpclass(nan pinf) [[LHS:%.*]], float nofpclass(nan ninf) [[RHS:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT: [[ADD:%.*]] = fadd float [[LHS]], [[RHS]]
+; CHECK-NEXT: ret float [[ADD]]
+;
+ %add = fadd float %lhs, %rhs
+ ret float %add
+}
+
+define float @fadd__no_nan_ninf__no_nan_pinf(float nofpclass(nan ninf) %lhs, float nofpclass(nan pinf) %rhs) {
+; CHECK-LABEL: define nofpclass(snan) float @fadd__no_nan_ninf__no_nan_pinf(
+; CHECK-SAME: float nofpclass(nan ninf) [[LHS:%.*]], float nofpclass(nan pinf) [[RHS:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT: [[ADD:%.*]] = fadd float [[LHS]], [[RHS]]
+; CHECK-NEXT: ret float [[ADD]]
+;
+ %add = fadd float %lhs, %rhs
+ ret float %add
+}
+
+define float @fadd__no_nan_pinf__no_nan_pinf(float nofpclass(nan pinf) %lhs, float nofpclass(nan pinf) %rhs) {
+; CHECK-LABEL: define nofpclass(nan) float @fadd__no_nan_pinf__no_nan_pinf(
+; CHECK-SAME: float nofpclass(nan pinf) [[LHS:%.*]], float nofpclass(nan pinf) [[RHS:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT: [[ADD:%.*]] = fadd float [[LHS]], [[RHS]]
+; CHECK-NEXT: ret float [[ADD]]
+;
+ %add = fadd float %lhs, %rhs
+ ret float %add
+}
+
+define float @fsub__no_nan_ninf__no_nan_ninf(float nofpclass(nan ninf) %lhs, float nofpclass(nan ninf) %rhs) {
+; CHECK-LABEL: define nofpclass(snan) float @fsub__no_nan_ninf__no_nan_ninf(
+; CHECK-SAME: float nofpclass(nan ninf) [[LHS:%.*]], float nofpclass(nan ninf) [[RHS:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT: [[SUB:%.*]] = fsub float [[LHS]], [[RHS]]
+; CHECK-NEXT: ret float [[SUB]]
+;
+ %sub = fsub float %lhs, %rhs
+ ret float %sub
+}
+
+define float @fsub__no_nan_pinf__no_nan_ninf(float nofpclass(nan pinf) %lhs, float nofpclass(nan ninf) %rhs) {
+; CHECK-LABEL: define nofpclass(nan) float @fsub__no_nan_pinf__no_nan_ninf(
+; CHECK-SAME: float nofpclass(nan pinf) [[LHS:%.*]], float nofpclass(nan ninf) [[RHS:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT: [[SUB:%.*]] = fsub float [[LHS]], [[RHS]]
+; CHECK-NEXT: ret float [[SUB]]
+;
+ %sub = fsub float %lhs, %rhs
+ ret float %sub
+}
+
+define float @fsub__no_nan_ninf__no_nan_pinf(float nofpclass(nan ninf) %lhs, float nofpclass(nan pinf) %rhs) {
+; CHECK-LABEL: define nofpclass(nan) float @fsub__no_nan_ninf__no_nan_pinf(
+; CHECK-SAME: float nofpclass(nan ninf) [[LHS:%.*]], float nofpclass(nan pinf) [[RHS:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT: [[SUB:%.*]] = fsub float [[LHS]], [[RHS]]
+; CHECK-NEXT: ret float [[SUB]]
+;
+ %sub = fsub float %lhs, %rhs
+ ret float %sub
+}
+
+define float @fsub__no_nan_pinf__no_nan_pinf(float nofpclass(nan pinf) %lhs, float nofpclass(nan pinf) %rhs) {
+; CHECK-LABEL: define nofpclass(snan) float @fsub__no_nan_pinf__no_nan_pinf(
+; CHECK-SAME: float nofpclass(nan pinf) [[LHS:%.*]], float nofpclass(nan pinf) [[RHS:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT: [[SUB:%.*]] = fsub float [[LHS]], [[RHS]]
+; CHECK-NEXT: ret float [[SUB]]
+;
+ %sub = fsub float %lhs, %rhs
+ ret float %sub
+}
+
+;-------------------------------------------------------------------------------
+
+; Rule out infinity.
+
+define float @fadd__no_pinf_psub_pnorm__no_pinf(float nofpclass(pinf psub pnorm) %lhs, float nofpclass(pinf) %rhs) {
+; CHECK-LABEL: define nofpclass(pinf) float @fadd__no_pinf_psub_pnorm__no_pinf(
+; CHECK-SAME: float nofpclass(pinf psub pnorm) [[LHS:%.*]], float nofpclass(pinf) [[RHS:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT: [[ADD:%.*]] = fadd float [[LHS]], [[RHS]]
+; CHECK-NEXT: ret float [[ADD]]
+;
+ %add = fadd float %lhs, %rhs
+ ret float %add
+}
+
+define float @fadd__no_pinf__no_pinf_psub_pnorm(float nofpclass(pinf) %lhs, float nofpclass(pinf psub pnorm) %rhs) {
+; CHECK-LABEL: define nofpclass(pinf) float @fadd__no_pinf__no_pinf_psub_pnorm(
+; CHECK-SAME: float nofpclass(pinf) [[LHS:%.*]], float nofpclass(pinf psub pnorm) [[RHS:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT: [[ADD:%.*]] = fadd float [[LHS]], [[RHS]]
+; CHECK-NEXT: ret float [[ADD]]
+;
+ %add = fadd float %lhs, %rhs
+ ret float %add
+}
+
+define float @fadd__no_pinf_pnorm__no_pinf(float nofpclass(pinf pnorm) %lhs, float nofpclass(pinf) %rhs) {
+; CHECK-LABEL: define float @fadd__no_pinf_pnorm__no_pinf(
+; CHECK-SAME: float nofpclass(pinf pnorm) [[LHS:%.*]], float nofpclass(pinf) [[RHS:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT: [[ADD:%.*]] = fadd float [[LHS]], [[RHS]]
+; CHECK-NEXT: ret float [[ADD]]
+;
+ %add = fadd float %lhs, %rhs
+ ret float %add
+}
+
+define float @fadd__no_pinf__no_pinf_pnorm(float nofpclass(pinf) %lhs, float nofpclass(pinf pnorm) %rhs) {
+; CHECK-LABEL: define float @fadd__no_pinf__no_pinf_pnorm(
+; CHECK-SAME: float nofpclass(pinf) [[LHS:%.*]], float nofpclass(pinf pnorm) [[RHS:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT: [[ADD:%.*]] = fadd float [[LHS]], [[RHS]]
+; CHECK-NEXT: ret float [[ADD]]
+;
+ %add = fadd float %lhs, %rhs
+ ret float %add
+}
+
+define float @fadd__no_pinf_pnorm__no_pinf_pnorm(float nofpclass(pinf pnorm) %lhs, float nofpclass(pinf pnorm) %rhs) {
+; CHECK-LABEL: define float @fadd__no_pinf_pnorm__no_pinf_pnorm(
+; CHECK-SAME: float nofpclass(pinf pnorm) [[LHS:%.*]], float nofpclass(pinf pnorm) [[RHS:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT: [[ADD:%.*]] = fadd float [[LHS]], [[RHS]]
+; CHECK-NEXT: ret float [[ADD]]
+;
+ %add = fadd float %lhs, %rhs
+ ret float %add
+}
+
+define float @fadd__no_ninf_nsub_nnorm__no_ninf(float nofpclass(ninf nsub nnorm) %lhs, float nofpclass(ninf) %rhs) {
+; CHECK-LABEL: define nofpclass(ninf) float @fadd__no_ninf_nsub_nnorm__no_ninf(
+; CHECK-SAME: float nofpclass(ninf nsub nnorm) [[LHS:%.*]], float nofpclass(ninf) [[RHS:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT: [[ADD:%.*]] = fadd float [[LHS]], [[RHS]]
+; CHECK-NEXT: ret float [[ADD]]
+;
+ %add = fadd float %lhs, %rhs
+ ret float %add
+}
+
+define float @fadd__no_ninf__no_ninf_nsub_nnorm(float nofpclass(ninf) %lhs, float nofpclass(ninf nsub nnorm) %rhs) {
+; CHECK-LABEL: define nofpclass(ninf) float @fadd__no_ninf__no_ninf_nsub_nnorm(
+; CHECK-SAME: float nofpclass(ninf) [[LHS:%.*]], float nofpclass(ninf nsub nnorm) [[RHS:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT: [[ADD:%.*]] = fadd float [[LHS]], [[RHS]]
+; CHECK-NEXT: ret float [[ADD]]
+;
+ %add = fadd float %lhs, %rhs
+ ret float %add
+}
+
+define float @fadd__no_ninf_nnorm__no_ninf(float nofpclass(ninf nnorm) %lhs, float nofpclass(ninf) %rhs) {
+; CHECK-LABEL: define float @fadd__no_ninf_nnorm__no_ninf(
+; CHECK-SAME: float nofpclass(ninf nnorm) [[LHS:%.*]], float nofpclass(ninf) [[RHS:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT: [[ADD:%.*]] = fadd float [[LHS]], [[RHS]]
+; CHECK-NEXT: ret float [[ADD]]
+;
+ %add = fadd float %lhs, %rhs
+ ret float %add
+}
+
+define float @fadd__no_ninf__no_ninf_nnorm(float nofpclass(ninf) %lhs, float nofpclass(ninf nnorm) %rhs) {
+; CHECK-LABEL: define float @fadd__no_ninf__no_ninf_nnorm(
+; CHECK-SAME: float nofpclass(ninf) [[LHS:%.*]], float nofpclass(ninf nnorm) [[RHS:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT: [[ADD:%.*]] = fadd float [[LHS]], [[RHS]]
+; CHECK-NEXT: ret float [[ADD]]
+;
+ %add = fadd float %lhs, %rhs
+ ret float %add
+}
+
+define float @fadd__no_ninf_nnorm__no_ninf_nnorm(float nofpclass(ninf nnorm) %lhs, float nofpclass(ninf nnorm) %rhs) {
+; CHECK-LABEL: define float @fadd__no_ninf_nnorm__no_ninf_nnorm(
+; CHECK-SAME: float nofpclass(ninf nnorm) [[LHS:%.*]], float nofpclass(ninf nnorm) [[RHS:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT: [[ADD:%.*]] = fadd float [[LHS]], [[RHS]]
+; CHECK-NEXT: ret float [[ADD]]
+;
+ %add = fadd float %lhs, %rhs
+ ret float %add
+}
+
+;-------------------------------------------------------------------------------
+
+; Rule out normal and subnormal classes.
+
+define float @fadd__no_psub_pnorm__no_psub_pnorm(float nofpclass(psub pnorm) %lhs, float nofpclass(psub pnorm) %rhs) {
+; CHECK-LABEL: define nofpclass(psub pnorm) float @fadd__no_psub_pnorm__no_psub_pnorm(
+; CHECK-SAME: float nofpclass(psub pnorm) [[LHS:%.*]], float nofpclass(psub pnorm) [[RHS:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT: [[ADD:%.*]] = fadd float [[LHS]], [[RHS]]
+; CHECK-NEXT: ret float [[ADD]]
+;
+ %add = fadd float %lhs, %rhs
+ ret float %add
+}
+
+define float @fadd__no_zero_sub_pnorm__no_psub_pnorm(float nofpclass(zero sub pnorm) %lhs, float nofpclass(psub pnorm) %rhs) {
+; CHECK-LABEL: define nofpclass(zero sub pnorm) float @fadd__no_zero_sub_pnorm__no_psub_pnorm(
+; CHECK-SAME: float nofpclass(zero sub pnorm) [[LHS:%.*]], float nofpclass(psub pnorm) [[RHS:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT: [[ADD:%.*]] = fadd float [[LHS]], [[RHS]]
+; CHECK-NEXT: ret float [[ADD]]
+;
+ %add = fadd float %lhs, %rhs
+ ret float %add
+}
+
+define float @fadd__no_psub_pnorm__no_zero_sub_pnorm(float nofpclass(psub pnorm) %lhs, float nofpclass(zero sub pnorm) %rhs) {
+; CHECK-LABEL: define nofpclass(zero sub pnorm) float @fadd__no_psub_pnorm__no_zero_sub_pnorm(
+; CHECK-SAME: float nofpclass(psub pnorm) [[LHS:%.*]], float nofpclass(zero sub pnorm) [[RHS:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT: [[ADD:%.*]] = fadd float [[LHS]], [[RHS]]
+; CHECK-NEXT: ret float [[ADD]]
+;
+ %add = fadd float %lhs, %rhs
+ ret float %add
+}
+
+define float @fadd__no_zero_psub_pnorm__no_psub_pnorm(float nofpclass(zero psub pnorm) %lhs, float nofpclass(psub pnorm) %rhs) {
+; CHECK-LABEL: define nofpclass(nzero psub pnorm) float @fadd__no_zero_psub_pnorm__no_psub_pnorm(
+; CHECK-SAME: float nofpclass(zero psub pnorm) [[LHS:%.*]], float nofpclass(psub pnorm) [[RHS:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT: [[ADD:%.*]] = fadd float [[LHS]], [[RHS]]
+; CHECK-NEXT: ret float [[ADD]]
+;
+ %add = fadd float %lhs, %rhs
+ ret float %add
+}
+
+define float @fadd__no_psub_pnorm__no_zero_psub_pnorm(float nofpclass(psub pnorm) %lhs, float nofpclass(zero psub pnorm) %rhs) {
+; CHECK-LABEL: define nofpclass(nzero psub pnorm) float @fadd__no_psub_pnorm__no_zero_psub_pnorm(
+; CHECK-SAME: float nofpclass(psub pnorm) [[LHS:%.*]], float nofpclass(zero psub pnorm) [[RHS:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT: [[ADD:%.*]] = fadd float [[LHS]], [[RHS]]
+; CHECK-NEXT: ret float [[ADD]]
+;
+ %add = fadd float %lhs, %rhs
+ ret float %add
+}
+
+define float @fadd__no_psub_pnorm__no_pnorm(float nofpclass(psub pnorm) %lhs, float nofpclass(pnorm) %rhs) {
+; CHECK-LABEL: define float @fadd__no_psub_pnorm__no_pnorm(
+; CHECK-SAME: float nofpclass(psub pnorm) [[LHS:%.*]], float nofpclass(pnorm) [[RHS:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT: [[ADD:%.*]] = fadd float [[LHS]], [[RHS]]
+; CHECK-NEXT: ret float [[ADD]]
+;
+ %add = fadd float %lhs, %rhs
+ ret float %add
+}
+
+define float @fadd__no_pnorm__no_psub_pnorm(float nofpclass(pnorm) %lhs, float nofpclass(psub pnorm) %rhs) {
+; CHECK-LABEL: define float @fadd__no_pnorm__no_psub_pnorm(
+; CHECK-SAME: float nofpclass(pnorm) [[LHS:%.*]], float nofpclass(psub pnorm) [[RHS:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT: [[ADD:%.*]] = fadd float [[LHS]], [[RHS]]
+; CHECK-NEXT: ret float [[ADD]]
+;
+ %add = fadd float %lhs, %rhs
+ ret float %add
+}
+
+define float @fadd__no_nsub_nnorm__no_nsub_nnorm(float nofpclass(nsub nnorm) %lhs, float nofpclass(nsub nnorm) %rhs) {
+; CHECK-LABEL: define nofpclass(nsub nnorm) float @...
[truncated]
|
| define half @ret_fma_square__nan_inf__any(half noundef nofpclass(zero sub norm) %arg0, half %arg1) { | ||
| ; CHECK-LABEL: define half @ret_fma_square__nan_inf__any( |
There was a problem hiding this comment.
This is the only other case where we could rule out negative infinity for fma_square, since NaN + -inf and +inf + -inf are both NaN. It is not a very useful deduction to go after however, and I just included it for coverage.
| @@ -486,7 +486,7 @@ define <4 x float> @powi_v4f32_i32_constint_odd(<4 x float> %arg) { | |||
| } | |||
|
|
|||
| define <4 x float> @powi_v4f32_i32_regression(<4 x float> %arg) { | |||
| ; CHECK-LABEL: define nofpclass(nzero) <4 x float> @powi_v4f32_i32_regression | |||
| ; CHECK-LABEL: define nofpclass(ninf nzero) <4 x float> @powi_v4f32_i32_regression | |||
There was a problem hiding this comment.
powi(x, 4) produces positive | nan, and (positive | nan) - 1.0 is not negative infinity.
| if (KnownLHS.cannotBeOrderedLessThanZero() && | ||
| KnownRHS.cannotBeOrderedLessThanZero()) { | ||
| Known.knownNot(KnownFPClass::OrderedLessThanZeroMask); | ||
| // Rule out infinity. |
There was a problem hiding this comment.
These changes are also valid for fma, but I will handle them separately after this PR is merged #240081
Improved
fadd/fsubdeductions for ruling out infinity. Additionally, we don't need to worry if one of the inputs is infinity when ruling out finite classes, because adding or subtracting infinity will only result in infinity or NaN.Also adds test coverage for
fadd/fsubNaN deductions.AI Disclosure:
I used Claude Opus 5 to help write the tests and to help analyze the correctness of the changes.