This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug target/33359] [4.3 Regression] libgcc is miscompiled on SH
- From: "kkojima at gcc dot gnu dot org" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: 17 Sep 2007 02:22:03 -0000
- Subject: [Bug target/33359] [4.3 Regression] libgcc is miscompiled on SH
- References: <bug-33359-5208@http.gcc.gnu.org/bugzilla/>
- Reply-to: gcc-bugzilla at gcc dot gnu dot org
------- 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