User account creation filtered due to spam.
On sh4-linux, the function foo1 of gcc.c-torture/execute/941015-1.c int foo1 (value) long long value; { register const long long constant = 0xc000000080000000LL; if (value < constant) return 1; else return 2; } is assembled to a wrong code with -O1 foo1: mov.l .L7,r1 cmp/gt r1,r5 bt/s .L10 mov #2,r0 cmp/ge r1,r5 bf/s .L10 mov #1,r0 .L10: rts nop .L9: .align 2 .L7: .long -1073741824 It looks delayed branch optimization causes this.
Before dbr_schedule, the insns look like: r1 := 0xc0000000 (A) if (r5 > r1) goto L0 (B) if (r5 < r1) goto L1 r1 := 0x80000000 (C) if (r4 >= r1) goto L0 L1: r0 := 1 goto L2 L0: r0 := 2 L2: On SH, insns (A),(B),(C) can have delayed slot. dbr_schedule fills a slot of (A) first: r1 := 0xc0000000 (A) [if (r5 > r1) goto L2 | r0 := 2] (B) if (r5 < r1) goto L1 r1 := 0x80000000 (C) if (r4 >= r1) goto L0 L1: r0 := 1 goto L2 L0: r0 := 2 L2: Curiously, in the problematic case, dbr_schedule tries (C) next and redundant_insn checks that r0 := 2 is whether redundant or not with scanning insns backward from (C). It finds the insn in the slot of (A) and deletes the insn r0 := 2 at L0 as an unnecessary one. r1 := 0xc0000000 (A) [if (r5 > r1) goto L2 | r0 := 2] (B) if (r5 < r1) goto L1 r1 := 0x80000000 (C) if (r4 >= r1) goto L0 L1: r0 := 1 goto L2 L0: L2: Then dbr_schedule fills the slot of (B): r1 := 0xc0000000 (A) [if (r5 > r1) goto L2 | r0 := 2] (B) [if (r5 < r1) goto L2 | r0 := 1] r1 := 0x80000000 (C) if (r4 >= r1) goto L0 L1: r0 := 1 goto L2 L0: L2: Now (C) and r0 := 1 at L1 are useless because r0 is 1 before (C). It seems to me that the above is an unexpected scenario to redundant_insn, i.e. dbr_schedule uses it unsafely somewhere, though I gave up to find where problematic use occurs. An easy patch below might be a bit overkill but it fixes the problem for me. --- ORIG/trunk/gcc/reorg.c 2013-01-11 11:35:58.000000000 +0900 +++ trunk/gcc/reorg.c 2013-02-25 17:17:34.000000000 +0900 @@ -1514,7 +1514,7 @@ redundant_insn (rtx insn, rtx target, rt trial && insns_to_search > 0; trial = PREV_INSN (trial)) { - if (LABEL_P (trial)) + if (LABEL_P (trial) || JUMP_P (trial)) return 0; if (!INSN_P (trial))
GCC 4.8.0 is being released, adjusting target milestone.
I'd like to add Steven to the CC list, as he recently brought up a DBR topic on the mailing list: http://gcc.gnu.org/ml/gcc/2013-04/msg00163.html I didn't follow it, but it looks related.
GCC 4.8.1 has been released.
GCC 4.8.2 has been released.
Hm, I'm just poking around here, sorry if it's just useless noise ... In dbr_schedule, doing: fill_simple_delay_slots (1); fill_simple_delay_slots (0); fill_eager_delay_slots (); relax_delay_slots (first); or // fill_simple_delay_slots (1); fill_simple_delay_slots (0); fill_eager_delay_slots (); relax_delay_slots (first); -> produces bad code. fill_simple_delay_slots (1); fill_simple_delay_slots (0); // fill_eager_delay_slots (); relax_delay_slots (first); -> doesn't do anything to the code. // fill_simple_delay_slots (1); // fill_simple_delay_slots (0); fill_eager_delay_slots (); relax_delay_slots (first); or fill_simple_delay_slots (1); // fill_simple_delay_slots (0); fill_eager_delay_slots (); relax_delay_slots (first); -> results in the following code (looks OK): mov.l .L8,r1 cmp/ge r1,r5 bf/s .L11 mov #1,r0 cmp/gt r1,r5 bt/s .L6 mov #2,r0 mov.l .L9,r1 cmp/hs r1,r4 bt .L6 mov #1,r0 .L6: .align 1 .L11: rts nop .L10:
GCC 4.8.3 is being released, adjusting target milestone.
GCC 4.8.4 has been released.
The gcc-4_8-branch is being closed, re-targeting regressions to 4.9.3.
GCC 4.9.3 has been released.
GCC 4.9 branch is being closed