http://gcc.gnu.org/bugzilla/show_bug.cgi?id=56157



--- Comment #8 from Richard Biener <rguenth at gcc dot gnu.org> 2013-01-31 
14:45:46 UTC ---

The check



          /* In the end of a pattern sequence we have a use of the original

stmt,

             so we need to compare OPRND with the original def.  */

          if (is_pattern_stmt_p (vinfo_for_stmt (first_def))

              && !STMT_VINFO_IN_PATTERN_P (vinfo_for_stmt (first_stmt))

              && !is_pattern_stmt_p (vinfo_for_stmt (first_stmt)))



seems bogus.  We have two adjacent (but independent) pattern stmts, so

first_stmt and first_def are both patterns.  I think what the code tries to

do is check whether first_def is the "main" pattern stmt (thus if

the scalar stmt _10 = _9 * 65535 would have the pattern

_tem = ...; patt_10 = _tem ...; thus be of size 2 it likes to know if

first_def is patt_10 and not _tem).



So, something like



          if (is_pattern_stmt_p (vinfo_for_stmt (first_def))

              && STMT_VINFO_RELATED_STMT 

                  (vinfo_for_stmt 

                    (STMT_VINFO_RELATED_STMT 

                      (vinfo_for_stmt (first_def)))) == first_def)



that is, if the main pattern stmt (RELATED_STMT) of the scalar stmt

for the pattern group (RELATED_STMT of first_def if that is a pattern)

is first_def.



Well.  If I remember the mess of pattern vs. RELATED_STMT correctly ...



That doesn't fix the ICE, but the generated code looks better.  Apart

from that we still have a weird



  vect_cst_.14_38 = {_64, _60, _56, _52, _64, _60, _56, _52};



now without any defs for the operands ... it's from



_64 = (unsigned short) _8;

patt_63 = _64 w* 65535;



the pattern generated for



_9 = (unsigned int) _8;

_10 = _9 * 65535



but STMT_VINFO_RELATED_STMT are



_64 = (unsigned short) _8; -> _9 = (unsigned int) _8;

_9 = (unsigned int) _8; -> _64 = (unsigned short) _8;



t.c:11: note: patt_63 = _64 w* 65535;

t.c:11: note: pattern recognized: patt_63 = _64 w* 65535;

t.c:11: note: additional pattern stmt: _64 = (unsigned short) _8;



that's unexpected to me.  It seems there is no way to detect this

"end of a pattern sequence"?  Maybe what really is wanted is



          /* In the end of a pattern sequence we have a use of the original

stmt,

             so we need to compare OPRND with the original def.  */

          first_def_info = vinfo_for_stmt (first_def);

          if (STMT_VINFO_IN_PATTERN_P (first_def_info))

            first_def = STMT_VINFO_RELATED_STMT (first_def_info);



?!



What it seems to try to do is see if we are processing operands of a

"leaf" pattern stmt - thus one with operands not in a pattern.

Then it tries to compensate for that with using the scalar stmt

for the pattern stmt of the definition of the operand.



But it seems to me that the def always has to match the operand

anyway, be it pattern or not, and thus the check is completely

superflous?  Seems to work at least.  Giving it more testing.



Hmm, it breaks BB SLP at least.  Here the ops array we hand to

vect_get_slp_defs does not match up with SLP_TREE_CHILDREN.

Like for _12 = x_11(D) * a0_4; we get one child, but that matches up

with x_11(D) - which is of course wrong.  So it seems that the

operand comparison code is to verify we are indeed looking at the

correct SLP_TREE_CHILDREN entry ... skipping appearantly "unused" ones.

*sigh*

Reply via email to