------- Comment #24 from bergner at vnet dot ibm dot com 2006-11-08 03:30 ------- Ok, Anton hit another test case the last patch doesn't transform. It's actually the same test case as in comment #13, except, "int *base" is now a global variable rather than a function parameter.
int *base; int indexedload(int len) { int i, sum = 0; for (i=0; i < len; i++) sum += base[i]; return sum; } With this case, we get the following RTL generated for the load of *base into a register: ;; base.1 = base (insn 24 22 25 (set (reg:SI 129) (high:SI (symbol_ref:SI ("base") [flags 0x84] <var_decl 0x400a6930 base>))) -1 (nil) (nil)) (insn 25 24 26 (set (reg/f:SI 128) (lo_sum:SI (reg:SI 129) (symbol_ref:SI ("base") [flags 0x84] <var_decl 0x400a6930 base>))) -1 (nil) (expr_list:REG_EQUAL (symbol_ref:SI ("base") [flags 0x84] <var_decl 0x400a6930 base>) (nil))) (insn 26 25 0 (set (reg:SI 124 [ base.1 ]) (mem/c/i:SI (reg/f:SI 128) [3 base+0 S4 A32])) -1 (nil) (nil)) There seem to be two problems here. First, the mem/c/i:SI (reg/f:SI 128) seems to be missing a MEM_POINTER attribute. I tracked that down to rtl.h:MEM_COPY_ATTRIBUTES(LHS,RHS) not copying the MEM_POINTER attribute from RHS to LHS. I added the code to do that, so the mem above does get the MEM_POINTER flag set. However, the reg:SI 124 [base.1] is still missing the REG_POINTER flag. This second problem seems to be a problem in expand_one_register_var(tree var). In this specific case, var seems to be a pointer type, but looks to be "artifical", so we skip the code that would have marked the reg rtx with the REG_POINTER: Breakpoint 4, expand_one_register_var (var=0x400a6d90) at /home/bergner/gcc/gcc-mainline-rtlanal/gcc/cfgexpand.c:643 643 tree type = TREE_TYPE (var); (gdb) call debug_tree (var) <var_decl 0x400a6d90 base.1 type <pointer_type 0x4009ae38 type <integer_type 0x4009a340 int sizes-gimplified public SI size <integer_cst 0x4008e5e0 constant invariant 32> unit size <integer_cst 0x4008e2a0 constant invariant 4> align 32 symtab 0 alias set 2 precision 32 min <integer_cst 0x4008e580 -2147483648> max <integer_cst 0x4008e5a0 2147483647> pointer_to_this <pointer_type 0x4009ae38>> public unsigned SI size <integer_cst 0x4008e5e0 32> unit size <integer_cst 0x4008e2a0 4> align 32 symtab 0 alias set 3> used unsigned ignored SI file indexedload5.c line 7 size <integer_cst 0x4008e5e0 32> unit size <integer_cst 0x4008e2a0 4> align 32 context <function_decl 0x40151f00 indexedload> chain <var_decl 0x400a6e00 D.1531>> (gdb) p var->decl_common.artificial_flag $8 = 1 If I clear var->decl_common.artificial_flag with the debugger and continue, then we get the REG_POINTER flag set and the indexed load is generated with the base pointer first like we want. Does anyone know why var above was marked as artifical? -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=28690