Skip to content

Conversation

@jyli0116
Copy link
Contributor

@jyli0116 jyli0116 commented May 1, 2025

Handles bitreverse for vector types which were previously falling back onto Selection DAG. Includes 8-bit element vectors greater than 128 bits and less than 64 bits: <32 x i8>, <4 x i8>, and odd vector types: <9 x i8>.

@llvmbot
Copy link
Member

llvmbot commented May 1, 2025

@llvm/pr-subscribers-llvm-globalisel

Author: None (jyli0116)

Changes

Handles bitreverse for vector types which were previously falling back onto Selection DAG. Includes 8-bit element vectors greater than 128 bits and less than 64 bits: <32 x i8>, <4 x i8>, and odd vector types: <9 x i8>.


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

3 Files Affected:

  • (modified) llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp (+1)
  • (modified) llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp (+2)
  • (modified) llvm/test/CodeGen/AArch64/bitreverse.ll (+46)
diff --git a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
index 4052060271331..a1d0683269a97 100644
--- a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
@@ -6139,6 +6139,7 @@ LegalizerHelper::moreElementsVector(MachineInstr &MI, unsigned TypeIdx,
   case TargetOpcode::G_INTRINSIC_ROUND:
   case TargetOpcode::G_INTRINSIC_ROUNDEVEN:
   case TargetOpcode::G_INTRINSIC_TRUNC:
+  case TargetOpcode::G_BITREVERSE:
   case TargetOpcode::G_BSWAP:
   case TargetOpcode::G_FCANONICALIZE:
   case TargetOpcode::G_SEXT_INREG:
diff --git a/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp b/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp
index c36b20badfc09..28957f2664282 100644
--- a/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp
+++ b/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp
@@ -366,6 +366,8 @@ AArch64LegalizerInfo::AArch64LegalizerInfo(const AArch64Subtarget &ST)
       .legalFor({s32, s64, v8s8, v16s8})
       .widenScalarToNextPow2(0, /*Min = */ 32)
       .clampScalar(0, s32, s64)
+      .clampNumElements(0, v8s8, v16s8)
+      .moreElementsToNextPow2(0)
       .lower();
 
   getActionDefinitionsBuilder(G_BSWAP)
diff --git a/llvm/test/CodeGen/AArch64/bitreverse.ll b/llvm/test/CodeGen/AArch64/bitreverse.ll
index 04b78c5825a2d..90f651f16e6a2 100644
--- a/llvm/test/CodeGen/AArch64/bitreverse.ll
+++ b/llvm/test/CodeGen/AArch64/bitreverse.ll
@@ -136,6 +136,50 @@ define <16 x i8> @g_vec_16x8(<16 x i8> %a) {
   ret <16 x i8> %b
 }
 
+declare <32 x i8> @llvm.bitreverse.v32i8(<32 x i8>) readnone
+
+define <32 x i8> @g_vec_32x8(<32 x i8> %a) {
+; CHECK-LABEL: g_vec_32x8:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    rbit v0.16b, v0.16b
+; CHECK-NEXT:    rbit v1.16b, v1.16b
+; CHECK-NEXT:    ret
+  %b = call <32 x i8> @llvm.bitreverse.v32i8(<32 x i8> %a)
+  ret <32 x i8> %b
+}
+
+declare <4 x i8> @llvm.bitreverse.v4i8(<4 x i8>) readnone
+
+define <4 x i8> @g_vec_4x8(<4 x i8> %a) {
+; SDAG-LABEL: g_vec_4x8:
+; SDAG:       // %bb.0:
+; SDAG-NEXT:    rev16 v0.8b, v0.8b
+; SDAG-NEXT:    rbit v0.8b, v0.8b
+; SDAG-NEXT:    ushr v0.4h, v0.4h, #8
+; SDAG-NEXT:    ret
+;
+; GISEL-LABEL: g_vec_4x8:
+; GISEL:       // %bb.0:
+; GISEL-NEXT:    uzp1 v0.8b, v0.8b, v0.8b
+; GISEL-NEXT:    rbit v0.8b, v0.8b
+; GISEL-NEXT:    ushll v0.8h, v0.8b, #0
+; GISEL-NEXT:    // kill: def $d0 killed $d0 killed $q0
+; GISEL-NEXT:    ret
+  %b = call <4 x i8> @llvm.bitreverse.v4i8(<4 x i8> %a)
+  ret <4 x i8> %b
+}
+
+declare <9 x i8> @llvm.bitreverse.v9i8(<9 x i8>) readnone
+
+define <9 x i8> @g_vec_9x8(<9 x i8> %a) {
+; CHECK-LABEL: g_vec_9x8:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    rbit v0.16b, v0.16b
+; CHECK-NEXT:    ret
+  %b = call <9 x i8> @llvm.bitreverse.v9i8(<9 x i8> %a)
+  ret <9 x i8> %b
+}
+
 declare <4 x i16> @llvm.bitreverse.v4i16(<4 x i16>) readnone
 
 define <4 x i16> @g_vec_4x16(<4 x i16> %a) {
@@ -329,3 +373,5 @@ define <2 x i64> @g_vec_2x64(<2 x i64> %a) {
   %b = call <2 x i64> @llvm.bitreverse.v2i64(<2 x i64> %a)
   ret <2 x i64> %b
 }
+
+

@llvmbot
Copy link
Member

llvmbot commented May 1, 2025

@llvm/pr-subscribers-backend-aarch64

Author: None (jyli0116)

Changes

Handles bitreverse for vector types which were previously falling back onto Selection DAG. Includes 8-bit element vectors greater than 128 bits and less than 64 bits: <32 x i8>, <4 x i8>, and odd vector types: <9 x i8>.


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

3 Files Affected:

  • (modified) llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp (+1)
  • (modified) llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp (+2)
  • (modified) llvm/test/CodeGen/AArch64/bitreverse.ll (+46)
diff --git a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
index 4052060271331..a1d0683269a97 100644
--- a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
@@ -6139,6 +6139,7 @@ LegalizerHelper::moreElementsVector(MachineInstr &MI, unsigned TypeIdx,
   case TargetOpcode::G_INTRINSIC_ROUND:
   case TargetOpcode::G_INTRINSIC_ROUNDEVEN:
   case TargetOpcode::G_INTRINSIC_TRUNC:
+  case TargetOpcode::G_BITREVERSE:
   case TargetOpcode::G_BSWAP:
   case TargetOpcode::G_FCANONICALIZE:
   case TargetOpcode::G_SEXT_INREG:
diff --git a/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp b/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp
index c36b20badfc09..28957f2664282 100644
--- a/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp
+++ b/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp
@@ -366,6 +366,8 @@ AArch64LegalizerInfo::AArch64LegalizerInfo(const AArch64Subtarget &ST)
       .legalFor({s32, s64, v8s8, v16s8})
       .widenScalarToNextPow2(0, /*Min = */ 32)
       .clampScalar(0, s32, s64)
+      .clampNumElements(0, v8s8, v16s8)
+      .moreElementsToNextPow2(0)
       .lower();
 
   getActionDefinitionsBuilder(G_BSWAP)
diff --git a/llvm/test/CodeGen/AArch64/bitreverse.ll b/llvm/test/CodeGen/AArch64/bitreverse.ll
index 04b78c5825a2d..90f651f16e6a2 100644
--- a/llvm/test/CodeGen/AArch64/bitreverse.ll
+++ b/llvm/test/CodeGen/AArch64/bitreverse.ll
@@ -136,6 +136,50 @@ define <16 x i8> @g_vec_16x8(<16 x i8> %a) {
   ret <16 x i8> %b
 }
 
+declare <32 x i8> @llvm.bitreverse.v32i8(<32 x i8>) readnone
+
+define <32 x i8> @g_vec_32x8(<32 x i8> %a) {
+; CHECK-LABEL: g_vec_32x8:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    rbit v0.16b, v0.16b
+; CHECK-NEXT:    rbit v1.16b, v1.16b
+; CHECK-NEXT:    ret
+  %b = call <32 x i8> @llvm.bitreverse.v32i8(<32 x i8> %a)
+  ret <32 x i8> %b
+}
+
+declare <4 x i8> @llvm.bitreverse.v4i8(<4 x i8>) readnone
+
+define <4 x i8> @g_vec_4x8(<4 x i8> %a) {
+; SDAG-LABEL: g_vec_4x8:
+; SDAG:       // %bb.0:
+; SDAG-NEXT:    rev16 v0.8b, v0.8b
+; SDAG-NEXT:    rbit v0.8b, v0.8b
+; SDAG-NEXT:    ushr v0.4h, v0.4h, #8
+; SDAG-NEXT:    ret
+;
+; GISEL-LABEL: g_vec_4x8:
+; GISEL:       // %bb.0:
+; GISEL-NEXT:    uzp1 v0.8b, v0.8b, v0.8b
+; GISEL-NEXT:    rbit v0.8b, v0.8b
+; GISEL-NEXT:    ushll v0.8h, v0.8b, #0
+; GISEL-NEXT:    // kill: def $d0 killed $d0 killed $q0
+; GISEL-NEXT:    ret
+  %b = call <4 x i8> @llvm.bitreverse.v4i8(<4 x i8> %a)
+  ret <4 x i8> %b
+}
+
+declare <9 x i8> @llvm.bitreverse.v9i8(<9 x i8>) readnone
+
+define <9 x i8> @g_vec_9x8(<9 x i8> %a) {
+; CHECK-LABEL: g_vec_9x8:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    rbit v0.16b, v0.16b
+; CHECK-NEXT:    ret
+  %b = call <9 x i8> @llvm.bitreverse.v9i8(<9 x i8> %a)
+  ret <9 x i8> %b
+}
+
 declare <4 x i16> @llvm.bitreverse.v4i16(<4 x i16>) readnone
 
 define <4 x i16> @g_vec_4x16(<4 x i16> %a) {
@@ -329,3 +373,5 @@ define <2 x i64> @g_vec_2x64(<2 x i64> %a) {
   %b = call <2 x i64> @llvm.bitreverse.v2i64(<2 x i64> %a)
   ret <2 x i64> %b
 }
+
+

@jyli0116 jyli0116 changed the title [GlobalISel] Handles bitreverse to prevent falling back [GlobalISel][AArch64] Handles bitreverse to prevent falling back May 1, 2025
@davemgreen davemgreen requested review from aemerson and davemgreen May 1, 2025 16:10
Copy link
Collaborator

@davemgreen davemgreen left a comment

Choose a reason for hiding this comment

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

LGTM

@jyli0116 jyli0116 force-pushed the GISel_rbit_legal branch from b0341fd to a8058d7 Compare May 6, 2025 08:55
@davemgreen davemgreen merged commit fd80048 into llvm:main May 6, 2025
6 of 10 checks passed
@jyli0116 jyli0116 deleted the GISel_rbit_legal branch May 6, 2025 12:54
GeorgeARM pushed a commit to GeorgeARM/llvm-project that referenced this pull request May 7, 2025
…m#138150)

Handles bitreverse for vector types which were previously falling back
onto Selection DAG. Includes 8-bit element vectors greater than 128 bits
and less than 64 bits: <32 x i8>, <4 x i8>, and odd vector types: <9 x
i8>.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants