diff mbox

PowerPC -mcmodel related regression on power6/7

Message ID 20110129035406.GI9489@bubble.grove.modra.org
State New
Headers show

Commit Message

Alan Modra Jan. 29, 2011, 3:54 a.m. UTC
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.

Comments

David Edelsohn Jan. 30, 2011, 4:12 p.m. UTC | #1
On Fri, Jan 28, 2011 at 10:54 PM, Alan Modra <amodra@gmail.com> wrote:

> 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.

Okay.

Thanks, David
diff mbox

Patch

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 '&':