https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67765
Bug ID: 67765 Summary: [SH] Improve treg_combine pass Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: target Assignee: unassigned at gcc dot gnu.org Reporter: olegendo at gcc dot gnu.org Target Milestone: --- Target: sh*-*-* Currently the sh_treg_combine.cc pass uses conditional branches as a trigger for its optimizations. However, if the addsicc pattern is added from PR 54236 attachment 36012, then the following reduced test case, compiled with -O2 -m4 -ml, will exhibit the following sequence: cmp/eq #32,r0 movt r7 .L7: cmp/hi r6,r2 bf/s .L8 tst r7,r7 << r7 known to be 0 or 1 because of preceeding movt mov #-1,r1 addc r1,r2 << r7 == 0: r2 = r2 + (-1) + 1 = r2 + 0 r7 == 1: r2 = r2 + (-1) + 0 = r2 - 1 r2 = r2 - r1 Without the addsicc pattern, a "sub r1,r2" is generated. The treg_combine pass should actually be triggered by the tst insn and should propagate known reg values that originated from a movt or movrt insn into the following insns. extern void free_bootmem (unsigned long addr, unsigned long size); struct { unsigned long addr, size, type; } memory_chunk[16] = { { 0 } }; static char command_line[896] = { 0, }; void setup_arch(char **cmdline_p) { char c = ' ', cn, *to = command_line, *from = ((char *) (0x10480)); unsigned long start_pfn, end_pfn; int i = 0; for (;;) { cn = *(from++); if (!cn) break; if (cn == ' ' && c == ' ') continue; c = cn; if (to - command_line >= 896) break; *(to++) = c; } if (c == ' ' && to > command_line) to--; *to = '\0'; unsigned long start_chunk, end_chunk; start_chunk = (memory_chunk[i].addr + (1UL << 12) - 1); start_chunk >>= 12; end_chunk = (memory_chunk[i].addr + memory_chunk[i].size); end_chunk >>= 12; if (start_chunk < start_pfn) start_chunk = start_pfn; if (end_chunk > end_pfn) end_chunk = end_pfn; if (start_chunk < end_chunk) free_bootmem(start_chunk << 12, (end_chunk - start_chunk) << 12); }