https://gcc.gnu.org/g:33a3834398dfdf72f719b39bbc1ae8626002aa7c

commit r16-5955-g33a3834398dfdf72f719b39bbc1ae8626002aa7c
Author: Tamar Christina <[email protected]>
Date:   Mon Dec 8 09:12:01 2025 +0000

    AArch64: fix subregs in boolean reductions [PR123026]
    
    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.

Diff:
---
 gcc/config/aarch64/aarch64-simd.md          | 12 ++++++------
 gcc/testsuite/gcc.target/aarch64/pr123026.c | 21 +++++++++++++++++++++
 2 files changed, 27 insertions(+), 6 deletions(-)

diff --git a/gcc/config/aarch64/aarch64-simd.md 
b/gcc/config/aarch64/aarch64-simd.md
index 3f9d5f6295bc..c02ffd66c2c3 100644
--- a/gcc/config/aarch64/aarch64-simd.md
+++ b/gcc/config/aarch64/aarch64-simd.md
@@ -3544,10 +3544,10 @@
       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);
@@ -3607,10 +3607,10 @@
       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
index 000000000000..4dcce8a6289f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/pr123026.c
@@ -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;
+}

Reply via email to