[llvm] [AARch64] Funnel Shift now uses rev32/rev64 instructions (PR #136707)

via llvm-commits llvm-commits at lists.llvm.org
Tue Apr 22 08:03:37 PDT 2025


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-backend-aarch64

Author: None (jyli0116)

<details>
<summary>Changes</summary>

Fixes #<!-- -->130469 

Now uses REV32/REV64 instructions to complete operation.

New Output:
```
G1:
        rev64   v0.4s, v0.4s
        ret
G2:
        rev32   v0.8h, v0.8h
        ret
G3:
        rev16   v0.16b, v0.16b
        ret
G4:
        rev32   v0.4h, v0.4h
        ret
G5:
        rev16   v0.8b, v0.8b
        ret
```

Old Output:

```
G1:
        shl     v1.2d, v0.2d, #<!-- -->32
        usra    v1.2d, v0.2d, #<!-- -->32
        mov     v0.16b, v1.16b
        ret

G2:
        shl     v1.4s, v0.4s, #<!-- -->16
        usra    v1.4s, v0.4s, #<!-- -->16
        mov     v0.16b, v1.16b
        ret

G3:
        rev16   v0.16b, v0.16b
        ret

G4:
        shl     v1.2s, v0.2s, #<!-- -->16
        usra    v1.2s, v0.2s, #<!-- -->16
        fmov    d0, d1
        ret

G5:
        rev16   v0.8b, v0.8b
        ret```

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


2 Files Affected:

- (modified) llvm/lib/Target/AArch64/AArch64InstrInfo.td (+8) 
- (added) llvm/test/CodeGen/AArch64/aarch64-fshl-rev.ll (+29) 


``````````diff
diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.td b/llvm/lib/Target/AArch64/AArch64InstrInfo.td
index a060a2f597ccd..e7aa9c53a8343 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrInfo.td
+++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.td
@@ -5679,6 +5679,14 @@ def : Pat<(v4i32 (bswap (v4i32 V128:$Rn))),
 def : Pat<(v2i64 (bswap (v2i64 V128:$Rn))),
           (v2i64 (REV64v16i8 (v2i64 V128:$Rn)))>;
 
+// Patterns for funnel shifts to be matched to equivalent REV instructions
+def : Pat<(v2i64 (or (v2i64 (AArch64vshl (v2i64 V128:$Rn), (i32 32))), (v2i64 (AArch64vlshr (v2i64 V128:$Rn), (i32 32))))), 
+          (v2i64 (REV64v4i32 (v2i64 V128:$Rn)))>;
+def : Pat<(v4i32 (or (v4i32 (AArch64vshl (v4i32 V128:$Rn), (i32 16))), (v4i32 (AArch64vlshr (v4i32 V128:$Rn), (i32 16))))), 
+          (v4i32 (REV32v8i16 (v4i32 V128:$Rn)))>;
+def : Pat<(v2i32 (or (v2i32 (AArch64vshl (v2i32 V64:$Rn), (i32 16))), (v2i32 (AArch64vlshr (v2i32 V64:$Rn), (i32 16))))), 
+          (v2i32 (REV32v4i16 (v2i32 V64:$Rn)))>;
+
 //===----------------------------------------------------------------------===//
 // Advanced SIMD three vector instructions.
 //===----------------------------------------------------------------------===//
diff --git a/llvm/test/CodeGen/AArch64/aarch64-fshl-rev.ll b/llvm/test/CodeGen/AArch64/aarch64-fshl-rev.ll
new file mode 100644
index 0000000000000..503bc307e7777
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/aarch64-fshl-rev.ll
@@ -0,0 +1,29 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
+; RUN: llc -mtriple=aarch64 %s -o - | FileCheck %s
+
+define <2 x i64> @fhsl_to_rev2i64(<2 x i64> %r) {
+; CHECK-LABEL: fhsl_to_rev2i64:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    rev64 v0.4s, v0.4s
+; CHECK-NEXT:    ret
+    %or = tail call <2 x i64> @llvm.fshl.v2i64(<2 x i64> %r, <2 x i64> %r, <2 x i64> splat (i64 32))
+    ret <2 x i64> %or
+}
+
+define <4 x i32> @fshl_to_rev4i32(<4 x i32> %r) {
+; CHECK-LABEL: fshl_to_rev4i32:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    rev32 v0.8h, v0.8h
+; CHECK-NEXT:    ret
+    %or = tail call <4 x i32> @llvm.fshl.v4i32(<4 x i32> %r, <4 x i32> %r, <4 x i32> splat (i32 16))
+    ret <4 x i32> %or
+}
+
+define <2 x i32> @fshl_to_rev2i32(<2 x i32> %r) {
+; CHECK-LABEL: fshl_to_rev2i32:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    rev32 v0.4h, v0.4h
+; CHECK-NEXT:    ret
+    %or = tail call <2 x i32> @llvm.fshl.v2i32(<2 x i32> %r, <2 x i32> %r, <2 x i32> splat (i32 16))
+    ret <2 x i32> %or
+}

``````````

</details>


https://github.com/llvm/llvm-project/pull/136707


More information about the llvm-commits mailing list