]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
AArch64: fix subregs in boolean reductions [PR123026]
authorTamar Christina <tamar.christina@arm.com>
Mon, 8 Dec 2025 09:12:01 +0000 (09:12 +0000)
committerTamar Christina <tamar.christina@arm.com>
Mon, 8 Dec 2025 09:12:01 +0000 (09:12 +0000)
The Adv. SIMD boolean reduction patterns were accidentally
overriding one of the input arguments.  This fixes it and
removes unneeded intermediate moves around the subreg type
castings.

gcc/ChangeLog:

PR target/123026
* config/aarch64/aarch64-simd.md (reduc_sbool_ior_scal_<mode>,
reduc_sbool_and_scal_<mode>): Fix tmp operands[1] override.

gcc/testsuite/ChangeLog:

PR target/123026
* gcc.target/aarch64/pr123026.c: New test.

gcc/config/aarch64/aarch64-simd.md
gcc/testsuite/gcc.target/aarch64/pr123026.c [new file with mode: 0644]

index 3f9d5f6295bc5259a8cc65ce5ea694c559ce3e81..c02ffd66c2c35fe9372b84b7c37704df101177b7 100644 (file)
       rtx reduc = gen_lowpart (V4SImode, tmp);
       rtx res = gen_reg_rtx (V4SImode);
       emit_insn (gen_aarch64_uminpv4si (res, reduc, reduc));
-      emit_move_insn (tmp, gen_lowpart (<MODE>mode, res));
+      tmp = gen_lowpart (<MODE>mode, res);
     }
-  rtx val = gen_reg_rtx (DImode);
-  emit_move_insn (val, gen_lowpart (DImode, tmp));
+
+  rtx val = force_lowpart_subreg (DImode, tmp, <MODE>mode);
   rtx cc_reg = aarch64_gen_compare_reg (EQ, val, constm1_rtx);
   rtx cmp = gen_rtx_fmt_ee (EQ, SImode, cc_reg, constm1_rtx);
   rtx tmp2 = gen_reg_rtx (SImode);
       rtx reduc = gen_lowpart (V4SImode, tmp);
       rtx res = gen_reg_rtx (V4SImode);
       emit_insn (gen_aarch64_umaxpv4si (res, reduc, reduc));
-      emit_move_insn (tmp, gen_lowpart (<MODE>mode, res));
+      tmp = gen_lowpart (<MODE>mode, res);
     }
-  rtx val = gen_reg_rtx (DImode);
-  emit_move_insn (val, gen_lowpart (DImode, tmp));
+
+  rtx val = force_lowpart_subreg (DImode, tmp, <MODE>mode);
   rtx cc_reg = aarch64_gen_compare_reg (NE, val, const0_rtx);
   rtx cmp = gen_rtx_fmt_ee (NE, SImode, cc_reg, const0_rtx);
   rtx tmp2 = gen_reg_rtx (SImode);
diff --git a/gcc/testsuite/gcc.target/aarch64/pr123026.c b/gcc/testsuite/gcc.target/aarch64/pr123026.c
new file mode 100644 (file)
index 0000000..4dcce8a
--- /dev/null
@@ -0,0 +1,21 @@
+/* { dg-do run } */
+/* { dg-additional-options "-O3 -march=armv8-a -std=c99" } */
+
+#include <stdbool.h>
+
+int g;
+
+__attribute__ ((noipa)) void
+foo(bool a) {
+  for (int i = 0; i < 4; i++)
+    if (!i || a)
+      g += 1;
+}
+
+int main()
+{
+  foo(0);
+  if (g != 1)
+    __builtin_abort();
+  return 0;
+}