===================================================================
@@ -1335,34 +1335,56 @@ const_binop (enum tree_code code, tree a
return NULL_TREE;
}
if (real && imag)
return build_complex (type, real, imag);
}
if (TREE_CODE (arg1) == VECTOR_CST
&& TREE_CODE (arg2) == VECTOR_CST)
{
- tree type = TREE_TYPE(arg1);
+ tree type = TREE_TYPE (arg1);
int count = TYPE_VECTOR_SUBPARTS (type), i;
tree *elts = XALLOCAVEC (tree, count);
for (i = 0; i < count; i++)
{
tree elem1 = VECTOR_CST_ELT (arg1, i);
tree elem2 = VECTOR_CST_ELT (arg2, i);
elts[i] = const_binop (code, elem1, elem2);
/* It is possible that const_binop cannot handle the given
code and return NULL_TREE */
- if(elts[i] == NULL_TREE)
+ if (elts[i] == NULL_TREE)
+ return NULL_TREE;
+ }
+
+ return build_vector (type, elts);
+ }
+
+ /* Shifts allow a scalar offset for a vector. */
+ if (TREE_CODE (arg1) == VECTOR_CST)
+ {
+ tree type = TREE_TYPE (arg1);
+ int count = TYPE_VECTOR_SUBPARTS (type), i;
+ tree *elts = XALLOCAVEC (tree, count);
+
+ for (i = 0; i < count; i++)
+ {
+ tree elem1 = VECTOR_CST_ELT (arg1, i);
+
+ elts[i] = const_binop (code, elem1, arg2);
+
+ /* It is possible that const_binop cannot handle the given
+ code and return NULL_TREE */
+ if (elts[i] == NULL_TREE)
return NULL_TREE;
}
return build_vector (type, elts);
}
return NULL_TREE;
}
/* Create a sizetype INT_CST node with NUMBER sign extended. KIND
indicates which particular sizetype to create. */
@@ -9852,21 +9874,22 @@ fold_binary_loc (location_t loc,
STRIP_NOPS (arg1);
}
/* Note that TREE_CONSTANT isn't enough: static var addresses are
constant but we can't do arithmetic on them. */
if ((TREE_CODE (arg0) == INTEGER_CST && TREE_CODE (arg1) == INTEGER_CST)
|| (TREE_CODE (arg0) == REAL_CST && TREE_CODE (arg1) == REAL_CST)
|| (TREE_CODE (arg0) == FIXED_CST && TREE_CODE (arg1) == FIXED_CST)
|| (TREE_CODE (arg0) == FIXED_CST && TREE_CODE (arg1) == INTEGER_CST)
|| (TREE_CODE (arg0) == COMPLEX_CST && TREE_CODE (arg1) == COMPLEX_CST)
- || (TREE_CODE (arg0) == VECTOR_CST && TREE_CODE (arg1) == VECTOR_CST))
+ || (TREE_CODE (arg0) == VECTOR_CST && TREE_CODE (arg1) == VECTOR_CST)
+ || (TREE_CODE (arg0) == VECTOR_CST && TREE_CODE (arg1) == INTEGER_CST))
{
if (kind == tcc_binary)
{
/* Make sure type and arg0 have the same saturating flag. */
gcc_assert (TYPE_SATURATING (type)
== TYPE_SATURATING (TREE_TYPE (arg0)));
tem = const_binop (code, arg0, arg1);
}
else if (kind == tcc_comparison)
tem = fold_relational_const (code, type, arg0, arg1);
===================================================================
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-O -fdump-tree-ccp1" } */
+
+typedef int vec __attribute__ ((vector_size (4 * sizeof (int))));
+
+void f (vec *r)
+{
+ vec a = { 2, 3, 4, 5 };
+ *r = (a << 2) >> 1;
+}
+
+/* { dg-final { scan-tree-dump "{ 4, 6, 8, 10 }" "ccp1"} } */
+/* { dg-final { cleanup-tree-dump "ccp1" } } */