https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97417
--- Comment #43 from Levy <admin at levyhsu dot com> --- Thanks for pointing the hook out Jim. for both patched and unpatched, so far I've been traced through try_replace_in_use() to reload_combine_recognize_const_pattern() to reload_combine() to reload_cse_regs() to pass_postreload_cse::execute() in postreload.c ------------------------------------------------------------------- For reload_combine(), by printing each insn at front of the loop: (line 1302) for (insn = get_last_insn (); insn; insn = prev) { debug_rtx(insn) ... } ------------------------------------------------------------------- Unpatched gcc shows: (insn 13 11 14 2 (set (reg:DI 10 a0) (sign_extend:DI (mem:SI (plus:DI (reg/f:DI 15 a5 [88]) (const_int 44 [0x2c])) [1 MEM[(int *)array_5(D) + 812B]+0 S4 A32]))) "array_test.c":9:5 90 {extendsidi2} (nil)) (insn 11 10 13 2 (set (reg:SI 14 a4 [83]) (plus:SI (reg:SI 14 a4 [orig:84 MEM[(int *)array_5(D) + 808B] ] [84]) (reg:SI 10 a0 [80]))) "array_test.c":8:5 3 {addsi3} (nil)) (insn 10 8 11 2 (set (reg:DI 14 a4) (sign_extend:DI (mem:SI (plus:DI (reg/f:DI 15 a5 [88]) (const_int 40 [0x28])) [1 MEM[(int *)array_5(D) + 808B]+0 S4 A32]))) "array_test.c":8:5 90 {extendsidi2} (expr_list:REG_EQUIV (mem:SI (plus:DI (reg/f:DI 15 a5 [88]) (const_int 40 [0x28])) [1 MEM[(int *)array_5(D) + 808B]+0 S4 A32]) (nil))) (insn 8 7 10 2 (set (reg:SI 10 a0 [80]) (plus:SI (reg:SI 10 a0 [orig:81 MEM[(int *)array_5(D) + 800B] ] [81]) (reg:SI 14 a4 [orig:82 MEM[(int *)array_5(D) + 804B] ] [82]))) "array_test.c":7:5 3 {addsi3} (nil)) (insn 7 6 8 2 (set (reg:DI 14 a4) (sign_extend:DI (mem:SI (plus:DI (reg/f:DI 15 a5 [88]) (const_int 36 [0x24])) [1 MEM[(int *)array_5(D) + 804B]+0 S4 A32]))) "array_test.c":7:5 90 {extendsidi2} (expr_list:REG_EQUIV (mem:SI (plus:DI (reg/f:DI 15 a5 [88]) (const_int 36 [0x24])) [1 MEM[(int *)array_5(D) + 804B]+0 S4 A32]) (nil))) (insn 6 23 7 2 (set (reg:DI 10 a0) (sign_extend:DI (mem:SI (plus:DI (reg/f:DI 15 a5 [88]) (const_int 32 [0x20])) [1 MEM[(int *)array_5(D) + 800B]+0 S4 A32]))) "array_test.c":7:5 90 {extendsidi2} (expr_list:REG_EQUIV (mem:SI (plus:DI (reg/f:DI 15 a5 [88]) (const_int 32 [0x20])) [1 MEM[(int *)array_5(D) + 800B]+0 S4 A32]) (nil))) ------------------------------------------------------------------- Patched one shows already merged results: (insn 16 14 18 2 (set (reg:DI 10 a0 [orig:90 MEM[(int *)array_5(D) + 812B] ] [90]) (sign_extend:DI (mem:SI (plus:DI (reg:DI 10 a0 [96]) (const_int 812 [0x32c])) [1 MEM[(int *)array_5(D) + 812B]+0 S4 A32]))) "array_test.c":9:5 90 {extendsidi2} (nil)) (insn 14 12 16 2 (set (reg:SI 15 a5 [85]) (plus:SI (reg:SI 15 a5 [80]) (reg:SI 14 a4 [orig:87 MEM[(int *)array_5(D) + 808B] ] [87]))) "array_test.c":8:5 3 {addsi3} (nil)) (insn 12 10 14 2 (set (reg:DI 14 a4 [orig:87 MEM[(int *)array_5(D) + 808B] ] [87]) (sign_extend:DI (mem:SI (plus:DI (reg:DI 10 a0 [96]) (const_int 808 [0x328])) [1 MEM[(int *)array_5(D) + 808B]+0 S4 A32]))) "array_test.c":8:5 90 {extendsidi2} (nil)) (insn 10 8 12 2 (set (reg:SI 15 a5 [80]) (plus:SI (reg:SI 15 a5 [orig:84 MEM[(int *)array_5(D) + 804B] ] [84]) (reg:SI 14 a4 [orig:82 MEM[(int *)array_5(D) + 800B] ] [82]))) "array_test.c":7:5 3 {addsi3} (nil)) (insn 8 6 10 2 (set (reg:DI 15 a5 [orig:84 MEM[(int *)array_5(D) + 804B] ] [84]) (sign_extend:DI (mem:SI (plus:DI (reg:DI 10 a0 [96]) (const_int 804 [0x324])) [1 MEM[(int *)array_5(D) + 804B]+0 S4 A32]))) "array_test.c":7:5 90 {extendsidi2} (nil)) (insn 6 27 8 2 (set (reg:DI 14 a4 [orig:82 MEM[(int *)array_5(D) + 800B] ] [82]) (sign_extend:DI (mem:SI (plus:DI (reg:DI 10 a0 [96]) (const_int 800 [0x320])) [1 MEM[(int *)array_5(D) + 800B]+0 S4 A32]))) "array_test.c":7:5 90 {extendsidi2} (nil)) ------------------------------------------------------------------- Before reload_combine () is reload_cse_regs_1() in reload_cse_regs() which "detects no-op moves where we happened to assign two different pseudo-registers to the same hard register" and pass_postreload_cse::execute calls reload_cse_regs() pass_postreload_cse::execute() look like the entry point for postreload.c In order to confirm it's not in postreload.c, I put: ---------------------------------------------------------- rtx_insn *insn, *next; for (insn = get_insns (); insn; insn = next) { debug_rtx(insn); next = NEXT_INSN (insn); } ---------------------------------------------------------- in pass_postreload_cse::execute (function *fun) right after: if (!dbg_cnt (postreload_cse)) return 0; ---------------------------------------------------------- Unpathed: (note 1 0 4 NOTE_INSN_DELETED) (note 4 1 2 2 [bb 2] NOTE_INSN_BASIC_BLOCK) (note 2 4 3 2 NOTE_INSN_DELETED) (note 3 2 23 2 NOTE_INSN_FUNCTION_BEG) (insn 23 3 6 2 (set (reg/f:DI 15 a5 [88]) (plus:DI (reg:DI 10 a0 [92]) (const_int 768 [0x300]))) "array_test.c":7:5 4 {adddi3} (nil)) (insn 6 23 7 2 (set (reg:SI 10 a0 [orig:81 MEM[(int *)array_5(D) + 800B] ] [81]) (mem:SI (plus:DI (reg/f:DI 15 a5 [88]) (const_int 32 [0x20])) [1 MEM[(int *)array_5(D) + 800B]+0 S4 A32])) "array_test.c":7:5 136 {*movsi_internal} (expr_list:REG_EQUIV (mem:SI (plus:DI (reg/f:DI 15 a5 [88]) (const_int 32 [0x20])) [1 MEM[(int *)array_5(D) + 800B]+0 S4 A32]) (nil))) (insn 7 6 8 2 (set (reg:SI 14 a4 [orig:82 MEM[(int *)array_5(D) + 804B] ] [82]) (mem:SI (plus:DI (reg/f:DI 15 a5 [88]) (const_int 36 [0x24])) [1 MEM[(int *)array_5(D) + 804B]+0 S4 A32])) "array_test.c":7:5 136 {*movsi_internal} (expr_list:REG_EQUIV (mem:SI (plus:DI (reg/f:DI 15 a5 [88]) (const_int 36 [0x24])) [1 MEM[(int *)array_5(D) + 804B]+0 S4 A32]) (nil))) (insn 8 7 10 2 (set (reg:SI 10 a0 [80]) (plus:SI (reg:SI 10 a0 [orig:81 MEM[(int *)array_5(D) + 800B] ] [81]) (reg:SI 14 a4 [orig:82 MEM[(int *)array_5(D) + 804B] ] [82]))) "array_test.c":7:5 3 {addsi3} (nil)) (insn 10 8 11 2 (set (reg:SI 14 a4 [orig:84 MEM[(int *)array_5(D) + 808B] ] [84]) (mem:SI (plus:DI (reg/f:DI 15 a5 [88]) (const_int 40 [0x28])) [1 MEM[(int *)array_5(D) + 808B]+0 S4 A32])) "array_test.c":8:5 136 {*movsi_internal} (expr_list:REG_EQUIV (mem:SI (plus:DI (reg/f:DI 15 a5 [88]) (const_int 40 [0x28])) [1 MEM[(int *)array_5(D) + 808B]+0 S4 A32]) (nil))) (insn 11 10 13 2 (set (reg:SI 14 a4 [83]) (plus:SI (reg:SI 14 a4 [orig:84 MEM[(int *)array_5(D) + 808B] ] [84]) (reg:SI 10 a0 [80]))) "array_test.c":8:5 3 {addsi3} (nil)) (insn 13 11 14 2 (set (reg:SI 10 a0 [orig:86 MEM[(int *)array_5(D) + 812B] ] [86]) (mem:SI (plus:DI (reg/f:DI 15 a5 [88]) (const_int 44 [0x2c])) [1 MEM[(int *)array_5(D) + 812B]+0 S4 A32])) "array_test.c":9:5 136 {*movsi_internal} (nil)) ...... ---------------------------------------------------------- Patched: (note 1 0 4 NOTE_INSN_DELETED) (note 4 1 2 2 [bb 2] NOTE_INSN_BASIC_BLOCK) (note 2 4 3 2 NOTE_INSN_DELETED) (note 3 2 27 2 NOTE_INSN_FUNCTION_BEG) (note 27 3 6 2 NOTE_INSN_DELETED) (insn 6 27 8 2 (set (reg:DI 14 a4 [orig:82 MEM[(int *)array_5(D) + 800B] ] [82]) (sign_extend:DI (mem:SI (plus:DI (reg:DI 10 a0 [96]) (const_int 800 [0x320])) [1 MEM[(int *)array_5(D) + 800B]+0 S4 A32]))) "array_test.c":7:5 90 {extendsidi2} (nil)) (insn 8 6 10 2 (set (reg:DI 15 a5 [orig:84 MEM[(int *)array_5(D) + 804B] ] [84]) (sign_extend:DI (mem:SI (plus:DI (reg:DI 10 a0 [96]) (const_int 804 [0x324])) [1 MEM[(int *)array_5(D) + 804B]+0 S4 A32]))) "array_test.c":7:5 90 {extendsidi2} (nil)) (insn 10 8 12 2 (set (reg:SI 15 a5 [80]) (plus:SI (reg:SI 15 a5 [orig:84 MEM[(int *)array_5(D) + 804B] ] [84]) (reg:SI 14 a4 [orig:82 MEM[(int *)array_5(D) + 800B] ] [82]))) "array_test.c":7:5 3 {addsi3} (nil)) (insn 12 10 14 2 (set (reg:DI 14 a4 [orig:87 MEM[(int *)array_5(D) + 808B] ] [87]) (sign_extend:DI (mem:SI (plus:DI (reg:DI 10 a0 [96]) (const_int 808 [0x328])) [1 MEM[(int *)array_5(D) + 808B]+0 S4 A32]))) "array_test.c":8:5 90 {extendsidi2} (nil)) (insn 14 12 16 2 (set (reg:SI 15 a5 [85]) (plus:SI (reg:SI 15 a5 [80]) (reg:SI 14 a4 [orig:87 MEM[(int *)array_5(D) + 808B] ] [87]))) "array_test.c":8:5 3 {addsi3} (nil)) (insn 16 14 18 2 (set (reg:DI 10 a0 [orig:90 MEM[(int *)array_5(D) + 812B] ] [90]) (sign_extend:DI (mem:SI (plus:DI (reg:DI 10 a0 [96]) (const_int 812 [0x32c])) [1 MEM[(int *)array_5(D) + 812B]+0 S4 A32]))) "array_test.c":9:5 90 {extendsidi2} (nil)) ...... ---------------------------------------------------------- In other words this was before reload_cse_regs(), before reload_combine(), before reload_combine_recognize_const_pattern().... ------------------------------------------------------------------ In postreload.c at around line 939, comments says: /* We look for a REG1 = REG2 + CONSTANT insn, followed by either uses of REG1 inside an address, or inside another add insn. If possible and profitable, merge the addition into subsequent uses. */ Which really looks like the function we're looking for, but I've debug each insn from button to top, maybe I've missed something in between? I'll investigate other places where address_cost() are called.