[PATCH] Bad MEM_SIZE for cmpmem causes wrong scheduling

Ulrich Weigand weigand@i1.informatik.uni-erlangen.de
Fri Sep 24 23:03:00 GMT 2004


Richard Henderson wrote:

> For variable length, you mean?  Yes.  Who set the length to 
> be one?  Perhaps get_memory_rtx should be zapping MEM_SIZE?

Due to optimizations done on the tree level, the first argument
of expand_builtin_memcmp has the form &a[1], i.e.

 <addr_expr 0x4020dbc0
    type <pointer_type 0x40189b80
        type <integer_type 0x4017b480 char public unsigned QI
            size <integer_cst 0x4017a180 constant invariant 8>
            unit size <integer_cst 0x4017a1a0 constant invariant 1>
            align 8 symtab 0 alias set -1 precision 8 min <integer_cst 0x4017a280 0> max <integer_cst 0x4017a2a0 255>
            pointer_to_this <pointer_type 0x40189b80>>
        unsigned SI
        size <integer_cst 0x4017a4a0 constant invariant 32>
        unit size <integer_cst 0x4017a0e0 constant invariant 4>
        align 32 symtab 0 alias set -1>
    constant invariant
    arg 0 <array_ref 0x4020fe40 type <integer_type 0x4017b480 char>
        arg 0 <var_decl 0x4020e180 a type <array_type 0x4020e100>
            addressable used public static common BLK file xxx.c line 3
            size <integer_cst 0x4017a900 constant invariant 128>
            unit size <integer_cst 0x4017a920 constant invariant 16>
            align 8
            (mem/s:BLK (symbol_ref:SI ("a") <var_decl 0x4020e180 a>) [3 a+0 S16 A8]) chain <function_decl 0x4020e300 test>>
        arg 1 <integer_cst 0x4020d9c0 constant invariant 1>
        arg 2 <integer_cst 0x4017a100 constant invariant 0> arg 3 <integer_cst 0x4017a1a0 1>>>

Therefore, get_memory_rtx runs into the ADDR_EXPR path:

992       if (TREE_CODE (exp) == ADDR_EXPR)
993         {
994           exp = TREE_OPERAND (exp, 0);
995           set_mem_attributes (mem, exp, 0);
996         }

and calls set_mem_attributes on the inner expression of
the ADDR_EXPR, in this case a[1].  As this is of type 'char',
set_mem_attributes runs into this case:

1565      /* If the size is known, we can set that.  */
1566      if (TYPE_SIZE_UNIT (type) && host_integerp (TYPE_SIZE_UNIT (type), 1))
1567        size = GEN_INT (tree_low_cst (TYPE_SIZE_UNIT (type), 1));

and sets the size to 1.  While it later on does recognize the
expression as ARRAY_REF, it uses the additional information
gathered from that only to refine the alignment; the size is
left unchanged and stays 1.

Thus, the result of get_memory_rtx is:
(mem/s:BLK (reg/f:SI 44) [0 a+1 S1 A8])


> But after we get that resolved, your patch is ok.

Thanks,
Ulrich

-- 
  Dr. Ulrich Weigand
  weigand@informatik.uni-erlangen.de



More information about the Gcc-patches mailing list