Fix (<cond> ? FOO++ : BAR++) == 2 from misoptimizing FOO++ into ++FOO without bumping up the comparison value
From-SVN: r35046
This commit is contained in:
parent
bbed132f32
commit
4d06bcc527
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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.
|
||||
|
118
gcc/testsuite/gcc.c-torture/execute/20000715-1.c
Normal file
118
gcc/testsuite/gcc.c-torture/execute/20000715-1.c
Normal 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);
|
||||
}
|
Loading…
Reference in New Issue
Block a user