[llvm] [AArch64][SVE] Match (add_like x (lsr y, c)) -> usra x, y, c (PR #197657)
Harry Ramsey via llvm-commits
llvm-commits at lists.llvm.org
Thu May 14 04:45:34 PDT 2026
https://github.com/Harry-Ramsey created https://github.com/llvm/llvm-project/pull/197657
Modify SVEE USRA pattern to accept add_like, so both add and or disjoint forms can select usra.
Add known-bits support for predicated SVE logical shifts, allowing or_disjoint matching to prove disjointness for plain ORs where possible.
>From 0a89000985556bfebe4071f0b91a96e3778f5eaf Mon Sep 17 00:00:00 2001
From: Harry Ramsey <harry.ramsey at arm.com>
Date: Wed, 13 May 2026 15:46:55 +0000
Subject: [PATCH] [AArch64][SVE] Match (add_like x (lsr y, c)) -> usra x, y, c
Modify SVEE USRA pattern to accept add_like, so both add and or disjoint
forms can select usra.
Add known-bits support for predicated SVE logical shifts, allowing
or_disjoint matching to prove disjointness for plain ORs where possible.
---
.../lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 5 ----
.../Target/AArch64/AArch64ISelLowering.cpp | 12 ++++++++++
.../lib/Target/AArch64/AArch64SVEInstrInfo.td | 2 +-
llvm/test/CodeGen/AArch64/sve2-sli-sri.ll | 24 ++++++++++++-------
4 files changed, 29 insertions(+), 14 deletions(-)
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index 9af378ec28868..29bad5c513c55 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -4525,11 +4525,6 @@ KnownBits SelectionDAG::computeKnownBits(SDValue Op, const APInt &DemandedElts,
case ISD::INTRINSIC_WO_CHAIN:
case ISD::INTRINSIC_W_CHAIN:
case ISD::INTRINSIC_VOID:
- // TODO: Probably okay to remove after audit; here to reduce change size
- // in initial enablement patch for scalable vectors
- if (Op.getValueType().isScalableVector())
- break;
-
// Allow the target to implement this method for its nodes.
TLI->computeKnownBitsForTargetNode(Op, Known, DemandedElts, *this, Depth);
break;
diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index 9de0b461a216c..e78fd18f6604a 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -2902,6 +2902,18 @@ void AArch64TargetLowering::computeKnownBitsForTargetNode(
}
break;
}
+ case AArch64ISD::SHL_PRED:
+ case AArch64ISD::SRL_PRED: {
+ KnownBits KnownVal =
+ DAG.computeKnownBits(Op->getOperand(1), DemandedElts, Depth + 1);
+ KnownBits KnownAmt =
+ DAG.computeKnownBits(Op->getOperand(2), DemandedElts, Depth + 1);
+
+ Known = Op.getOpcode() == AArch64ISD::SHL_PRED
+ ? KnownBits::shl(KnownVal, KnownAmt)
+ : KnownBits::lshr(KnownVal, KnownAmt);
+ break;
+ }
case ISD::INTRINSIC_WO_CHAIN:
case ISD::INTRINSIC_VOID: {
unsigned IntNo = Op.getConstantOperandVal(0);
diff --git a/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td b/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td
index 9df77f8e93c64..e4c281a84d72b 100644
--- a/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td
+++ b/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td
@@ -362,7 +362,7 @@ def AArch64uaba : PatFrags<(ops node:$op1, node:$op2, node:$op3),
def AArch64usra : PatFrags<(ops node:$op1, node:$op2, node:$op3),
[(int_aarch64_sve_usra node:$op1, node:$op2, node:$op3),
- (add node:$op1, (AArch64lsr_p (SVEAnyPredicate), node:$op2, (SVEShiftSplatImmR (i32 node:$op3))))]>;
+ (add_like node:$op1, (AArch64lsr_p (SVEAnyPredicate), node:$op2, (SVEShiftSplatImmR (i32 node:$op3))))]>;
def AArch64ssra : PatFrags<(ops node:$op1, node:$op2, node:$op3),
[(int_aarch64_sve_ssra node:$op1, node:$op2, node:$op3),
diff --git a/llvm/test/CodeGen/AArch64/sve2-sli-sri.ll b/llvm/test/CodeGen/AArch64/sve2-sli-sri.ll
index 80999fb1f4864..a7048731850d3 100644
--- a/llvm/test/CodeGen/AArch64/sve2-sli-sri.ll
+++ b/llvm/test/CodeGen/AArch64/sve2-sli-sri.ll
@@ -118,14 +118,22 @@ define <vscale x 8 x i16> @testRightGood8x16(<vscale x 8 x i16> %src1, <vscale x
}
define <vscale x 8 x i16> @testRightBad8x16(<vscale x 8 x i16> %src1, <vscale x 8 x i16> %src2) {
-; CHECK-LABEL: testRightBad8x16:
-; CHECK: // %bb.0:
-; CHECK-NEXT: mov w8, #16500 // =0x4074
-; CHECK-NEXT: lsr z1.h, z1.h, #14
-; CHECK-NEXT: mov z2.h, w8
-; CHECK-NEXT: and z0.d, z0.d, z2.d
-; CHECK-NEXT: orr z0.d, z0.d, z1.d
-; CHECK-NEXT: ret
+; SVE-LABEL: testRightBad8x16:
+; SVE: // %bb.0:
+; SVE-NEXT: mov w8, #16500 // =0x4074
+; SVE-NEXT: lsr z1.h, z1.h, #14
+; SVE-NEXT: mov z2.h, w8
+; SVE-NEXT: and z0.d, z0.d, z2.d
+; SVE-NEXT: orr z0.d, z0.d, z1.d
+; SVE-NEXT: ret
+;
+; SVE2-LABEL: testRightBad8x16:
+; SVE2: // %bb.0:
+; SVE2-NEXT: mov w8, #16500 // =0x4074
+; SVE2-NEXT: mov z2.h, w8
+; SVE2-NEXT: and z0.d, z0.d, z2.d
+; SVE2-NEXT: usra z0.h, z1.h, #14
+; SVE2-NEXT: ret
%and.i = and <vscale x 8 x i16> %src1, splat(i16 16500)
%vshl_n = lshr <vscale x 8 x i16> %src2, splat(i16 14)
%result = or <vscale x 8 x i16> %and.i, %vshl_n
More information about the llvm-commits
mailing list