Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Merged
merged 2 commits into from
Jul 5, 2024

Conversation

bjope
Copy link
Collaborator

@bjope bjope commented Jul 4, 2024

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.

@llvmbot llvmbot added the llvm:SelectionDAG SelectionDAGISel as well label Jul 4, 2024
@llvmbot
Copy link
Collaborator

llvmbot commented Jul 4, 2024

@llvm/pr-subscribers-backend-x86

@llvm/pr-subscribers-llvm-selectiondag

Author: Björn Pettersson (bjope)

Changes

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.


Full diff: https://github.com/llvm/llvm-project/pull/97695.diff

1 Files Affected:

  • (modified) llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp (+15)
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)

@bjope
Copy link
Collaborator Author

bjope commented Jul 4, 2024

No regression tests yet. If anyone has a good idea how and where to put them, let me know.

The need for this was found downstream as DAG Combiner prefer (SHL (ANY_EXTEND (ASHR ...))) instead of (SHL (SIGN_EXTEND (ASHR ...))), which actually is bad for ComputeNumSignBits.

dtcxzyw added a commit to dtcxzyw/llvm-codegen-benchmark that referenced this pull request Jul 4, 2024
@bjope
Copy link
Collaborator Author

bjope commented Jul 4, 2024

Added some test cases based on the (sshlsat x, c) -> (shl x, c) fold to verify number of sign bits that are computed.

@bjope bjope requested a review from RKSimon July 4, 2024 16:08
Copy link
Collaborator

@RKSimon RKSimon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A couple of minor comments

@@ -0,0 +1,158 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
; RUN: llc < %s -mtriple=x86_64-linux | FileCheck %s --check-prefix=X64
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(pedantic) rename to known-signtbits-shl.ll to

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)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use ISD::isExtOpcode(Op.getOperand(0).getOpcode())

SDValue Src = Op.getOperand(0);
EVT SrcVT = Src.getValueType();
SDValue ExtendedOp = Op.getOperand(0).getOperand(0);
EVT ExtendedOpVT = ExtendedOp.getValueType();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(pedantic) ExtendedOp isn't extended - it's the pre-extended source value

EVT ExtendeeVT = Extendee.getValueType();
uint64_t SizeDifference =
ExtVT.getScalarSizeInBits() - ExtendeeVT.getScalarSizeInBits();
if (SizeDifference <= MinShAmt) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add a explanation comment (similar to the patch summary)

Copy link
Collaborator

@RKSimon RKSimon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM - cheers

bjope added 2 commits July 5, 2024 22:37
…lvm#97695)

Adding test cases aiming at showing possibility to look through
ZERO_EXTEND/ANY_EXTEND when computing number of sign bits for an
SHL node. If all extended bits are shifted out we can analyze the
operand that is extended.
…#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.
@bjope bjope merged commit c2fbc70 into llvm:main Jul 5, 2024
3 of 6 checks passed
@bjope
Copy link
Collaborator Author

bjope commented Jul 5, 2024

LGTM - cheers

Thanks!

kbluck pushed a commit to kbluck/llvm-project that referenced this pull request Jul 6, 2024
…lvm#97695)

Adding test cases aiming at showing possibility to look through
ZERO_EXTEND/ANY_EXTEND when computing number of sign bits for an
SHL node. If all extended bits are shifted out we can analyze the
operand that is extended.
kbluck pushed a commit to kbluck/llvm-project that referenced this pull request Jul 6, 2024
…#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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backend:X86 llvm:SelectionDAG SelectionDAGISel as well
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants