https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84681
Bug ID: 84681
Summary: tree-ter moving code too much
Product: gcc
Version: 8.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: middle-end
Assignee: unassigned at gcc dot gnu.org
Reporter: amonakov at gcc dot gnu.org
Target Milestone: ---
Target: x86_64
The following code (derived from a hot loop in a Huffman encoder, reported by
Fabian Giesen) suffers from TER activity too much on x86-64. TER lifts
loads+zero_extends to the BB head, sinking variable-length shifts and
increasing register pressure too badly.
Not being very familiar with TER, I think it would be good to understand why
loads are lifted all the way up to BB head like that. That's probably not
supposed to happen (and may be fixable without a TER overhaul?)
unsigned long long f(unsigned char *from,
unsigned char *from_end,
unsigned long long *codes,
unsigned char *lens)
{
unsigned char sym0, sym1, sym2;
unsigned long long bits0=0, bits1=0, bits2=0;
unsigned char count0=0, count1=0, count2=0;
do {
sym0 = *from++; bits0 |= codes[sym0] << count0; count0 += lens[sym0];
sym1 = *from++; bits1 |= codes[sym1] << count1; count1 += lens[sym1];
sym2 = *from++; bits2 |= codes[sym2] << count2; count2 += lens[sym2];
sym0 = *from++; bits0 |= codes[sym0] << count0; count0 += lens[sym0];
sym1 = *from++; bits1 |= codes[sym1] << count1; count1 += lens[sym1];
sym2 = *from++; bits2 |= codes[sym2] << count2; count2 += lens[sym2];
sym0 = *from++; bits0 |= codes[sym0] << count0; count0 += lens[sym0];
sym1 = *from++; bits1 |= codes[sym1] << count1; count1 += lens[sym1];
sym2 = *from++; bits2 |= codes[sym2] << count2; count2 += lens[sym2];
sym0 = *from++; bits0 |= codes[sym0] << count0; count0 += lens[sym0];
sym1 = *from++; bits1 |= codes[sym1] << count1; count1 += lens[sym1];
sym2 = *from++; bits2 |= codes[sym2] << count2; count2 += lens[sym2];
sym0 = *from++; bits0 |= codes[sym0] << count0; count0 += lens[sym0];
sym1 = *from++; bits1 |= codes[sym1] << count1; count1 += lens[sym1];
sym2 = *from++; bits2 |= codes[sym2] << count2; count2 += lens[sym2];
} while(from != from_end);
return bits0+bits1+bits2;
}