aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Guenther <rguenther@suse.de>2007-11-16 10:10:05 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2007-11-16 10:10:05 +0000
commit7f879c9615a980c3874350e9739bce139c67f322 (patch)
tree68350f8f197b9af4a24605143e5aa07c643cbfdd /gcc
parentb2c3bcf47b9131455a7fccfaa699269ae108d76b (diff)
downloadgcc-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/ChangeLog8
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/g++.dg/torture/pr34099.C25
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/pr34099.c16
-rw-r--r--gcc/tree-ssa-ccp.c62
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