From: Jakub Jelinek Date: Wed, 19 Jan 2005 09:27:23 +0000 (+0100) Subject: re PR c/17297 (ICE with FP vector constructor containing qnan calculation) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=e89be13bdf98cff1cbbdd9490e4b4d5e20e68baf;p=gcc.git re PR c/17297 (ICE with FP vector constructor containing qnan calculation) PR c/17297 * c-typeck.c (digest_init): Only call build_vector if all constructor elements are *_CST nodes. * gimplify.c (gimplify_init_constructor): Likewise. * gcc.c-torture/compile/20050113-1.c: New testcase. PR middle-end/19164 * c-typeck.c (digest_init): Only call build_vector if inside_init is a CONSTRUCTOR. * gcc.dg/20050113-1.c: New testcase. From-SVN: r93891 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index b210329d51c..ccb0faa7529 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +2005-01-19 Jakub Jelinek + + PR c/17297 + * c-typeck.c (digest_init): Only call build_vector if all constructor + elements are *_CST nodes. + * gimplify.c (gimplify_init_constructor): Likewise. + + PR middle-end/19164 + * c-typeck.c (digest_init): Only call build_vector if inside_init + is a CONSTRUCTOR. + 2005-01-18 Tobias Schl"uter * toplev.c (init_asm_output): Remove dead #ifdef. diff --git a/gcc/c-typeck.c b/gcc/c-typeck.c index f26e3868813..186cb62bd2a 100644 --- a/gcc/c-typeck.c +++ b/gcc/c-typeck.c @@ -4143,18 +4143,32 @@ digest_init (tree type, tree init, bool strict_string, int require_constant) /* Build a VECTOR_CST from a *constant* vector constructor. If the vector constructor is not constant (e.g. {1,2,3,foo()}) then punt below and handle as a constructor. */ - if (code == VECTOR_TYPE - && TREE_CODE (TREE_TYPE (inside_init)) == VECTOR_TYPE - && vector_types_convertible_p (TREE_TYPE (inside_init), type) - && TREE_CONSTANT (inside_init)) - { - if (TREE_CODE (inside_init) == VECTOR_CST - && comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (inside_init)), - TYPE_MAIN_VARIANT (type))) - return inside_init; - else - return build_vector (type, CONSTRUCTOR_ELTS (inside_init)); - } + if (code == VECTOR_TYPE + && TREE_CODE (TREE_TYPE (inside_init)) == VECTOR_TYPE + && vector_types_convertible_p (TREE_TYPE (inside_init), type) + && TREE_CONSTANT (inside_init)) + { + if (TREE_CODE (inside_init) == VECTOR_CST + && comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (inside_init)), + TYPE_MAIN_VARIANT (type))) + return inside_init; + + if (TREE_CODE (inside_init) == CONSTRUCTOR) + { + tree link; + + /* Iterate through elements and check if all constructor + elements are *_CSTs. */ + for (link = CONSTRUCTOR_ELTS (inside_init); + link; + link = TREE_CHAIN (link)) + if (! CONSTANT_CLASS_P (TREE_VALUE (link))) + break; + + if (link == NULL) + return build_vector (type, CONSTRUCTOR_ELTS (inside_init)); + } + } /* Any type can be initialized from an expression of the same type, optionally with braces. */ diff --git a/gcc/gimplify.c b/gcc/gimplify.c index d86379ca2c8..12822c47055 100644 --- a/gcc/gimplify.c +++ b/gcc/gimplify.c @@ -2761,20 +2761,33 @@ gimplify_init_constructor (tree *expr_p, tree *pre_p, case VECTOR_TYPE: /* Go ahead and simplify constant constructors to VECTOR_CST. */ if (TREE_CONSTANT (ctor)) - TREE_OPERAND (*expr_p, 1) = build_vector (type, elt_list); - else { - /* Vector types use CONSTRUCTOR all the way through gimple - compilation as a general initializer. */ - for (; elt_list; elt_list = TREE_CHAIN (elt_list)) + tree tem; + + /* Even when ctor is constant, it might contain non-*_CST + elements (e.g. { 1.0/0.0 - 1.0/0.0, 0.0 }) and those don't + belong into VECTOR_CST nodes. */ + for (tem = elt_list; tem; tem = TREE_CHAIN (tem)) + if (! CONSTANT_CLASS_P (TREE_VALUE (tem))) + break; + + if (! tem) { - enum gimplify_status tret; - tret = gimplify_expr (&TREE_VALUE (elt_list), pre_p, post_p, - is_gimple_val, fb_rvalue); - if (tret == GS_ERROR) - ret = GS_ERROR; + TREE_OPERAND (*expr_p, 1) = build_vector (type, elt_list); + break; } } + + /* Vector types use CONSTRUCTOR all the way through gimple + compilation as a general initializer. */ + for (; elt_list; elt_list = TREE_CHAIN (elt_list)) + { + enum gimplify_status tret; + tret = gimplify_expr (&TREE_VALUE (elt_list), pre_p, post_p, + is_gimple_val, fb_rvalue); + if (tret == GS_ERROR) + ret = GS_ERROR; + } break; default: diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 2657d130752..922b4287d90 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,11 @@ +2005-01-19 Jakub Jelinek + + PR c/17297 + * gcc.c-torture/compile/20050113-1.c: New testcase. + + PR middle-end/19164 + * gcc.dg/20050113-1.c: New testcase. + 2005-01-19 Dorit Naishlos * gcc.dg/vect/vect-85.c: Add comment. diff --git a/gcc/testsuite/gcc.c-torture/compile/20050113-1.c b/gcc/testsuite/gcc.c-torture/compile/20050113-1.c new file mode 100644 index 00000000000..6e36ed6fd7c --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/compile/20050113-1.c @@ -0,0 +1,16 @@ +/* PR c/17297 */ + +typedef float V2SF __attribute__ ((vector_size (8))); + +int test0 (V2SF, V2SF); + +int +main (void) +{ + V2SF a = (V2SF) {1.0f/0.0f - 1.0f/0.0f, 1.0f/0.0f - 1.0f/0.0f}; + V2SF b = (V2SF) {567.345, 1984.0}; + int i; + + i = test0 (a, b); + return i; +} diff --git a/gcc/testsuite/gcc.dg/20050113-1.c b/gcc/testsuite/gcc.dg/20050113-1.c new file mode 100644 index 00000000000..e7f69e36641 --- /dev/null +++ b/gcc/testsuite/gcc.dg/20050113-1.c @@ -0,0 +1,6 @@ +/* PR middle-end/19164 */ +/* { dg-do compile { target i?86-*-* x86_64-*-* } } */ +/* { dg-options "-mmmx" } */ + +typedef short int V __attribute__ ((vector_size (8))); +static V v = (V) 0x00FF00FF00FF00FFLL; /* { dg-error "is not constant" } */