[llvm] [SelectionDAG] Let ComputeKnownSignBits handle (shl (ext X), C) (PR #97695)

Björn Pettersson via llvm-commits llvm-commits at lists.llvm.org
Thu Jul 4 01:48:03 PDT 2024


https://github.com/bjope created https://github.com/llvm/llvm-project/pull/97695

Add simple support for looking through ZEXT/ANYEXT/SEXT when doing ComputeKnownSignBits for SHL. This is valid for the case when all extended bits are shifted out, because then the number of sign bits can be found by analysing the EXT operand.

A future improvement could be to pass along the "shifted left by" information in the recursive calls to ComputeKnownSignBits. Allowing us to handle this more generically.

>From 2460c6fdd156210021d8aae73a477588fbe4d7f2 Mon Sep 17 00:00:00 2001
From: Bjorn Pettersson <bjorn.a.pettersson at ericsson.com>
Date: Thu, 4 Jul 2024 10:34:04 +0200
Subject: [PATCH] [SelectionDAG] Let ComputeKnownSignBits handle (shl (ext X),
 C)

Add simple support for looking through ZEXT/ANYEXT/SEXT when doing
ComputeKnownSignBits for SHL. This is valid for the case when all
extended bits are shifted out, because then the number of sign bits
can be found by analysing the EXT operand.

A future improvement could be to pass along the "shifted left by"
information in the recursive calls to ComputeKnownSignBits. Allowing
us to handle this more generically.
---
 llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index 96242305e9eab..991df60a5e650 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -4617,6 +4617,21 @@ unsigned SelectionDAG::ComputeNumSignBits(SDValue Op, const APInt &DemandedElts,
   case ISD::SHL:
     if (std::optional<uint64_t> ShAmt =
             getValidMaximumShiftAmount(Op, DemandedElts, Depth + 1)) {
+      if (Op.getOperand(0).getOpcode() == ISD::ANY_EXTEND ||
+          Op.getOperand(0).getOpcode() == ISD::ZERO_EXTEND ||
+          Op.getOperand(0).getOpcode() == ISD::SIGN_EXTEND) {
+        SDValue Src = Op.getOperand(0);
+        EVT SrcVT = Src.getValueType();
+        SDValue ExtendedOp = Op.getOperand(0).getOperand(0);
+        EVT ExtendedOpVT = ExtendedOp.getValueType();
+        uint64_t ExtendedWidth =
+            SrcVT.getScalarSizeInBits() - ExtendedOpVT.getScalarSizeInBits();
+        if (ExtendedWidth <= *ShAmt) {
+          Tmp = ComputeNumSignBits(ExtendedOp, DemandedElts, Depth + 1);
+          if (*ShAmt - ExtendedWidth < Tmp)
+            return Tmp - (*ShAmt - ExtendedWidth);
+        }
+      }
       // shl destroys sign bits, ensure it doesn't shift out all sign bits.
       Tmp = ComputeNumSignBits(Op.getOperand(0), DemandedElts, Depth + 1);
       if (*ShAmt < Tmp)



More information about the llvm-commits mailing list