re PR rtl-optimization/6233 (simple loop miscompilation)
authorAlan Modra <amodra@bigpond.net.au>
Wed, 10 Apr 2002 03:50:39 +0000 (03:50 +0000)
committerAlan Modra <amodra@gcc.gnu.org>
Wed, 10 Apr 2002 03:50:39 +0000 (13:20 +0930)
PR optimization/6233
* rtlanal.c (pure_call_p): New function.
* rtl.h (pure_call_p): Declare.
* loop.c (prescan_loop): Use it to set has_nonconst_call.
* gcse.c (store_killed_in_insn): Use pure_call_p here too.

From-SVN: r52110

gcc/ChangeLog
gcc/gcse.c
gcc/loop.c
gcc/rtl.h
gcc/rtlanal.c

index fb618b47dfba657398b53e01e137cc04f1dc5132..1def463bd49d1f4a88dd61642a6b4a66d04bcfe1 100644 (file)
@@ -1,3 +1,11 @@
+2002-04-10  Alan Modra  <amodra@bigpond.net.au>
+
+       PR optimization/6233
+       * rtlanal.c (pure_call_p): New function.
+       * rtl.h (pure_call_p): Declare.
+       * loop.c (prescan_loop): Use it to set has_nonconst_call.
+       * gcse.c (store_killed_in_insn): Use pure_call_p here too.
+
 2002-04-09  Eric Christopher  <echristo@redhat.com>
 
        * config/mips/mips.h (ASM_OUTPUT_ALIGNED_DECL_COMMON): Add additional
index 7a49ffc895511be526a3ffa3846dfb1b2cd90310..ba83712e249a9b6adcfe7379c4bdce2e546002fb 100644 (file)
@@ -6528,21 +6528,7 @@ store_killed_in_insn (x, insn)
     {
       /* A normal or pure call might read from pattern,
         but a const call will not.  */
-      if (CONST_OR_PURE_CALL_P (insn))
-       {
-         rtx link;
-
-         for (link = CALL_INSN_FUNCTION_USAGE (insn);
-              link;
-              link = XEXP (link, 1))
-           if (GET_CODE (XEXP (link, 0)) == USE
-               && GET_CODE (XEXP (XEXP (link, 0), 0)) == MEM
-               && GET_CODE (XEXP (XEXP (XEXP (link, 0), 0), 0)) == SCRATCH)
-             return 1;
-         return 0;
-       }
-      else
-       return 1;
+      return ! CONST_OR_PURE_CALL_P (insn) || pure_call_p (insn);
     }
   
   if (GET_CODE (PATTERN (insn)) == SET)
index 53b9caa3aa06b38319ed33236f3fc6435dca7175..468dc20951dbecbac0c84eb459350e5b29b0f0e0 100644 (file)
@@ -2494,6 +2494,8 @@ prescan_loop (loop)
              loop_info->unknown_address_altered = 1;
              loop_info->has_nonconst_call = 1;
            }
+         else if (pure_call_p (insn))
+           loop_info->has_nonconst_call = 1;
          loop_info->has_call = 1;
          if (can_throw_internal (insn))
            loop_info->has_multiple_exit_targets = 1;
index d795a4a64b9fb8e53c77c0fbab927ce718a3c84c..7f62b91ef6922cf05d3d9cf91b74c7f3ed7a2500 100644 (file)
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -1502,6 +1502,7 @@ extern rtx find_reg_equal_equiv_note      PARAMS ((rtx));
 extern int find_reg_fusage             PARAMS ((rtx, enum rtx_code, rtx));
 extern int find_regno_fusage           PARAMS ((rtx, enum rtx_code,
                                                 unsigned int));
+extern int pure_call_p                 PARAMS ((rtx));
 extern void remove_note                        PARAMS ((rtx, rtx));
 extern int side_effects_p              PARAMS ((rtx));
 extern int volatile_refs_p             PARAMS ((rtx));
index 9348fd01d118d75f0959351fcde942a5e9d2b6a4..07cb6d8d6a7318bdc1ff0ec2b6203262f942d12d 100644 (file)
@@ -2011,6 +2011,31 @@ find_regno_fusage (insn, code, regno)
 
   return 0;
 }
+
+/* Return true if INSN is a call to a pure function.  */
+
+int
+pure_call_p (insn)
+     rtx insn;
+{
+  rtx link;
+
+  if (GET_CODE (insn) != CALL_INSN || ! CONST_OR_PURE_CALL_P (insn))
+    return 0;
+
+  /* Look for the note that differentiates const and pure functions.  */
+  for (link = CALL_INSN_FUNCTION_USAGE (insn); link; link = XEXP (link, 1))
+    {
+      rtx u, m;
+
+      if (GET_CODE (u = XEXP (link, 0)) == USE
+         && GET_CODE (m = XEXP (u, 0)) == MEM && GET_MODE (m) == BLKmode
+         && GET_CODE (XEXP (m, 0)) == SCRATCH)
+       return 1;
+    }
+
+  return 0;
+}
 \f
 /* Remove register note NOTE from the REG_NOTES of INSN.  */