summaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>2011-12-10 20:43:03 +0000
committerrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>2011-12-10 20:43:03 +0000
commitd9198d8536af4470fffc9d1e70626d106d8a8ac7 (patch)
tree64952c5ea5b975ebfc52549bce82d112fa6ee2eb /gcc
parentde44e2b0d694d2d0f596cdb2cd88624106650ed5 (diff)
downloadgcc-d9198d8536af4470fffc9d1e70626d106d8a8ac7.tar.gz
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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@182192 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/expr.c17
-rw-r--r--gcc/optabs.c5
3 files changed, 26 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 3490874dd46..885f535b671 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,11 @@
2011-12-10 Richard Henderson <rth@redhat.com>
+ * 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.
+
+2011-12-10 Richard Henderson <rth@redhat.com>
+
* genmodes.c (struct mode_data): Remove wider_2x member.
(blank_mode): Adjust initializer.
(calc_wider_mode): Use XALLOCAVEC.
diff --git a/gcc/expr.c b/gcc/expr.c
index b2166bdac81..aa78468a96b 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -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;
diff --git a/gcc/optabs.c b/gcc/optabs.c
index 3f50177aea8..2c3a6405ab9 100644
--- a/gcc/optabs.c
+++ b/gcc/optabs.c
@@ -7038,7 +7038,8 @@ expand_vec_perm (enum machine_mode mode, rtx v0, rtx v1, rtx sel, rtx target)
}
/* If the input is a constant, expand it specially. */
- if (CONSTANT_P (sel))
+ gcc_assert (GET_MODE_CLASS (GET_MODE (sel)) == MODE_VECTOR_INT);
+ if (GET_CODE (sel) == CONST_VECTOR)
{
icode = direct_optab_handler (vec_perm_const_optab, mode);
if (icode != CODE_FOR_nothing)
@@ -7056,7 +7057,7 @@ expand_vec_perm (enum machine_mode mode, rtx v0, rtx v1, rtx sel, rtx target)
{
unsigned int j, this_e;
- this_e = INTVAL (XVECEXP (sel, 0, i));
+ this_e = INTVAL (CONST_VECTOR_ELT (sel, i));
this_e &= 2 * e - 1;
this_e *= u;