re PR tree-optimization/44485 (ICE in get_expr_operands, at tree-ssa-operands.c:1020)
PR tree-optimization/44485 * calls.c (flags_from_decl_or_type): For const or pure noreturn functions return ECF_LOOPING_CONST_OR_PURE|ECF_NORETURN together with ECF_CONST resp. ECF_PURE. * builtins.c (expand_builtin): Use flags_from_decl_or_type instead of querying flags directly. * tree-ssa-loop-niter.c (finite_loop_p): Likewise. * tree-ssa-dce.c (find_obviously_necessary_stmts): Likewise. * gcc.dg/pr44485.c: New test. From-SVN: r163568
This commit is contained in:
parent
350b707024
commit
9e3920e97f
7 changed files with 63 additions and 11 deletions
|
@ -1,3 +1,14 @@
|
|||
2010-08-26 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR tree-optimization/44485
|
||||
* calls.c (flags_from_decl_or_type): For const or pure
|
||||
noreturn functions return ECF_LOOPING_CONST_OR_PURE|ECF_NORETURN
|
||||
together with ECF_CONST resp. ECF_PURE.
|
||||
* builtins.c (expand_builtin): Use flags_from_decl_or_type
|
||||
instead of querying flags directly.
|
||||
* tree-ssa-loop-niter.c (finite_loop_p): Likewise.
|
||||
* tree-ssa-dce.c (find_obviously_necessary_stmts): Likewise.
|
||||
|
||||
2010-08-26 Richard Guenther <rguenther@suse.de>
|
||||
|
||||
PR tree-optimization/45255
|
||||
|
|
|
@ -5748,6 +5748,7 @@ expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
|
|||
tree fndecl = get_callee_fndecl (exp);
|
||||
enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
|
||||
enum machine_mode target_mode = TYPE_MODE (TREE_TYPE (exp));
|
||||
int flags;
|
||||
|
||||
if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
|
||||
return targetm.expand_builtin (exp, target, subtarget, mode, ignore);
|
||||
|
@ -5770,8 +5771,8 @@ expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
|
|||
none of its arguments are volatile, we can avoid expanding the
|
||||
built-in call and just evaluate the arguments for side-effects. */
|
||||
if (target == const0_rtx
|
||||
&& (DECL_PURE_P (fndecl) || TREE_READONLY (fndecl))
|
||||
&& !DECL_LOOPING_CONST_OR_PURE_P (fndecl))
|
||||
&& ((flags = flags_from_decl_or_type (fndecl)) & (ECF_CONST | ECF_PURE))
|
||||
&& !(flags & ECF_LOOPING_CONST_OR_PURE))
|
||||
{
|
||||
bool volatilep = false;
|
||||
tree arg;
|
||||
|
|
10
gcc/calls.c
10
gcc/calls.c
|
@ -601,7 +601,7 @@ flags_from_decl_or_type (const_tree exp)
|
|||
flags |= ECF_RETURNS_TWICE;
|
||||
|
||||
/* Process the pure and const attributes. */
|
||||
if (TREE_READONLY (exp) && ! TREE_THIS_VOLATILE (exp))
|
||||
if (TREE_READONLY (exp))
|
||||
flags |= ECF_CONST;
|
||||
if (DECL_PURE_P (exp))
|
||||
flags |= ECF_PURE;
|
||||
|
@ -616,11 +616,15 @@ flags_from_decl_or_type (const_tree exp)
|
|||
|
||||
flags = special_function_p (exp, flags);
|
||||
}
|
||||
else if (TYPE_P (exp) && TYPE_READONLY (exp) && ! TREE_THIS_VOLATILE (exp))
|
||||
else if (TYPE_P (exp) && TYPE_READONLY (exp))
|
||||
flags |= ECF_CONST;
|
||||
|
||||
if (TREE_THIS_VOLATILE (exp))
|
||||
flags |= ECF_NORETURN;
|
||||
{
|
||||
flags |= ECF_NORETURN;
|
||||
if (flags & (ECF_CONST|ECF_PURE))
|
||||
flags |= ECF_LOOPING_CONST_OR_PURE;
|
||||
}
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
2010-08-26 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR tree-optimization/44485
|
||||
* gcc.dg/pr44485.c: New test.
|
||||
|
||||
2010-08-26 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
|
||||
|
||||
* gcc.dg/tls/thr-init-2.c: Use dg-add-options tls.
|
||||
|
|
31
gcc/testsuite/gcc.dg/pr44485.c
Normal file
31
gcc/testsuite/gcc.dg/pr44485.c
Normal file
|
@ -0,0 +1,31 @@
|
|||
/* PR tree-optimization/44485 */
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-O1 -funsafe-math-optimizations" } */
|
||||
|
||||
unsigned short b;
|
||||
int bar (unsigned);
|
||||
|
||||
void
|
||||
baz (void)
|
||||
{
|
||||
if (bar (0))
|
||||
for (b = 0; b < 30; b++)
|
||||
;
|
||||
}
|
||||
|
||||
int
|
||||
bar (unsigned z)
|
||||
{
|
||||
unsigned short c;
|
||||
for (; ; z += 1)
|
||||
l1:
|
||||
if (z)
|
||||
goto l2;
|
||||
l2:
|
||||
for (z = 0; z < 9; z++)
|
||||
if (z)
|
||||
goto l1;
|
||||
for (c = 0; c; c = (__UINTPTR_TYPE__) baz)
|
||||
;
|
||||
return 0;
|
||||
}
|
|
@ -433,6 +433,7 @@ find_obviously_necessary_stmts (struct edge_list *el)
|
|||
gimple_stmt_iterator gsi;
|
||||
edge e;
|
||||
gimple phi, stmt;
|
||||
int flags;
|
||||
|
||||
FOR_EACH_BB (bb)
|
||||
{
|
||||
|
@ -454,9 +455,8 @@ find_obviously_necessary_stmts (struct edge_list *el)
|
|||
|
||||
/* Pure and const functions are finite and thus have no infinite loops in
|
||||
them. */
|
||||
if ((TREE_READONLY (current_function_decl)
|
||||
|| DECL_PURE_P (current_function_decl))
|
||||
&& !DECL_LOOPING_CONST_OR_PURE_P (current_function_decl))
|
||||
flags = flags_from_decl_or_type (current_function_decl);
|
||||
if ((flags & (ECF_CONST|ECF_PURE)) && !(flags & ECF_LOOPING_CONST_OR_PURE))
|
||||
return;
|
||||
|
||||
/* Prevent the empty possibly infinite loops from being removed. */
|
||||
|
|
|
@ -1970,12 +1970,12 @@ finite_loop_p (struct loop *loop)
|
|||
edge ex;
|
||||
struct tree_niter_desc desc;
|
||||
bool finite = false;
|
||||
int flags;
|
||||
|
||||
if (flag_unsafe_loop_optimizations)
|
||||
return true;
|
||||
if ((TREE_READONLY (current_function_decl)
|
||||
|| DECL_PURE_P (current_function_decl))
|
||||
&& !DECL_LOOPING_CONST_OR_PURE_P (current_function_decl))
|
||||
flags = flags_from_decl_or_type (current_function_decl);
|
||||
if ((flags & (ECF_CONST|ECF_PURE)) && !(flags & ECF_LOOPING_CONST_OR_PURE))
|
||||
{
|
||||
if (dump_file && (dump_flags & TDF_DETAILS))
|
||||
fprintf (dump_file, "Found loop %i to be finite: it is within pure or const function.\n",
|
||||
|
|
Loading…
Add table
Reference in a new issue