diff options
author | Richard Henderson <rth@redhat.com> | 2011-12-10 12:43:03 -0800 |
---|---|---|
committer | Richard Henderson <rth@gcc.gnu.org> | 2011-12-10 12:43:03 -0800 |
commit | ccdfb0e2c6ad7c93ca7657a79a773f0af8f40be7 (patch) | |
tree | 64952c5ea5b975ebfc52549bce82d112fa6ee2eb /gcc/expr.c | |
parent | a7de2c2a71940a25408c1320498c1c1ca2472313 (diff) | |
download | gcc-ccdfb0e2c6ad7c93ca7657a79a773f0af8f40be7.zip gcc-ccdfb0e2c6ad7c93ca7657a79a773f0af8f40be7.tar.gz gcc-ccdfb0e2c6ad7c93ca7657a79a773f0af8f40be7.tar.bz2 |
Force the creation of a CONST_VECTOR for expand_vec_perm.
* expr.c (expand_expr_real_2) [VEC_PERM_EXPR]: Avoid passing a
CONST_INT to expand_vec_perm as the selector.
* optabs.c (expand_vec_perm): Assert the selector is of a proper mode.
From-SVN: r182192
Diffstat (limited to 'gcc/expr.c')
-rw-r--r-- | gcc/expr.c | 17 |
1 files changed, 17 insertions, 0 deletions
@@ -8716,6 +8716,23 @@ expand_expr_real_2 (sepops ops, rtx target, enum machine_mode tmode, case VEC_PERM_EXPR: expand_operands (treeop0, treeop1, target, &op0, &op1, EXPAND_NORMAL); op2 = expand_normal (treeop2); + + /* Careful here: if the target doesn't support integral vector modes, + a constant selection vector could wind up smooshed into a normal + integral constant. */ + if (CONSTANT_P (op2) && GET_CODE (op2) != CONST_VECTOR) + { + tree sel_type = TREE_TYPE (treeop2); + enum machine_mode vmode + = mode_for_vector (TYPE_MODE (TREE_TYPE (sel_type)), + TYPE_VECTOR_SUBPARTS (sel_type)); + gcc_assert (GET_MODE_CLASS (vmode) == MODE_VECTOR_INT); + op2 = simplify_subreg (vmode, op2, TYPE_MODE (sel_type), 0); + gcc_assert (op2 && GET_CODE (op2) == CONST_VECTOR); + } + else + gcc_assert (GET_MODE_CLASS (GET_MODE (op2)) == MODE_VECTOR_INT); + temp = expand_vec_perm (mode, op0, op1, op2, target); gcc_assert (temp); return temp; |