From patchwork Sat Jan 29 03:54:06 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: PowerPC -mcmodel related regression on power6/7 From: Alan Modra X-Patchwork-Id: 80920 Message-Id: <20110129035406.GI9489@bubble.grove.modra.org> To: gcc-patches@gcc.gnu.org Cc: David Edelsohn Date: Sat, 29 Jan 2011 14:24:06 +1030 On Wed, Jan 26, 2011 at 05:39:04PM -0600, Peter Bergner wrote: > On Thu, 2011-01-27 at 09:50 +1030, Alan Modra wrote: > > On Wed, Jan 26, 2011 at 04:18:34PM -0600, Peter Bergner wrote: > > > bergner@igoo:~/gcc/BUGS/with-cpu/power7> cat DFcmp.i > > > double glob1; > > > int > > > reg0limm1 (double r0) > > > { > > > if (r0 <= ((double) ((int) &glob1))) > > > return 1; > > > else > > > return 0; > > > } > > > > Ick, what sort of code is this? Comparing a fp value against an address?? > > It came from the gcc testsuite :) > > > It strikes me as odd that the addis and addi don't match, in both > > versions of code. They ought to both be .LC0+4 you'd think. Perhaps > > the +0 part has been eliminated as dead code? I'll look into it. > > Yes, I was a little surprised too. Thanks for looking into it! Well it seems that combine is merging a subreg with a load from mem, which is OK, I think, but that's how the +4 offset happens. For power6/7 we also combine to get a lfiwax insn, which can't take an offset. So the address gets reloaded into a reg. All of a sudden the toc-relative address is no longer in a mem, instead being in a largetoc_low insn. When final.c emits the insn, print_operand is called rather than print_operand_address, bypassing the hack I added there to rearrange the addend to suit gas. Bootstrapped and regression tested powerpc64-linux. OK to apply? * config/rs6000/rs6000.c (print_operand): Rearrange addends in toc relative expressions as we do in print_operand_address. Index: gcc/config/rs6000/rs6000.c =================================================================== --- gcc/config/rs6000/rs6000.c (revision 169076) +++ gcc/config/rs6000/rs6000.c (working copy) @@ -16182,7 +16182,18 @@ print_operand (FILE *file, rtx x, int co output_address (XEXP (x, 0)); } else - output_addr_const (file, x); + { + if (toc_relative_expr_p (x)) + /* This hack along with a corresponding hack in + rs6000_output_addr_const_extra arranges to output addends + where the assembler expects to find them. eg. + (const (plus (unspec [symbol_ref ("x") tocrel]) 4)) + without this hack would be output as "x@toc+4". We + want "x+4@toc". */ + output_addr_const (file, tocrel_base); + else + output_addr_const (file, x); + } return; case '&':