Hi! Unlike narrowing conversion that needs cvt_type, when widening conversion needs cvt_type, we want to actually convert stuff (possibly using multiple steps) to cvt_type and only at the end convert to the vectype_out type. Without this patch we'd attempt on the vect testcases mentioned in the PR on arm first converted V?HI mode to V?SF using an integer unpacking, and then finally do a FLOAT_EXPR conversion from V?SF mode to V?SI. For narrowing conversions the code did the right thing, there cvt_type conversion is done first to vec_dest temporary and then possibly multistep demotion using vec_dest vector.
Bootstrapped/regtested on x86_64-linux and i686-linux, additionally regtested on x86_64-linux with -mavx and -msse4 and tested on the few testcases with cross to arm. Ok for trunk? 2012-01-20 Jakub Jelinek <ja...@redhat.com> PR tree-optimization/51914 * tree-vect-stmts.c (vectorizable_conversion): For cvt_type && modifier == WIDEN, put temporary with cvt_type at the beginning of vec_dsts and set vec_dest to temporary with vectype_out. --- gcc/tree-vect-stmts.c.jj 2011-12-27 11:39:49.000000000 +0100 +++ gcc/tree-vect-stmts.c 2012-01-20 12:27:00.932766457 +0100 @@ -2420,7 +2420,9 @@ vectorizable_conversion (gimple stmt, gi from supportable_*_operation, and store them in the correct order for future use in vect_create_vectorized_*_stmts (). */ vec_dsts = VEC_alloc (tree, heap, multi_step_cvt + 1); - vec_dest = vect_create_destination_var (scalar_dest, vectype_out); + vec_dest = vect_create_destination_var (scalar_dest, + (cvt_type && modifier == WIDEN) + ? cvt_type : vectype_out); VEC_quick_push (tree, vec_dsts, vec_dest); if (multi_step_cvt) @@ -2435,7 +2437,9 @@ vectorizable_conversion (gimple stmt, gi } if (cvt_type) - vec_dest = vect_create_destination_var (scalar_dest, cvt_type); + vec_dest = vect_create_destination_var (scalar_dest, + modifier == WIDEN + ? vectype_out : cvt_type); if (!slp_node) { Jakub