[llvm] [AArch64] Define constructive EXT_ZZZI pseudo instruction (PR #152552)

Gaƫtan Bossu via llvm-commits llvm-commits at lists.llvm.org
Thu Aug 7 10:30:31 PDT 2025


================
@@ -0,0 +1,91 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 5
+# RUN: llc -mtriple=aarch64 -mattr=+sve -run-pass=aarch64-expand-pseudo -verify-machineinstrs %s -o - | FileCheck %s
+
+# Test the expansion of constructive ternary operations into their
+# destructive counterparts.
+
+
+# EXT_ZZZI
+
+---
+name:            test_ext_zzzi_unique
+body:             |
+  bb.0:
+    ; CHECK-LABEL: name: test_ext_zzzi_unique
+    ; CHECK: BUNDLE implicit-def $z2, implicit-def $q2, implicit-def $d2, implicit-def $s2, implicit-def $h2, implicit-def $b2, implicit-def $b2_hi, implicit-def $h2_hi, implicit-def $s2_hi, implicit-def $d2_hi, implicit-def $q2_hi, implicit $z0, implicit killed $z1 {
+    ; CHECK-NEXT:   $z2 = MOVPRFX_ZZ $z0
+    ; CHECK-NEXT:   $z2 = EXT_ZZI internal killed $z2, killed $z1, 1
+    ; CHECK-NEXT: }
+    ; CHECK-NEXT: RET undef $lr, implicit killed $z2
+    $z2 = EXT_ZZZI killed $z0, killed $z1, 1
+    RET_ReallyLR implicit killed $z2
+...
+
+# Here the destination register is the same as the second operand,
+# we cannot use movprfx.
+---
+name:            test_ext_zzzi_not_unique
+body:             |
+  bb.0:
+    ; CHECK-LABEL: name: test_ext_zzzi_not_unique
+    ; CHECK: BUNDLE implicit-def $z2, implicit-def $q2, implicit-def $d2, implicit-def $s2, implicit-def $h2, implicit-def $b2, implicit-def $b2_hi, implicit-def $h2_hi, implicit-def $s2_hi, implicit-def $d2_hi, implicit-def $q2_hi, implicit $z0 {
+    ; CHECK-NEXT:   $z2 = ORR_ZZZ $z0, $z0
+    ; CHECK-NEXT:   $z2 = EXT_ZZI internal killed $z2, internal killed $z2, 1
+    ; CHECK-NEXT: }
----------------
gbossu wrote:

The `BUNDLE` really shouldn't be needed beause the ORR is free to move.

But if you look at `test_ext_zzzi_unique_implicit_ops` below, you'll see that the implicit defs and uses aren't really properly maintained (because it's hard to do when splitting one instruction into two). As a consequence, it's just safer to keep the two instructions together in a `BUNDLE` (which seems to have correct implicit ops) to avoid introducing weird dependencies later in the `MachineScheduler`.

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


More information about the llvm-commits mailing list