[llvm] [AArch64][CodeGen] Don't try to compute stack addresses in xzr (PR #213009)
Simon Tatham via llvm-commits
llvm-commits at lists.llvm.org
Fri Jul 31 01:14:31 PDT 2026
================
@@ -0,0 +1,149 @@
+# RUN: llc -mtriple=aarch64 -O1 -run-pass=aarch64-cond-br-tuning %s -o - \
+# RUN: | FileCheck %s
+# RUN: llc -mtriple=aarch64 -O1 %s -o - -verify-machineinstrs
+
+# Source: an llvm-reduced version of fuzzer-generated compiler input in
+# https://github.com/llvm/llvm-project/issues/212528
+#
+# The point of this test is to ensure we don't generate an add instruction
+# involving a stack slot with xzr as the destination, e.g.
+#
+# $xzr = ADDSXri %stack.0, 0, 0, implicit-def $nzcv
+#
+# because in this case, since there are SVE registers on the stack, that would
+# expand to a sequence of instructions such as
+#
+# $xzr = ADDXri $sp, 12, 0
+# $xzr = ADDVL_XXI $xzr, 1, implicit $vg
+# $xzr = ADDSXri $xzr, 0, 0, implicit-def $nzcv
+#
+# and none of those is a legal AArch64 instruction (ADD and ADDVL can't target
+# xzr at all, and ADDS can't use it as an input). Also, if they were legal,
+# they wouldn't compute the intended value, since the results of the first two
+# instructions would be thrown away.
+#
+# We check the output of the phase that could have generated this unwanted
+# ADDS, and also check that the full code generation passes
+# -verify-machineinstrs.
+
+--- |
+ ; ModuleID = '<stdin>'
+ source_filename = "<stdin>"
+ target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32"
+ target triple = "aarch64"
+
+ define void @launch(i1 %0, ptr %g28, ptr %g10) #0 {
+ %2 = alloca i8, align 4
+ br label %3
+
+ 3: ; preds = %8, %6, %1
+ %4 = phi <2 x i8> [ zeroinitializer, %1 ], [ %5, %8 ], [ zeroinitializer, %6 ]
+ %5 = xor <2 x i8> %4, splat (i8 1)
+ br i1 %0, label %8, label %6
+
+ 6: ; preds = %3
+ %7 = extractelement <2 x i8> %4, i64 0
+ store <4 x i16> splat (i16 1), ptr %g28, align 8
+ br label %3
+
+ 8: ; preds = %3
+ %9 = call ptr @f20()
+ store i8 0, ptr %g10, align 4
+ %10 = icmp eq ptr null, %2
+ br i1 %10, label %3, label %11
+
+ 11: ; preds = %8
+ ret void
+ }
+
+ declare ptr @f20() #1
+
+ attributes #0 = { "frame-pointer"="non-leaf-no-reserve" "target-features"="+sve,+armv9a" }
+ attributes #1 = { "target-features"="+armv9a" }
+...
+---
+name: launch
+alignment: 4
+tracksRegLiveness: true
+noPhis: false
+isSSA: true
+noVRegs: false
+hasFakeUses: false
+registers:
+ - { id: 0, class: fpr64 }
+ - { id: 1, class: fpr64 }
+ - { id: 2, class: gpr32 }
+ - { id: 3, class: gpr64common }
+ - { id: 4, class: gpr64common }
+ - { id: 5, class: gpr32 }
+ - { id: 6, class: fpr64 }
+ - { id: 7, class: fpr128 }
+ - { id: 8, class: zpr }
+ - { id: 9, class: zpr }
+ - { id: 10, class: zpr }
+ - { id: 11, class: fpr64 }
+ - { id: 12, class: fpr64 }
+ - { id: 13, class: fpr128 }
+ - { id: 14, class: gpr64all }
+ - { id: 15, class: gpr32 }
+ - { id: 16, class: gpr64common }
----------------
statham-arm wrote:
This is already the result of both `llvm-reduce` and `--simplify-mir`!
I think in particular that the presence of an SVE register in the stack frame is important, because it's what causes the add-to-frame-index to expand into multiple instructions. Otherwise it would do the thing I said in the comment (before I cut it down just now): a _simple_ add-to-frame-index turns into just `add xN, sp, #M`, and in that simple form, it _is_ legal and correct to replace `xN` with `xzr`.
https://github.com/llvm/llvm-project/pull/213009
More information about the llvm-commits
mailing list