https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108048
Bug ID: 108048 Summary: PPCLE: gcc does not recognize that lbzx does zero extend Product: gcc Version: 12.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: target Assignee: unassigned at gcc dot gnu.org Reporter: jens.seifert at de dot ibm.com Target Milestone: --- extern unsigned char magic1[256]; unsigned int hash(const unsigned char inp[4]) { const unsigned long long INIT = 0x1ULL; unsigned long long h1 = INIT; h1 = magic1[((unsigned long long)inp[0]) ^ h1]; h1 = magic1[((unsigned long long)inp[1]) ^ h1]; h1 = magic1[((unsigned long long)inp[2]) ^ h1]; h1 = magic1[((unsigned long long)inp[3]) ^ h1]; return h1; } Generates: hash(unsigned char const*): .LCF0: addi 2,2,.TOC.-.LCF0@l lbz 9,0(3) addis 10,2,.LC0@toc@ha ld 10,.LC0@toc@l(10) lbz 6,1(3) lbz 7,2(3) lbz 8,3(3) xori 9,9,0x1 lbzx 9,10,9 xor 9,9,6 rlwinm 9,9,0,0xff <= unnecessary lbzx 9,10,9 xor 9,9,7 rlwinm 9,9,0,0xff <= unnecessary lbzx 9,10,9 xor 9,9,8 rlwinm 9,9,0,0xff <= unnecessary lbzx 3,10,9 blr All XOR operations are done in unsigned long long (64-bit). gcc adds unnecessary rlwinm. lbz and lbzx does zero extension (no cleanup of upper bits required).