re PR rtl-optimization/8165 (builtin string functions SEGV on alpha-pc-linux-gnu...
authorRichard Henderson <rth@redhat.com>
Fri, 11 Oct 2002 22:42:31 +0000 (15:42 -0700)
committerRichard Henderson <rth@gcc.gnu.org>
Fri, 11 Oct 2002 22:42:31 +0000 (15:42 -0700)
PR opt/8165
* gcse.c (adjust_libcall_notes): Also adjust notes for INSN.
* gcc.c-torture/execute/20021011-1.c: New.

From-SVN: r58071

gcc/ChangeLog
gcc/gcse.c
gcc/testsuite/gcc.c-torture/execute/20021011-1.c [new file with mode: 0644]

index 618f7a294b51881d5deda5f0149529c832c9e52d..c84e8eb94690d85625837dea1159859cec0fd43d 100644 (file)
@@ -1,3 +1,8 @@
+2002-10-11  Richard Henderson  <rth@redhat.com>
+
+       PR opt/8165
+       * gcse.c (adjust_libcall_notes): Also adjust notes for INSN.
+
 2002-10-11  John David Anglin  <dave@hiauly1.hia.nrc.ca>
 
        * cfganal.c (dfs_enumerate_from): Use PARAMS.
index 081275a0c7de1e87728c2d40c6094f28c991455b..bdde90f4e0c2e8128fe092f32c90a4ea04d91885 100644 (file)
@@ -4251,6 +4251,7 @@ cprop_insn (insn, alter_jumps)
 
 /* LIBCALL_SP is a zero-terminated array of insns at the end of a libcall;
    their REG_EQUAL notes need updating.  */
+
 static bool
 do_local_cprop (x, insn, alter_jumps, libcall_sp)
      rtx x;
@@ -4260,10 +4261,12 @@ do_local_cprop (x, insn, alter_jumps, libcall_sp)
 {
   rtx newreg = NULL, newcnst = NULL;
 
-  /* Rule out USE instructions and ASM statements as we don't want to change the hard registers mentioned.  */
+  /* Rule out USE instructions and ASM statements as we don't want to
+     change the hard registers mentioned.  */
   if (GET_CODE (x) == REG
       && (REGNO (x) >= FIRST_PSEUDO_REGISTER
-          || (GET_CODE (PATTERN (insn)) != USE && asm_noperands (PATTERN (insn)) < 0)))
+          || (GET_CODE (PATTERN (insn)) != USE
+             && asm_noperands (PATTERN (insn)) < 0)))
     {
       cselib_val *val = cselib_lookup (x, GET_MODE (x), 0);
       struct elt_loc_list *l;
@@ -4327,17 +4330,23 @@ do_local_cprop (x, insn, alter_jumps, libcall_sp)
 
 /* LIBCALL_SP is a zero-terminated array of insns at the end of a libcall;
    their REG_EQUAL notes need updating to reflect that OLDREG has been
-   replaced with NEWVAL in INSN.  Return true if all substitutions could
-   be made.  */
+   replaced with NEWVAL in INSN.  Also update the REG_EQUAL notes in INSN.
+
+   Return true if all substitutions could be made.  */
+
 static bool
 adjust_libcall_notes (oldreg, newval, insn, libcall_sp)
      rtx oldreg, newval, insn, *libcall_sp;
 {
-  rtx end;
+  rtx end, note;
+
+  note = find_reg_equal_equiv_note (insn);
+  if (note)
+    XEXP (note, 0) = replace_rtx (XEXP (note, 0), oldreg, newval);
 
   while ((end = *libcall_sp++))
     {
-      rtx note = find_reg_equal_equiv_note (end);
+      note = find_reg_equal_equiv_note (end);
 
       if (! note)
        continue;
diff --git a/gcc/testsuite/gcc.c-torture/execute/20021011-1.c b/gcc/testsuite/gcc.c-torture/execute/20021011-1.c
new file mode 100644 (file)
index 0000000..b1b2c40
--- /dev/null
@@ -0,0 +1,24 @@
+/* PR opt/8165.  */
+
+extern void abort (void);
+
+char buf[64];
+
+int
+main (void)
+{
+  int i;
+
+  __builtin_strcpy (buf, "mystring");
+  if (__builtin_strcmp (buf, "mystring") != 0)
+    abort ();
+
+  for (i = 0; i < 16; ++i)
+    {
+      __builtin_strcpy (buf + i, "mystring");
+      if (__builtin_strcmp (buf + i, "mystring") != 0)
+       abort ();
+    }
+
+  return 0;
+}