https://gcc.gnu.org/bugzilla/show_bug.cgi?id=54589
Jakub Jelinek <jakub at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |jakub at gcc dot gnu.org, | |segher at gcc dot gnu.org --- Comment #5 from Jakub Jelinek <jakub at gcc dot gnu.org> --- Note, in other cases combine is sucessful. E.g. consider: struct S { int a, b, c, d; }; struct T { struct S e[16]; struct S f[1024]; } t; int foo (unsigned long x) { return t.f[x + 5].a; } int bar (struct T *x, unsigned long y) { return x->f[y + 5].b; } On x86_64-linux with -O2, we have before combine in both cases (idx + 21) << 4 and in foo combine says: Trying 7, 8 -> 10: 7: {r87:DI=r91:DI+0x15;clobber flags:CC;} REG_DEAD r91:DI REG_UNUSED flags:CC 8: {r88:DI=r87:DI<<0x4;clobber flags:CC;} REG_DEAD r87:DI REG_UNUSED flags:CC 10: r90:SI=[r88:DI+`t'] REG_DEAD r88:DI Failed to match this instruction: (set (reg:SI 90 [ t.f[_1].a ]) (mem:SI (plus:DI (mult:DI (reg:DI 91) (const_int 16 [0x10])) (const:DI (plus:DI (symbol_ref:DI ("t") [flags 0x2] <var_decl 0x7f837b94cab0 t>) (const_int 336 [0x150])))) [1 t.f[_1].a+0 S4 A32])) Successfully matched this instruction: (set (reg:DI 88) (ashift:DI (reg:DI 91) (const_int 4 [0x4]))) Successfully matched this instruction: (set (reg:SI 90 [ t.f[_1].a ]) (mem:SI (plus:DI (reg:DI 88) (const:DI (plus:DI (symbol_ref:DI ("t") [flags 0x2] <var_decl 0x7f837b94cab0 t>) (const_int 336 [0x150])))) [1 t.f[_1].a+0 S4 A32])) and it is merged the way we want: salq $4, %rdi movl t+336(%rdi), %eax while in bar: Failed to match this instruction: (set (reg:SI 91 [ x_4(D)->f[_1].b ]) (mem:SI (plus:DI (plus:DI (mult:DI (reg:DI 93) (const_int 16 [0x10])) (reg:DI 92)) (const_int 340 [0x154])) [1 x_4(D)->f[_1].b+0 S4 A32])) Failed to match this instruction: (set (reg:DI 88) (plus:DI (ashift:DI (reg:DI 93) (const_int 4 [0x4])) (reg:DI 92))) and it is not merged: addq $21, %rsi salq $4, %rsi movl 4(%rsi,%rdi), %eax when it could be: salq $4, %rsi movl 340(%rsi,%rdi), %eax It isn't x86 specific though, e.g. on powerpc64-linux we end up with: addi 4,4,21 sldi 4,4,4 add 4,3,4 lwa 3,4(4) for bar, where I guess: sldi 4,4,4 add 4,3,4 lwa 3,340(4) would work too.