[llvm] [DAG] Add ISD::FSQRT handling to computeKnownFPClass (PR #213620)

Varad Rahul Kamthe via llvm-commits llvm-commits at lists.llvm.org
Mon Aug 3 04:23:28 PDT 2026


https://github.com/varadk27 updated https://github.com/llvm/llvm-project/pull/213620

>From bda910d3fe47bc71309f2ddddca4d8f8a8d8a008 Mon Sep 17 00:00:00 2001
From: Varad Kamthe <varadk.2704 at gmail.com>
Date: Mon, 3 Aug 2026 14:05:20 +0530
Subject: [PATCH 1/2] [DAG] Add ISD::FSQRT handling to computeKnownFPClass

Ports the ISD::FSQRT case from ValueTracking.cpp's computeKnownFPClass
to the SelectionDAG version, per #189583.

sqrt can never produce a negative normal or -infinity; with nnan set,
it also can't produce NaN. Unlike an earlier attempt (#195405), this
does not treat nsz as proof that the result can't be negative zero,
since nsz is a fast-math hint rather than a guarantee -- doing so risks
promoting a value to poison.

Fixes #189583
---
 .../lib/CodeGen/SelectionDAG/SelectionDAG.cpp |  19 +++
 .../CodeGen/RISCV/fold-is-fpclass-sqrt.ll     | 124 ++++++++++++++++++
 2 files changed, 143 insertions(+)
 create mode 100644 llvm/test/CodeGen/RISCV/fold-is-fpclass-sqrt.ll

diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index 683cf2517b2f5..21f2727927e60 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -6191,6 +6191,25 @@ KnownFPClass SelectionDAG::computeKnownFPClass(SDValue Op,
     Known.fneg();
     break;
   }
+  case ISD::FSQRT: {
+    FPClassTest InterestedSrcs = InterestedClasses;
+    if (InterestedClasses & fcNan)
+      InterestedSrcs |= KnownFPClass::OrderedLessThanZeroMask;
+
+    KnownFPClass KnownSrc = computeKnownFPClass(Op.getOperand(0), DemandedElts,
+                                                InterestedSrcs, Depth + 1);
+
+    const fltSemantics &FltSem =
+        Op.getValueType().getScalarType().getFltSemantics();
+    DenormalMode Mode = getMachineFunction().getDenormalMode(FltSem);
+
+    Known = KnownFPClass::sqrt(KnownSrc, Mode);
+
+    if (Op->getFlags().hasNoNaNs())
+      Known.knownNot(fcNan);
+
+    break;
+  }
   case ISD::BUILD_VECTOR: {
     assert(!VT.isScalableVector());
     bool First = true;
diff --git a/llvm/test/CodeGen/RISCV/fold-is-fpclass-sqrt.ll b/llvm/test/CodeGen/RISCV/fold-is-fpclass-sqrt.ll
new file mode 100644
index 0000000000000..9472259c62cc9
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/fold-is-fpclass-sqrt.ll
@@ -0,0 +1,124 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
+; RUN: llc -mtriple=riscv64 -mattr=+f,+d,+v -target-abi=lp64d < %s | FileCheck %s
+
+define i1 @sqrt_nnan_check_f32(float %a0) {
+; CHECK-LABEL: sqrt_nnan_check_f32:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    li a0, 0
+; CHECK-NEXT:    ret
+  %sqr = call nnan float @llvm.sqrt.f32(float %a0)
+  %res = tail call i1 @llvm.is.fpclass.f32(float %sqr, i32 3)
+  ret i1 %res
+}
+
+define i1 @sqrt_neginf_f32(float %a0) {
+; CHECK-LABEL: sqrt_neginf_f32:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    li a0, 0
+; CHECK-NEXT:    ret
+  %sqr = call float @llvm.sqrt.f32(float %a0)
+  %res = tail call i1 @llvm.is.fpclass.f32(float %sqr, i32 4)
+  ret i1 %res
+}
+
+define i1 @sqrt_negnormal_f32(float %a0) {
+; CHECK-LABEL: sqrt_negnormal_f32:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    li a0, 0
+; CHECK-NEXT:    ret
+  %sqr = call float @llvm.sqrt.f32(float %a0)
+  %res = tail call i1 @llvm.is.fpclass.f32(float %sqr, i32 8)
+  ret i1 %res
+}
+
+define i1 @sqrt_nsz_negzero_f32(float %a0) {
+; CHECK-LABEL: sqrt_nsz_negzero_f32:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    fsqrt.s fa5, fa0
+; CHECK-NEXT:    fclass.s a0, fa5
+; CHECK-NEXT:    slli a0, a0, 60
+; CHECK-NEXT:    srli a0, a0, 63
+; CHECK-NEXT:    ret
+  %sqr = call nsz float @llvm.sqrt.f32(float %a0)
+  %res = tail call i1 @llvm.is.fpclass.f32(float %sqr, i32 32)
+  ret i1 %res
+}
+
+define i1 @sqrt_posinf_f32(float %a0) {
+; CHECK-LABEL: sqrt_posinf_f32:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    fsqrt.s fa5, fa0
+; CHECK-NEXT:    fclass.s a0, fa5
+; CHECK-NEXT:    slli a0, a0, 56
+; CHECK-NEXT:    srli a0, a0, 63
+; CHECK-NEXT:    ret
+  %sqr = call float @llvm.sqrt.f32(float %a0)
+  %res = tail call i1 @llvm.is.fpclass.f32(float %sqr, i32 512)
+  ret i1 %res
+}
+
+declare float @llvm.sqrt.f32(float)
+declare i1 @llvm.is.fpclass.f32(float, i32)
+
+declare <vscale x 2 x float> @llvm.sqrt.nxv2f32(<vscale x 2 x float>)
+declare <vscale x 2 x i1> @llvm.is.fpclass.nxv2f32(<vscale x 2 x float>, i32)
+
+define <vscale x 2 x i1> @vsqrt_nnan_check_nxv2f32(<vscale x 2 x float> %a0) {
+; CHECK-LABEL: vsqrt_nnan_check_nxv2f32:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    vsetvli a0, zero, e8, mf4, ta, ma
+; CHECK-NEXT:    vmclr.m v0
+; CHECK-NEXT:    ret
+  %sqr = call nnan <vscale x 2 x float> @llvm.sqrt.nxv2f32(<vscale x 2 x float> %a0)
+  %res = tail call <vscale x 2 x i1> @llvm.is.fpclass.nxv2f32(<vscale x 2 x float> %sqr, i32 3)
+  ret <vscale x 2 x i1> %res
+}
+
+define <vscale x 2 x i1> @vsqrt_neginf_nxv2f32(<vscale x 2 x float> %a0) {
+; CHECK-LABEL: vsqrt_neginf_nxv2f32:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    vsetvli a0, zero, e8, mf4, ta, ma
+; CHECK-NEXT:    vmclr.m v0
+; CHECK-NEXT:    ret
+  %sqr = call <vscale x 2 x float> @llvm.sqrt.nxv2f32(<vscale x 2 x float> %a0)
+  %res = tail call <vscale x 2 x i1> @llvm.is.fpclass.nxv2f32(<vscale x 2 x float> %sqr, i32 4)
+  ret <vscale x 2 x i1> %res
+}
+
+define <vscale x 2 x i1> @vsqrt_negnormal_nxv2f32(<vscale x 2 x float> %a0) {
+; CHECK-LABEL: vsqrt_negnormal_nxv2f32:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    vsetvli a0, zero, e8, mf4, ta, ma
+; CHECK-NEXT:    vmclr.m v0
+; CHECK-NEXT:    ret
+  %sqr = call <vscale x 2 x float> @llvm.sqrt.nxv2f32(<vscale x 2 x float> %a0)
+  %res = tail call <vscale x 2 x i1> @llvm.is.fpclass.nxv2f32(<vscale x 2 x float> %sqr, i32 8)
+  ret <vscale x 2 x i1> %res
+}
+
+define <vscale x 2 x i1> @vsqrt_nsz_negzero_nxv2f32(<vscale x 2 x float> %a0) {
+; CHECK-LABEL: vsqrt_nsz_negzero_nxv2f32:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    vsetvli a0, zero, e32, m1, ta, ma
+; CHECK-NEXT:    vfsqrt.v v8, v8
+; CHECK-NEXT:    vfclass.v v8, v8
+; CHECK-NEXT:    vmseq.vi v0, v8, 8
+; CHECK-NEXT:    ret
+  %sqr = call nsz <vscale x 2 x float> @llvm.sqrt.nxv2f32(<vscale x 2 x float> %a0)
+  %res = tail call <vscale x 2 x i1> @llvm.is.fpclass.nxv2f32(<vscale x 2 x float> %sqr, i32 32)
+  ret <vscale x 2 x i1> %res
+}
+
+define <vscale x 2 x i1> @vsqrt_posinf_nxv2f32(<vscale x 2 x float> %a0) {
+; CHECK-LABEL: vsqrt_posinf_nxv2f32:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    vsetvli a0, zero, e32, m1, ta, ma
+; CHECK-NEXT:    vfsqrt.v v8, v8
+; CHECK-NEXT:    vfclass.v v8, v8
+; CHECK-NEXT:    li a0, 128
+; CHECK-NEXT:    vmseq.vx v0, v8, a0
+; CHECK-NEXT:    ret
+  %sqr = call <vscale x 2 x float> @llvm.sqrt.nxv2f32(<vscale x 2 x float> %a0)
+  %res = tail call <vscale x 2 x i1> @llvm.is.fpclass.nxv2f32(<vscale x 2 x float> %sqr, i32 512)
+  ret <vscale x 2 x i1> %res
+}

>From 5507a8e4c142420915f3b8408a1e0d5644a942b9 Mon Sep 17 00:00:00 2001
From: Varad Kamthe <varadk.2704 at gmail.com>
Date: Mon, 3 Aug 2026 16:52:48 +0530
Subject: [PATCH 2/2] [DAG] Move nnan/ninf flag handling into scope_exit,
 matching IR version

Per review feedback, replaces the manual nnan check in the FSQRT case
with a generic scope_exit-based mechanism applied before the switch,
mirroring ValueTracking.cpp's computeKnownFPClass.

Wraps the switch in an explicit nested block so the scope_exit
destructor runs before the function's return statement, rather than
racing NRVO -- without this, the flag-based exclusion could silently
fail to apply depending on whether the compiler elides the copy.

Diff looks larger than expected because wrapping the switch requires
reindenting the whole block; no logic inside the switch changed.
---
 .../lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 329 +++++++++---------
 1 file changed, 170 insertions(+), 159 deletions(-)

diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index 21f2727927e60..bd95f8ac4c16a 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -20,6 +20,7 @@
 #include "llvm/ADT/DenseSet.h"
 #include "llvm/ADT/FoldingSet.h"
 #include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/ScopeExit.h"
 #include "llvm/ADT/SmallPtrSet.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/Twine.h"
@@ -6178,186 +6179,196 @@ KnownFPClass SelectionDAG::computeKnownFPClass(SDValue Op,
   if (!DemandedElts)
     return Known;
 
-  unsigned Opcode = Op.getOpcode();
-  switch (Opcode) {
-  case ISD::POISON: {
-    Known.KnownFPClasses = fcNone;
-    Known.SignBit = false;
-    break;
-  }
-  case ISD::FNEG: {
-    Known = computeKnownFPClass(Op.getOperand(0), DemandedElts,
-                                InterestedClasses, Depth + 1);
-    Known.fneg();
-    break;
-  }
-  case ISD::FSQRT: {
-    FPClassTest InterestedSrcs = InterestedClasses;
-    if (InterestedClasses & fcNan)
-      InterestedSrcs |= KnownFPClass::OrderedLessThanZeroMask;
+  {
+    FPClassTest KnownNotFromFlags = fcNone;
+    if (Op->getFlags().hasNoNaNs())
+      KnownNotFromFlags |= fcNan;
+    if (Op->getFlags().hasNoInfs())
+      KnownNotFromFlags |= fcInf;
 
-    KnownFPClass KnownSrc = computeKnownFPClass(Op.getOperand(0), DemandedElts,
-                                                InterestedSrcs, Depth + 1);
+    llvm::scope_exit ClearClassesFromFlags(
+        [=, &Known] { Known.knownNot(KnownNotFromFlags); });
 
-    const fltSemantics &FltSem =
-        Op.getValueType().getScalarType().getFltSemantics();
-    DenormalMode Mode = getMachineFunction().getDenormalMode(FltSem);
+    unsigned Opcode = Op.getOpcode();
+    switch (Opcode) {
+    case ISD::POISON: {
+      Known.KnownFPClasses = fcNone;
+      Known.SignBit = false;
+      break;
+    }
+    case ISD::FNEG: {
+      Known = computeKnownFPClass(Op.getOperand(0), DemandedElts,
+                                  InterestedClasses, Depth + 1);
+      Known.fneg();
+      break;
+    }
+    case ISD::FSQRT: {
+      FPClassTest InterestedSrcs = InterestedClasses;
+      if (InterestedClasses & fcNan)
+        InterestedSrcs |= KnownFPClass::OrderedLessThanZeroMask;
 
-    Known = KnownFPClass::sqrt(KnownSrc, Mode);
+      KnownFPClass KnownSrc = computeKnownFPClass(
+          Op.getOperand(0), DemandedElts, InterestedSrcs, Depth + 1);
 
-    if (Op->getFlags().hasNoNaNs())
-      Known.knownNot(fcNan);
+      const fltSemantics &FltSem =
+          Op.getValueType().getScalarType().getFltSemantics();
+      DenormalMode Mode = getMachineFunction().getDenormalMode(FltSem);
 
-    break;
-  }
-  case ISD::BUILD_VECTOR: {
-    assert(!VT.isScalableVector());
-    bool First = true;
-    for (unsigned I = 0, E = Op.getNumOperands(); I != E; ++I) {
-      if (!DemandedElts[I])
-        continue;
+      Known = KnownFPClass::sqrt(KnownSrc, Mode);
+      break;
+    }
+    case ISD::BUILD_VECTOR: {
+      assert(!VT.isScalableVector());
+      bool First = true;
+      for (unsigned I = 0, E = Op.getNumOperands(); I != E; ++I) {
+        if (!DemandedElts[I])
+          continue;
+
+        if (First) {
+          Known = computeKnownFPClass(Op.getOperand(I), InterestedClasses,
+                                      Depth + 1);
+          First = false;
+        } else {
+          Known |= computeKnownFPClass(Op.getOperand(I), InterestedClasses,
+                                       Depth + 1);
+        }
 
-      if (First) {
-        Known =
-            computeKnownFPClass(Op.getOperand(I), InterestedClasses, Depth + 1);
-        First = false;
+        if (Known.isUnknown())
+          break;
+      }
+      break;
+    }
+    case ISD::EXTRACT_VECTOR_ELT: {
+      SDValue Src = Op.getOperand(0);
+      auto *CIdx = dyn_cast<ConstantSDNode>(Op.getOperand(1));
+      EVT SrcVT = Src.getValueType();
+      if (SrcVT.isFixedLengthVector() && CIdx) {
+        if (CIdx->getAPIntValue().ult(SrcVT.getVectorNumElements())) {
+          APInt DemandedSrcElts = APInt::getOneBitSet(
+              SrcVT.getVectorNumElements(), CIdx->getZExtValue());
+          Known = computeKnownFPClass(Src, DemandedSrcElts, InterestedClasses,
+                                      Depth + 1);
+        } else {
+          // Out of bounds index is poison.
+          Known.KnownFPClasses = fcNone;
+        }
       } else {
-        Known |=
-            computeKnownFPClass(Op.getOperand(I), InterestedClasses, Depth + 1);
+        Known = computeKnownFPClass(Src, InterestedClasses, Depth + 1);
       }
-
-      if (Known.isUnknown())
+      break;
+    }
+    case ISD::SPLAT_VECTOR: {
+      Known =
+          computeKnownFPClass(Op.getOperand(0), InterestedClasses, Depth + 1);
+      break;
+    }
+    case ISD::BITCAST: {
+      // FIXME: It should not be necessary to check for an elementwise bitcast.
+      // If a bitcast is not elementwise between vector / scalar types,
+      // computeKnownBits already splices the known bits of the source elements
+      // appropriately so as to line up with the bits of the result's demanded
+      // elements.
+      EVT SrcVT = Op.getOperand(0).getValueType();
+      if (VT.isScalableVector() || SrcVT.isScalableVector())
+        break;
+      unsigned VTNumElts = VT.isVector() ? VT.getVectorNumElements() : 1;
+      unsigned SrcVTNumElts =
+          SrcVT.isVector() ? SrcVT.getVectorNumElements() : 1;
+      if (VTNumElts != SrcVTNumElts)
         break;
+
+      KnownBits Bits = computeKnownBits(Op, DemandedElts, Depth + 1);
+      Known = KnownFPClass::bitcast(VT.getFltSemantics(), Bits);
+      break;
     }
-    break;
-  }
-  case ISD::EXTRACT_VECTOR_ELT: {
-    SDValue Src = Op.getOperand(0);
-    auto *CIdx = dyn_cast<ConstantSDNode>(Op.getOperand(1));
-    EVT SrcVT = Src.getValueType();
-    if (SrcVT.isFixedLengthVector() && CIdx) {
-      if (CIdx->getAPIntValue().ult(SrcVT.getVectorNumElements())) {
-        APInt DemandedSrcElts = APInt::getOneBitSet(
-            SrcVT.getVectorNumElements(), CIdx->getZExtValue());
+    case ISD::FABS: {
+      Known = computeKnownFPClass(Op.getOperand(0), DemandedElts,
+                                  InterestedClasses, Depth + 1);
+      Known.fabs();
+      break;
+    }
+    case ISD::FCOPYSIGN: {
+      Known = computeKnownFPClass(Op.getOperand(0), DemandedElts,
+                                  InterestedClasses, Depth + 1);
+      KnownFPClass KnownSign = computeKnownFPClass(
+          Op.getOperand(1), DemandedElts, InterestedClasses, Depth + 1);
+      Known.copysign(KnownSign);
+      break;
+    }
+    case ISD::AssertNoFPClass: {
+      Known = computeKnownFPClass(Op.getOperand(0), DemandedElts,
+                                  InterestedClasses, Depth + 1);
+      FPClassTest AssertedClasses =
+          static_cast<FPClassTest>(Op->getConstantOperandVal(1));
+      Known.KnownFPClasses &= ~AssertedClasses;
+      break;
+    }
+    case ISD::EXTRACT_SUBVECTOR: {
+      SDValue Src = Op.getOperand(0);
+      EVT SrcVT = Src.getValueType();
+      if (SrcVT.isFixedLengthVector()) {
+        unsigned Idx = Op.getConstantOperandVal(1);
+        unsigned NumSrcElts = SrcVT.getVectorNumElements();
+
+        APInt DemandedSrcElts = DemandedElts.zextOrTrunc(NumSrcElts).shl(Idx);
         Known = computeKnownFPClass(Src, DemandedSrcElts, InterestedClasses,
                                     Depth + 1);
       } else {
-        // Out of bounds index is poison.
-        Known.KnownFPClasses = fcNone;
+        Known = computeKnownFPClass(Src, InterestedClasses, Depth + 1);
       }
-    } else {
-      Known = computeKnownFPClass(Src, InterestedClasses, Depth + 1);
+      break;
     }
-    break;
-  }
-  case ISD::SPLAT_VECTOR: {
-    Known = computeKnownFPClass(Op.getOperand(0), InterestedClasses, Depth + 1);
-    break;
-  }
-  case ISD::BITCAST: {
-    // FIXME: It should not be necessary to check for an elementwise bitcast.
-    // If a bitcast is not elementwise between vector / scalar types,
-    // computeKnownBits already splices the known bits of the source elements
-    // appropriately so as to line up with the bits of the result's demanded
-    // elements.
-    EVT SrcVT = Op.getOperand(0).getValueType();
-    if (VT.isScalableVector() || SrcVT.isScalableVector())
+    case ISD::INSERT_SUBVECTOR: {
+      SDValue BaseVector = Op.getOperand(0);
+      SDValue SubVector = Op.getOperand(1);
+      EVT BaseVT = BaseVector.getValueType();
+      if (BaseVT.isFixedLengthVector()) {
+        unsigned Idx = Op.getConstantOperandVal(2);
+        unsigned NumBaseElts = BaseVT.getVectorNumElements();
+        unsigned NumSubElts = SubVector.getValueType().getVectorNumElements();
+
+        APInt DemandedMask =
+            APInt::getBitsSet(NumBaseElts, Idx, Idx + NumSubElts);
+        APInt DemandedSrcElts = DemandedElts & ~DemandedMask;
+        APInt DemandedSubElts = DemandedElts.extractBits(NumSubElts, Idx);
+
+        if (!DemandedSrcElts.isZero())
+          Known = computeKnownFPClass(BaseVector, DemandedSrcElts,
+                                      InterestedClasses, Depth + 1);
+        if (!DemandedSubElts.isZero()) {
+          KnownFPClass SubKnown = computeKnownFPClass(
+              SubVector, DemandedSubElts, InterestedClasses, Depth + 1);
+          Known = DemandedSrcElts.isZero() ? SubKnown : (Known | SubKnown);
+        }
+      } else {
+        Known = computeKnownFPClass(SubVector, InterestedClasses, Depth + 1);
+        if (!Known.isUnknown())
+          Known |=
+              computeKnownFPClass(BaseVector, InterestedClasses, Depth + 1);
+      }
       break;
-    unsigned VTNumElts = VT.isVector() ? VT.getVectorNumElements() : 1;
-    unsigned SrcVTNumElts = SrcVT.isVector() ? SrcVT.getVectorNumElements() : 1;
-    if (VTNumElts != SrcVTNumElts)
+    }
+    case ISD::SELECT:
+    case ISD::VSELECT: {
+      // TODO: Add adjustKnownFPClassForSelectArm clamp recognition as in
+      // IR-level ValueTracking.
+      KnownFPClass KnownFalseClass = computeKnownFPClass(
+          Op.getOperand(2), DemandedElts, InterestedClasses, Depth + 1);
+      if (KnownFalseClass.isUnknown())
+        break;
+      KnownFPClass KnownTrueClass = computeKnownFPClass(
+          Op.getOperand(1), DemandedElts, InterestedClasses, Depth + 1);
+      Known = KnownTrueClass.intersectWith(KnownFalseClass);
       break;
-
-    KnownBits Bits = computeKnownBits(Op, DemandedElts, Depth + 1);
-    Known = KnownFPClass::bitcast(VT.getFltSemantics(), Bits);
-    break;
-  }
-  case ISD::FABS: {
-    Known = computeKnownFPClass(Op.getOperand(0), DemandedElts,
-                                InterestedClasses, Depth + 1);
-    Known.fabs();
-    break;
-  }
-  case ISD::FCOPYSIGN: {
-    Known = computeKnownFPClass(Op.getOperand(0), DemandedElts,
-                                InterestedClasses, Depth + 1);
-    KnownFPClass KnownSign = computeKnownFPClass(Op.getOperand(1), DemandedElts,
-                                                 InterestedClasses, Depth + 1);
-    Known.copysign(KnownSign);
-    break;
-  }
-  case ISD::AssertNoFPClass: {
-    Known = computeKnownFPClass(Op.getOperand(0), DemandedElts,
-                                InterestedClasses, Depth + 1);
-    FPClassTest AssertedClasses =
-        static_cast<FPClassTest>(Op->getConstantOperandVal(1));
-    Known.KnownFPClasses &= ~AssertedClasses;
-    break;
-  }
-  case ISD::EXTRACT_SUBVECTOR: {
-    SDValue Src = Op.getOperand(0);
-    EVT SrcVT = Src.getValueType();
-    if (SrcVT.isFixedLengthVector()) {
-      unsigned Idx = Op.getConstantOperandVal(1);
-      unsigned NumSrcElts = SrcVT.getVectorNumElements();
-
-      APInt DemandedSrcElts = DemandedElts.zextOrTrunc(NumSrcElts).shl(Idx);
-      Known = computeKnownFPClass(Src, DemandedSrcElts, InterestedClasses,
-                                  Depth + 1);
-    } else {
-      Known = computeKnownFPClass(Src, InterestedClasses, Depth + 1);
     }
-    break;
-  }
-  case ISD::INSERT_SUBVECTOR: {
-    SDValue BaseVector = Op.getOperand(0);
-    SDValue SubVector = Op.getOperand(1);
-    EVT BaseVT = BaseVector.getValueType();
-    if (BaseVT.isFixedLengthVector()) {
-      unsigned Idx = Op.getConstantOperandVal(2);
-      unsigned NumBaseElts = BaseVT.getVectorNumElements();
-      unsigned NumSubElts = SubVector.getValueType().getVectorNumElements();
-
-      APInt DemandedMask =
-          APInt::getBitsSet(NumBaseElts, Idx, Idx + NumSubElts);
-      APInt DemandedSrcElts = DemandedElts & ~DemandedMask;
-      APInt DemandedSubElts = DemandedElts.extractBits(NumSubElts, Idx);
-
-      if (!DemandedSrcElts.isZero())
-        Known = computeKnownFPClass(BaseVector, DemandedSrcElts,
-                                    InterestedClasses, Depth + 1);
-      if (!DemandedSubElts.isZero()) {
-        KnownFPClass SubKnown = computeKnownFPClass(
-            SubVector, DemandedSubElts, InterestedClasses, Depth + 1);
-        Known = DemandedSrcElts.isZero() ? SubKnown : (Known | SubKnown);
+    default:
+      if (Opcode >= ISD::BUILTIN_OP_END || Opcode == ISD::INTRINSIC_WO_CHAIN ||
+          Opcode == ISD::INTRINSIC_W_CHAIN || Opcode == ISD::INTRINSIC_VOID) {
+        TLI->computeKnownFPClassForTargetNode(Op, Known, DemandedElts, *this,
+                                              Depth);
       }
-    } else {
-      Known = computeKnownFPClass(SubVector, InterestedClasses, Depth + 1);
-      if (!Known.isUnknown())
-        Known |= computeKnownFPClass(BaseVector, InterestedClasses, Depth + 1);
-    }
-    break;
-  }
-  case ISD::SELECT:
-  case ISD::VSELECT: {
-    // TODO: Add adjustKnownFPClassForSelectArm clamp recognition as in
-    // IR-level ValueTracking.
-    KnownFPClass KnownFalseClass = computeKnownFPClass(
-        Op.getOperand(2), DemandedElts, InterestedClasses, Depth + 1);
-    if (KnownFalseClass.isUnknown())
       break;
-    KnownFPClass KnownTrueClass = computeKnownFPClass(
-        Op.getOperand(1), DemandedElts, InterestedClasses, Depth + 1);
-    Known = KnownTrueClass.intersectWith(KnownFalseClass);
-    break;
-  }
-  default:
-    if (Opcode >= ISD::BUILTIN_OP_END || Opcode == ISD::INTRINSIC_WO_CHAIN ||
-        Opcode == ISD::INTRINSIC_W_CHAIN || Opcode == ISD::INTRINSIC_VOID) {
-      TLI->computeKnownFPClassForTargetNode(Op, Known, DemandedElts, *this,
-                                            Depth);
     }
-    break;
   }
 
   return Known;



More information about the llvm-commits mailing list