[llvm] 78f429c - [AArch64][SVE] Match (add_like x (lsr y, c)) -> usra x, y, c

via llvm-commits llvm-commits at lists.llvm.org
Mon Jun 1 01:07:01 PDT 2026


Author: Harry Ramsey
Date: 2026-06-01T09:06:56+01:00
New Revision: 78f429c3b2aeb8105c888133008dea0023b8eebb

URL: https://github.com/llvm/llvm-project/commit/78f429c3b2aeb8105c888133008dea0023b8eebb
DIFF: https://github.com/llvm/llvm-project/commit/78f429c3b2aeb8105c888133008dea0023b8eebb.diff

LOG: [AArch64][SVE] Match (add_like x (lsr y, c)) -> usra x, y, c

Modify SVE 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.

Added: 
    

Modified: 
    llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td
    llvm/test/CodeGen/AArch64/sve2-sra.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td b/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td
index 9df77f8e93c64..f1ff8e402c345 100644
--- a/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td
+++ b/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td
@@ -362,11 +362,11 @@ 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),
-                            (add node:$op1, (AArch64asr_p (SVEAnyPredicate), node:$op2, (SVEShiftSplatImmR (i32 node:$op3))))]>;
+                            (add_like node:$op1, (AArch64asr_p (SVEAnyPredicate), node:$op2, (SVEShiftSplatImmR (i32 node:$op3))))]>;
 
 def AArch64ursra : PatFrags<(ops node:$op1, node:$op2, node:$op3),
                             [(int_aarch64_sve_ursra node:$op1, node:$op2, node:$op3),

diff  --git a/llvm/test/CodeGen/AArch64/sve2-sra.ll b/llvm/test/CodeGen/AArch64/sve2-sra.ll
index eafcd60bc1605..0b951b01a5e90 100644
--- a/llvm/test/CodeGen/AArch64/sve2-sra.ll
+++ b/llvm/test/CodeGen/AArch64/sve2-sra.ll
@@ -255,6 +255,86 @@ define <vscale x 2 x i64> @ssra_intr_u_i64(<vscale x 2 x i1> %pg, <vscale x 2 x
   ret <vscale x 2 x i64> %add
 }
 
+define <vscale x 16 x i8> @usra_disjoint_or16xi8(<vscale x 16 x i8> %a, <vscale x 16 x i8> %b) #0 {
+; CHECK-LABEL: usra_disjoint_or16xi8:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    usra z0.b, z1.b, #4
+; CHECK-NEXT:    ret
+  %shift = lshr <vscale x 16 x i8> %b, splat(i8 4)
+  %add = or disjoint <vscale x 16 x i8> %a, %shift
+  ret <vscale x 16 x i8> %add
+}
+
+define <vscale x 8 x i16> @usra_disjoint_or8xi16(<vscale x 8 x i16> %a, <vscale x 8 x i16> %b) #0 {
+; CHECK-LABEL: usra_disjoint_or8xi16:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    usra z0.h, z1.h, #4
+; CHECK-NEXT:    ret
+  %shift = lshr <vscale x 8 x i16> %b, splat(i16 4)
+  %add = or disjoint <vscale x 8 x i16> %a, %shift
+  ret <vscale x 8 x i16> %add
+}
+
+define <vscale x 4 x i32> @usra_disjoint_or4xi32(<vscale x 4 x i32> %a, <vscale x 4 x i32> %b) #0 {
+; CHECK-LABEL: usra_disjoint_or4xi32:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    usra z0.s, z1.s, #4
+; CHECK-NEXT:    ret
+  %shift = lshr <vscale x 4 x i32> %b, splat(i32 4)
+  %add = or disjoint <vscale x 4 x i32> %a, %shift
+  ret <vscale x 4 x i32> %add
+}
+
+define <vscale x 2 x i64> @usra_disjoint_or2xi64(<vscale x 2 x i64> %a, <vscale x 2 x i64> %b) #0 {
+; CHECK-LABEL: usra_disjoint_or2xi64:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    usra z0.d, z1.d, #4
+; CHECK-NEXT:    ret
+  %shift = lshr <vscale x 2 x i64> %b, splat(i64 4)
+  %add = or disjoint <vscale x 2 x i64> %a, %shift
+  ret <vscale x 2 x i64> %add
+}
+
+define <vscale x 16 x i8> @ssra_disjoint_or16xi8(<vscale x 16 x i8> %a, <vscale x 16 x i8> %b) #0 {
+; CHECK-LABEL: ssra_disjoint_or16xi8:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    ssra z0.b, z1.b, #4
+; CHECK-NEXT:    ret
+  %shift = ashr <vscale x 16 x i8> %b, splat(i8 4)
+  %add = or disjoint <vscale x 16 x i8> %a, %shift
+  ret <vscale x 16 x i8> %add
+}
+
+define <vscale x 8 x i16> @ssra_disjoint_or8xi16(<vscale x 8 x i16> %a, <vscale x 8 x i16> %b) #0 {
+; CHECK-LABEL: ssra_disjoint_or8xi16:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    ssra z0.h, z1.h, #4
+; CHECK-NEXT:    ret
+  %shift = ashr <vscale x 8 x i16> %b, splat(i16 4)
+  %add = or disjoint <vscale x 8 x i16> %a, %shift
+  ret <vscale x 8 x i16> %add
+}
+
+define <vscale x 4 x i32> @ssra_disjoint_or4xi32(<vscale x 4 x i32> %a, <vscale x 4 x i32> %b) #0 {
+; CHECK-LABEL: ssra_disjoint_or4xi32:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    ssra z0.s, z1.s, #4
+; CHECK-NEXT:    ret
+  %shift = ashr <vscale x 4 x i32> %b, splat(i32 4)
+  %add = or disjoint <vscale x 4 x i32> %a, %shift
+  ret <vscale x 4 x i32> %add
+}
+
+define <vscale x 2 x i64> @ssra_disjoint_or2xi64(<vscale x 2 x i64> %a, <vscale x 2 x i64> %b) #0 {
+; CHECK-LABEL: ssra_disjoint_or2xi64:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    ssra z0.d, z1.d, #4
+; CHECK-NEXT:    ret
+  %shift = ashr <vscale x 2 x i64> %b, splat(i64 4)
+  %add = or disjoint <vscale x 2 x i64> %a, %shift
+  ret <vscale x 2 x i64> %add
+}
+
 declare <vscale x 16 x i1> @llvm.aarch64.sve.ptrue.nxv16i1(i32 immarg)
 declare <vscale x 8 x i1> @llvm.aarch64.sve.ptrue.nxv8i1(i32 immarg)
 declare <vscale x 4 x i1> @llvm.aarch64.sve.ptrue.nxv4i1(i32 immarg)


        


More information about the llvm-commits mailing list