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 }.