[llvm] [AArch64][Isel] For fixed length vectors use sve for bitreverse when available (PR #196025)

Yashwant Singh via llvm-commits llvm-commits at lists.llvm.org
Sun May 10 21:27:34 PDT 2026


https://github.com/yashssh updated https://github.com/llvm/llvm-project/pull/196025

>From 499e6c4de1d19946349caa8516850390ba3ede48 Mon Sep 17 00:00:00 2001
From: Yashwant Singh <yashwants at nvidia.com>
Date: Thu, 16 Apr 2026 23:49:45 -0700
Subject: [PATCH 1/5] pre-commit test

---
 llvm/test/CodeGen/AArch64/bitreverse.ll | 149 +++++++++++++++++++++++-
 1 file changed, 148 insertions(+), 1 deletion(-)

diff --git a/llvm/test/CodeGen/AArch64/bitreverse.ll b/llvm/test/CodeGen/AArch64/bitreverse.ll
index 9e2228aa47c63..e151cdc4e7c0d 100644
--- a/llvm/test/CodeGen/AArch64/bitreverse.ll
+++ b/llvm/test/CodeGen/AArch64/bitreverse.ll
@@ -1,5 +1,6 @@
-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
 ; RUN: llc -mtriple=aarch64 %s -o - | FileCheck %s --check-prefixes=CHECK,SDAG
+; RUN: llc -mtriple=aarch64 -mattr=+sve %s -o - | FileCheck %s --check-prefixes=SVE
 ; RUN: llc -mtriple=aarch64 -global-isel -global-isel-abort=1 %s -o - | FileCheck %s --check-prefixes=CHECK,GISEL
 
 ; These tests just check that the plumbing is in place for @llvm.bitreverse.
@@ -14,6 +15,13 @@ define <2 x i16> @f(<2 x i16> %a) {
 ; SDAG-NEXT:    ushr v0.2s, v0.2s, #16
 ; SDAG-NEXT:    ret
 ;
+; SVE-LABEL: f:
+; SVE:       // %bb.0:
+; SVE-NEXT:    rev32 v0.8b, v0.8b
+; SVE-NEXT:    rbit v0.8b, v0.8b
+; SVE-NEXT:    ushr v0.2s, v0.2s, #16
+; SVE-NEXT:    ret
+;
 ; GISEL-LABEL: f:
 ; GISEL:       // %bb.0:
 ; GISEL-NEXT:    uzp1 v0.4h, v0.4h, v0.4h
@@ -34,6 +42,12 @@ define i8 @g(i8 %a) {
 ; CHECK-NEXT:    rbit w8, w0
 ; CHECK-NEXT:    lsr w0, w8, #24
 ; CHECK-NEXT:    ret
+;
+; SVE-LABEL: g:
+; SVE:       // %bb.0:
+; SVE-NEXT:    rbit w8, w0
+; SVE-NEXT:    lsr w0, w8, #24
+; SVE-NEXT:    ret
   %b = call i8 @llvm.bitreverse.i8(i8 %a)
   ret i8 %b
 }
@@ -46,6 +60,12 @@ define i16 @g_16(i16 %a) {
 ; CHECK-NEXT:    rbit w8, w0
 ; CHECK-NEXT:    lsr w0, w8, #16
 ; CHECK-NEXT:    ret
+;
+; SVE-LABEL: g_16:
+; SVE:       // %bb.0:
+; SVE-NEXT:    rbit w8, w0
+; SVE-NEXT:    lsr w0, w8, #16
+; SVE-NEXT:    ret
   %b = call i16 @llvm.bitreverse.i16(i16 %a)
   ret i16 %b
 }
@@ -57,6 +77,11 @@ define i32 @g_32(i32 %a) {
 ; CHECK:       // %bb.0:
 ; CHECK-NEXT:    rbit w0, w0
 ; CHECK-NEXT:    ret
+;
+; SVE-LABEL: g_32:
+; SVE:       // %bb.0:
+; SVE-NEXT:    rbit w0, w0
+; SVE-NEXT:    ret
   %b = call i32 @llvm.bitreverse.i32(i32 %a)
   ret i32 %b
 }
@@ -68,6 +93,11 @@ define i64 @g_64(i64 %a) {
 ; CHECK:       // %bb.0:
 ; CHECK-NEXT:    rbit x0, x0
 ; CHECK-NEXT:    ret
+;
+; SVE-LABEL: g_64:
+; SVE:       // %bb.0:
+; SVE-NEXT:    rbit x0, x0
+; SVE-NEXT:    ret
   %b = call i64 @llvm.bitreverse.i64(i64 %a)
   ret i64 %b
 }
@@ -81,6 +111,13 @@ define i128 @g_128(i128 %a) {
 ; CHECK-NEXT:    rbit x1, x0
 ; CHECK-NEXT:    mov x0, x8
 ; CHECK-NEXT:    ret
+;
+; SVE-LABEL: g_128:
+; SVE:       // %bb.0:
+; SVE-NEXT:    rbit x8, x1
+; SVE-NEXT:    rbit x1, x0
+; SVE-NEXT:    mov x0, x8
+; SVE-NEXT:    ret
   %b = call i128 @llvm.bitreverse.i128(i128 %a)
   ret i128 %b
 }
@@ -93,6 +130,12 @@ define <16 x i3> @g_vec_16x3(<16 x i3> %a) {
 ; CHECK-NEXT:    rbit v0.16b, v0.16b
 ; CHECK-NEXT:    ushr v0.16b, v0.16b, #5
 ; CHECK-NEXT:    ret
+;
+; SVE-LABEL: g_vec_16x3:
+; SVE:       // %bb.0:
+; SVE-NEXT:    rbit v0.16b, v0.16b
+; SVE-NEXT:    ushr v0.16b, v0.16b, #5
+; SVE-NEXT:    ret
   %b = call <16 x i3> @llvm.bitreverse.v16i3(<16 x i3> %a)
   ret <16 x i3> %b
 }
@@ -105,6 +148,12 @@ define <16 x i4> @g_vec_16x4(<16 x i4> %a) {
 ; CHECK-NEXT:    rbit v0.16b, v0.16b
 ; CHECK-NEXT:    ushr v0.16b, v0.16b, #4
 ; CHECK-NEXT:    ret
+;
+; SVE-LABEL: g_vec_16x4:
+; SVE:       // %bb.0:
+; SVE-NEXT:    rbit v0.16b, v0.16b
+; SVE-NEXT:    ushr v0.16b, v0.16b, #4
+; SVE-NEXT:    ret
   %b = call <16 x i4> @llvm.bitreverse.v16i4(<16 x i4> %a)
   ret <16 x i4> %b
 }
@@ -116,6 +165,11 @@ define <8 x i8> @g_vec(<8 x i8> %a) {
 ; CHECK:       // %bb.0:
 ; CHECK-NEXT:    rbit v0.8b, v0.8b
 ; CHECK-NEXT:    ret
+;
+; SVE-LABEL: g_vec:
+; SVE:       // %bb.0:
+; SVE-NEXT:    rbit v0.8b, v0.8b
+; SVE-NEXT:    ret
   %b = call <8 x i8> @llvm.bitreverse.v8i8(<8 x i8> %a)
   ret <8 x i8> %b
 }
@@ -127,6 +181,11 @@ define <16 x i8> @g_vec_16x8(<16 x i8> %a) {
 ; CHECK:       // %bb.0:
 ; CHECK-NEXT:    rbit v0.16b, v0.16b
 ; CHECK-NEXT:    ret
+;
+; SVE-LABEL: g_vec_16x8:
+; SVE:       // %bb.0:
+; SVE-NEXT:    rbit v0.16b, v0.16b
+; SVE-NEXT:    ret
   %b = call <16 x i8> @llvm.bitreverse.v16i8(<16 x i8> %a)
   ret <16 x i8> %b
 }
@@ -139,6 +198,12 @@ define <32 x i8> @g_vec_32x8(<32 x i8> %a) {
 ; CHECK-NEXT:    rbit v0.16b, v0.16b
 ; CHECK-NEXT:    rbit v1.16b, v1.16b
 ; CHECK-NEXT:    ret
+;
+; SVE-LABEL: g_vec_32x8:
+; SVE:       // %bb.0:
+; SVE-NEXT:    rbit v0.16b, v0.16b
+; SVE-NEXT:    rbit v1.16b, v1.16b
+; SVE-NEXT:    ret
   %b = call <32 x i8> @llvm.bitreverse.v32i8(<32 x i8> %a)
   ret <32 x i8> %b
 }
@@ -153,6 +218,13 @@ define <4 x i8> @g_vec_4x8(<4 x i8> %a) {
 ; SDAG-NEXT:    ushr v0.4h, v0.4h, #8
 ; SDAG-NEXT:    ret
 ;
+; SVE-LABEL: g_vec_4x8:
+; SVE:       // %bb.0:
+; SVE-NEXT:    rev16 v0.8b, v0.8b
+; SVE-NEXT:    rbit v0.8b, v0.8b
+; SVE-NEXT:    ushr v0.4h, v0.4h, #8
+; SVE-NEXT:    ret
+;
 ; GISEL-LABEL: g_vec_4x8:
 ; GISEL:       // %bb.0:
 ; GISEL-NEXT:    uzp1 v0.8b, v0.8b, v0.8b
@@ -171,6 +243,11 @@ define <9 x i8> @g_vec_9x8(<9 x i8> %a) {
 ; CHECK:       // %bb.0:
 ; CHECK-NEXT:    rbit v0.16b, v0.16b
 ; CHECK-NEXT:    ret
+;
+; SVE-LABEL: g_vec_9x8:
+; SVE:       // %bb.0:
+; SVE-NEXT:    rbit v0.16b, v0.16b
+; SVE-NEXT:    ret
   %b = call <9 x i8> @llvm.bitreverse.v9i8(<9 x i8> %a)
   ret <9 x i8> %b
 }
@@ -183,6 +260,12 @@ define <4 x i16> @g_vec_4x16(<4 x i16> %a) {
 ; CHECK-NEXT:    rev16 v0.8b, v0.8b
 ; CHECK-NEXT:    rbit v0.8b, v0.8b
 ; CHECK-NEXT:    ret
+;
+; SVE-LABEL: g_vec_4x16:
+; SVE:       // %bb.0:
+; SVE-NEXT:    rev16 v0.8b, v0.8b
+; SVE-NEXT:    rbit v0.8b, v0.8b
+; SVE-NEXT:    ret
   %b = call <4 x i16> @llvm.bitreverse.v4i16(<4 x i16> %a)
   ret <4 x i16> %b
 }
@@ -195,6 +278,12 @@ define <8 x i16> @g_vec_8x16(<8 x i16> %a) {
 ; CHECK-NEXT:    rev16 v0.16b, v0.16b
 ; CHECK-NEXT:    rbit v0.16b, v0.16b
 ; CHECK-NEXT:    ret
+;
+; SVE-LABEL: g_vec_8x16:
+; SVE:       // %bb.0:
+; SVE-NEXT:    rev16 v0.16b, v0.16b
+; SVE-NEXT:    rbit v0.16b, v0.16b
+; SVE-NEXT:    ret
   %b = call <8 x i16> @llvm.bitreverse.v8i16(<8 x i16> %a)
   ret <8 x i16> %b
 }
@@ -209,6 +298,14 @@ define <16 x i16> @g_vec_16x16(<16 x i16> %a) {
 ; CHECK-NEXT:    rbit v0.16b, v0.16b
 ; CHECK-NEXT:    rbit v1.16b, v1.16b
 ; CHECK-NEXT:    ret
+;
+; SVE-LABEL: g_vec_16x16:
+; SVE:       // %bb.0:
+; SVE-NEXT:    rev16 v0.16b, v0.16b
+; SVE-NEXT:    rev16 v1.16b, v1.16b
+; SVE-NEXT:    rbit v0.16b, v0.16b
+; SVE-NEXT:    rbit v1.16b, v1.16b
+; SVE-NEXT:    ret
   %b = call <16 x i16> @llvm.bitreverse.v16i16(<16 x i16> %a)
   ret <16 x i16> %b
 }
@@ -221,6 +318,12 @@ define <2 x i32> @g_vec_2x32(<2 x i32> %a) {
 ; CHECK-NEXT:    rev32 v0.8b, v0.8b
 ; CHECK-NEXT:    rbit v0.8b, v0.8b
 ; CHECK-NEXT:    ret
+;
+; SVE-LABEL: g_vec_2x32:
+; SVE:       // %bb.0:
+; SVE-NEXT:    rev32 v0.8b, v0.8b
+; SVE-NEXT:    rbit v0.8b, v0.8b
+; SVE-NEXT:    ret
   %b = call <2 x i32> @llvm.bitreverse.v2i32(<2 x i32> %a)
   ret <2 x i32> %b
 }
@@ -233,6 +336,12 @@ define <4 x i32> @g_vec_4x32(<4 x i32> %a) {
 ; CHECK-NEXT:    rev32 v0.16b, v0.16b
 ; CHECK-NEXT:    rbit v0.16b, v0.16b
 ; CHECK-NEXT:    ret
+;
+; SVE-LABEL: g_vec_4x32:
+; SVE:       // %bb.0:
+; SVE-NEXT:    rev32 v0.16b, v0.16b
+; SVE-NEXT:    rbit v0.16b, v0.16b
+; SVE-NEXT:    ret
   %b = call <4 x i32> @llvm.bitreverse.v4i32(<4 x i32> %a)
   ret <4 x i32> %b
 }
@@ -247,6 +356,14 @@ define <8 x i32> @g_vec_8x32(<8 x i32> %a) {
 ; CHECK-NEXT:    rbit v0.16b, v0.16b
 ; CHECK-NEXT:    rbit v1.16b, v1.16b
 ; CHECK-NEXT:    ret
+;
+; SVE-LABEL: g_vec_8x32:
+; SVE:       // %bb.0:
+; SVE-NEXT:    rev32 v0.16b, v0.16b
+; SVE-NEXT:    rev32 v1.16b, v1.16b
+; SVE-NEXT:    rbit v0.16b, v0.16b
+; SVE-NEXT:    rbit v1.16b, v1.16b
+; SVE-NEXT:    ret
   %b = call <8 x i32> @llvm.bitreverse.v8i32(<8 x i32> %a)
   ret <8 x i32> %b
 }
@@ -260,6 +377,12 @@ define <1 x i64> @g_vec_1x64(<1 x i64> %a) {
 ; SDAG-NEXT:    rbit v0.8b, v0.8b
 ; SDAG-NEXT:    ret
 ;
+; SVE-LABEL: g_vec_1x64:
+; SVE:       // %bb.0:
+; SVE-NEXT:    rev64 v0.8b, v0.8b
+; SVE-NEXT:    rbit v0.8b, v0.8b
+; SVE-NEXT:    ret
+;
 ; GISEL-LABEL: g_vec_1x64:
 ; GISEL:       // %bb.0:
 ; GISEL-NEXT:    fmov x8, d0
@@ -278,6 +401,12 @@ define <2 x i64> @g_vec_2x64(<2 x i64> %a) {
 ; CHECK-NEXT:    rev64 v0.16b, v0.16b
 ; CHECK-NEXT:    rbit v0.16b, v0.16b
 ; CHECK-NEXT:    ret
+;
+; SVE-LABEL: g_vec_2x64:
+; SVE:       // %bb.0:
+; SVE-NEXT:    rev64 v0.16b, v0.16b
+; SVE-NEXT:    rbit v0.16b, v0.16b
+; SVE-NEXT:    ret
   %b = call <2 x i64> @llvm.bitreverse.v2i64(<2 x i64> %a)
   ret <2 x i64> %b
 }
@@ -292,6 +421,14 @@ define <4 x i64> @g_vec_4x64(<4 x i64> %a) {
 ; CHECK-NEXT:    rbit v0.16b, v0.16b
 ; CHECK-NEXT:    rbit v1.16b, v1.16b
 ; CHECK-NEXT:    ret
+;
+; SVE-LABEL: g_vec_4x64:
+; SVE:       // %bb.0:
+; SVE-NEXT:    rev64 v0.16b, v0.16b
+; SVE-NEXT:    rev64 v1.16b, v1.16b
+; SVE-NEXT:    rbit v0.16b, v0.16b
+; SVE-NEXT:    rbit v1.16b, v1.16b
+; SVE-NEXT:    ret
   %b = call <4 x i64> @llvm.bitreverse.v4i64(<4 x i64> %a)
   ret <4 x i64> %b
 }
@@ -308,6 +445,16 @@ define <2 x i128> @g_vec_2x128(<2 x i128> %a) {
 ; CHECK-NEXT:    mov x0, x8
 ; CHECK-NEXT:    mov x2, x9
 ; CHECK-NEXT:    ret
+;
+; SVE-LABEL: g_vec_2x128:
+; SVE:       // %bb.0:
+; SVE-NEXT:    rbit x8, x1
+; SVE-NEXT:    rbit x9, x3
+; SVE-NEXT:    rbit x1, x0
+; SVE-NEXT:    rbit x3, x2
+; SVE-NEXT:    mov x0, x8
+; SVE-NEXT:    mov x2, x9
+; SVE-NEXT:    ret
   %b = call <2 x i128> @llvm.bitreverse.v2i128(<2 x i128> %a)
   ret <2 x i128> %b
 }

>From fb7c79a4d63a094bc0859a3150e671a24ced0f97 Mon Sep 17 00:00:00 2001
From: Yashwant Singh <yashwants at nvidia.com>
Date: Fri, 17 Apr 2026 00:20:44 -0700
Subject: [PATCH 2/5] [AArch64]Use sve for bitreverse when available

Speedups after the patch

uint8x8_t   1.01x
uint16x4_t  2.02x
uint32x2_t  2.01x
uint64x1_t  2.02x
uint8x16_t  1.00x
uint16x8_t  2.03x
uint32x4_t  2.03x
uint64x2_t  2.02x
---
 .../Target/AArch64/AArch64ISelLowering.cpp    | 18 ++++-
 llvm/test/CodeGen/AArch64/bitreverse.ll       | 79 ++++++++++++-------
 2 files changed, 68 insertions(+), 29 deletions(-)

diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index f5082b779d1db..a52f0bb40c601 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -1332,6 +1332,8 @@ AArch64TargetLowering::AArch64TargetLowering(const TargetMachine &TM,
       setOperationAction(ISD::CTLS, VT, Legal);
     setOperationAction(ISD::BITREVERSE, MVT::v8i8, Legal);
     setOperationAction(ISD::BITREVERSE, MVT::v16i8, Legal);
+    setOperationAction(ISD::BITREVERSE, MVT::v4i16, Custom);
+    setOperationAction(ISD::BITREVERSE, MVT::v8i16, Custom);
     setOperationAction(ISD::BITREVERSE, MVT::v2i32, Custom);
     setOperationAction(ISD::BITREVERSE, MVT::v4i32, Custom);
     setOperationAction(ISD::BITREVERSE, MVT::v1i64, Custom);
@@ -11821,7 +11823,7 @@ SDValue AArch64TargetLowering::LowerBitreverse(SDValue Op,
 
   if (VT.isScalableVector() ||
       useSVEForFixedLengthVectorVT(
-          VT, /*OverrideNEON=*/Subtarget->useSVEForFixedLengthVectors()))
+          VT, /*OverrideNEON=*/Subtarget->isSVEorStreamingSVEAvailable()))
     return LowerToPredicatedOp(Op, DAG, AArch64ISD::BITREVERSE_MERGE_PASSTHRU);
 
   SDLoc DL(Op);
@@ -11832,6 +11834,20 @@ SDValue AArch64TargetLowering::LowerBitreverse(SDValue Op,
   default:
     llvm_unreachable("Invalid type for bitreverse!");
 
+  case MVT::v4i16: {
+    SDValue Bswap = DAG.getNode(ISD::BSWAP, DL, VT, Op.getOperand(0));
+    VST = MVT::v8i8;
+    REVB = DAG.getBitcast(VST, Bswap);
+    break;
+  }
+
+  case MVT::v8i16: {
+    SDValue Bswap = DAG.getNode(ISD::BSWAP, DL, VT, Op.getOperand(0));
+    VST = MVT::v16i8;
+    REVB = DAG.getBitcast(VST, Bswap);
+    break;
+  }
+
   case MVT::v2i32: {
     VST = MVT::v8i8;
     REVB = DAG.getNode(AArch64ISD::REV32, DL, VST, Op.getOperand(0));
diff --git a/llvm/test/CodeGen/AArch64/bitreverse.ll b/llvm/test/CodeGen/AArch64/bitreverse.ll
index e151cdc4e7c0d..1ff3687f0f7a8 100644
--- a/llvm/test/CodeGen/AArch64/bitreverse.ll
+++ b/llvm/test/CodeGen/AArch64/bitreverse.ll
@@ -17,8 +17,9 @@ define <2 x i16> @f(<2 x i16> %a) {
 ;
 ; SVE-LABEL: f:
 ; SVE:       // %bb.0:
-; SVE-NEXT:    rev32 v0.8b, v0.8b
-; SVE-NEXT:    rbit v0.8b, v0.8b
+; SVE-NEXT:    ptrue p0.s, vl2
+; SVE-NEXT:    // kill: def $d0 killed $d0 def $z0
+; SVE-NEXT:    rbit z0.s, p0/m, z0.s
 ; SVE-NEXT:    ushr v0.2s, v0.2s, #16
 ; SVE-NEXT:    ret
 ;
@@ -220,8 +221,9 @@ define <4 x i8> @g_vec_4x8(<4 x i8> %a) {
 ;
 ; SVE-LABEL: g_vec_4x8:
 ; SVE:       // %bb.0:
-; SVE-NEXT:    rev16 v0.8b, v0.8b
-; SVE-NEXT:    rbit v0.8b, v0.8b
+; SVE-NEXT:    ptrue p0.h, vl4
+; SVE-NEXT:    // kill: def $d0 killed $d0 def $z0
+; SVE-NEXT:    rbit z0.h, p0/m, z0.h
 ; SVE-NEXT:    ushr v0.4h, v0.4h, #8
 ; SVE-NEXT:    ret
 ;
@@ -263,8 +265,10 @@ define <4 x i16> @g_vec_4x16(<4 x i16> %a) {
 ;
 ; SVE-LABEL: g_vec_4x16:
 ; SVE:       // %bb.0:
-; SVE-NEXT:    rev16 v0.8b, v0.8b
-; SVE-NEXT:    rbit v0.8b, v0.8b
+; SVE-NEXT:    ptrue p0.h, vl4
+; SVE-NEXT:    // kill: def $d0 killed $d0 def $z0
+; SVE-NEXT:    rbit z0.h, p0/m, z0.h
+; SVE-NEXT:    // kill: def $d0 killed $d0 killed $z0
 ; SVE-NEXT:    ret
   %b = call <4 x i16> @llvm.bitreverse.v4i16(<4 x i16> %a)
   ret <4 x i16> %b
@@ -281,8 +285,10 @@ define <8 x i16> @g_vec_8x16(<8 x i16> %a) {
 ;
 ; SVE-LABEL: g_vec_8x16:
 ; SVE:       // %bb.0:
-; SVE-NEXT:    rev16 v0.16b, v0.16b
-; SVE-NEXT:    rbit v0.16b, v0.16b
+; SVE-NEXT:    ptrue p0.h, vl8
+; SVE-NEXT:    // kill: def $q0 killed $q0 def $z0
+; SVE-NEXT:    rbit z0.h, p0/m, z0.h
+; SVE-NEXT:    // kill: def $q0 killed $q0 killed $z0
 ; SVE-NEXT:    ret
   %b = call <8 x i16> @llvm.bitreverse.v8i16(<8 x i16> %a)
   ret <8 x i16> %b
@@ -301,10 +307,13 @@ define <16 x i16> @g_vec_16x16(<16 x i16> %a) {
 ;
 ; SVE-LABEL: g_vec_16x16:
 ; SVE:       // %bb.0:
-; SVE-NEXT:    rev16 v0.16b, v0.16b
-; SVE-NEXT:    rev16 v1.16b, v1.16b
-; SVE-NEXT:    rbit v0.16b, v0.16b
-; SVE-NEXT:    rbit v1.16b, v1.16b
+; SVE-NEXT:    ptrue p0.h, vl8
+; SVE-NEXT:    // kill: def $q1 killed $q1 def $z1
+; SVE-NEXT:    // kill: def $q0 killed $q0 def $z0
+; SVE-NEXT:    rbit z0.h, p0/m, z0.h
+; SVE-NEXT:    rbit z1.h, p0/m, z1.h
+; SVE-NEXT:    // kill: def $q0 killed $q0 killed $z0
+; SVE-NEXT:    // kill: def $q1 killed $q1 killed $z1
 ; SVE-NEXT:    ret
   %b = call <16 x i16> @llvm.bitreverse.v16i16(<16 x i16> %a)
   ret <16 x i16> %b
@@ -321,8 +330,10 @@ define <2 x i32> @g_vec_2x32(<2 x i32> %a) {
 ;
 ; SVE-LABEL: g_vec_2x32:
 ; SVE:       // %bb.0:
-; SVE-NEXT:    rev32 v0.8b, v0.8b
-; SVE-NEXT:    rbit v0.8b, v0.8b
+; SVE-NEXT:    ptrue p0.s, vl2
+; SVE-NEXT:    // kill: def $d0 killed $d0 def $z0
+; SVE-NEXT:    rbit z0.s, p0/m, z0.s
+; SVE-NEXT:    // kill: def $d0 killed $d0 killed $z0
 ; SVE-NEXT:    ret
   %b = call <2 x i32> @llvm.bitreverse.v2i32(<2 x i32> %a)
   ret <2 x i32> %b
@@ -339,8 +350,10 @@ define <4 x i32> @g_vec_4x32(<4 x i32> %a) {
 ;
 ; SVE-LABEL: g_vec_4x32:
 ; SVE:       // %bb.0:
-; SVE-NEXT:    rev32 v0.16b, v0.16b
-; SVE-NEXT:    rbit v0.16b, v0.16b
+; SVE-NEXT:    ptrue p0.s, vl4
+; SVE-NEXT:    // kill: def $q0 killed $q0 def $z0
+; SVE-NEXT:    rbit z0.s, p0/m, z0.s
+; SVE-NEXT:    // kill: def $q0 killed $q0 killed $z0
 ; SVE-NEXT:    ret
   %b = call <4 x i32> @llvm.bitreverse.v4i32(<4 x i32> %a)
   ret <4 x i32> %b
@@ -359,10 +372,13 @@ define <8 x i32> @g_vec_8x32(<8 x i32> %a) {
 ;
 ; SVE-LABEL: g_vec_8x32:
 ; SVE:       // %bb.0:
-; SVE-NEXT:    rev32 v0.16b, v0.16b
-; SVE-NEXT:    rev32 v1.16b, v1.16b
-; SVE-NEXT:    rbit v0.16b, v0.16b
-; SVE-NEXT:    rbit v1.16b, v1.16b
+; SVE-NEXT:    ptrue p0.s, vl4
+; SVE-NEXT:    // kill: def $q1 killed $q1 def $z1
+; SVE-NEXT:    // kill: def $q0 killed $q0 def $z0
+; SVE-NEXT:    rbit z0.s, p0/m, z0.s
+; SVE-NEXT:    rbit z1.s, p0/m, z1.s
+; SVE-NEXT:    // kill: def $q0 killed $q0 killed $z0
+; SVE-NEXT:    // kill: def $q1 killed $q1 killed $z1
 ; SVE-NEXT:    ret
   %b = call <8 x i32> @llvm.bitreverse.v8i32(<8 x i32> %a)
   ret <8 x i32> %b
@@ -379,8 +395,10 @@ define <1 x i64> @g_vec_1x64(<1 x i64> %a) {
 ;
 ; SVE-LABEL: g_vec_1x64:
 ; SVE:       // %bb.0:
-; SVE-NEXT:    rev64 v0.8b, v0.8b
-; SVE-NEXT:    rbit v0.8b, v0.8b
+; SVE-NEXT:    ptrue p0.d, vl1
+; SVE-NEXT:    // kill: def $d0 killed $d0 def $z0
+; SVE-NEXT:    rbit z0.d, p0/m, z0.d
+; SVE-NEXT:    // kill: def $d0 killed $d0 killed $z0
 ; SVE-NEXT:    ret
 ;
 ; GISEL-LABEL: g_vec_1x64:
@@ -404,8 +422,10 @@ define <2 x i64> @g_vec_2x64(<2 x i64> %a) {
 ;
 ; SVE-LABEL: g_vec_2x64:
 ; SVE:       // %bb.0:
-; SVE-NEXT:    rev64 v0.16b, v0.16b
-; SVE-NEXT:    rbit v0.16b, v0.16b
+; SVE-NEXT:    ptrue p0.d, vl2
+; SVE-NEXT:    // kill: def $q0 killed $q0 def $z0
+; SVE-NEXT:    rbit z0.d, p0/m, z0.d
+; SVE-NEXT:    // kill: def $q0 killed $q0 killed $z0
 ; SVE-NEXT:    ret
   %b = call <2 x i64> @llvm.bitreverse.v2i64(<2 x i64> %a)
   ret <2 x i64> %b
@@ -424,10 +444,13 @@ define <4 x i64> @g_vec_4x64(<4 x i64> %a) {
 ;
 ; SVE-LABEL: g_vec_4x64:
 ; SVE:       // %bb.0:
-; SVE-NEXT:    rev64 v0.16b, v0.16b
-; SVE-NEXT:    rev64 v1.16b, v1.16b
-; SVE-NEXT:    rbit v0.16b, v0.16b
-; SVE-NEXT:    rbit v1.16b, v1.16b
+; SVE-NEXT:    ptrue p0.d, vl2
+; SVE-NEXT:    // kill: def $q1 killed $q1 def $z1
+; SVE-NEXT:    // kill: def $q0 killed $q0 def $z0
+; SVE-NEXT:    rbit z0.d, p0/m, z0.d
+; SVE-NEXT:    rbit z1.d, p0/m, z1.d
+; SVE-NEXT:    // kill: def $q0 killed $q0 killed $z0
+; SVE-NEXT:    // kill: def $q1 killed $q1 killed $z1
 ; SVE-NEXT:    ret
   %b = call <4 x i64> @llvm.bitreverse.v4i64(<4 x i64> %a)
   ret <4 x i64> %b

>From 0420e9496b41953c33c57dbe7f7742b6030a19c8 Mon Sep 17 00:00:00 2001
From: Yashwant Singh <yashwants at nvidia.com>
Date: Wed, 6 May 2026 02:46:40 -0700
Subject: [PATCH 3/5] Update filecheck labels

---
 llvm/test/CodeGen/AArch64/bitreverse.ll | 220 +++++++++++-------------
 1 file changed, 101 insertions(+), 119 deletions(-)

diff --git a/llvm/test/CodeGen/AArch64/bitreverse.ll b/llvm/test/CodeGen/AArch64/bitreverse.ll
index 1ff3687f0f7a8..d1c3e9acd85cf 100644
--- a/llvm/test/CodeGen/AArch64/bitreverse.ll
+++ b/llvm/test/CodeGen/AArch64/bitreverse.ll
@@ -1,6 +1,6 @@
 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
 ; RUN: llc -mtriple=aarch64 %s -o - | FileCheck %s --check-prefixes=CHECK,SDAG
-; RUN: llc -mtriple=aarch64 -mattr=+sve %s -o - | FileCheck %s --check-prefixes=SVE
+; RUN: llc -mtriple=aarch64 -mattr=+sve %s -o - | FileCheck %s --check-prefixes=CHECK,SVE
 ; RUN: llc -mtriple=aarch64 -global-isel -global-isel-abort=1 %s -o - | FileCheck %s --check-prefixes=CHECK,GISEL
 
 ; These tests just check that the plumbing is in place for @llvm.bitreverse.
@@ -43,12 +43,6 @@ define i8 @g(i8 %a) {
 ; CHECK-NEXT:    rbit w8, w0
 ; CHECK-NEXT:    lsr w0, w8, #24
 ; CHECK-NEXT:    ret
-;
-; SVE-LABEL: g:
-; SVE:       // %bb.0:
-; SVE-NEXT:    rbit w8, w0
-; SVE-NEXT:    lsr w0, w8, #24
-; SVE-NEXT:    ret
   %b = call i8 @llvm.bitreverse.i8(i8 %a)
   ret i8 %b
 }
@@ -61,12 +55,6 @@ define i16 @g_16(i16 %a) {
 ; CHECK-NEXT:    rbit w8, w0
 ; CHECK-NEXT:    lsr w0, w8, #16
 ; CHECK-NEXT:    ret
-;
-; SVE-LABEL: g_16:
-; SVE:       // %bb.0:
-; SVE-NEXT:    rbit w8, w0
-; SVE-NEXT:    lsr w0, w8, #16
-; SVE-NEXT:    ret
   %b = call i16 @llvm.bitreverse.i16(i16 %a)
   ret i16 %b
 }
@@ -78,11 +66,6 @@ define i32 @g_32(i32 %a) {
 ; CHECK:       // %bb.0:
 ; CHECK-NEXT:    rbit w0, w0
 ; CHECK-NEXT:    ret
-;
-; SVE-LABEL: g_32:
-; SVE:       // %bb.0:
-; SVE-NEXT:    rbit w0, w0
-; SVE-NEXT:    ret
   %b = call i32 @llvm.bitreverse.i32(i32 %a)
   ret i32 %b
 }
@@ -94,11 +77,6 @@ define i64 @g_64(i64 %a) {
 ; CHECK:       // %bb.0:
 ; CHECK-NEXT:    rbit x0, x0
 ; CHECK-NEXT:    ret
-;
-; SVE-LABEL: g_64:
-; SVE:       // %bb.0:
-; SVE-NEXT:    rbit x0, x0
-; SVE-NEXT:    ret
   %b = call i64 @llvm.bitreverse.i64(i64 %a)
   ret i64 %b
 }
@@ -112,13 +90,6 @@ define i128 @g_128(i128 %a) {
 ; CHECK-NEXT:    rbit x1, x0
 ; CHECK-NEXT:    mov x0, x8
 ; CHECK-NEXT:    ret
-;
-; SVE-LABEL: g_128:
-; SVE:       // %bb.0:
-; SVE-NEXT:    rbit x8, x1
-; SVE-NEXT:    rbit x1, x0
-; SVE-NEXT:    mov x0, x8
-; SVE-NEXT:    ret
   %b = call i128 @llvm.bitreverse.i128(i128 %a)
   ret i128 %b
 }
@@ -131,12 +102,6 @@ define <16 x i3> @g_vec_16x3(<16 x i3> %a) {
 ; CHECK-NEXT:    rbit v0.16b, v0.16b
 ; CHECK-NEXT:    ushr v0.16b, v0.16b, #5
 ; CHECK-NEXT:    ret
-;
-; SVE-LABEL: g_vec_16x3:
-; SVE:       // %bb.0:
-; SVE-NEXT:    rbit v0.16b, v0.16b
-; SVE-NEXT:    ushr v0.16b, v0.16b, #5
-; SVE-NEXT:    ret
   %b = call <16 x i3> @llvm.bitreverse.v16i3(<16 x i3> %a)
   ret <16 x i3> %b
 }
@@ -149,12 +114,6 @@ define <16 x i4> @g_vec_16x4(<16 x i4> %a) {
 ; CHECK-NEXT:    rbit v0.16b, v0.16b
 ; CHECK-NEXT:    ushr v0.16b, v0.16b, #4
 ; CHECK-NEXT:    ret
-;
-; SVE-LABEL: g_vec_16x4:
-; SVE:       // %bb.0:
-; SVE-NEXT:    rbit v0.16b, v0.16b
-; SVE-NEXT:    ushr v0.16b, v0.16b, #4
-; SVE-NEXT:    ret
   %b = call <16 x i4> @llvm.bitreverse.v16i4(<16 x i4> %a)
   ret <16 x i4> %b
 }
@@ -166,11 +125,6 @@ define <8 x i8> @g_vec(<8 x i8> %a) {
 ; CHECK:       // %bb.0:
 ; CHECK-NEXT:    rbit v0.8b, v0.8b
 ; CHECK-NEXT:    ret
-;
-; SVE-LABEL: g_vec:
-; SVE:       // %bb.0:
-; SVE-NEXT:    rbit v0.8b, v0.8b
-; SVE-NEXT:    ret
   %b = call <8 x i8> @llvm.bitreverse.v8i8(<8 x i8> %a)
   ret <8 x i8> %b
 }
@@ -182,11 +136,6 @@ define <16 x i8> @g_vec_16x8(<16 x i8> %a) {
 ; CHECK:       // %bb.0:
 ; CHECK-NEXT:    rbit v0.16b, v0.16b
 ; CHECK-NEXT:    ret
-;
-; SVE-LABEL: g_vec_16x8:
-; SVE:       // %bb.0:
-; SVE-NEXT:    rbit v0.16b, v0.16b
-; SVE-NEXT:    ret
   %b = call <16 x i8> @llvm.bitreverse.v16i8(<16 x i8> %a)
   ret <16 x i8> %b
 }
@@ -199,12 +148,6 @@ define <32 x i8> @g_vec_32x8(<32 x i8> %a) {
 ; CHECK-NEXT:    rbit v0.16b, v0.16b
 ; CHECK-NEXT:    rbit v1.16b, v1.16b
 ; CHECK-NEXT:    ret
-;
-; SVE-LABEL: g_vec_32x8:
-; SVE:       // %bb.0:
-; SVE-NEXT:    rbit v0.16b, v0.16b
-; SVE-NEXT:    rbit v1.16b, v1.16b
-; SVE-NEXT:    ret
   %b = call <32 x i8> @llvm.bitreverse.v32i8(<32 x i8> %a)
   ret <32 x i8> %b
 }
@@ -245,11 +188,6 @@ define <9 x i8> @g_vec_9x8(<9 x i8> %a) {
 ; CHECK:       // %bb.0:
 ; CHECK-NEXT:    rbit v0.16b, v0.16b
 ; CHECK-NEXT:    ret
-;
-; SVE-LABEL: g_vec_9x8:
-; SVE:       // %bb.0:
-; SVE-NEXT:    rbit v0.16b, v0.16b
-; SVE-NEXT:    ret
   %b = call <9 x i8> @llvm.bitreverse.v9i8(<9 x i8> %a)
   ret <9 x i8> %b
 }
@@ -257,11 +195,11 @@ define <9 x i8> @g_vec_9x8(<9 x i8> %a) {
 declare <4 x i16> @llvm.bitreverse.v4i16(<4 x i16>) readnone
 
 define <4 x i16> @g_vec_4x16(<4 x i16> %a) {
-; CHECK-LABEL: g_vec_4x16:
-; CHECK:       // %bb.0:
-; CHECK-NEXT:    rev16 v0.8b, v0.8b
-; CHECK-NEXT:    rbit v0.8b, v0.8b
-; CHECK-NEXT:    ret
+; SDAG-LABEL: g_vec_4x16:
+; SDAG:       // %bb.0:
+; SDAG-NEXT:    rev16 v0.8b, v0.8b
+; SDAG-NEXT:    rbit v0.8b, v0.8b
+; SDAG-NEXT:    ret
 ;
 ; SVE-LABEL: g_vec_4x16:
 ; SVE:       // %bb.0:
@@ -270,6 +208,12 @@ define <4 x i16> @g_vec_4x16(<4 x i16> %a) {
 ; SVE-NEXT:    rbit z0.h, p0/m, z0.h
 ; SVE-NEXT:    // kill: def $d0 killed $d0 killed $z0
 ; SVE-NEXT:    ret
+;
+; GISEL-LABEL: g_vec_4x16:
+; GISEL:       // %bb.0:
+; GISEL-NEXT:    rev16 v0.8b, v0.8b
+; GISEL-NEXT:    rbit v0.8b, v0.8b
+; GISEL-NEXT:    ret
   %b = call <4 x i16> @llvm.bitreverse.v4i16(<4 x i16> %a)
   ret <4 x i16> %b
 }
@@ -277,11 +221,11 @@ define <4 x i16> @g_vec_4x16(<4 x i16> %a) {
 declare <8 x i16> @llvm.bitreverse.v8i16(<8 x i16>) readnone
 
 define <8 x i16> @g_vec_8x16(<8 x i16> %a) {
-; CHECK-LABEL: g_vec_8x16:
-; CHECK:       // %bb.0:
-; CHECK-NEXT:    rev16 v0.16b, v0.16b
-; CHECK-NEXT:    rbit v0.16b, v0.16b
-; CHECK-NEXT:    ret
+; SDAG-LABEL: g_vec_8x16:
+; SDAG:       // %bb.0:
+; SDAG-NEXT:    rev16 v0.16b, v0.16b
+; SDAG-NEXT:    rbit v0.16b, v0.16b
+; SDAG-NEXT:    ret
 ;
 ; SVE-LABEL: g_vec_8x16:
 ; SVE:       // %bb.0:
@@ -290,6 +234,12 @@ define <8 x i16> @g_vec_8x16(<8 x i16> %a) {
 ; SVE-NEXT:    rbit z0.h, p0/m, z0.h
 ; SVE-NEXT:    // kill: def $q0 killed $q0 killed $z0
 ; SVE-NEXT:    ret
+;
+; GISEL-LABEL: g_vec_8x16:
+; GISEL:       // %bb.0:
+; GISEL-NEXT:    rev16 v0.16b, v0.16b
+; GISEL-NEXT:    rbit v0.16b, v0.16b
+; GISEL-NEXT:    ret
   %b = call <8 x i16> @llvm.bitreverse.v8i16(<8 x i16> %a)
   ret <8 x i16> %b
 }
@@ -297,13 +247,13 @@ define <8 x i16> @g_vec_8x16(<8 x i16> %a) {
 declare <16 x i16> @llvm.bitreverse.v16i16(<16 x i16>) readnone
 
 define <16 x i16> @g_vec_16x16(<16 x i16> %a) {
-; CHECK-LABEL: g_vec_16x16:
-; CHECK:       // %bb.0:
-; CHECK-NEXT:    rev16 v0.16b, v0.16b
-; CHECK-NEXT:    rev16 v1.16b, v1.16b
-; CHECK-NEXT:    rbit v0.16b, v0.16b
-; CHECK-NEXT:    rbit v1.16b, v1.16b
-; CHECK-NEXT:    ret
+; SDAG-LABEL: g_vec_16x16:
+; SDAG:       // %bb.0:
+; SDAG-NEXT:    rev16 v0.16b, v0.16b
+; SDAG-NEXT:    rev16 v1.16b, v1.16b
+; SDAG-NEXT:    rbit v0.16b, v0.16b
+; SDAG-NEXT:    rbit v1.16b, v1.16b
+; SDAG-NEXT:    ret
 ;
 ; SVE-LABEL: g_vec_16x16:
 ; SVE:       // %bb.0:
@@ -315,6 +265,14 @@ define <16 x i16> @g_vec_16x16(<16 x i16> %a) {
 ; SVE-NEXT:    // kill: def $q0 killed $q0 killed $z0
 ; SVE-NEXT:    // kill: def $q1 killed $q1 killed $z1
 ; SVE-NEXT:    ret
+;
+; GISEL-LABEL: g_vec_16x16:
+; GISEL:       // %bb.0:
+; GISEL-NEXT:    rev16 v0.16b, v0.16b
+; GISEL-NEXT:    rev16 v1.16b, v1.16b
+; GISEL-NEXT:    rbit v0.16b, v0.16b
+; GISEL-NEXT:    rbit v1.16b, v1.16b
+; GISEL-NEXT:    ret
   %b = call <16 x i16> @llvm.bitreverse.v16i16(<16 x i16> %a)
   ret <16 x i16> %b
 }
@@ -322,11 +280,11 @@ define <16 x i16> @g_vec_16x16(<16 x i16> %a) {
 declare <2 x i32> @llvm.bitreverse.v2i32(<2 x i32>) readnone
 
 define <2 x i32> @g_vec_2x32(<2 x i32> %a) {
-; CHECK-LABEL: g_vec_2x32:
-; CHECK:       // %bb.0:
-; CHECK-NEXT:    rev32 v0.8b, v0.8b
-; CHECK-NEXT:    rbit v0.8b, v0.8b
-; CHECK-NEXT:    ret
+; SDAG-LABEL: g_vec_2x32:
+; SDAG:       // %bb.0:
+; SDAG-NEXT:    rev32 v0.8b, v0.8b
+; SDAG-NEXT:    rbit v0.8b, v0.8b
+; SDAG-NEXT:    ret
 ;
 ; SVE-LABEL: g_vec_2x32:
 ; SVE:       // %bb.0:
@@ -335,6 +293,12 @@ define <2 x i32> @g_vec_2x32(<2 x i32> %a) {
 ; SVE-NEXT:    rbit z0.s, p0/m, z0.s
 ; SVE-NEXT:    // kill: def $d0 killed $d0 killed $z0
 ; SVE-NEXT:    ret
+;
+; GISEL-LABEL: g_vec_2x32:
+; GISEL:       // %bb.0:
+; GISEL-NEXT:    rev32 v0.8b, v0.8b
+; GISEL-NEXT:    rbit v0.8b, v0.8b
+; GISEL-NEXT:    ret
   %b = call <2 x i32> @llvm.bitreverse.v2i32(<2 x i32> %a)
   ret <2 x i32> %b
 }
@@ -342,11 +306,11 @@ define <2 x i32> @g_vec_2x32(<2 x i32> %a) {
 declare <4 x i32> @llvm.bitreverse.v4i32(<4 x i32>) readnone
 
 define <4 x i32> @g_vec_4x32(<4 x i32> %a) {
-; CHECK-LABEL: g_vec_4x32:
-; CHECK:       // %bb.0:
-; CHECK-NEXT:    rev32 v0.16b, v0.16b
-; CHECK-NEXT:    rbit v0.16b, v0.16b
-; CHECK-NEXT:    ret
+; SDAG-LABEL: g_vec_4x32:
+; SDAG:       // %bb.0:
+; SDAG-NEXT:    rev32 v0.16b, v0.16b
+; SDAG-NEXT:    rbit v0.16b, v0.16b
+; SDAG-NEXT:    ret
 ;
 ; SVE-LABEL: g_vec_4x32:
 ; SVE:       // %bb.0:
@@ -355,6 +319,12 @@ define <4 x i32> @g_vec_4x32(<4 x i32> %a) {
 ; SVE-NEXT:    rbit z0.s, p0/m, z0.s
 ; SVE-NEXT:    // kill: def $q0 killed $q0 killed $z0
 ; SVE-NEXT:    ret
+;
+; GISEL-LABEL: g_vec_4x32:
+; GISEL:       // %bb.0:
+; GISEL-NEXT:    rev32 v0.16b, v0.16b
+; GISEL-NEXT:    rbit v0.16b, v0.16b
+; GISEL-NEXT:    ret
   %b = call <4 x i32> @llvm.bitreverse.v4i32(<4 x i32> %a)
   ret <4 x i32> %b
 }
@@ -362,13 +332,13 @@ define <4 x i32> @g_vec_4x32(<4 x i32> %a) {
 declare <8 x i32> @llvm.bitreverse.v8i32(<8 x i32>) readnone
 
 define <8 x i32> @g_vec_8x32(<8 x i32> %a) {
-; CHECK-LABEL: g_vec_8x32:
-; CHECK:       // %bb.0:
-; CHECK-NEXT:    rev32 v0.16b, v0.16b
-; CHECK-NEXT:    rev32 v1.16b, v1.16b
-; CHECK-NEXT:    rbit v0.16b, v0.16b
-; CHECK-NEXT:    rbit v1.16b, v1.16b
-; CHECK-NEXT:    ret
+; SDAG-LABEL: g_vec_8x32:
+; SDAG:       // %bb.0:
+; SDAG-NEXT:    rev32 v0.16b, v0.16b
+; SDAG-NEXT:    rev32 v1.16b, v1.16b
+; SDAG-NEXT:    rbit v0.16b, v0.16b
+; SDAG-NEXT:    rbit v1.16b, v1.16b
+; SDAG-NEXT:    ret
 ;
 ; SVE-LABEL: g_vec_8x32:
 ; SVE:       // %bb.0:
@@ -380,6 +350,14 @@ define <8 x i32> @g_vec_8x32(<8 x i32> %a) {
 ; SVE-NEXT:    // kill: def $q0 killed $q0 killed $z0
 ; SVE-NEXT:    // kill: def $q1 killed $q1 killed $z1
 ; SVE-NEXT:    ret
+;
+; GISEL-LABEL: g_vec_8x32:
+; GISEL:       // %bb.0:
+; GISEL-NEXT:    rev32 v0.16b, v0.16b
+; GISEL-NEXT:    rev32 v1.16b, v1.16b
+; GISEL-NEXT:    rbit v0.16b, v0.16b
+; GISEL-NEXT:    rbit v1.16b, v1.16b
+; GISEL-NEXT:    ret
   %b = call <8 x i32> @llvm.bitreverse.v8i32(<8 x i32> %a)
   ret <8 x i32> %b
 }
@@ -414,11 +392,11 @@ define <1 x i64> @g_vec_1x64(<1 x i64> %a) {
 declare <2 x i64> @llvm.bitreverse.v2i64(<2 x i64>) readnone
 
 define <2 x i64> @g_vec_2x64(<2 x i64> %a) {
-; CHECK-LABEL: g_vec_2x64:
-; CHECK:       // %bb.0:
-; CHECK-NEXT:    rev64 v0.16b, v0.16b
-; CHECK-NEXT:    rbit v0.16b, v0.16b
-; CHECK-NEXT:    ret
+; SDAG-LABEL: g_vec_2x64:
+; SDAG:       // %bb.0:
+; SDAG-NEXT:    rev64 v0.16b, v0.16b
+; SDAG-NEXT:    rbit v0.16b, v0.16b
+; SDAG-NEXT:    ret
 ;
 ; SVE-LABEL: g_vec_2x64:
 ; SVE:       // %bb.0:
@@ -427,6 +405,12 @@ define <2 x i64> @g_vec_2x64(<2 x i64> %a) {
 ; SVE-NEXT:    rbit z0.d, p0/m, z0.d
 ; SVE-NEXT:    // kill: def $q0 killed $q0 killed $z0
 ; SVE-NEXT:    ret
+;
+; GISEL-LABEL: g_vec_2x64:
+; GISEL:       // %bb.0:
+; GISEL-NEXT:    rev64 v0.16b, v0.16b
+; GISEL-NEXT:    rbit v0.16b, v0.16b
+; GISEL-NEXT:    ret
   %b = call <2 x i64> @llvm.bitreverse.v2i64(<2 x i64> %a)
   ret <2 x i64> %b
 }
@@ -434,13 +418,13 @@ define <2 x i64> @g_vec_2x64(<2 x i64> %a) {
 declare <4 x i64> @llvm.bitreverse.v4i64(<4 x i64>) readnone
 
 define <4 x i64> @g_vec_4x64(<4 x i64> %a) {
-; CHECK-LABEL: g_vec_4x64:
-; CHECK:       // %bb.0:
-; CHECK-NEXT:    rev64 v0.16b, v0.16b
-; CHECK-NEXT:    rev64 v1.16b, v1.16b
-; CHECK-NEXT:    rbit v0.16b, v0.16b
-; CHECK-NEXT:    rbit v1.16b, v1.16b
-; CHECK-NEXT:    ret
+; SDAG-LABEL: g_vec_4x64:
+; SDAG:       // %bb.0:
+; SDAG-NEXT:    rev64 v0.16b, v0.16b
+; SDAG-NEXT:    rev64 v1.16b, v1.16b
+; SDAG-NEXT:    rbit v0.16b, v0.16b
+; SDAG-NEXT:    rbit v1.16b, v1.16b
+; SDAG-NEXT:    ret
 ;
 ; SVE-LABEL: g_vec_4x64:
 ; SVE:       // %bb.0:
@@ -452,6 +436,14 @@ define <4 x i64> @g_vec_4x64(<4 x i64> %a) {
 ; SVE-NEXT:    // kill: def $q0 killed $q0 killed $z0
 ; SVE-NEXT:    // kill: def $q1 killed $q1 killed $z1
 ; SVE-NEXT:    ret
+;
+; GISEL-LABEL: g_vec_4x64:
+; GISEL:       // %bb.0:
+; GISEL-NEXT:    rev64 v0.16b, v0.16b
+; GISEL-NEXT:    rev64 v1.16b, v1.16b
+; GISEL-NEXT:    rbit v0.16b, v0.16b
+; GISEL-NEXT:    rbit v1.16b, v1.16b
+; GISEL-NEXT:    ret
   %b = call <4 x i64> @llvm.bitreverse.v4i64(<4 x i64> %a)
   ret <4 x i64> %b
 }
@@ -468,16 +460,6 @@ define <2 x i128> @g_vec_2x128(<2 x i128> %a) {
 ; CHECK-NEXT:    mov x0, x8
 ; CHECK-NEXT:    mov x2, x9
 ; CHECK-NEXT:    ret
-;
-; SVE-LABEL: g_vec_2x128:
-; SVE:       // %bb.0:
-; SVE-NEXT:    rbit x8, x1
-; SVE-NEXT:    rbit x9, x3
-; SVE-NEXT:    rbit x1, x0
-; SVE-NEXT:    rbit x3, x2
-; SVE-NEXT:    mov x0, x8
-; SVE-NEXT:    mov x2, x9
-; SVE-NEXT:    ret
   %b = call <2 x i128> @llvm.bitreverse.v2i128(<2 x i128> %a)
   ret <2 x i128> %b
 }

>From f33b253ae8d7df5a17d97cdf4cbb662d4ad22fca Mon Sep 17 00:00:00 2001
From: Yashwant Singh <yashwants at nvidia.com>
Date: Thu, 7 May 2026 22:50:25 -0700
Subject: [PATCH 4/5] Address review comments

---
 .../Target/AArch64/AArch64ISelLowering.cpp    | 24 ++++---------------
 1 file changed, 5 insertions(+), 19 deletions(-)

diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index a52f0bb40c601..02c3051c084aa 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -1332,8 +1332,6 @@ AArch64TargetLowering::AArch64TargetLowering(const TargetMachine &TM,
       setOperationAction(ISD::CTLS, VT, Legal);
     setOperationAction(ISD::BITREVERSE, MVT::v8i8, Legal);
     setOperationAction(ISD::BITREVERSE, MVT::v16i8, Legal);
-    setOperationAction(ISD::BITREVERSE, MVT::v4i16, Custom);
-    setOperationAction(ISD::BITREVERSE, MVT::v8i16, Custom);
     setOperationAction(ISD::BITREVERSE, MVT::v2i32, Custom);
     setOperationAction(ISD::BITREVERSE, MVT::v4i32, Custom);
     setOperationAction(ISD::BITREVERSE, MVT::v1i64, Custom);
@@ -1933,6 +1931,10 @@ AArch64TargetLowering::AArch64TargetLowering(const TargetMachine &TM,
       setOperationAction(ISD::MULHU, VT, Custom);
     }
 
+    for (auto VT : {MVT::v4i16, MVT::v8i16, MVT::v2i32, MVT::v4i32, MVT::v1i64,
+                    MVT::v2i64})
+      setOperationAction(ISD::BITREVERSE, VT, Custom);
+
     // NEON doesn't support 64-bit vector integer muls, but SVE does.
     setOperationAction(ISD::MUL, MVT::v1i64, Custom);
     setOperationAction(ISD::MUL, MVT::v2i64, Custom);
@@ -11821,9 +11823,7 @@ SDValue AArch64TargetLowering::LowerBitreverse(SDValue Op,
                                                SelectionDAG &DAG) const {
   EVT VT = Op.getValueType();
 
-  if (VT.isScalableVector() ||
-      useSVEForFixedLengthVectorVT(
-          VT, /*OverrideNEON=*/Subtarget->isSVEorStreamingSVEAvailable()))
+  if (Subtarget->isSVEorStreamingSVEAvailable())
     return LowerToPredicatedOp(Op, DAG, AArch64ISD::BITREVERSE_MERGE_PASSTHRU);
 
   SDLoc DL(Op);
@@ -11834,20 +11834,6 @@ SDValue AArch64TargetLowering::LowerBitreverse(SDValue Op,
   default:
     llvm_unreachable("Invalid type for bitreverse!");
 
-  case MVT::v4i16: {
-    SDValue Bswap = DAG.getNode(ISD::BSWAP, DL, VT, Op.getOperand(0));
-    VST = MVT::v8i8;
-    REVB = DAG.getBitcast(VST, Bswap);
-    break;
-  }
-
-  case MVT::v8i16: {
-    SDValue Bswap = DAG.getNode(ISD::BSWAP, DL, VT, Op.getOperand(0));
-    VST = MVT::v16i8;
-    REVB = DAG.getBitcast(VST, Bswap);
-    break;
-  }
-
   case MVT::v2i32: {
     VST = MVT::v8i8;
     REVB = DAG.getNode(AArch64ISD::REV32, DL, VST, Op.getOperand(0));

>From ea8cfa989371882c6149217dc35bca5a5ebcb70d Mon Sep 17 00:00:00 2001
From: Yashwant Singh <yashwants at nvidia.com>
Date: Sun, 10 May 2026 21:25:08 -0700
Subject: [PATCH 5/5] Remove stale BITREVERSE lowering enteries

---
 llvm/lib/Target/AArch64/AArch64ISelLowering.cpp        |  6 ++----
 .../CodeGen/AArch64/sve-fixed-length-bit-counting.ll   |  8 ++------
 llvm/test/CodeGen/AArch64/sve-fixed-length-rev.ll      | 10 ++--------
 3 files changed, 6 insertions(+), 18 deletions(-)

diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index 02c3051c084aa..ce499e5463d5f 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -1973,7 +1973,6 @@ AArch64TargetLowering::AArch64TargetLowering(const TargetMachine &TM,
         setOperationAction(ISD::FP_ROUND, VT, Custom);
 
       // These operations are not supported on NEON but SVE can do them.
-      setOperationAction(ISD::BITREVERSE, MVT::v1i64, Custom);
       setOperationAction(ISD::CTLZ, MVT::v1i64, Custom);
       setOperationAction(ISD::CTLZ, MVT::v2i64, Custom);
       setOperationAction(ISD::CTTZ, MVT::v1i64, Custom);
@@ -1991,9 +1990,8 @@ AArch64TargetLowering::AArch64TargetLowering(const TargetMachine &TM,
       setOperationAction(ISD::VECREDUCE_UMIN, MVT::v2i64, Custom);
 
       // Int operations with no NEON support.
-      for (auto VT : {MVT::v8i8, MVT::v16i8, MVT::v4i16, MVT::v8i16,
-                      MVT::v2i32, MVT::v4i32, MVT::v2i64}) {
-        setOperationAction(ISD::BITREVERSE, VT, Custom);
+      for (auto VT : {MVT::v8i8, MVT::v16i8, MVT::v4i16, MVT::v8i16, MVT::v2i32,
+                      MVT::v4i32, MVT::v2i64}) {
         setOperationAction(ISD::CTTZ, VT, Custom);
         setOperationAction(ISD::VECREDUCE_AND, VT, Custom);
         setOperationAction(ISD::VECREDUCE_OR, VT, Custom);
diff --git a/llvm/test/CodeGen/AArch64/sve-fixed-length-bit-counting.ll b/llvm/test/CodeGen/AArch64/sve-fixed-length-bit-counting.ll
index b62b850434469..2de1976322db0 100644
--- a/llvm/test/CodeGen/AArch64/sve-fixed-length-bit-counting.ll
+++ b/llvm/test/CodeGen/AArch64/sve-fixed-length-bit-counting.ll
@@ -740,9 +740,7 @@ define void @ctpop_v32i64(ptr %a) vscale_range(16,0) #0 {
 define <8 x i8> @cttz_v8i8(<8 x i8> %op) vscale_range(2,0) #0 {
 ; CHECK-LABEL: cttz_v8i8:
 ; CHECK:       // %bb.0:
-; CHECK-NEXT:    ptrue p0.b, vl8
-; CHECK-NEXT:    // kill: def $d0 killed $d0 def $z0
-; CHECK-NEXT:    rbit z0.b, p0/m, z0.b
+; CHECK-NEXT:    rbit v0.8b, v0.8b
 ; CHECK-NEXT:    clz v0.8b, v0.8b
 ; CHECK-NEXT:    ret
   %res = call <8 x i8> @llvm.cttz.v8i8(<8 x i8> %op)
@@ -752,9 +750,7 @@ define <8 x i8> @cttz_v8i8(<8 x i8> %op) vscale_range(2,0) #0 {
 define <16 x i8> @cttz_v16i8(<16 x i8> %op) vscale_range(2,0) #0 {
 ; CHECK-LABEL: cttz_v16i8:
 ; CHECK:       // %bb.0:
-; CHECK-NEXT:    ptrue p0.b, vl16
-; CHECK-NEXT:    // kill: def $q0 killed $q0 def $z0
-; CHECK-NEXT:    rbit z0.b, p0/m, z0.b
+; CHECK-NEXT:    rbit v0.16b, v0.16b
 ; CHECK-NEXT:    clz v0.16b, v0.16b
 ; CHECK-NEXT:    ret
   %res = call <16 x i8> @llvm.cttz.v16i8(<16 x i8> %op)
diff --git a/llvm/test/CodeGen/AArch64/sve-fixed-length-rev.ll b/llvm/test/CodeGen/AArch64/sve-fixed-length-rev.ll
index 82d350f6e28f8..7cf981d63f674 100644
--- a/llvm/test/CodeGen/AArch64/sve-fixed-length-rev.ll
+++ b/llvm/test/CodeGen/AArch64/sve-fixed-length-rev.ll
@@ -12,10 +12,7 @@ target triple = "aarch64-unknown-linux-gnu"
 define <8 x i8> @bitreverse_v8i8(<8 x i8> %op) vscale_range(2,0) #0 {
 ; CHECK-LABEL: bitreverse_v8i8:
 ; CHECK:       // %bb.0:
-; CHECK-NEXT:    ptrue p0.b, vl8
-; CHECK-NEXT:    // kill: def $d0 killed $d0 def $z0
-; CHECK-NEXT:    rbit z0.b, p0/m, z0.b
-; CHECK-NEXT:    // kill: def $d0 killed $d0 killed $z0
+; CHECK-NEXT:    rbit v0.8b, v0.8b
 ; CHECK-NEXT:    ret
   %res = call <8 x i8> @llvm.bitreverse.v8i8(<8 x i8> %op)
   ret <8 x i8> %res
@@ -24,10 +21,7 @@ define <8 x i8> @bitreverse_v8i8(<8 x i8> %op) vscale_range(2,0) #0 {
 define <16 x i8> @bitreverse_v16i8(<16 x i8> %op) vscale_range(2,0) #0 {
 ; CHECK-LABEL: bitreverse_v16i8:
 ; CHECK:       // %bb.0:
-; CHECK-NEXT:    ptrue p0.b, vl16
-; CHECK-NEXT:    // kill: def $q0 killed $q0 def $z0
-; CHECK-NEXT:    rbit z0.b, p0/m, z0.b
-; CHECK-NEXT:    // kill: def $q0 killed $q0 killed $z0
+; CHECK-NEXT:    rbit v0.16b, v0.16b
 ; CHECK-NEXT:    ret
   %res = call <16 x i8> @llvm.bitreverse.v16i8(<16 x i8> %op)
   ret <16 x i8> %res



More information about the llvm-commits mailing list