[llvm] feat: add flag to disable known bits analysis (PR #228000)

Luisa Cicolini via llvm-commits llvm-commits at lists.llvm.org
Thu Oct 1 02:57:04 PDT 2026


https://github.com/luisacicolini updated https://github.com/llvm/llvm-project/pull/228000

>From 80f16248fbee35a7418e5355e4a1ce9685de282a Mon Sep 17 00:00:00 2001
From: luisacicolini <lc985 at cam.ac.uk>
Date: Thu, 1 Oct 2026 10:03:28 +0100
Subject: [PATCH 1/2] remove kba

---
 llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp     | 8 ++++++++
 llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp | 8 ++++++++
 llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp         | 7 +++++++
 llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp        | 8 ++++----
 4 files changed, 27 insertions(+), 4 deletions(-)

diff --git a/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp b/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp
index 598893ef3c0d7..b4eb464d52893 100644
--- a/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp
@@ -35,6 +35,7 @@
 #include "llvm/IR/FMF.h"
 #include "llvm/InitializePasses.h"
 #include "llvm/MC/TargetRegistry.h"
+#include "llvm/Support/CommandLine.h"
 #include "llvm/Support/KnownBits.h"
 #include "llvm/Support/KnownFPClass.h"
 #include "llvm/Target/TargetMachine.h"
@@ -44,6 +45,10 @@
 using namespace llvm;
 using namespace MIPatternMatch;
 
+static cl::opt<bool> DisableGISelKnownBits(
+    "gisel-disable-known-bits", cl::Hidden, cl::init(false),
+    cl::desc("Disable GlobalISel known bits analysis (always return unknown)"));
+
 char llvm::GISelValueTrackingAnalysisLegacy::ID = 0;
 
 INITIALIZE_PASS(GISelValueTrackingAnalysisLegacy, DEBUG_TYPE,
@@ -278,6 +283,9 @@ void GISelValueTracking::computeKnownBitsImpl(Register R, KnownBits &Known,
   unsigned BitWidth = DstTy.getScalarSizeInBits();
   Known = KnownBits(BitWidth); // Don't know anything
 
+  if (DisableGISelKnownBits)
+    return;
+
   // Depth may get bigger than max depth if it gets passed to a different
   // GISelValueTracking object.
   // This may happen when say a generic part uses a GISelValueTracking object
diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
index 5b6329c2560eb..fc636fd91acb9 100644
--- a/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
@@ -3438,6 +3438,14 @@ ExpandShiftWithKnownAmountBit(SDNode *N, SDValue &Lo, SDValue &Hi) {
   APInt HighBitMask = APInt::getHighBitsSet(ShBits, ShBits - Log2_32(NVTBits));
   KnownBits Known = DAG.computeKnownBits(Amt);
 
+  // Recognize a masked shift amount structurally, so that termination of
+  // ExpandIntRes_ShiftThroughStack does not depend on computeKnownBits (which
+  // may be disabled via -dag-disable-known-bits).
+  if (Amt.getOpcode() == ISD::AND)
+    if (auto *C = dyn_cast<ConstantSDNode>(Amt.getOperand(1)))
+      if (!C->getAPIntValue().intersects(HighBitMask))
+        Known.Zero |= HighBitMask;
+
   // If we don't know anything about the high bits, exit.
   if (((Known.Zero | Known.One) & HighBitMask) == 0)
     return false;
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index e22907c88f654..2c96affdd6920 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -120,6 +120,10 @@ static cl::opt<int> VScaleUnrollLimit(
     cl::desc("Maximum vscale for which vector unrolling is allowed."),
     cl::Hidden, cl::init(64));
 
+static cl::opt<bool> DisableDAGKnownBits(
+    "dag-disable-known-bits", cl::Hidden, cl::init(false),
+    cl::desc("Disable SelectionDAG known bits analysis (always return unknown)"));
+
 static void NewSDValueDbgMsg(SDValue V, StringRef Msg, SelectionDAG *G) {
   LLVM_DEBUG(dbgs() << Msg; V.getNode()->dump(G););
 }
@@ -3352,6 +3356,9 @@ KnownBits SelectionDAG::computeKnownBits(SDValue Op, const APInt &DemandedElts,
 
   KnownBits Known(BitWidth);   // Don't know anything.
 
+  if (DisableDAGKnownBits)
+    return Known;
+
   if (auto OptAPInt = Op->bitcastToAPInt()) {
     // We know all of the bits for a constant!
     return KnownBits::makeConstant(*std::move(OptAPInt));
diff --git a/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp b/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp
index 48c0e37151b9c..fcca01562fc10 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp
@@ -3511,10 +3511,10 @@ static bool isBitfieldPositioningOpFromAnd(SelectionDAG *CurDAG, SDValue Op,
   //   1) (AndImm & (1 << POS) == 0)
   //   2) the result of AND is not zero at POS bit (according to NonZeroBits)
   //
-  // 1) and 2) don't agree so something must be wrong (e.g., in
-  // 'SelectionDAG::computeKnownBits')
-  assert((~AndImm & NonZeroBits) == 0 &&
-         "Something must be wrong (e.g., in SelectionDAG::computeKnownBits)");
+  // 1) and 2) don't agree, which can happen if known bits analysis is
+  // imprecise (e.g., disabled via -dag-disable-known-bits). Bail out.
+  if ((~AndImm & NonZeroBits) != 0)
+    return false;
 
   SDValue AndOp0 = Op.getOperand(0);
 

>From a645604ac82e0b45af3008ca943aec41f3569e0b Mon Sep 17 00:00:00 2001
From: luisacicolini <lc985 at cam.ac.uk>
Date: Thu, 1 Oct 2026 10:56:46 +0100
Subject: [PATCH 2/2] disable more stuff

---
 llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp |  6 +++++-
 llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp     | 10 ++++++++--
 llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp   | 11 +++++++++++
 3 files changed, 24 insertions(+), 3 deletions(-)

diff --git a/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp b/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp
index b4eb464d52893..908ab95553714 100644
--- a/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp
@@ -47,7 +47,8 @@ using namespace MIPatternMatch;
 
 static cl::opt<bool> DisableGISelKnownBits(
     "gisel-disable-known-bits", cl::Hidden, cl::init(false),
-    cl::desc("Disable GlobalISel known bits analysis (always return unknown)"));
+    cl::desc("Disable GlobalISel known bits and num sign bits analyses "
+             "(always return unknown)"));
 
 char llvm::GISelValueTrackingAnalysisLegacy::ID = 0;
 
@@ -2465,6 +2466,9 @@ unsigned GISelValueTracking::computeNumSignBits(Register R,
   MachineInstr &MI = *MRI.getVRegDef(R);
   unsigned Opcode = MI.getOpcode();
 
+  if (DisableGISelKnownBits)
+    return 1;
+
   if (Opcode == TargetOpcode::G_CONSTANT)
     return MI.getOperand(1).getCImm()->getValue().getNumSignBits();
 
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index 2c96affdd6920..8c7b3064d6af8 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -120,9 +120,12 @@ static cl::opt<int> VScaleUnrollLimit(
     cl::desc("Maximum vscale for which vector unrolling is allowed."),
     cl::Hidden, cl::init(64));
 
-static cl::opt<bool> DisableDAGKnownBits(
+namespace llvm {
+cl::opt<bool> DisableDAGKnownBits(
     "dag-disable-known-bits", cl::Hidden, cl::init(false),
-    cl::desc("Disable SelectionDAG known bits analysis (always return unknown)"));
+    cl::desc("Disable SelectionDAG known bits, num sign bits and demanded bits "
+             "analyses (always return unknown / no simplification)"));
+} // namespace llvm
 
 static void NewSDValueDbgMsg(SDValue V, StringRef Msg, SelectionDAG *G) {
   LLVM_DEBUG(dbgs() << Msg; V.getNode()->dump(G););
@@ -4945,6 +4948,9 @@ unsigned SelectionDAG::ComputeNumSignBits(SDValue Op, const APInt &DemandedElts,
   assert((!VT.isScalableVector() || NumElts == 1) &&
          "DemandedElts for scalable vectors must be 1 to represent all lanes");
 
+  if (DisableDAGKnownBits)
+    return 1;
+
   if (auto *C = dyn_cast<ConstantSDNode>(Op)) {
     const APInt &Val = C->getAPIntValue();
     return Val.getNumSignBits();
diff --git a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
index 1eeab43bd480e..115b553a063f0 100644
--- a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
@@ -30,6 +30,7 @@
 #include "llvm/IR/LLVMContext.h"
 #include "llvm/MC/MCAsmInfo.h"
 #include "llvm/MC/MCExpr.h"
+#include "llvm/Support/CommandLine.h"
 #include "llvm/Support/DivisionByConstantInfo.h"
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/KnownBits.h"
@@ -40,6 +41,10 @@
 using namespace llvm;
 using namespace llvm::SDPatternMatch;
 
+namespace llvm {
+extern cl::opt<bool> DisableDAGKnownBits;
+} // namespace llvm
+
 /// NOTE: The TargetMachine owns TLOF.
 TargetLowering::TargetLowering(const TargetMachine &tm,
                                const TargetSubtargetInfo &STI)
@@ -807,6 +812,9 @@ SDValue TargetLowering::SimplifyMultipleUseDemandedBits(
     SelectionDAG &DAG, unsigned Depth) const {
   EVT VT = Op.getValueType();
 
+  if (DisableDAGKnownBits)
+    return SDValue();
+
   // Limit search depth.
   if (Depth >= SelectionDAG::MaxRecursionDepth)
     return SDValue();
@@ -1272,6 +1280,9 @@ bool TargetLowering::SimplifyDemandedBits(
   // Don't know anything.
   Known = KnownBits(BitWidth);
 
+  if (DisableDAGKnownBits)
+    return false;
+
   EVT VT = Op.getValueType();
   bool IsLE = TLO.DAG.getDataLayout().isLittleEndian();
   unsigned NumElts = OriginalDemandedElts.getBitWidth();



More information about the llvm-commits mailing list