This fixes PR64829 where widening shift pattern detection fails to verify the widening operation is used only in the shift.
Bootstrap and regtest running on x86_64-unknown-linux-gnu. Richard. 2015-01-28 Richard Biener <rguent...@suse.de> PR tree-optimization/64829 * tree-vect-patterns.c (vect_recog_widen_shift_pattern): Check that the shift operand has a single use only. * gcc.dg/vect/pr64829.c: New testcase. Index: gcc/tree-vect-patterns.c =================================================================== --- gcc/tree-vect-patterns.c (revision 220205) +++ gcc/tree-vect-patterns.c (working copy) @@ -1732,9 +1732,11 @@ vect_recog_widen_shift_pattern (vec<gimp if (TREE_CODE (oprnd0) != SSA_NAME || TREE_CODE (oprnd1) != INTEGER_CST) return NULL; - /* Check operand 0: it has to be defined by a type promotion. */ - if (!type_conversion_p (oprnd0, last_stmt, false, &half_type0, &def_stmt0, - &promotion) + /* Check operand 0: it has to be defined by a type promotion and it + should be only used by the shift. */ + if (!has_single_use (oprnd0) + || !type_conversion_p (oprnd0, last_stmt, false, &half_type0, &def_stmt0, + &promotion) || !promotion) return NULL; Index: gcc/testsuite/gcc.dg/vect/pr64829.c =================================================================== --- gcc/testsuite/gcc.dg/vect/pr64829.c (revision 0) +++ gcc/testsuite/gcc.dg/vect/pr64829.c (working copy) @@ -0,0 +1,66 @@ +/* { dg-do compile } */ + +typedef unsigned char Uint8; +typedef int Sint32; +typedef unsigned int Uint32; + +typedef union RMColorDataRef +{ + Uint8* data8; +} RMColorDataRef; + +typedef struct RMColorData +{ + Uint32 dataCount; + RMColorDataRef dataRef; +} RMColorData; + +typedef struct RMColorTable +{ + Uint8 dataCompsOut; + RMColorDataRef dataRef; +} RMColorTable; + +int fail ( const RMColorData * pInColor, + RMColorData * pOutColor, + const RMColorTable * pColorTable ) +{ + Uint32 comp; + Uint8 nCompOut; + + Sint32 result; + + Uint32 interpFrac1, interpFrac2, interpFrac3; + Sint32 val0, val1, val2, val3; + + Uint8 * pOut; + + const Uint8 * pClutData; + const Uint8 * pCornerPoint0; + + Uint8 lastOut[((8) > (4) ? (8) : (4))]; + + pOut = pOutColor->dataRef.data8; + pClutData = pColorTable->dataRef.data8; + + nCompOut = pColorTable->dataCompsOut; + + pCornerPoint0 = pClutData; + + for (comp = 0; comp < nCompOut; comp++) + { + val0 = *pCornerPoint0++; + + result = val0 << 4; + + result += (val1 - val0) * interpFrac1; + result += (val2 - val1) * interpFrac2; + result += (val3 - val2) * interpFrac3; + + *pOut++ = lastOut[comp] = (Uint8)(result >> 4); + } + + return (0); +} + +/* { dg-final { cleanup-tree-dump "vect" } } */