This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
ICE on 2.6.7-rc1 kernel at -O2 (SPARC)
- From: Eric Botcazou <ebotcazou at libertysurf dot fr>
- To: Jakub Jelinek <jakub at redhat dot com>,Richard Henderson <rth at redhat dot com>
- Cc: gcc-bugs at gcc dot gnu dot org
- Date: Fri, 28 May 2004 12:09:58 +0200
- Subject: ICE on 2.6.7-rc1 kernel at -O2 (SPARC)
Hi Jakub, Richard,
I need your help for this one. GCC 3.3.3, 3.3.4pre, 3.4.0, 3.4.1pre ICE at
-O2 on the following testcase extracted from the 2.6.7-rc1 kernel:
static __inline__ __attribute__ ((always_inline))
int page_mapping (unsigned flags)
{
if (1u & (flags >> 16))
return 1;
return 0;
}
void install_page (unsigned flags)
{
if (__builtin_expect (!page_mapping (flags), 0))
__builtin_trap ();
}
pr15693.c: In function `install_page':
pr15693.c:12: error: unrecognizable insn:
(insn 53 16 54 0 0x401ad380 (set (reg:SI 112)
(zero_extract:SI (reg:SI 110)
(const_int 1 [0x1])
(const_int 31 [0x1f]))) -1 (nil)
(expr_list:REG_DEAD (reg:SI 110)
(nil)))
pr15693.c:12: internal compiler error: in extract_insn, at recog.c:2175
What happens if that combine builds the following valid insn:
(insn 17 16 18 0 0x401ad3c0 (set (reg:CC 100 %icc)
(compare:CC (zero_extract:SI (reg:SI 110)
(const_int 1 [0x1])
(const_int 31 [0x1f]))
(const_int 0 [0x0]))) 149 {*cmp_zero_extract} (insn_list 15
(nil))
(expr_list:REG_DEAD (reg:SI 110)
(nil)))
and ce2 splits it back into:
(insn 53 16 54 0 0x401ad380 (set (reg:SI 112)
(zero_extract:SI (reg:SI 110)
(const_int 1 [0x1])
(const_int 31 [0x1f]))) -1 (nil)
(expr_list:REG_DEAD (reg:SI 110)
(nil)))
(insn 54 53 55 0 0x401ad380 (set (reg:CC 100 %icc)
(compare:CC (reg:SI 112)
(const_int 0 [0x0]))) -1 (nil)
(expr_list:REG_DEAD (reg:SI 112)
(nil)))
which is not valid anymore.
This is a regression from GCC 3.3.2 which was introduced/exposed by
2004-01-11 Jakub Jelinek <jakub@redhat.com>
PR middle-end/13392
* builtins.c (expand_builtin_expect_jump): Handle conditional jumps
to drop through label. Don't fall back to SCC even when conditional
jump has not been found.
Before the patch, a NOTE_INSN_EXPECTED_VALUE was emitted along with the
unusual insn:
(insn 30 29 31 (nil) (parallel [
(set (reg:SI 113)
(eq:SI (reg:SI 114)
(const_int 0 [0x0])))
(clobber (reg:CC 100 %icc))
]) -1 (nil)
(nil))
(note 31 30 32 (eq (reg:SI 113)
(const_int 0 [0x0])) NOTE_INSN_EXPECTED_VALUE)
After the patch, they are not emitted anymore.
In both cases (before and after the patch), the __builtin_expect jump is
given the same prob in 03.jump:
(jump_insn 33 32 45 3 0x401ad380 (set (pc)
(if_then_else (eq (reg:CC 100 %icc)
(const_int 0 [0x0]))
(label_ref 40)
(pc))) 37 {*normal_branch} (nil)
(expr_list:REG_BR_PRED (concat (const_int 6 [0x6])
(const_int 9001 [0x2329]))
(nil)))
;; End of basic block 3, registers live:
(nil)
;; Start of basic block 4, registers live: (nil)
(note 45 33 35 4 [bb 4] NOTE_INSN_BASIC_BLOCK)
(insn 35 45 36 4 0x401ad380 (trap_if (const_int 1 [0x1])
(const_int 5 [0x5])) -1 (nil)
(nil))
;; End of basic block 4, registers live:
(nil)
However, after the patch (presumably because of the absence of the unusual
insn), GCSE is able to thread the jumps and the __builtin_expect jump is
eliminated altogether. We eventually end up with
(jump_insn 18 17 40 0 0x401ad3c0 (set (pc)
(if_then_else (ne (reg:CC 100 %icc)
(const_int 0 [0x0]))
(label_ref 37)
(pc))) 37 {*normal_branch} (insn_list 17 (nil))
(expr_list:REG_DEAD (reg:CC 100 %icc)
(expr_list:REG_BR_PROB (const_int 3300 [0xce4])
(nil))))
;; End of basic block 0, registers live:
14 [%sp] 31 [%i7] 101 [%sfp]
;; Start of basic block 1, registers live: 14 [%sp] 101 [%sfp]
(note 40 18 32 1 [bb 1] NOTE_INSN_BASIC_BLOCK)
(insn 32 40 33 1 0x401ad380 (trap_if (const_int 1 [0x1])
(const_int 5 [0x5])) -1 (nil)
(nil))
;; End of basic block 1, registers live:
14 [%sp] 101 [%sfp]
in 19.combine, that is the expected jump is wrongly predicted!
The compiler generates the invalid insn when it applies the TRAP-IF
transformation to the RTL during ce2 right after combine. This didn't
happen before the patch because the TRAP-IF was applied during ce1, which
runs before combine.
What should we fix? If we fix the back-end, can we generate code as
efficient as what was emitted by GCC 3.3.2? With a peephole?
install_page:
!#PROLOGUE# 0
!#PROLOGUE# 1
srl %o0, 16, %o0
andcc %o0, 1, %g0
te 5
retl
nop
Thanks in advance.
--
Eric Botcazou