[llvm] [AArch64] Define constructive EXT_ZZZI pseudo instruction (PR #152552)
Gaƫtan Bossu via llvm-commits
llvm-commits at lists.llvm.org
Mon Aug 11 06:32:07 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: }
+ ; CHECK-NEXT: RET undef $lr, implicit killed $z2
+ $z2 = EXT_ZZZI killed $z0, killed $z2, 1
----------------
gbossu wrote:
This is the typical trap when re-writing two-address instructions, and I fell into it head first :(
I don't think there is an easy way around that other than convincing the register allocator to give different registers to the two inputs.
I also think the existing lowering of `DestructiveBinary` pseudo instructions is unsafe for the same reason. This can be seen in the `test_bic_zpzz_not_unique_regs` test case where the incoming value of `z2` is overwritten. I'll probably open a PR to disable `DestructiveBinary` pseudos for now.
For the `EXT` case, I'll probably go with @paulwalker-arm 's suggestion and create a variant of `EXT` that takes a single Z input.
https://github.com/llvm/llvm-project/pull/152552
More information about the llvm-commits
mailing list