+2004-09-09 Roger Sayle <roger@eyesopen.com>
+
+ PR middle-end/17055
+ * fold-const.c (build_zero_vector): New function to construct a
+ vector (either floating point or integer) of zeros.
+ (fold_convert): Internally, enable conversions of integer zero
+ to arbitrary vector types, using the new build_zero_vector.
+
2004-09-09 Roger Sayle <roger@eyesopen.com>
* config/i386/i386.c (ix86_expand_ashlsi3_const): New function to
static tree split_tree (tree, enum tree_code, tree *, tree *, tree *, int);
static tree associate_trees (tree, tree, enum tree_code, tree);
static tree const_binop (enum tree_code, tree, tree, int);
+static tree build_zero_vector (tree);
static tree fold_convert_const (enum tree_code, tree, tree);
static enum tree_code invert_tree_comparison (enum tree_code, bool);
static enum comparison_code comparison_to_compcode (enum tree_code);
arg1, arg0)));
}
\f
+/* Construct a vector of zero elements of vector type TYPE. */
+
+static tree
+build_zero_vector (tree type)
+{
+ tree elem, list;
+ int i, units;
+
+ elem = fold_convert_const (NOP_EXPR, TREE_TYPE (type), integer_zero_node);
+ units = TYPE_VECTOR_SUBPARTS (type);
+
+ list = NULL_TREE;
+ for (i = 0; i < units; i++)
+ list = tree_cons (NULL_TREE, elem, list);
+ return build_vector (type, list);
+}
+
/* Attempt to fold type conversion operation CODE of expression ARG1 to
type TYPE. If no simplification can be done return NULL_TREE. */
}
case VECTOR_TYPE:
+ if (integer_zerop (arg))
+ return build_zero_vector (type);
gcc_assert (tree_int_cst_equal (TYPE_SIZE (type), TYPE_SIZE (orig)));
gcc_assert (INTEGRAL_TYPE_P (orig) || POINTER_TYPE_P (orig)
|| TREE_CODE (orig) == VECTOR_TYPE);
--- /dev/null
+/* PR middle-end/17055. */
+/* { dg-do compile } */
+/* { dg-options "-O2 -ffast-math" } */
+
+/* This test used to abort, beacuse we do an "integer" fold to zero, i.e.
+ x - x = (T)0 where T is the type of x. Unfortunately, fold_convert
+ was unable to convert integer_zero_node to the appropriate vector type. */
+
+typedef float v4sf __attribute__((vector_size(16)));
+typedef int v4si __attribute__((vector_size(16)));
+
+v4sf ivf, ovf;
+v4si ivi, ovi;
+
+void testf (void)
+{
+ ovf = ivf - ivf;
+}
+
+void testi (void)
+{
+ ovi = ivi - ivi;
+}
+