Fix (<cond> ? FOO++ : BAR++) == 2 from misoptimizing FOO++ into ++FOO without bumping up the comparison value

From-SVN: r35046
This commit is contained in:
Michael Meissner 2000-07-15 14:58:53 +00:00 committed by Michael Meissner
parent bbed132f32
commit 4d06bcc527
4 changed files with 152 additions and 8 deletions

View File

@ -1,3 +1,9 @@
2000-07-15 Michael Meissner <meissner@redhat.com>
* fold-const.c (fold): When optimizing FOO++ == CONST into ++FOO
== CONST + INCREMENT, don't overwrite the tree node for FOO++,
create a new node instead.
2000-07-15 Neil Booth <NeilB@earthling.net>
* README.Portability: Correct example about calling a function

View File

@ -6136,7 +6136,15 @@ fold (expr)
tree newconst
= fold (build (PLUS_EXPR, TREE_TYPE (varop),
constop, TREE_OPERAND (varop, 1)));
TREE_SET_CODE (varop, PREINCREMENT_EXPR);
/* Do not overwrite the current varop to be a preincrement,
create a new node so that we won't confuse our caller who
might create trees and throw them away, reusing the
arguments that they passed to build. This shows up in
the THEN or ELSE parts of ?: being postincrements. */
varop = build (PREINCREMENT_EXPR, TREE_TYPE (varop),
TREE_OPERAND (varop, 0),
TREE_OPERAND (varop, 1));
/* If VAROP is a reference to a bitfield, we must mask
the constant by the width of the field. */
@ -6180,9 +6188,9 @@ fold (expr)
}
t = build (code, type, TREE_OPERAND (t, 0),
TREE_OPERAND (t, 1));
TREE_OPERAND (t, constopnum) = newconst;
t = build (code, type,
(constopnum == 0) ? newconst : varop,
(constopnum == 1) ? newconst : varop);
return t;
}
}
@ -6195,7 +6203,15 @@ fold (expr)
tree newconst
= fold (build (MINUS_EXPR, TREE_TYPE (varop),
constop, TREE_OPERAND (varop, 1)));
TREE_SET_CODE (varop, PREDECREMENT_EXPR);
/* Do not overwrite the current varop to be a predecrement,
create a new node so that we won't confuse our caller who
might create trees and throw them away, reusing the
arguments that they passed to build. This shows up in
the THEN or ELSE parts of ?: being postdecrements. */
varop = build (PREDECREMENT_EXPR, TREE_TYPE (varop),
TREE_OPERAND (varop, 0),
TREE_OPERAND (varop, 1));
if (TREE_CODE (TREE_OPERAND (varop, 0)) == COMPONENT_REF
&& DECL_BIT_FIELD(TREE_OPERAND
@ -6234,9 +6250,9 @@ fold (expr)
}
t = build (code, type, TREE_OPERAND (t, 0),
TREE_OPERAND (t, 1));
TREE_OPERAND (t, constopnum) = newconst;
t = build (code, type,
(constopnum == 0) ? newconst : varop,
(constopnum == 1) ? newconst : varop);
return t;
}
}

View File

@ -1,3 +1,7 @@
2000-07-15 Michael Meissner <meissner@redhat.com>
* gcc.c-torture/execute/20000715-1.c: New test.
2000-07-13 Jakub Jelinek <jakub@redhat.com>
* gcc.c-torture/execute/20000707-1.c: New test.

View File

@ -0,0 +1,118 @@
void abort(void);
void exit(int);
void
test1(void)
{
int x = 3, y = 2;
if ((x < y ? x++ : y++) != 2)
abort ();
if (x != 3)
abort ();
if (y != 3)
abort ();
}
void
test2(void)
{
int x = 3, y = 2, z;
z = (x < y) ? x++ : y++;
if (z != 2)
abort ();
if (x != 3)
abort ();
if (y != 3)
abort ();
}
void
test3(void)
{
int x = 3, y = 2;
int xx = 3, yy = 2;
if ((xx < yy ? x++ : y++) != 2)
abort ();
if (x != 3)
abort ();
if (y != 3)
abort ();
}
int x, y;
static void
init_xy(void)
{
x = 3;
y = 2;
}
void
test4(void)
{
init_xy();
if ((x < y ? x++ : y++) != 2)
abort ();
if (x != 3)
abort ();
if (y != 3)
abort ();
}
void
test5(void)
{
int z;
init_xy();
z = (x < y) ? x++ : y++;
if (z != 2)
abort ();
if (x != 3)
abort ();
if (y != 3)
abort ();
}
void
test6(void)
{
int xx = 3, yy = 2;
int z;
init_xy();
z = (xx < y) ? x++ : y++;
if (z != 2)
abort ();
if (x != 3)
abort ();
if (y != 3)
abort ();
}
int
main(){
test1 ();
test2 ();
test3 ();
test4 ();
test5 ();
test6 ();
exit (0);
}