https://gcc.gnu.org/bugzilla/show_bug.cgi?id=123544

--- Comment #4 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
It is when trying to simplify
(insn 15 14 16 3 (set (reg:SI 112)
        (and:SI (subreg:SI (lshiftrt:HI (subreg:HI (reg/v:SI 108 [ x ]) 0)
                    (const_int 8 [0x8])) 0)
            (const_int 32767 [0x7fff]))) "pr123544.c":14:5 discrim 1 551
{andsi3}
     (expr_list:REG_DEAD (reg:HI 104 [ iftmp.0_4 ])
        (nil)))
The r16-5022 added code is called with AND SImode op0
(subreg:SI (lshiftrt:HI (subreg:HI (reg/v:SI 108 [ x ]) 0)
        (const_int 8 [0x8])) 0)
and op1 (const_int 32767 [0x7fff]) and simplifies that into
(and:SI (lshiftrt:SI (reg/v:SI 108 [ x ])
        (const_int 8 [0x8]))
    (const_int 32767 [0x7fff]))
This looks wrong to me.
Consider (reg/v:SI 108 [ x ]) 0) could have value 0x12345678U.
The original expression takes lowpart 16-bits from that, i.e. 0x5678U, shifts
that
right logically by 8 bits, so 0x56U, makes a paradoxical SUBREG from that, i.e.
0x????0056U and masks that with 0x7fff, i.e. result is 0x56U.
The new expression shifts 0x12345678U logically right by 8 bits, i.e. 0x123456U
and
masks it by 0x7fff, result 0x3456U.

Reply via email to