https://gcc.gnu.org/bugzilla/show_bug.cgi?id=54589
Jakub Jelinek <jakub at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|RESOLVED |REOPENED Resolution|FIXED |--- --- Comment #11 from Jakub Jelinek <jakub at gcc dot gnu.org> --- That is because e.g. on: struct S { int a, b, c, d; }; struct T { struct S a; struct S b[256]; } *v; int foo (unsigned char *x) { return v->b[*x].a; } we have: (insn 6 3 7 2 (set (reg/f:DI 88 [ v ]) (mem/f/c:DI (symbol_ref:DI ("v") [flags 0x2] <var_decl 0x7f5f67c7aab0 v>) [1 v+0 S8 A64])) "pr54589-3.c":7:18 66 {*movdi_internal} (nil)) (insn 7 6 8 2 (set (reg:SI 89 [ *x_5(D) ]) (zero_extend:SI (mem:QI (reg/v/f:DI 86 [ x ]) [0 *x_5(D)+0 S1 A8]))) "pr54589-3.c":7:15 119 {*zero_extendqisi2} (expr_list:REG_DEAD (reg/v/f:DI 86 [ x ]) (nil))) (insn 8 7 9 2 (set (reg:DI 90 [ *x_5(D) ]) (sign_extend:DI (reg:SI 89 [ *x_5(D) ]))) "pr54589-3.c":7:18 128 {*extendsidi2_rex64} (expr_list:REG_DEAD (reg:SI 89 [ *x_5(D) ]) (nil))) (insn 9 8 10 2 (parallel [ (set (reg:DI 91) (plus:DI (reg:DI 90 [ *x_5(D) ]) (const_int 1 [0x1]))) (clobber (reg:CC 17 flags)) ]) "pr54589-3.c":7:18 191 {*adddi_1} (expr_list:REG_DEAD (reg:DI 90 [ *x_5(D) ]) (expr_list:REG_UNUSED (reg:CC 17 flags) (nil)))) (insn 10 9 11 2 (parallel [ (set (reg:DI 92) (ashift:DI (reg:DI 91) (const_int 4 [0x4]))) (clobber (reg:CC 17 flags)) ]) "pr54589-3.c":7:18 518 {*ashldi3_1} (expr_list:REG_DEAD (reg:DI 91) (expr_list:REG_UNUSED (reg:CC 17 flags) (nil)))) (insn 11 10 12 2 (parallel [ (set (reg/f:DI 93) (plus:DI (reg/f:DI 88 [ v ]) (reg:DI 92))) (clobber (reg:CC 17 flags)) ]) "pr54589-3.c":7:18 191 {*adddi_1} (expr_list:REG_DEAD (reg:DI 92) (expr_list:REG_DEAD (reg/f:DI 88 [ v ]) (expr_list:REG_UNUSED (reg:CC 17 flags) (nil))))) (insn 12 11 17 2 (set (reg:SI 94 [ v.0_1->b[_3].a ]) (mem:SI (reg/f:DI 93) [2 v.0_1->b[_3].a+0 S4 A32])) "pr54589-3.c":7:18 67 {*movsi_internal} (expr_list:REG_DEAD (reg/f:DI 93) (nil))) and combine would handle that fine if it tried to combine 9, 10, 11 -> 12 first, but unfortunately for this case it tries 6 -> 11 first and, if the combination of everything doesn't simplify, we try to split it only into two parts, which in this case isn't enough, we'd need to split those 4 instructions into 3 (one to do the shift, one to do the v load and last to do the mem read with the 16(reg1, reg2) addressing. Unless the combiner grows the possibility to split into 3 functions, I'm afraid this would need to be solved in machine reorg or something similar.