This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[3.4 Committed] PR middle-end/19068: Backport fix for PR18548


The following patch addresses PR middle-end/19068 which is a wrong-code
regression on the 3.3 and 3.4 branches that was fixed on mainline by my
recent patch for PR 18548.

The following backport has been tested against the gcc-3_4-branch on
i686-pc-linux-gnu with a full "make bootstrap", all default languages,
and regression tested with a top-level "make -k check" with no new
failures.

Committed to the gcc-3_4-branch.  I've also added the new test case to
mainline.  I intend to apply this same patch to the 3.3 branch after
bootstrapping and regression testing completes successfully.



2004-12-19  Roger Sayle  <roger@eyesopen.com>

	PR middle-end/19068
	* expr.c (expand_expr_real_1) <MAX_EXPR>: Ensure that target, op0
	and op1 are all registers (or constants) before expanding the RTL
	comparison sequence [to avoid reg_overlap_mentioned (target, op1)].

	* g++.dg/opt/max1.C: New test case.


Index: expr.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/expr.c,v
retrieving revision 1.615.4.18
diff -c -3 -p -r1.615.4.18 expr.c
*** expr.c	5 Dec 2004 05:20:56 -0000	1.615.4.18
--- expr.c	19 Dec 2004 15:37:34 -0000
*************** expand_expr_real (tree exp, rtx target,
*** 8107,8113 ****
        /* At this point, a MEM target is no longer useful; we will get better
  	 code without it.  */

!       if (GET_CODE (target) == MEM)
  	target = gen_reg_rtx (mode);

        /* If op1 was placed in target, swap op0 and op1.  */
--- 8107,8113 ----
        /* At this point, a MEM target is no longer useful; we will get better
  	 code without it.  */

!       if (! REG_P (target))
  	target = gen_reg_rtx (mode);

        /* If op1 was placed in target, swap op0 and op1.  */
*************** expand_expr_real (tree exp, rtx target,
*** 8118,8123 ****
--- 8118,8128 ----
  	  op1 = tem;
  	}

+       /* We generate better code and avoid problems with op1 mentioning
+ 	 target by forcing op1 into a pseudo if it isn't a constant.  */
+       if (! CONSTANT_P (op1))
+ 	op1 = force_reg (mode, op1);
+
        if (target != op0)
  	emit_move_insn (target, op0);


/* PR middle-end/19068 */
/* Test case by Andrew Pinski <pinskia@physics.uc.edu> */
/* { dg-do run } */
/* { dg-options "-O2" } */

extern "C" void abort (void);

long fff[10];

void f(long a)
{
  int i;
  a =  *((long*)(a+5)) >? *((long*)(a+1));

  for(i=0;i<10;i++)
   fff[i] = a;
}

int main(void)
{
  int i;
  long a[2] = {10,5};
  f((long)(&a)-1);
  for(i = 0;i<10;i++)
   if (fff[i]!=10)
    abort ();
  return 0;
}


Roger
--


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]