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

Reply via email to