https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89954
--- Comment #6 from Hongtao.liu <crazylht at gmail dot com> --- (In reply to Uroš Bizjak from comment #5) > (In reply to Hongtao.liu from comment #4) > > It looks like there's splitter in aarch64 which combines > > load+xor+zero_extend to zero_extend(mem) + xor, x86 doesn't have. The simple > > way is to add corresponding define_split for x86. > > > > ---------x86 dump----------- > > Failed to match this instruction: > > (set (reg:SI 85) > > (sign_extend:SI (xor:QI (mem/c:QI (symbol_ref:DI ("c") [flags 0x2] > > <var_decl 0x7f94fd2e8c60 c>) [0 c+0 S1 A8]) > > (const_int 1 [0x1])))) > > -----------dump end---------- > > Maybe I'm missing something, but I don't think this transformation is > correct. Please consider the following analysis with the emphasis on the > sign bit of the QImode operation: > > r = sext:HI (xor:QI (a, b)); b IMM > > a 0xxxxxxx > b 0xxxxxxx > r 00000000 0xxxxxxx > > a 1xxxxxxx > b 0xxxxxxx > r 11111111 1xxxxxxx > > a 0xxxxxxx > b 1xxxxxxx > r 11111111 1xxxxxxx > > a 1xxxxxxx > b 1xxxxxxx > r 00000000 0xxxxxxx > > r = xor:HI ((a, b); a ZEXT, b IMM movzbl maybe confuse you, there's no ZEXT here, just movqi_internal. also at the stage of combine it is xorqi_1 not xorsi_1, and b here is const_int 1, the most significant bit is zero. here's dump before combine. (insn 5 2 6 2 (set (reg:QI 87 [ c ]) (mem/c:QI (symbol_ref:DI ("c") [flags 0x2] <var_decl 0x7ff23f550c60 c>) [0 c+0 S1 A8])) "test.c":4:14 79 {*movqi_internal} (nil)) (insn 6 5 7 2 (parallel [ (set (reg:QI 86) (xor:QI (reg:QI 87 [ c ]) (const_int 1 [0x1]))) (clobber (reg:CC 17 flags)) ]) "test.c":4:14 556 {*xorqi_1} (expr_list:REG_DEAD (reg:QI 87 [ c ]) (expr_list:REG_UNUSED (reg:CC 17 flags) (expr_list:REG_EQUAL (xor:QI (mem/c:QI (symbol_ref:DI ("c") [flags 0x2] <var_decl 0x7ff23f550c60 c>) [0 c+0 S1 A8]) (const_int 1 [0x1])) (nil))))) (insn 7 6 12 2 (set (reg:SI 85) (sign_extend:SI (reg:QI 86))) "test.c":4:14 156 {extendqisi2} (expr_list:REG_DEAD (reg:QI 86) > > a 00000000 0xxxxxxx > b 00000000 0xxxxxxx > r 00000000 0xxxxxxx > > a 00000000 1xxxxxxx > b 00000000 0xxxxxxx > r 00000000 1xxxxxxx > > a 00000000 0xxxxxxx > b 11111111 1xxxxxxx > r 11111111 1xxxxxxx > > a 00000000 1xxxxxxx > b 11111111 1xxxxxxx > r 11111111 0xxxxxxx > > As demonstrated above, results differ when sign bit of the value a is set. > > The conversion works when the value a is loaded with a sign-extend operation. > > r = xor:HI ((a, b); a SEXT, b IMM > > a 00000000 0xxxxxxx > b 00000000 0xxxxxxx > r 00000000 0xxxxxxx > > a 11111111 1xxxxxxx > b 00000000 0xxxxxxx > r 11111111 1xxxxxxx > > a 00000000 0xxxxxxx > b 11111111 1xxxxxxx > r 11111111 1xxxxxxx > > a 11111111 1xxxxxxx > b 11111111 1xxxxxxx > r 00000000 0xxxxxxx