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.
---
gcc/avoid-store-forwarding.cc | 11 ++++++++---
gcc/testsuite/gcc.dg/pr119160.c | 26 ++++++++++++++++++++++++++
2 files changed, 34 insertions(+), 3 deletions(-)
create mode 100644 gcc/testsuite/gcc.dg/pr119160.c
diff --git a/gcc/avoid-store-forwarding.cc b/gcc/avoid-store-forwarding.cc
index 34a7bba4043..ded8d7e596e 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 00000000000..b4629a11d9d
--- /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
--
2.43.0