This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug target/33359] [4.3 Regression] libgcc is miscompiled on SH



------- Comment #2 from kkojima at gcc dot gnu dot org  2007-09-17 02:22 -------
I've looked at the issue for gc-improv branch.  I'd like to
add Laurynas to the CC list.

It seems the following back end patch fix the error in #0
on r128224.

--- ORIG/gc-improv/gcc/config/sh/sh.c   2007-09-14 08:56:42.000000000 +0900
+++ LOCAL/gc-improv/gcc/config/sh/sh.c  2007-09-14 09:41:59.000000000 +0900
@@ -4480,7 +4480,7 @@ gen_far_branch (struct far_branch *bp)
     emit_barrier_after (jump);
   emit_label_after (bp->near_label, insn);
   JUMP_LABEL (jump) = bp->far_label;
-  ok = invert_jump (insn, label, 1);
+  ok = invert_jump (insn, label, 0);
   gcc_assert (ok);

   /* If we are branching around a jump (rather than a return), prevent

though I get an another error during compiling libiberty/hashtab.c.
A reduced testcase is

unsigned int searches;
unsigned int collisions;

double
htab_collisions (void)
{
  if (searches == 0)
    return 0.0;
  return (double) collisions / (double) searches;
}

which segfaults in final.c:insn_current_reference_address
with a null NEXT_INSN (PREV_INSN (branch)) at -O2.
This problem seems to be generic for the architectures with
delayed branch slots.  In the problematic case, the insn
just before the delayed branch is splitted, i.e. insn A in

 (insn A P B ...)
 (insn B A N (seq [
        (jump_insn C A D ... )
        (insn D C N ...)
        ]))

is splitted to insn_1, insn_2, ... and insn_n with try_split.
try_split inserts insn_1, insn_2, ..., insn_n to just after
insn A

 (insn A P B ...)
 (insn_1        A1 A A2)
 (insn_2 A2 A1 A3)
 ...
 (insn_n An An-1 B)
 (insn B An N (seq [
        (jump_insn C A D ... )
        (insn D C N ...)
        ]))

then deletes insn A with delete_insn.  Thus the inner jump insn
in insn B has a bad PREV_INSN.  It seems that the following
patch fix this issue.

--- ORIG/gc-improv/gcc/emit-rtl.c       2007-09-14 08:56:59.000000000 +0900
+++ LOCAL/gc-improv/gcc/emit-rtl.c      2007-09-14 13:55:58.000000000 +0900
@@ -3368,6 +3368,14 @@ try_split (rtx pat, rtx trial, int last)
        }
     }

+  /* When the AFTER insn is a sequence, fix PREV_INSN of the first insn
+     of that sequence.  */
+  if (after)
+    {
+      if (NONJUMP_INSN_P (after) && GET_CODE (PATTERN (after)) == SEQUENCE)
+       PREV_INSN (XVECEXP (PATTERN (after), 0, 0)) = insn_last;
+    }
+
   tem = emit_insn_after_setloc (seq, trial, INSN_LOCATOR (trial));

   delete_insn (trial);

With these patches, SH is built successfully on r128224.
The latter patch is tested also for i686-pc-linux-gnu on
trunk (revision 128522) with bootstrap and the top level
"make -k check" with no new regressions.


-- 

kkojima at gcc dot gnu dot org changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |laurynas dot biveinis at
                   |                            |gmail dot com


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33359


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]