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; }