https://gcc.gnu.org/g:7e628ff49f7f890d5337369d7b4f8e21a1f17029

commit r16-15-g7e628ff49f7f890d5337369d7b4f8e21a1f17029
Author: kelefth <konstantinos.elefther...@vrull.eu>
Date:   Thu Mar 13 11:49:39 2025 +0100

    avoid-store-forwarding: Fix reg init on load-elimination [PR119160]
    
    In the case that we are eliminating the load instruction, we use zero_extend
    for the initialization of the base register for the zero-offset store.
    This causes issues when the store and the load use the same mode,
    as we are trying to generate a zero_extend with the same inner and
    outer modes.
    
    This patch fixes the issue by zero-extending the value stored in the
    base register only when the load's mode is wider than the store's mode.
    
            PR rtl-optimization/119160
    
    gcc/ChangeLog:
    
            * avoid-store-forwarding.cc (process_store_forwarding):
            Zero-extend the value stored in the base register, in case
            of load-elimination, only when the mode of the destination
            is wider.
    
    gcc/testsuite/ChangeLog:
    
            * gcc.dg/pr119160.c: New test.

Diff:
---
 gcc/avoid-store-forwarding.cc   | 11 ++++++++---
 gcc/testsuite/gcc.dg/pr119160.c | 26 ++++++++++++++++++++++++++
 2 files changed, 34 insertions(+), 3 deletions(-)

diff --git a/gcc/avoid-store-forwarding.cc b/gcc/avoid-store-forwarding.cc
index 34a7bba40439..ded8d7e596e0 100644
--- a/gcc/avoid-store-forwarding.cc
+++ b/gcc/avoid-store-forwarding.cc
@@ -238,10 +238,15 @@ process_store_forwarding (vec<store_fwd_info> &stores, 
rtx_insn *load_insn,
        {
          start_sequence ();
 
-         rtx ext0 = gen_rtx_ZERO_EXTEND (GET_MODE (dest), it->mov_reg);
-         if (ext0)
+         machine_mode dest_mode = GET_MODE (dest);
+         rtx base_reg = it->mov_reg;
+         if (known_gt (GET_MODE_BITSIZE (dest_mode),
+                       GET_MODE_BITSIZE (GET_MODE (it->mov_reg))))
+           base_reg = gen_rtx_ZERO_EXTEND (dest_mode, it->mov_reg);
+
+         if (base_reg)
            {
-             rtx_insn *move0 = emit_move_insn (dest, ext0);
+             rtx_insn *move0 = emit_move_insn (dest, base_reg);
              if (recog_memoized (move0) >= 0)
                {
                  insns = get_insns ();
diff --git a/gcc/testsuite/gcc.dg/pr119160.c b/gcc/testsuite/gcc.dg/pr119160.c
new file mode 100644
index 000000000000..b4629a11d9d2
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr119160.c
@@ -0,0 +1,26 @@
+/* { dg-do run } */
+/* { dg-options "-O2 -finstrument-functions-once -favoid-store-forwarding 
-fnon-call-exceptions -fschedule-insns -mgeneral-regs-only -Wno-psabi" } */
+
+typedef __attribute__((__vector_size__ (32))) int V;
+
+void
+foo (V v, V, V, V *r)
+{
+  V u = (V){} + v[0];
+  *r = u;
+}
+
+__attribute__((__noipa__)) void
+bar(int x)
+{
+ if (x != 2) __builtin_abort();
+}
+
+int
+main ()
+{
+  V x;
+  foo ((V){ 2, 3 }, (V){ }, (V){ }, &x);
+  for (unsigned i = 0; i < sizeof(x)/sizeof(x[0]); i++)
+    bar(x[i]);
+}
\ No newline at end of file

Reply via email to