The following patch makes fold_ternary no longer make VEC_PERMs valid for the target invalid. As pointed out in the PR we only need to make sure this doesn't happen after vector lowering.
I won't have time to improve on the following patch this week - Marc, can you take over here? Bootstrapped & tested on x86_64-unknown-linux-gnu. Thanks, Richard. 2014-10-30 Richard Biener <rguent...@suse.de> PR middle-end/63666 * fold-const.c: Include optabs.h. (fold_ternary_loc): Only change the VEC_PERM mask if it then is a valid constant permutation on the target. Index: gcc/fold-const.c =================================================================== --- gcc/fold-const.c (revision 216834) +++ gcc/fold-const.c (working copy) @@ -82,6 +82,7 @@ along with GCC; see the file COPYING3. #include "ipa-ref.h" #include "cgraph.h" #include "generic-match.h" +#include "optabs.h" /* Nonzero if we are folding constants inside an initializer; zero otherwise. */ @@ -14311,7 +14331,8 @@ fold_ternary_loc (location_t loc, enum t if (op0 == op1 && !single_arg) changed = true; - if (need_mask_canon && arg2 == op2) + if (need_mask_canon && arg2 == op2 + && can_vec_perm_p (TYPE_MODE (type), false, sel)) { tree *tsel = XALLOCAVEC (tree, nelts); tree eltype = TREE_TYPE (TREE_TYPE (arg2));