avoid-store-forwarding: fix reg init on load-eliminiation [PR117835]

During the initialization of the base register for the zero-offset
store, in the case that we are eliminating the load, we used a
paradoxical subreg assuming that we don't care about the higher bits
of the register. This led to writing wrong values when we were not
updating the whole register.

This patch fixes the issue by zero-extending the value stored in the
base register instead of using a paradoxical subreg.

Bootstrapped/regtested on x86 and AArch64.

	PR rtl-optimization/117835
	PR rtl-optimization/117872

gcc/ChangeLog:

	* avoid-store-forwarding.cc
	(store_forwarding_analyzer::process_store_forwarding):
	Zero-extend the value stored in the base register instead of
	using a paradoxical subreg.

gcc/testsuite/ChangeLog:

	* gcc.target/i386/pr117835.c: New test.
This commit is contained in:
kelefth 2024-12-16 14:36:59 +01:00 committed by Philipp Tomsich
parent 8a4e57e6bc
commit c86e1c54c6
2 changed files with 21 additions and 5 deletions

View file

@ -238,11 +238,7 @@ process_store_forwarding (vec<store_fwd_info> &stores, rtx_insn *load_insn,
{
start_sequence ();
/* We can use a paradoxical subreg to force this to a wider mode, as
the only use will be inserting the bits (i.e., we don't care about
the value of the higher bits). */
rtx ext0 = lowpart_subreg (GET_MODE (dest), it->mov_reg,
GET_MODE (it->mov_reg));
rtx ext0 = gen_rtx_ZERO_EXTEND (GET_MODE (dest), it->mov_reg);
if (ext0)
{
rtx_insn *move0 = emit_move_insn (dest, ext0);

View file

@ -0,0 +1,20 @@
/* { dg-do run } */
/* { dg-options "-O -favoid-store-forwarding -mno-push-args --param=store-forwarding-max-distance=0 -Wno-psabi" } */
typedef __attribute__((__vector_size__ (64))) unsigned short V;
__attribute__((__noipa__)) V
foo (V v, V)
{
return v;
}
int main ()
{
V a = (V){3, 5, 0, 8, 9, 3, 5, 1, 3, 4, 2, 5, 5, 0, 5, 3, 61886};
V b = (V){6, 80, 15, 2, 2, 1, 1, 3, 5};
V x = foo (a, b);
for (unsigned i = 0; i < sizeof(x)/sizeof(x[0]); i++)
if (x[i] != a[i])
__builtin_abort();
}