[llvm] [missed-opt][isel] Unnecessary shift count masking in 128 bit arithmetic (PR #172506)
via llvm-commits
llvm-commits at lists.llvm.org
Tue Dec 16 07:58:23 PST 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-selectiondag
Author: Bala_Bhuvan_Varma (Bhuvan1527)
<details>
<summary>Changes</summary>
For a particular example where user explicitly masking the shiftcount with 63, in a 128 bit shift instruction. We can ignore generating the explicit shift count masking with 63 , because X86 architecture will handle it implicitly.
However this pr attempts to address it in much higher level i.e. target independent during DAGCombine step after SelectionDAG is created.
---
Full diff: https://github.com/llvm/llvm-project/pull/172506.diff
1 Files Affected:
- (modified) llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp (+15)
``````````diff
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index 471bd39c3aef3..92d5393e1e1bf 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -10542,6 +10542,21 @@ SDValue DAGCombiner::visitSHL(SDNode *N) {
return DAG.getNode(ISD::SHL, DL, VT, N0, NewOp1);
}
+ // fold (shl x, (and y, 63)) -> (shl x, y)
+ // if VT is i64 then mask must be 63
+ // if VT is i32 then mask must be 31
+ if (N1.getOpcode() == ISD::AND) {
+ SDValue AndLHS = N1.getOperand(0);
+ SDValue AndRHS = N1.getOperand(1);
+ ConstantSDNode *AndRHSC = isConstOrConstSplat(AndRHS);
+ if (AndRHSC) {
+ APInt Mask = AndRHSC->getAPIntValue();
+ if ((VT == MVT::i64 && Mask == 63) || (VT == MVT::i32 && Mask == 31)) {
+ return DAG.getNode(ISD::SHL, DL, VT, N0, AndLHS);
+ }
+ }
+ }
+
// fold (shl (shl x, c1), c2) -> 0 or (shl x, (add c1, c2))
if (N0.getOpcode() == ISD::SHL) {
auto MatchOutOfRange = [OpSizeInBits](ConstantSDNode *LHS,
``````````
</details>
https://github.com/llvm/llvm-project/pull/172506
More information about the llvm-commits
mailing list