diff options
author | Richard Guenther <rguenther@suse.de> | 2007-11-16 10:10:05 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2007-11-16 10:10:05 +0000 |
commit | 7f879c9615a980c3874350e9739bce139c67f322 (patch) | |
tree | 68350f8f197b9af4a24605143e5aa07c643cbfdd /gcc | |
parent | b2c3bcf47b9131455a7fccfaa699269ae108d76b (diff) | |
download | gcc-7f879c9615a980c3874350e9739bce139c67f322.zip gcc-7f879c9615a980c3874350e9739bce139c67f322.tar.gz gcc-7f879c9615a980c3874350e9739bce139c67f322.tar.bz2 |
re PR tree-optimization/34099 (optimizer problem)
2007-11-16 Richard Guenther <rguenther@suse.de>
PR tree-optimization/34099
* tree-ssa-ccp.c (likely_value): Use a whitelist for operators
that produce UNDEFINED result if at least one of its operands
is UNDEFINED. By default the result is only UNDEFINED if all
operands are UNDEFINED.
* g++.dg/torture/pr3499.C: New testcase.
* gcc.c-torture/execute/pr34099.c: Likewise.
From-SVN: r130222
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/torture/pr34099.C | 25 | ||||
-rw-r--r-- | gcc/testsuite/gcc.c-torture/execute/pr34099.c | 16 | ||||
-rw-r--r-- | gcc/tree-ssa-ccp.c | 62 |
5 files changed, 114 insertions, 3 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 6db268f..80dac9c 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2007-11-16 Richard Guenther <rguenther@suse.de> + + PR tree-optimization/34099 + * tree-ssa-ccp.c (likely_value): Use a whitelist for operators + that produce UNDEFINED result if at least one of its operands + is UNDEFINED. By default the result is only UNDEFINED if all + operands are UNDEFINED. + 2007-11-16 Jakub Jelinek <jakub@redhat.com> PR driver/30460 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 0ef30d2..9c84667 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2007-11-16 Richard Guenther <rguenther@suse.de> + + PR tree-optimization/34099 + * g++.dg/torture/pr3499.C: New testcase. + * gcc.c-torture/execute/pr34099.c: Likewise. + 2007-11-16 Olivier Hainque <hainque@adacore.com> * gnat.dg/release_unc_maxalign.adb: New test. diff --git a/gcc/testsuite/g++.dg/torture/pr34099.C b/gcc/testsuite/g++.dg/torture/pr34099.C new file mode 100644 index 0000000..49fa9ca --- /dev/null +++ b/gcc/testsuite/g++.dg/torture/pr34099.C @@ -0,0 +1,25 @@ +/* { dg-do run } */ + +#include <complex> + +typedef std::complex<double> NumType; + +void +multiply(NumType a, NumType b, unsigned ac, NumType &ab) +{ + NumType s; + for (unsigned j=0; j<ac; j++) + s = a * b; + ab = s; +} +extern "C" void abort (void); +int main() +{ + NumType a(1,2), b(3,-2), c; + multiply(a, b, 1, c); + if (c.real() != 7 + || c.imag() != 4) + abort (); + return 0; +} + diff --git a/gcc/testsuite/gcc.c-torture/execute/pr34099.c b/gcc/testsuite/gcc.c-torture/execute/pr34099.c new file mode 100644 index 0000000..d6f5ad1 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/pr34099.c @@ -0,0 +1,16 @@ +int foo (int b, int c) +{ + int x; + if (b) + return x & c; + else + return 1; +} +extern void abort (void); +int main() +{ + if (foo(1, 0) != 0) + abort (); + return 0; +} + diff --git a/gcc/tree-ssa-ccp.c b/gcc/tree-ssa-ccp.c index 0fc4b47..fc40449 100644 --- a/gcc/tree-ssa-ccp.c +++ b/gcc/tree-ssa-ccp.c @@ -507,7 +507,8 @@ set_lattice_value (tree var, prop_value_t new_val) If STMT has no operands, then return CONSTANT. - Else if any operands of STMT are undefined, then return UNDEFINED. + Else if undefinedness of operands of STMT cause its value to be + undefined, then return UNDEFINED. Else if any operands of STMT are constants, then return CONSTANT. @@ -516,7 +517,7 @@ set_lattice_value (tree var, prop_value_t new_val) static ccp_lattice_t likely_value (tree stmt) { - bool has_constant_operand; + bool has_constant_operand, has_undefined_operand, all_undefined_operands; stmt_ann_t ann; tree use; ssa_op_iter iter; @@ -552,17 +553,72 @@ likely_value (tree stmt) return CONSTANT; has_constant_operand = false; + has_undefined_operand = false; + all_undefined_operands = true; FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_USE | SSA_OP_VUSE) { prop_value_t *val = get_value (use); if (val->lattice_val == UNDEFINED) - return UNDEFINED; + has_undefined_operand = true; + else + all_undefined_operands = false; if (val->lattice_val == CONSTANT) has_constant_operand = true; } + /* If the operation combines operands like COMPLEX_EXPR make sure to + not mark the result UNDEFINED if only one part of the result is + undefined. */ + if (has_undefined_operand + && all_undefined_operands) + return UNDEFINED; + else if (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT + && has_undefined_operand) + { + switch (TREE_CODE (GIMPLE_STMT_OPERAND (stmt, 1))) + { + /* 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. */ + return UNDEFINED; + + default: + ; + } + } + /* If there was an UNDEFINED operand but the result may be not UNDEFINED + fall back to VARYING even if there were CONSTANT operands. */ + if (has_undefined_operand) + return VARYING; + if (has_constant_operand /* We do not consider virtual operands here -- load from read-only memory may have only VARYING virtual operands, but still be |