[llvm-branch-commits] [llvm] InstCombine: Handle fsub in SimplifyDemandedFPClass (PR #175852)

via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Tue Jan 13 13:57:12 PST 2026


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-llvm-support

Author: Matt Arsenault (arsenm)

<details>
<summary>Changes</summary>

alive2 fails on some of the tests, but this is due to existing
folds in instsimplify and https://github.com/AliveToolkit/alive2/issues/1273

---

Patch is 36.18 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/175852.diff


5 Files Affected:

- (modified) llvm/include/llvm/Support/KnownFPClass.h (+5) 
- (modified) llvm/lib/Analysis/ValueTracking.cpp (+17-61) 
- (modified) llvm/lib/Support/KnownFPClass.cpp (+21) 
- (modified) llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp (+11-4) 
- (modified) llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-fsub.ll (+55-73) 


``````````diff
diff --git a/llvm/include/llvm/Support/KnownFPClass.h b/llvm/include/llvm/Support/KnownFPClass.h
index e2b0d20c790a9..010ca6a3e84ec 100644
--- a/llvm/include/llvm/Support/KnownFPClass.h
+++ b/llvm/include/llvm/Support/KnownFPClass.h
@@ -222,6 +222,11 @@ struct KnownFPClass {
   fadd_self(const KnownFPClass &Src,
             DenormalMode Mode = DenormalMode::getDynamic());
 
+  /// Report known values for fsub
+  LLVM_ABI static KnownFPClass
+  fsub(const KnownFPClass &LHS, const KnownFPClass &RHS,
+       DenormalMode Mode = DenormalMode::getDynamic());
+
   /// Report known values for fmul
   LLVM_ABI static KnownFPClass
   fmul(const KnownFPClass &LHS, const KnownFPClass &RHS,
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index 3dc321b28a060..471080cf66c17 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -5510,78 +5510,34 @@ void computeKnownFPClass(const Value *V, const APInt &DemandedElts,
                         KnownRHS, Q, Depth + 1);
 
     // Special case fadd x, x, which is the canonical form of fmul x, 2.
-    bool SelfAdd = Op->getOperand(0) == Op->getOperand(1) &&
-                   isGuaranteedNotToBeUndef(Op->getOperand(0), Q.AC, Q.CxtI,
-                                            Q.DT, Depth + 1);
-    if (SelfAdd)
+    bool Self = Op->getOperand(0) == Op->getOperand(1) &&
+                isGuaranteedNotToBeUndef(Op->getOperand(0), Q.AC, Q.CxtI, Q.DT,
+                                         Depth + 1);
+    if (Self)
       KnownLHS = KnownRHS;
 
     if ((WantNaN && KnownRHS.isKnownNeverNaN()) ||
         (WantNegative && KnownRHS.cannotBeOrderedLessThanZero()) ||
         WantNegZero || Opc == Instruction::FSub) {
 
-      if (!SelfAdd) {
-        // RHS is canonically cheaper to compute. Skip inspecting the LHS if
-        // there's no point.
-        computeKnownFPClass(Op->getOperand(0), DemandedElts, InterestedSrcs,
-                            KnownLHS, Q, Depth + 1);
-      }
-
-      // Adding positive and negative infinity produces NaN.
-      // TODO: Check sign of infinities.
-      if (KnownLHS.isKnownNeverNaN() && KnownRHS.isKnownNeverNaN() &&
-          (KnownLHS.isKnownNeverInfinity() || KnownRHS.isKnownNeverInfinity()))
-        Known.knownNot(fcNan);
-
       // FIXME: Context function should always be passed in separately
       const Function *F = cast<Instruction>(Op)->getFunction();
+      const fltSemantics &FltSem =
+          Op->getType()->getScalarType()->getFltSemantics();
+      DenormalMode Mode =
+          F ? F->getDenormalMode(FltSem) : DenormalMode::getDynamic();
 
-      if (Op->getOpcode() == Instruction::FAdd) {
-        if (KnownLHS.cannotBeOrderedLessThanZero() &&
-            KnownRHS.cannotBeOrderedLessThanZero())
-          Known.knownNot(KnownFPClass::OrderedLessThanZeroMask);
-        if (KnownLHS.cannotBeOrderedGreaterThanZero() &&
-            KnownRHS.cannotBeOrderedGreaterThanZero())
-          Known.knownNot(KnownFPClass::OrderedGreaterThanZeroMask);
-
-        if (!F)
-          break;
-
-        const fltSemantics &FltSem =
-            Op->getType()->getScalarType()->getFltSemantics();
-        DenormalMode Mode = F->getDenormalMode(FltSem);
-
-        // Doubling 0 will give the same 0.
-        if (SelfAdd && KnownRHS.isKnownNeverLogicalPosZero(Mode) &&
-            (Mode.Output == DenormalMode::IEEE ||
-             (Mode.Output == DenormalMode::PreserveSign &&
-              KnownRHS.isKnownNeverPosSubnormal()) ||
-             (Mode.Output == DenormalMode::PositiveZero &&
-              KnownRHS.isKnownNeverSubnormal())))
-          Known.knownNot(fcPosZero);
-
-        // (fadd x, 0.0) is guaranteed to return +0.0, not -0.0.
-        if ((KnownLHS.isKnownNeverLogicalNegZero(Mode) ||
-             KnownRHS.isKnownNeverLogicalNegZero(Mode)) &&
-            // Make sure output negative denormal can't flush to -0
-            (Mode.Output == DenormalMode::IEEE ||
-             Mode.Output == DenormalMode::PositiveZero))
-          Known.knownNot(fcNegZero);
+      if (Self && Opc == Instruction::FAdd) {
+        Known = KnownFPClass::fadd_self(KnownLHS, Mode);
       } else {
-        if (!F)
-          break;
+        // RHS is canonically cheaper to compute. Skip inspecting the LHS if
+        // there's no point.
+        computeKnownFPClass(Op->getOperand(0), DemandedElts, InterestedSrcs,
+                            KnownLHS, Q, Depth + 1);
 
-        const fltSemantics &FltSem =
-            Op->getType()->getScalarType()->getFltSemantics();
-        DenormalMode Mode = F->getDenormalMode(FltSem);
-
-        // Only fsub -0, +0 can return -0
-        if ((KnownLHS.isKnownNeverLogicalNegZero(Mode) ||
-             KnownRHS.isKnownNeverLogicalPosZero(Mode)) &&
-            // Make sure output negative denormal can't flush to -0
-            (Mode.Output == DenormalMode::IEEE ||
-             Mode.Output == DenormalMode::PositiveZero))
-          Known.knownNot(fcNegZero);
+        Known = Opc == Instruction::FAdd
+                    ? KnownFPClass::fadd(KnownLHS, KnownRHS, Mode)
+                    : KnownFPClass::fsub(KnownLHS, KnownRHS, Mode);
       }
     }
 
diff --git a/llvm/lib/Support/KnownFPClass.cpp b/llvm/lib/Support/KnownFPClass.cpp
index ae8c4a9133897..dbd5707873f5d 100644
--- a/llvm/lib/Support/KnownFPClass.cpp
+++ b/llvm/lib/Support/KnownFPClass.cpp
@@ -279,6 +279,27 @@ KnownFPClass KnownFPClass::fadd_self(const KnownFPClass &KnownSrc,
   return Known;
 }
 
+KnownFPClass KnownFPClass::fsub(const KnownFPClass &KnownLHS,
+                                const KnownFPClass &KnownRHS,
+                                DenormalMode Mode) {
+  KnownFPClass Known;
+  // Adding positive and negative infinity produces NaN.
+  // TODO: Check sign of infinities.
+  if (KnownLHS.isKnownNeverNaN() && KnownRHS.isKnownNeverNaN() &&
+      (KnownLHS.isKnownNeverInfinity() || KnownRHS.isKnownNeverInfinity()))
+    Known.knownNot(fcNan);
+
+  // Only fsub -0, +0 can return -0
+  if ((KnownLHS.isKnownNeverLogicalNegZero(Mode) ||
+       KnownRHS.isKnownNeverLogicalPosZero(Mode)) &&
+      // Make sure output negative denormal can't flush to -0
+      (Mode.Output == DenormalMode::IEEE ||
+       Mode.Output == DenormalMode::PositiveZero))
+    Known.knownNot(fcNegZero);
+
+  return Known;
+}
+
 KnownFPClass KnownFPClass::fmul(const KnownFPClass &KnownLHS,
                                 const KnownFPClass &KnownRHS,
                                 DenormalMode Mode) {
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
index 58499bdd0f8e9..295d148494b52 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
@@ -2081,13 +2081,15 @@ Value *InstCombinerImpl::SimplifyDemandedUseFPClass(Instruction *I,
     Known.fneg();
     break;
   }
-  case Instruction::FAdd: {
+  case Instruction::FAdd:
+  case Instruction::FSub: {
     KnownFPClass KnownLHS, KnownRHS;
 
     const SimplifyQuery &SQ = getSimplifyQuery();
 
     // fadd x, x can be handled more aggressively.
     if (I->getOperand(0) == I->getOperand(1) &&
+        I->getOpcode() == Instruction::FAdd &&
         isGuaranteedNotToBeUndef(I->getOperand(0), SQ.AC, CxtI, SQ.DT,
                                  Depth + 1)) {
       Type *EltTy = VTy->getScalarType();
@@ -2141,7 +2143,10 @@ Value *InstCombinerImpl::SimplifyDemandedUseFPClass(Instruction *I,
 
       Type *EltTy = VTy->getScalarType();
       DenormalMode Mode = F.getDenormalMode(EltTy->getFltSemantics());
-      Known = KnownFPClass::fadd(KnownLHS, KnownRHS, Mode);
+
+      Known = I->getOpcode() == Instruction::FAdd
+                  ? KnownFPClass::fadd(KnownLHS, KnownRHS, Mode)
+                  : KnownFPClass::fsub(KnownLHS, KnownRHS, Mode);
     }
 
     FPClassTest ValidResults = DemandedMask & Known.KnownFPClasses;
@@ -2157,11 +2162,13 @@ Value *InstCombinerImpl::SimplifyDemandedUseFPClass(Instruction *I,
     }
 
     // With nnan: X + {+/-}Inf --> {+/-}Inf
-    if (KnownRHS.isKnownAlways(fcInf | fcNan) &&
-        KnownLHS.isKnownNever(fcNan))
+    if (I->getOpcode() == Instruction::FAdd &&
+        KnownRHS.isKnownAlways(fcInf | fcNan) && KnownLHS.isKnownNever(fcNan)) {
       return I->getOperand(1);
+    }
 
     // With nnan: {+/-}Inf + X --> {+/-}Inf
+    // With nnan: {+/-}Inf - X --> {+/-}Inf
     if (KnownLHS.isKnownAlways(fcInf | fcNan) &&
         KnownRHS.isKnownNever(fcNan))
       return I->getOperand(0);
diff --git a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-fsub.ll b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-fsub.ll
index 53c2817612662..b4a98bd59c71c 100644
--- a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-fsub.ll
+++ b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-fsub.ll
@@ -34,8 +34,7 @@ declare void @use(half)
 define nofpclass(inf zero sub norm) half @ret_only_nan(half %x, half %y) {
 ; CHECK-LABEL: define nofpclass(inf zero sub norm) half @ret_only_nan(
 ; CHECK-SAME: half [[X:%.*]], half [[Y:%.*]]) {
-; CHECK-NEXT:    [[ADD:%.*]] = fsub half [[X]], [[Y]]
-; CHECK-NEXT:    ret half [[ADD]]
+; CHECK-NEXT:    ret half 0xH7E00
 ;
   %add = fsub half %x, %y
   ret half %add
@@ -64,7 +63,7 @@ define nofpclass(qnan inf zero sub norm) half @ret_only_snan(half %x, half %y) {
 define nofpclass(nan inf sub norm) half @ret_only_zero(half %x, half %y) {
 ; CHECK-LABEL: define nofpclass(nan inf sub norm) half @ret_only_zero(
 ; CHECK-SAME: half [[X:%.*]], half [[Y:%.*]]) {
-; CHECK-NEXT:    [[ADD:%.*]] = fsub half [[X]], [[Y]]
+; CHECK-NEXT:    [[ADD:%.*]] = fsub nnan half [[X]], [[Y]]
 ; CHECK-NEXT:    ret half [[ADD]]
 ;
   %add = fsub half %x, %y
@@ -92,7 +91,7 @@ define nofpclass(nan inf pzero sub norm) half @ret_only_nzero(half %x, half %y)
 define nofpclass(nan zero sub norm) half @ret_only_inf(half %x, half %y) {
 ; CHECK-LABEL: define nofpclass(nan zero sub norm) half @ret_only_inf(
 ; CHECK-SAME: half [[X:%.*]], half [[Y:%.*]]) {
-; CHECK-NEXT:    [[ADD:%.*]] = fsub half [[X]], [[Y]]
+; CHECK-NEXT:    [[ADD:%.*]] = fsub nnan half [[X]], [[Y]]
 ; CHECK-NEXT:    ret half [[ADD]]
 ;
   %add = fsub half %x, %y
@@ -218,9 +217,7 @@ define nofpclass(nan inf) half @ret_nofpclass_inf_nan__fsub_select_unknown_or_in
 ; CHECK-SAME: i1 [[COND:%.*]], half [[X:%.*]], half [[Y:%.*]]) {
 ; CHECK-NEXT:    [[INF0:%.*]] = call half @returns_inf()
 ; CHECK-NEXT:    [[INF1:%.*]] = call half @returns_inf()
-; CHECK-NEXT:    [[X_OR_INF:%.*]] = select i1 [[COND]], half [[X]], half [[INF0]]
-; CHECK-NEXT:    [[Y_OR_INF:%.*]] = select i1 [[COND]], half [[Y]], half [[INF1]]
-; CHECK-NEXT:    [[ADD:%.*]] = fsub half [[X_OR_INF]], [[Y_OR_INF]]
+; CHECK-NEXT:    [[ADD:%.*]] = fsub nnan half [[X]], [[Y]]
 ; CHECK-NEXT:    ret half [[ADD]]
 ;
   %inf0 = call half @returns_inf()
@@ -236,7 +233,7 @@ define nofpclass(inf sub norm) half @nan_result_demands_inf_input_lhs(i1 %cond,
 ; CHECK-LABEL: define nofpclass(inf sub norm) half @nan_result_demands_inf_input_lhs(
 ; CHECK-SAME: i1 [[COND:%.*]], half nofpclass(zero) [[X:%.*]], half nofpclass(nan inf zero) [[Y:%.*]]) {
 ; CHECK-NEXT:    [[PINF:%.*]] = call half @returns_pinf()
-; CHECK-NEXT:    [[X_OR_INF:%.*]] = select i1 [[COND]], half [[X]], half [[PINF]]
+; CHECK-NEXT:    [[X_OR_INF:%.*]] = select i1 [[COND]], half [[X]], half 0xH7C00
 ; CHECK-NEXT:    [[ADD:%.*]] = fsub half [[X_OR_INF]], [[Y]]
 ; CHECK-NEXT:    ret half [[ADD]]
 ;
@@ -251,7 +248,7 @@ define nofpclass(inf sub norm) half @nan_result_demands_inf_input_rhs(i1 %cond,
 ; CHECK-LABEL: define nofpclass(inf sub norm) half @nan_result_demands_inf_input_rhs(
 ; CHECK-SAME: i1 [[COND:%.*]], half nofpclass(zero) [[X:%.*]], half [[Y:%.*]]) {
 ; CHECK-NEXT:    [[PINF:%.*]] = call half @returns_pinf()
-; CHECK-NEXT:    [[Y_OR_INF:%.*]] = select i1 [[COND]], half [[Y]], half [[PINF]]
+; CHECK-NEXT:    [[Y_OR_INF:%.*]] = select i1 [[COND]], half [[Y]], half 0xH7C00
 ; CHECK-NEXT:    [[ADD:%.*]] = fsub half [[X]], [[Y_OR_INF]]
 ; CHECK-NEXT:    ret half [[ADD]]
 ;
@@ -267,7 +264,7 @@ define nofpclass(nan sub norm zero) half @inf_result_demands_inf_input_lhs(i1 %c
 ; CHECK-SAME: i1 [[COND:%.*]], half nofpclass(zero) [[X:%.*]], half nofpclass(zero) [[Y:%.*]]) {
 ; CHECK-NEXT:    [[INF:%.*]] = call half @returns_inf()
 ; CHECK-NEXT:    [[X_OR_INF:%.*]] = select i1 [[COND]], half [[X]], half [[INF]]
-; CHECK-NEXT:    [[ADD:%.*]] = fsub half [[X_OR_INF]], [[Y]]
+; CHECK-NEXT:    [[ADD:%.*]] = fsub nnan half [[X_OR_INF]], [[Y]]
 ; CHECK-NEXT:    ret half [[ADD]]
 ;
   %inf = call half @returns_inf()
@@ -282,7 +279,7 @@ define nofpclass(nan sub norm zero) half @inf_result_demands_inf_input_rhs(i1 %c
 ; CHECK-SAME: i1 [[COND:%.*]], half nofpclass(zero) [[X:%.*]], half nofpclass(zero) [[Y:%.*]]) {
 ; CHECK-NEXT:    [[INF:%.*]] = call half @returns_inf()
 ; CHECK-NEXT:    [[Y_OR_INF:%.*]] = select i1 [[COND]], half [[Y]], half [[INF]]
-; CHECK-NEXT:    [[ADD:%.*]] = fsub half [[X]], [[Y_OR_INF]]
+; CHECK-NEXT:    [[ADD:%.*]] = fsub nnan half [[X]], [[Y_OR_INF]]
 ; CHECK-NEXT:    ret half [[ADD]]
 ;
   %inf = call half @returns_inf()
@@ -296,8 +293,8 @@ define nofpclass(nan sub norm zero) half @inf_result_demands_pinf_input_lhs(i1 %
 ; CHECK-LABEL: define nofpclass(nan zero sub norm) half @inf_result_demands_pinf_input_lhs(
 ; CHECK-SAME: i1 [[COND:%.*]], half nofpclass(zero) [[X:%.*]], half nofpclass(zero) [[Y:%.*]]) {
 ; CHECK-NEXT:    [[PINF:%.*]] = call half @returns_pinf()
-; CHECK-NEXT:    [[X_OR_INF:%.*]] = select i1 [[COND]], half [[X]], half [[PINF]]
-; CHECK-NEXT:    [[ADD:%.*]] = fsub half [[X_OR_INF]], [[Y]]
+; CHECK-NEXT:    [[X_OR_INF:%.*]] = select i1 [[COND]], half [[X]], half 0xH7C00
+; CHECK-NEXT:    [[ADD:%.*]] = fsub nnan half [[X_OR_INF]], [[Y]]
 ; CHECK-NEXT:    ret half [[ADD]]
 ;
   %pinf = call half @returns_pinf()
@@ -311,8 +308,8 @@ define nofpclass(nan sub norm zero) half @inf_result_demands_pinf_input_rhs(i1 %
 ; CHECK-LABEL: define nofpclass(nan zero sub norm) half @inf_result_demands_pinf_input_rhs(
 ; CHECK-SAME: i1 [[COND:%.*]], half nofpclass(zero) [[X:%.*]], half nofpclass(zero) [[Y:%.*]]) {
 ; CHECK-NEXT:    [[PINF:%.*]] = call half @returns_pinf()
-; CHECK-NEXT:    [[Y_OR_INF:%.*]] = select i1 [[COND]], half [[Y]], half [[PINF]]
-; CHECK-NEXT:    [[ADD:%.*]] = fsub half [[X]], [[Y_OR_INF]]
+; CHECK-NEXT:    [[Y_OR_INF:%.*]] = select i1 [[COND]], half [[Y]], half 0xH7C00
+; CHECK-NEXT:    [[ADD:%.*]] = fsub nnan half [[X]], [[Y_OR_INF]]
 ; CHECK-NEXT:    ret half [[ADD]]
 ;
   %pinf = call half @returns_pinf()
@@ -326,8 +323,8 @@ define nofpclass(nan sub norm zero) half @inf_result_demands_ninf_input_lhs(i1 %
 ; CHECK-LABEL: define nofpclass(nan zero sub norm) half @inf_result_demands_ninf_input_lhs(
 ; CHECK-SAME: i1 [[COND:%.*]], half nofpclass(zero) [[X:%.*]], half nofpclass(zero) [[Y:%.*]]) {
 ; CHECK-NEXT:    [[NINF:%.*]] = call half @returns_ninf()
-; CHECK-NEXT:    [[X_OR_INF:%.*]] = select i1 [[COND]], half [[X]], half [[NINF]]
-; CHECK-NEXT:    [[ADD:%.*]] = fsub half [[X_OR_INF]], [[Y]]
+; CHECK-NEXT:    [[X_OR_INF:%.*]] = select i1 [[COND]], half [[X]], half 0xHFC00
+; CHECK-NEXT:    [[ADD:%.*]] = fsub nnan half [[X_OR_INF]], [[Y]]
 ; CHECK-NEXT:    ret half [[ADD]]
 ;
   %ninf = call half @returns_ninf()
@@ -341,8 +338,8 @@ define nofpclass(nan sub norm zero) half @inf_result_demands_ninf_input_rhs(i1 %
 ; CHECK-LABEL: define nofpclass(nan zero sub norm) half @inf_result_demands_ninf_input_rhs(
 ; CHECK-SAME: i1 [[COND:%.*]], half nofpclass(zero) [[X:%.*]], half nofpclass(zero) [[Y:%.*]]) {
 ; CHECK-NEXT:    [[NINF:%.*]] = call half @returns_ninf()
-; CHECK-NEXT:    [[Y_OR_INF:%.*]] = select i1 [[COND]], half [[Y]], half [[NINF]]
-; CHECK-NEXT:    [[ADD:%.*]] = fsub half [[X]], [[Y_OR_INF]]
+; CHECK-NEXT:    [[Y_OR_INF:%.*]] = select i1 [[COND]], half [[Y]], half 0xHFC00
+; CHECK-NEXT:    [[ADD:%.*]] = fsub nnan half [[X]], [[Y_OR_INF]]
 ; CHECK-NEXT:    ret half [[ADD]]
 ;
   %ninf = call half @returns_ninf()
@@ -367,7 +364,7 @@ define nofpclass(snan) half @no_nans_inputs(half nofpclass(nan) %x, half nofpcla
 define nofpclass(nan) half @no_nans_input_and_output(half nofpclass(nan) %x, half nofpclass(nan) %y) {
 ; CHECK-LABEL: define nofpclass(nan) half @no_nans_input_and_output(
 ; CHECK-SAME: half nofpclass(nan) [[X:%.*]], half nofpclass(nan) [[Y:%.*]]) {
-; CHECK-NEXT:    [[ADD:%.*]] = fsub half [[X]], [[Y]]
+; CHECK-NEXT:    [[ADD:%.*]] = fsub nnan half [[X]], [[Y]]
 ; CHECK-NEXT:    ret half [[ADD]]
 ;
   %add = fsub half %x, %y
@@ -390,7 +387,7 @@ define nofpclass(snan) half @no_infs_inputs(half nofpclass(inf) %x, half nofpcla
 define nofpclass(inf) half @no_infs_inputs_and_outputs(half nofpclass(inf) %x, half nofpclass(inf) %y) {
 ; CHECK-LABEL: define nofpclass(inf) half @no_infs_inputs_and_outputs(
 ; CHECK-SAME: half nofpclass(inf) [[X:%.*]], half nofpclass(inf) [[Y:%.*]]) {
-; CHECK-NEXT:    [[ADD:%.*]] = fsub half [[X]], [[Y]]
+; CHECK-NEXT:    [[ADD:%.*]] = fsub ninf half [[X]], [[Y]]
 ; CHECK-NEXT:    ret half [[ADD]]
 ;
   %add = fsub half %x, %y
@@ -401,7 +398,7 @@ define nofpclass(inf) half @no_infs_inputs_and_outputs(half nofpclass(inf) %x, h
 define nofpclass(snan) half @no_nans_infs_inputs(half nofpclass(nan inf) %x, half nofpclass(nan inf) %y) {
 ; CHECK-LABEL: define nofpclass(snan) half @no_nans_infs_inputs(
 ; CHECK-SAME: half nofpclass(nan inf) [[X:%.*]], half nofpclass(nan inf) [[Y:%.*]]) {
-; CHECK-NEXT:    [[ADD:%.*]] = fsub half [[X]], [[Y]]
+; CHECK-NEXT:    [[ADD:%.*]] = fsub nnan half [[X]], [[Y]]
 ; CHECK-NEXT:    ret half [[ADD]]
 ;
   %add = fsub half %x, %y
@@ -412,7 +409,7 @@ define nofpclass(snan) half @no_nans_infs_inputs(half nofpclass(nan inf) %x, hal
 define nofpclass(inf) half @no_nans_infs_inputs__noinfs_output(half nofpclass(nan inf) %x, half nofpclass(nan inf) %y) {
 ; CHECK-LABEL: define nofpclass(inf) half @no_nans_infs_inputs__noinfs_output(
 ; CHECK-SAME: half nofpclass(nan inf) [[X:%.*]], half nofpclass(nan inf) [[Y:%.*]]) {
-; CHECK-NEXT:    [[ADD:%.*]] = fsub half [[X]], [[Y]]
+; CHECK-NEXT:    [[ADD:%.*]] = fsub nnan ninf half [[X]], [[Y]]
 ; CHECK-NEXT:    ret half [[ADD]]
 ;
   %add = fsub half %x, %y
@@ -423,7 +420,7 @@ define nofpclass(inf) half @no_nans_infs_inputs__noinfs_output(half nofpclass(na
 define nofpclass(nan) half @no_nans_infs_inputs__nonans_output(half nofpclass(nan inf) %x, half nofpclass(nan inf) %y) {
 ; CHECK-LABEL: define nofpclass(nan) half @no_nans_infs_inputs__nonans_output(
 ; CHECK-SAME: half nofpclass(nan inf) [[X:%.*]], half nofpclass(nan inf) [[Y:%.*]]) {
-; CHECK-NEXT:    [[ADD:%.*]] = fsub half [[X]], [[Y]]
+; CHECK-NEXT:    [[ADD:%.*]] = fsub nnan half [[X]], [[Y]]
 ; CHECK-NEXT:    ret half [[ADD]]
 ;
   %add = fsub half %x, %y
@@ -434,7 +431,7 @@ define nofpclass(nan) half @no_nans_infs_inputs__nonans_output(half nofpclass(na
 define nofpclass(nzero) half @inferred_nan_output__noinfs_only_lhs(half nofpclass(nan inf) %x, half nofpclass(nan) %y) {
 ; CHECK-LABEL: define nofpclass(nzero) half @inferred_nan_output__noinfs_only_lhs(
 ; CHECK-SAME: half nofpclass(nan inf) [[X:%.*]], half nofpclass(nan) [[Y:%.*]]) {
-; CHECK-NEXT:    [[ADD:%.*]] = fsub half [[X]], [[Y]]
+; CHECK-NEXT:    [[ADD:%.*]] = fsub nnan half [[X]], [[Y]]
 ; CHECK-NEXT:    ret half [[ADD]]
 ;
   %add = fsub half %x, %y
@@ -445,7 +442,7 @@ define nofpclass(nzero) half @inferred_nan_output__noinfs_only_lhs(half nofpclas
 define nofpclass(nzero) half @inferred_nan_output__noinfs_only_rhs(half nofpclass(nan) %x, half nofpclass(nan inf) %y) {
 ; CHECK-LABEL: define nofpclass(nzero) half @inferred_nan_output__noinfs_only_rhs(
 ; CHECK-SAME: half nofpclass(nan) [[X:%.*]], half nofpclass(nan inf) [[Y:%.*]]) {
-; CHECK-NEXT:    [[ADD:%.*]] = fsub half [[X]], [[Y]]
+; CHECK-NEXT:    [[ADD:%.*]] = fsub nnan half [[X]], [[Y]]
 ; CHECK-NEXT:    ret half [[ADD]]
 ;
   %add = fsub half %x, %y
@@ -516,7 +513,7 @@ define nofpclass(nan) half @ret_nonan_fabs_fsub_known_positive_or_nan_sources()
 ; CHECK-LABEL: define nofpclass(nan) half @ret_nonan_fabs_fsub_known_positive_or_nan_sources() {
 ; CHECK-NEXT:    [[POSITIVE_OR_NAN0:%.*]] = call half @returns_positive_or_nan()
 ; CHECK-NEXT:    [[POSITIVE_OR_NAN1:%.*]] = call half @returns_positive_or_nan()
-; CHECK-NEXT:    [[KNOWN_POSITIVE_ADD:%.*]] = f...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/175852


More information about the llvm-branch-commits mailing list