mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-04-03 02:40:30 +08:00
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
This commit is contained in:
parent
b2c3bcf47b
commit
7f879c9615
@ -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
|
||||
|
@ -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.
|
||||
|
25
gcc/testsuite/g++.dg/torture/pr34099.C
Normal file
25
gcc/testsuite/g++.dg/torture/pr34099.C
Normal file
@ -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;
|
||||
}
|
||||
|
16
gcc/testsuite/gcc.c-torture/execute/pr34099.c
Normal file
16
gcc/testsuite/gcc.c-torture/execute/pr34099.c
Normal file
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user