re PR tree-optimization/44485 (ICE in get_expr_operands, at tree-ssa-operands.c:1020)
authorJakub Jelinek <jakub@redhat.com>
Thu, 26 Aug 2010 16:39:26 +0000 (18:39 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Thu, 26 Aug 2010 16:39:26 +0000 (18:39 +0200)
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

gcc/ChangeLog
gcc/builtins.c
gcc/calls.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/pr44485.c [new file with mode: 0644]
gcc/tree-ssa-dce.c
gcc/tree-ssa-loop-niter.c

index 164bd56..3609760 100644 (file)
@@ -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
index e8974e1..6d755a1 100644 (file)
@@ -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;
index cd0d9c5..c50a792 100644 (file)
@@ -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;
 }
index d27a2e2..8eb2f3a 100644 (file)
@@ -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.
diff --git a/gcc/testsuite/gcc.dg/pr44485.c b/gcc/testsuite/gcc.dg/pr44485.c
new file mode 100644 (file)
index 0000000..82f05f8
--- /dev/null
@@ -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;
+}
index edec49d..a1a5191 100644 (file)
@@ -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.  */
index 2630faf..d23592d 100644 (file)
@@ -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",