This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug target/67765] New: [SH] Improve treg_combine pass
- From: "olegendo at gcc dot gnu.org" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: Tue, 29 Sep 2015 13:44:16 +0000
- Subject: [Bug target/67765] New: [SH] Improve treg_combine pass
- Auto-submitted: auto-generated
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);
}