From: Roger Sayle Date: Sun, 19 Dec 2004 20:01:36 +0000 (+0000) Subject: re PR middle-end/19068 ([3.3 only] Wrong code for MIN_EXPR and MAX_EXPR) X-Git-Tag: releases/gcc-3.4.4~386 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=51bc37ca52fe4514e0646213bdb855263c19afd3;p=thirdparty%2Fgcc.git re PR middle-end/19068 ([3.3 only] Wrong code for MIN_EXPR and MAX_EXPR) PR middle-end/19068 * expr.c (expand_expr_real_1) : 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. From-SVN: r92386 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c0a6bd10ebd3..a84cbe4603d2 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2004-12-19 Roger Sayle + + PR middle-end/19068 + * expr.c (expand_expr_real_1) : Ensure that target, op0 + and op1 are all registers (or constants) before expanding the RTL + comparison sequence [to avoid reg_overlap_mentioned (target, op1)]. + 2004-12-18 Eric Botcazou PR rtl-optimization/16968 diff --git a/gcc/expr.c b/gcc/expr.c index aa80ae63f46b..fcb5b0c78d68 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -8107,7 +8107,7 @@ expand_expr_real (tree exp, rtx target, enum machine_mode tmode, /* At this point, a MEM target is no longer useful; we will get better code without it. */ - if (GET_CODE (target) == MEM) + if (! REG_P (target)) target = gen_reg_rtx (mode); /* If op1 was placed in target, swap op0 and op1. */ @@ -8118,6 +8118,11 @@ expand_expr_real (tree exp, rtx target, enum machine_mode tmode, 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); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 505f5fa33707..d3b6dcd2d145 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2004-12-19 Roger Sayle + + PR middle-end/19068 + * g++.dg/opt/max1.C: New test case. + 2004-12-18 Jakub Jelinek * gcc.c-torture/execute/20041218-1.c: New test. diff --git a/gcc/testsuite/g++.dg/opt/max1.C b/gcc/testsuite/g++.dg/opt/max1.C new file mode 100644 index 000000000000..714116bfb03e --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/max1.C @@ -0,0 +1,29 @@ +/* PR middle-end/19068 */ +/* Test case by Andrew Pinski */ +/* { 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; +} +