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

--- Comment #13 from Uroš Bizjak <ubizjak at gmail dot com> ---
(In reply to Richard Biener from comment #12)
> I can see cprop1 adds the REG_EQUAL note:
> 
> (insn 22 21 23 4 (set (reg:V8HI 100)
>         (zero_extend:V8HI (vec_select:V8QI (subreg:V16QI (reg:V4QI 98) 0)
>                 (parallel [
>                         (const_int 0 [0])
>                         (const_int 1 [0x1])
>                         (const_int 2 [0x2])
>                         (const_int 3 [0x3])
>                         (const_int 4 [0x4])
>                         (const_int 5 [0x5])
>                          (const_int 6 [0x6])
>                          (const_int 7 [0x7])
>                      ])))) "t.c":12:42 7557 {sse4_1_zero_extendv8qiv8hi2}
> -     (expr_list:REG_DEAD (reg:V4QI 98)
> -        (nil)))
> +     (expr_list:REG_EQUAL (const_vector:V8HI [
> +                (const_int 204 [0xcc]) repeated x8
> +            ])
> +        (expr_list:REG_DEAD (reg:V4QI 98)
> +            (nil))))
> 
> but I don't see yet what the actual wrong transform based on this REG_EQUAL
> note is?

We constant fold V4QImode const_vector to a V8HImode const_vector with 8
defined elements. We started with undefined top four bytes, but now we
magically define them.

> 
> It looks like we CSE the above with
> 
> -   46: r122:V8QI=[`*.LC3']
> -      REG_EQUAL const_vector
> -   48: r125:V8HI=zero_extend(vec_select(r122:V8QI#0,parallel))
> -      REG_EQUAL const_vector
> -      REG_DEAD r122:V8QI
> -   49: r126:V8HI=r124:V8HI*r125:V8HI
> -      REG_DEAD r125:V8HI
> +   49: r126:V8HI=r124:V8HI*r100:V8HI
> 
> but otherwise do nothing.  So the issue is that we rely on the "undefined"
> vals to have a specific value (from the earlier REG_EQUAL note) but actual
> code generation doesn't ensure this (it doesn't need to).  That said,
> the issue isn't the constant folding per-se but that we do not actually
> constant fold but register an equality that doesn't hold.

The above CSE is the consequence of REG_EQUAL note that compiler set on the
insn. Compiler claims that the value of (insn 22) equals an array of 8 consts {
204 , ... , 204 }, but in reality (c.f. Comment #3) the value in the register
%xmm4 before VPMULLW insn is { 0, 0, 0, 0, 204, 204, 204, 204 }.

Reply via email to