https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89954
--- Comment #5 from Uroš Bizjak <ubizjak at gmail dot com> ---
(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
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