[llvm] [DAG] isKnownNeverZero - add ISD::SHL DemandedElts handling and tests (PR #183772)

via llvm-commits llvm-commits at lists.llvm.org
Wed Mar 4 20:51:54 PST 2026


https://github.com/Joeljm1 updated https://github.com/llvm/llvm-project/pull/183772

>From 9b3c3d5100cf124af25b571d0cdb4fc712a7dfc5 Mon Sep 17 00:00:00 2001
From: Joel Joseph Mathews <joeljosephcl10 at gmail.com>
Date: Fri, 27 Feb 2026 22:28:38 +0530
Subject: [PATCH 1/2] [DAG] isKnownNeverZero - add ISD::SHL DemandedElts
 handling and tests

added DemandedElts to ISD::SHL case in isKnowNeverZero and required
tests
---
 .../lib/CodeGen/SelectionDAG/SelectionDAG.cpp |  4 +-
 .../AArch64/AArch64SelectionDAGTest.cpp       | 50 +++++++++++++++++++
 2 files changed, 52 insertions(+), 2 deletions(-)

diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index 4a2bd811b5214..b1e2b07f0c1fb 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -6209,13 +6209,13 @@ bool SelectionDAG::isKnownNeverZero(SDValue Op, const APInt &DemandedElts,
 
   case ISD::SHL: {
     if (Op->getFlags().hasNoSignedWrap() || Op->getFlags().hasNoUnsignedWrap())
-      return isKnownNeverZero(Op.getOperand(0), Depth + 1);
+      return isKnownNeverZero(Op.getOperand(0),DemandedElts, Depth + 1);
     KnownBits ValKnown = computeKnownBits(Op.getOperand(0), Depth + 1);
     // 1 << X is never zero.
     if (ValKnown.One[0])
       return true;
     // If max shift cnt of known ones is non-zero, result is non-zero.
-    APInt MaxCnt = computeKnownBits(Op.getOperand(1), Depth + 1).getMaxValue();
+    APInt MaxCnt = computeKnownBits(Op.getOperand(1),DemandedElts ,Depth + 1).getMaxValue();
     if (MaxCnt.ult(ValKnown.getBitWidth()) &&
         !ValKnown.One.shl(MaxCnt).isZero())
       return true;
diff --git a/llvm/unittests/Target/AArch64/AArch64SelectionDAGTest.cpp b/llvm/unittests/Target/AArch64/AArch64SelectionDAGTest.cpp
index b0c48e8c97995..90a765dc16433 100644
--- a/llvm/unittests/Target/AArch64/AArch64SelectionDAGTest.cpp
+++ b/llvm/unittests/Target/AArch64/AArch64SelectionDAGTest.cpp
@@ -1574,4 +1574,54 @@ TEST_F(AArch64SelectionDAGTest, KnownNeverZero_Select) {
   EXPECT_FALSE(DAG->isKnownNeverZero(VSelect444Big, DemandAll));
   EXPECT_TRUE(DAG->isKnownNeverZero(VSelect4444, DemandAll));
 }
+
+TEST_F(AArch64SelectionDAGTest, KnownNeverZero_SHL_DemandedElts) {
+  SDLoc Loc;
+  EVT VT = EVT::getVectorVT(Context, MVT::i32, 4);
+
+  // Vector: < -2147483648, 1, 0 -8 >
+  SDValue V1 = DAG->getConstant(-2147483648, Loc, MVT::i32);
+  SDValue V2 = DAG->getConstant(1, Loc, MVT::i32);
+  SDValue V3 = DAG->getConstant(0, Loc, MVT::i32);
+  SDValue V4 = DAG->getConstant(-8, Loc, MVT::i32);
+
+  SDValue Vec = DAG->getBuildVector(VT, Loc, {V1, V2, V3, V4});
+
+  SDValue Shift1 = DAG->getConstant(1, Loc, VT);
+  SDValue Shift31 = DAG->getConstant(31, Loc, VT);
+  SDValue ShiftOverflow = DAG->getConstant(32, Loc, VT);
+  SDValue ShiftUnkown = DAG->getExternalSymbol("unknown", VT);
+
+  SDValue Op1 = DAG->getNode(ISD::SHL, Loc, VT, Vec, Shift1);
+  SDValue Op31 = DAG->getNode(ISD::SHL, Loc, VT, Vec, Shift31);
+  SDValue Op32 = DAG->getNode(ISD::SHL, Loc, VT, Vec, ShiftOverflow);
+  SDValue OpUnkown = DAG->getNode(ISD::SHL, Loc, VT, Vec, ShiftUnkown);
+  // Lane 0: -2147483648 << 1 = 0
+  APInt Lane0(4, 1);
+  EXPECT_FALSE(DAG->isKnownNeverZero(Op1, Lane0));
+  EXPECT_FALSE(DAG->isKnownNeverZero(OpUnkown, Lane0));
+  // Lane 1: 1 << 31 = -2147483648
+  APInt Lane1(4, 2);
+  EXPECT_TRUE(DAG->isKnownNeverZero(Op31, Lane1));
+  // Lane 2: 0 << 1 = 0
+  APInt Lane2(4, 4);
+  EXPECT_FALSE(DAG->isKnownNeverZero(Op1, Lane2));
+  EXPECT_FALSE(DAG->isKnownNeverZero(OpUnkown, Lane2));
+  EXPECT_FALSE(DAG->isKnownNeverZero(Op32, Lane2));
+  // Lane 3: -8 << 1 = -16
+  APInt Lane3(4, 8);
+  EXPECT_TRUE(DAG->isKnownNeverZero(Op1, Lane3));
+  EXPECT_FALSE(DAG->isKnownNeverZero(Op32, Lane3));
+  EXPECT_FALSE(DAG->isKnownNeverZero(Op31, Lane3));
+  // lane 2 and 4
+  APInt Lane1AND4(4, -6);
+  EXPECT_TRUE(DAG->isKnownNeverZero(Op1, Lane1AND4));
+  EXPECT_FALSE(DAG->isKnownNeverZero(Op31, Lane1AND4));
+  EXPECT_FALSE(DAG->isKnownNeverZero(OpUnkown, Lane1AND4));
+  // all lanes
+  APInt LaneAll(4, -1);
+  EXPECT_FALSE(DAG->isKnownNeverZero(Op1, LaneAll));
+  EXPECT_FALSE(DAG->isKnownNeverZero(OpUnkown, LaneAll));
+  EXPECT_FALSE(DAG->isKnownNeverZero(Op32, LaneAll));
+}
 } // end namespace llvm

>From cedf95e471e32fd9c00cafefc3de1796bd2b9824 Mon Sep 17 00:00:00 2001
From: Joeljm1 <143259392+Joeljm1 at users.noreply.github.com>
Date: Fri, 27 Feb 2026 20:54:52 +0300
Subject: [PATCH 2/2] Update llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp

Add a missing DemandedElts in isKnownNeverZero ISD::SHL case

Co-authored-by: Simon Pilgrim <git at redking.me.uk>
---
 llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index b1e2b07f0c1fb..34a8e3c6d1cc5 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -6210,7 +6210,7 @@ bool SelectionDAG::isKnownNeverZero(SDValue Op, const APInt &DemandedElts,
   case ISD::SHL: {
     if (Op->getFlags().hasNoSignedWrap() || Op->getFlags().hasNoUnsignedWrap())
       return isKnownNeverZero(Op.getOperand(0),DemandedElts, Depth + 1);
-    KnownBits ValKnown = computeKnownBits(Op.getOperand(0), Depth + 1);
+    KnownBits ValKnown = computeKnownBits(Op.getOperand(0), DemandedElts, Depth + 1);
     // 1 << X is never zero.
     if (ValKnown.One[0])
       return true;



More information about the llvm-commits mailing list