diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 4fafa8dc9363df4e11312ebfcb7ff322202d168e..97f6a0806ea68c5715c0f614a66117c51fe25f75 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2007-11-19 Richard Guenther <rguenther@suse.de> + + PR tree-optimization/34099 + * tree-ssa-ccp.c (likely_value): Exclude all but PLUS_EXPR, + MINUS_EXPR and POINTER_PLUS_EXPR from handling as UNDEFINED + if only one operand is undefined. + 2007-11-19 Eric Botcazou <ebotcazou@libertysurf.fr> PR tree-optimization/34036 diff --git a/gcc/testsuite/gcc.c-torture/execute/pr34099-2.c b/gcc/testsuite/gcc.c-torture/execute/pr34099-2.c new file mode 100644 index 0000000000000000000000000000000000000000..d335673e30f2de9527421044acc232b6aede32dd --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/pr34099-2.c @@ -0,0 +1,47 @@ +int test1 (int b, int c) +{ + char x; + if (b) + return x / c; + else + return 1; +} +int test2 (int b, int c) +{ + int x; + if (b) + return x * c; + else + return 1; +} +int test3 (int b, int c) +{ + int x; + if (b) + return x % c; + else + return 1; +} +int test4 (int b, int c) +{ + char x; + if (b) + return x == c; + else + return 1; +} + +extern void abort (void); +int main() +{ + if (test1(1, 1000) != 0) + abort (); + if (test2(1, 0) != 0) + abort (); + if (test3(1, 1) != 0) + abort (); + if (test4(1, 1000) != 0) + abort (); + return 0; +} + diff --git a/gcc/tree-ssa-ccp.c b/gcc/tree-ssa-ccp.c index fc40449be8db8584d0ee0ca15963e0e8275ffd29..19d82563a81379748dd894869c8aef020a6b370f 100644 --- a/gcc/tree-ssa-ccp.c +++ b/gcc/tree-ssa-ccp.c @@ -582,32 +582,13 @@ likely_value (tree stmt) /* Unary operators are handled with all_undefined_operands. */ case PLUS_EXPR: case MINUS_EXPR: - case MULT_EXPR: case POINTER_PLUS_EXPR: - case TRUNC_DIV_EXPR: - case CEIL_DIV_EXPR: - case FLOOR_DIV_EXPR: - case ROUND_DIV_EXPR: - case TRUNC_MOD_EXPR: - case CEIL_MOD_EXPR: - case FLOOR_MOD_EXPR: - case ROUND_MOD_EXPR: - case RDIV_EXPR: - case EXACT_DIV_EXPR: - case LSHIFT_EXPR: - case RSHIFT_EXPR: - case LROTATE_EXPR: - case RROTATE_EXPR: - case EQ_EXPR: - case NE_EXPR: - case LT_EXPR: - case GT_EXPR: /* Not MIN_EXPR, MAX_EXPR. One VARYING operand may be selected. Not bitwise operators, one VARYING operand may specify the result completely. Not logical operators for the same reason. - Not LE/GE comparisons or unordered comparisons. Not - COMPLEX_EXPR as one VARYING operand makes the result partly - not UNDEFINED. */ + Not COMPLEX_EXPR as one VARYING operand makes the result partly + not UNDEFINED. Not *DIV_EXPR, comparisons and shifts because + the undefined operand may be promoted. */ return UNDEFINED; default: