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>
|
2007-11-16 Jakub Jelinek <jakub@redhat.com>
|
||||||
|
|
||||||
PR driver/30460
|
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>
|
2007-11-16 Olivier Hainque <hainque@adacore.com>
|
||||||
|
|
||||||
* gnat.dg/release_unc_maxalign.adb: New test.
|
* gnat.dg/release_unc_maxalign.adb: New test.
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
|
@ -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.
|
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.
|
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
|
static ccp_lattice_t
|
||||||
likely_value (tree stmt)
|
likely_value (tree stmt)
|
||||||
{
|
{
|
||||||
bool has_constant_operand;
|
bool has_constant_operand, has_undefined_operand, all_undefined_operands;
|
||||||
stmt_ann_t ann;
|
stmt_ann_t ann;
|
||||||
tree use;
|
tree use;
|
||||||
ssa_op_iter iter;
|
ssa_op_iter iter;
|
||||||
|
@ -552,17 +553,72 @@ likely_value (tree stmt)
|
||||||
return CONSTANT;
|
return CONSTANT;
|
||||||
|
|
||||||
has_constant_operand = false;
|
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)
|
FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_USE | SSA_OP_VUSE)
|
||||||
{
|
{
|
||||||
prop_value_t *val = get_value (use);
|
prop_value_t *val = get_value (use);
|
||||||
|
|
||||||
if (val->lattice_val == UNDEFINED)
|
if (val->lattice_val == UNDEFINED)
|
||||||
return UNDEFINED;
|
has_undefined_operand = true;
|
||||||
|
else
|
||||||
|
all_undefined_operands = false;
|
||||||
|
|
||||||
if (val->lattice_val == CONSTANT)
|
if (val->lattice_val == CONSTANT)
|
||||||
has_constant_operand = true;
|
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
|
if (has_constant_operand
|
||||||
/* We do not consider virtual operands here -- load from read-only
|
/* We do not consider virtual operands here -- load from read-only
|
||||||
memory may have only VARYING virtual operands, but still be
|
memory may have only VARYING virtual operands, but still be
|
||||||
|
|
Loading…
Reference in New Issue