Help: webizer pass vs. i386's TARGET_STACK_PROBE

Roger Sayle roger@eyesopen.com
Thu Dec 18 04:55:00 GMT 2003


I'm currently analyzing an ICE on legal building some OpenEye
software with an x86 running cygwin/mingw with mainline CVS.

The failure is from the unrecognizable insn:

../../../OpenEye/libs/oechem/bin.cpp:560: error: unrecognizable insn:
(insn:HI 2028 2027 2030 77 (parallel [
            (unspec:SI [
                    (reg:SI 612)
                ] 10)
            (set (reg/f:SI %esp)
                (minus:SI (reg/f:SI %esp)
                    (reg:SI 612)))
            (clobber (reg:SI 4124))
            (clobber (reg:CC %eflags))
        ]) -1 (insn_list 2027 (nil))
    (expr_list:REG_DEAD (reg:SI 612)
        (expr_list:REG_UNUSED (reg:SI 4124)
            (expr_list:REG_UNUSED (reg:CC %eflags)
                (nil)))))
../../../OpenEye/libs/oechem/bin.cpp:560: internal compiler error: in
extract_insn, at recog.c:2061


The UNSPEC is i386.md's UNSPEC_STACK_PROBE which usually matches the
define_insn pattern for "allocate_stack_worker_1".

(define_insn "allocate_stack_worker_1"
  [(unspec:SI [(match_operand:SI 0 "register_operand" "a")] UNSPEC_STACK_PROBE)
   (set (reg:SI 7) (minus:SI (reg:SI 7) (match_dup 0)))
   (clobber (match_dup 0))
   (clobber (reg:CC 17))]
  "!TARGET_64BIT && TARGET_STACK_PROBE"
  "call\t__alloca"
  [(set_attr "type" "multi")
   (set_attr "length" "5")])


The problem appears to be that this pattern requires/expects the first
clobber to match both the contents of the UNSPEC, which should also
match the second operand to the subtraction.

When the instruction is originally created during RTL expansion, all
three references are indeed to the same reg:SI 612.  Analysing the logs
it appears the culprit that corrupts this instruction is the webizer
pass, which in decides to rename register 612 in 2028 and replace it
with 4124:

Web oldreg=612 newreg=4124
Updating insn 2028 (612->4124)

Clearly, the webizer isn't substituting all of the references to
reg 612 in insn 2028, which then results in the unrecognizable
instruction.  Unfortunately, looking at the code isn't much help,
replace_ref works with pointers provided by df_analyse, so perhaps
its the underlying data flow analysis that's incorrect/incomplete.


Interestingly, it looks like all of the "allocate_stack_worker_1"
patterns are being "corrupted" by the webizer.  However, most of
these instructions have valid INSN_CODES, and as the webizer doesn't
rerecognize insns after its modifications and the i386 backend doesn't
seem to care too much, these problems normally go unnoticed.  In
my extremely large proprietry testcase however, the loop pass has
reset the INSN_CODE of the above instruction to -1, to force the
instruction to be re-recognized later.  I believe this is "modus
operandi", but it has the effect of uncovering the fact that the
webizer has been screwing up the allocate_stack_worker_1 patterns.


Of course, another deeper problem might be that we shouldn't be
inlining a function (this failure requires -O3) that contains an
allocate_stack_worker_1 insn [which is really just a call to
__alloca], let alone have this insn/call end up in a loop!  I
haven't checked the dumps closely enough to see if there is a
corresponding deallocation in the loop yet, but I can imagine
much run-time unhappiness if there isnt.


Could someone who understands the webizer pass, GCC's data flow
analysis and/or i386.md's allocate_stack_worker_1 pattern explain
which of these three is probably at fault from the above
description?  If I knew which one isn't doing its job, I'd be
happy to continue investigating this problem even further.


Very many thanks in advance, and my apologies for any inconvenience.

Roger
--
Roger Sayle,                         E-mail: roger@eyesopen.com
OpenEye Scientific Software,         WWW: http://www.eyesopen.com/
Suite 1107, 3600 Cerrillos Road,     Tel: (+1) 505-473-7385
Santa Fe, New Mexico, 87507.         Fax: (+1) 505-473-0833



More information about the Gcc-patches mailing list