This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] PR middle-end/17055: Casting integer zero to a vector
- From: Roger Sayle <roger at eyesopen dot com>
- To: gcc-patches at gcc dot gnu dot org
- Cc: Jim Wilson <wilson at specifixinc dot com>
- Date: Wed, 8 Sep 2004 12:14:20 -0600 (MDT)
- Subject: [PATCH] PR middle-end/17055: Casting integer zero to a vector
The following is my proposed solution to PR middle-end/17055 which is
an ICE-on-valid known to affect 3.3, 3.4 and mainline.
The problem is that the middle end contains an optimization such that
anything subtracted from itself, i.e. x - x, is equivalent to "zero"
(for floating point test this is guarded by -ffast-math). This holds
for integers, enumerated types, pointers, floats, doubles, complex
types, references, offset types, etc... except vectors! It turns out
the middle-end is unable to cast integer zero to either a integer
vector type or a floating point vector type, hence the ICE.
There are two possible solutions. The first is to disable the "x - x"
constant folding transformation in "fold", by explicitly listing all of
the types that this is valid for. Or alternatively, as done below,
teach the middle-end internally how to cast integer zero to a suitable
VECTOR_CST. The latter is both conceptually simpler, and provides for
better optimization. Note that the conversion of integer zero to a
vector type is performed in "fold_convert", and is therefore independent
of (and doesn't affect/change) the front-end's semantics of vector casts,
which are handled in "convert".
Jim (and/or other vector folks) are you happy with this solution? The
new function build_zero_vector may also be useful elsewhere in the
compiler. I check all calls to build_vector to confirm that this
functionality doesn't already exist.
The following patch has been tested on i686-pc-linux-gnu with a full
"make bootstrap", all default languages, and regression tested with a
top-level "make -k check" with no new failures.
It isn't clear whether this is a regression, so the decision of whether
to backport to 3.4 and/or 3.3 (or WONTFIX the PR) is up to the release
managers.
Ok for mainline?
2004-09-08 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.
* gcc.dg/pr17055-1.c: New test case.
Index: fold-const.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/fold-const.c,v
retrieving revision 1.447
diff -c -3 -p -r1.447 fold-const.c
*** fold-const.c 1 Sep 2004 16:32:39 -0000 1.447
--- fold-const.c 8 Sep 2004 12:54:56 -0000
*************** static tree negate_expr (tree);
*** 89,94 ****
--- 89,95 ----
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);
*************** size_diffop (tree arg0, tree arg1)
*** 1681,1686 ****
--- 1682,1704 ----
arg1, arg0)));
}
+ /* 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. */
*************** fold_convert (tree type, tree arg)
*** 1930,1935 ****
--- 1948,1955 ----
}
else if (TREE_CODE (type) == VECTOR_TYPE)
{
+ if (integer_zerop (arg))
+ return build_zero_vector (type);
if ((INTEGRAL_TYPE_P (orig) || POINTER_TYPE_P (orig))
&& tree_int_cst_equal (TYPE_SIZE (type), TYPE_SIZE (orig)))
return fold (build1 (NOP_EXPR, type, arg));
/* 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;
}
Roger
--
Roger Sayle, E-mail: roger@eyesopen.com
OpenEye Scientific Software, WWW: http://www.eyesopen.com/
Suite 1107, 3600 Cerrillos Road, Tel: (+1) 505-473-7385
Santa Fe, New Mexico, 87507. Fax: (+1) 505-473-0833