------- Comment #5 from ubizjak at gmail dot com  2007-06-19 08:27 -------
(In reply to comment #4)

> No, this one is caused by dataflow.

Dataflow uncovered generic middle-end (RTL?) problem:

We have this comment in instantiate_virutal_regs():

  /* Scan through all the insns, instantiating every virtual register still
     present.  */
  for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
    if (INSN_P (insn))
      {
        /* These patterns in the instruction stream can never be recognized.
           Fortunately, they shouldn't contain virtual registers either.  */
        if (GET_CODE (PATTERN (insn)) == USE
            || GET_CODE (PATTERN (insn)) == CLOBBER
            || GET_CODE (PATTERN (insn)) == ADDR_VEC
            || GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC
            || GET_CODE (PATTERN (insn)) == ASM_INPUT)
          continue;

        instantiate_virtual_regs_in_insn (insn);

However, for reduced testcase we generate following creative sequence to put
*.LC0 into virtual-outgoing-args and 0 into virtual-outgoing-args+8 (these are
sections[0] values):

;; f (stderr, &""[0], &""[0], conf_name, 0, sections[0])
(insn 6 5 7 pr32374.c:13 (clobber (mem/s/c:BLK (plus:DI (reg/f:DI 54
virtual-stack-vars)
                (const_int -16 [0xfffffffffffffff0])) [5 A128])) -1 (nil))

(insn 7 6 8 pr32374.c:13 (set (mem/s/c:DI (plus:DI (reg/f:DI 54
virtual-stack-vars)
                (const_int -16 [0xfffffffffffffff0])) [4 S8 A128])
        (symbol_ref/f:DI ("*.LC0") [flags 0x2] <string_cst 0xb7cf1498>)) -1
(nil))

(insn 8 7 9 pr32374.c:13 (set (mem/s/c:SI (plus:DI (reg/f:DI 54
virtual-stack-vars)
                (const_int -8 [0xfffffffffffffff8])) [3 S4 A64])
        (const_int 0 [0x0])) -1 (nil))

(insn 9 8 10 pr32374.c:13 (set (reg:DI 59)
        (mem/s/c:DI (plus:DI (reg/f:DI 54 virtual-stack-vars)
                (const_int -16 [0xfffffffffffffff0])) [5 S8 A128])) -1 (nil))

(insn 10 9 11 pr32374.c:13 (set (mem:DI (reg/f:DI 56 virtual-outgoing-args) [0
S8 A64])
        (reg:DI 59)) -1 (nil))

(insn 11 10 12 pr32374.c:13 (set (reg:DI 60)
        (mem/s/c:DI (plus:DI (reg/f:DI 54 virtual-stack-vars)
                (const_int -8 [0xfffffffffffffff8])) [5 S8 A64])) -1 (nil))

(insn 12 11 13 pr32374.c:13 (set (mem:DI (plus:DI (reg/f:DI 56
virtual-outgoing-args)
                (const_int 8 [0x8])) [0 S8 A64])
        (reg:DI 60)) -1 (nil))


Putting a break on emit_insn_raw, we can backtrack where (invalid!) clobber is
generated:

#0  make_insn_raw (pattern=0xb7d0ad00) at
../../gcc-svn/trunk/gcc/emit-rtl.c:3312
#1  0x081861c2 in emit_insn (x=0xb7d0ad00) at
../../gcc-svn/trunk/gcc/emit-rtl.c:4347
#2  0x081a9821 in store_constructor (exp=0xb7d63dc8, target=0xb7d4f768,
cleared=0, size=16) at ../../gcc-svn/trunk/gcc/expr.c:5066
#3  0x081aee5b in expand_expr_real_1 (exp=0x11, target=0xb7d4f768,
tmode=VOIDmode, modifier=EXPAND_STACK_PARM, alt_rtl=0x0) at
../../gcc-svn/trunk/gcc/expr.c:7310
#4  0x081bf7cc in expand_expr_real (exp=0xb7d63dc8, target=0xb7d4f6f0,
tmode=VOIDmode, modifier=EXPAND_STACK_PARM, alt_rtl=0x0) at
../../gcc-svn/trunk/gcc/expr.c:6862
#5  0x081bf9b6 in expand_expr (exp=0x11, target=0xb7d0ad00, mode=VOIDmode,
modifier=EXPAND_STACK_PARM) at ../../gcc-svn/trunk/gcc/expr.h:504
#6  0x081bd4c4 in expand_expr_real_1 (exp=0xb7ca3058, target=0xb7d4f6f0,
tmode=dwarf2_read_address: Corrupted DWARF expression.
) at ../../gcc-svn/trunk/gcc/expr.c:7455
#7  0x081bf7cc in expand_expr_real (exp=0xb7ca3058, target=0xb7d4f6f0,
tmode=VOIDmode, modifier=EXPAND_STACK_PARM, alt_rtl=0x0) at
../../gcc-svn/trunk/gcc/expr.c:6862
#8  0x08115bd1 in store_one_arg (arg=0xbf96e8f0, argblock=0xb7c9c070, flags=0,
variable_size=0, reg_parm_stack_space=0) at ../../gcc-svn/trunk/gcc/expr.h:504
#9  0x0811ad60 in expand_call (exp=0xb7d5a240, target=0x0, ignore=1) at
../../gcc-svn/trunk/gcc/calls.c:2654

It can be tracked from expand_call() down to expr.c:7303, where we re-assign
target to virtual-stack-vars in this highly suspicious part of code (Irix 6?):

      else
        {
          /* Handle calls that pass values in multiple non-contiguous
             locations.  The Irix 6 ABI has examples of this.  */
          if (target == 0 || ! safe_from_p (target, exp, 1)
              || GET_CODE (target) == PARALLEL
              || modifier == EXPAND_STACK_PARM)
            target
              = assign_temp (build_qualified_type (type,
                                                   (TYPE_QUALS (type)
                                                    | (TREE_READONLY (exp)
                                                       * TYPE_QUAL_CONST))),
                             0, TREE_ADDRESSABLE (exp), 1);

          store_constructor (exp, target, 0, int_expr_size (exp));
          return target;
        }

Just before the call to store_constructor, we have:

p debug_rtx (target)
(mem/s/c:BLK (plus:DI (reg/f:DI 54 virtual-stack-vars)
        (const_int -16 [0xfffffffffffffff0])) [5 A128])


and in store_constructor():

in store_constructor (exp=0xb7d83dc8, target=0xb7d6f768, cleared=0, size=16) at
../../gcc-svn/trunk/gcc/expr.c:5066

we proceed through:

        if (! cleared)
          emit_insn (gen_rtx_CLOBBER (VOIDmode, target));

to generate the clobber above.


-- 

ubizjak at gmail dot com changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
          Component|rtl-optimization            |middle-end


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

Reply via email to