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 <andreas.kreb...@de.ibm.com> * 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;