Hi,
a problem in postreload causes a miscompilation of libgomp on s390x.
insn 1: r1 = r1 + r2
insn 2: r3 = r1
insn 3: unspec_volatile
insn 4: use r1
With the patch from http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49452
the regstate information is resetted at the unspec_volatile instead of
invalidated! So while doing a backward insn scan insn 2 is considered
to be the first use of r1 and postreload does the following
optimization causing r1 to hold an invalid value at insn 4:
insn 1: deleted
insn 2: r3 = r1 + r2
insn 3: unspec_volatile
insn 4: use r1
The attached patch fixes the problem for me. The patch invalidates
the reg_state if there has been a use already. Otherwise it is left as
is.
I don't have a testcase since the failure can only be seen in
combination with a reload patch I'm currently working on.
Bootstrapped on s390x and x86_64. No regressions.
Ok for mainline?
Bye,
-Andreas-
2011-11-14 Andreas Krebbel
* postreload.c (reload_combine): Mark reg_state as invalid at a
barrier if there has been a use already.
Index: gcc/postreload.c
===
*** gcc/postreload.c.orig
--- gcc/postreload.c
*** reload_combine (void)
*** 1315,1322
else if (BARRIER_P (insn)
|| (INSN_P (insn) && volatile_insn_p (PATTERN (insn
for (r = 0; r < FIRST_PSEUDO_REGISTER; r++)
! if (! fixed_regs[r])
! reg_state[r].use_index = RELOAD_COMBINE_MAX_USES;
if (! NONDEBUG_INSN_P (insn))
continue;
--- 1315,1323
else if (BARRIER_P (insn)
|| (INSN_P (insn) && volatile_insn_p (PATTERN (insn
for (r = 0; r < FIRST_PSEUDO_REGISTER; r++)
! if (! fixed_regs[r]
! && reg_state[r].use_index != RELOAD_COMBINE_MAX_USES)
! reg_state[r].use_index = -1;
if (! NONDEBUG_INSN_P (insn))
continue;