mirror of git://gcc.gnu.org/git/gcc.git
re PR rtl-optimization/16104 (ICE in reload_cse_simplify_operands, at postreload.c:378 with SSE2 code on -O2)
PR rtl-optimization/16104 * fold-const.c (fold_unary): Fix folding of vector conversions. * gcc.c-torture/execute/20050316-1.c: New test. From-SVN: r97529
This commit is contained in:
parent
edc3676fb0
commit
4b8d544bc6
|
@ -1,3 +1,9 @@
|
||||||
|
2005-04-04 Richard Henderson <rth@redhat.com>
|
||||||
|
Jakub Jelinek <jakub@redhat.com>
|
||||||
|
|
||||||
|
PR rtl-optimization/16104
|
||||||
|
* fold-const.c (fold_unary): Fix folding of vector conversions.
|
||||||
|
|
||||||
2005-04-04 Richard Sandiford <rsandifo@redhat.com>
|
2005-04-04 Richard Sandiford <rsandifo@redhat.com>
|
||||||
|
|
||||||
* config.gcc (xstormy16-*-elf): Set extra_options.
|
* config.gcc (xstormy16-*-elf): Set extra_options.
|
||||||
|
|
|
@ -6772,16 +6772,19 @@ fold_unary (enum tree_code code, tree type, tree op0)
|
||||||
int inside_int = INTEGRAL_TYPE_P (inside_type);
|
int inside_int = INTEGRAL_TYPE_P (inside_type);
|
||||||
int inside_ptr = POINTER_TYPE_P (inside_type);
|
int inside_ptr = POINTER_TYPE_P (inside_type);
|
||||||
int inside_float = FLOAT_TYPE_P (inside_type);
|
int inside_float = FLOAT_TYPE_P (inside_type);
|
||||||
|
int inside_vec = TREE_CODE (inside_type) == VECTOR_TYPE;
|
||||||
unsigned int inside_prec = TYPE_PRECISION (inside_type);
|
unsigned int inside_prec = TYPE_PRECISION (inside_type);
|
||||||
int inside_unsignedp = TYPE_UNSIGNED (inside_type);
|
int inside_unsignedp = TYPE_UNSIGNED (inside_type);
|
||||||
int inter_int = INTEGRAL_TYPE_P (inter_type);
|
int inter_int = INTEGRAL_TYPE_P (inter_type);
|
||||||
int inter_ptr = POINTER_TYPE_P (inter_type);
|
int inter_ptr = POINTER_TYPE_P (inter_type);
|
||||||
int inter_float = FLOAT_TYPE_P (inter_type);
|
int inter_float = FLOAT_TYPE_P (inter_type);
|
||||||
|
int inter_vec = TREE_CODE (inter_type) == VECTOR_TYPE;
|
||||||
unsigned int inter_prec = TYPE_PRECISION (inter_type);
|
unsigned int inter_prec = TYPE_PRECISION (inter_type);
|
||||||
int inter_unsignedp = TYPE_UNSIGNED (inter_type);
|
int inter_unsignedp = TYPE_UNSIGNED (inter_type);
|
||||||
int final_int = INTEGRAL_TYPE_P (type);
|
int final_int = INTEGRAL_TYPE_P (type);
|
||||||
int final_ptr = POINTER_TYPE_P (type);
|
int final_ptr = POINTER_TYPE_P (type);
|
||||||
int final_float = FLOAT_TYPE_P (type);
|
int final_float = FLOAT_TYPE_P (type);
|
||||||
|
int final_vec = TREE_CODE (type) == VECTOR_TYPE;
|
||||||
unsigned int final_prec = TYPE_PRECISION (type);
|
unsigned int final_prec = TYPE_PRECISION (type);
|
||||||
int final_unsignedp = TYPE_UNSIGNED (type);
|
int final_unsignedp = TYPE_UNSIGNED (type);
|
||||||
|
|
||||||
|
@ -6801,12 +6804,15 @@ fold_unary (enum tree_code code, tree type, tree op0)
|
||||||
since then we sometimes need the inner conversion. Likewise if
|
since then we sometimes need the inner conversion. Likewise if
|
||||||
the outer has a precision not equal to the size of its mode. */
|
the outer has a precision not equal to the size of its mode. */
|
||||||
if ((((inter_int || inter_ptr) && (inside_int || inside_ptr))
|
if ((((inter_int || inter_ptr) && (inside_int || inside_ptr))
|
||||||
|| (inter_float && inside_float))
|
|| (inter_float && inside_float)
|
||||||
|
|| (inter_vec && inside_vec))
|
||||||
&& inter_prec >= inside_prec
|
&& inter_prec >= inside_prec
|
||||||
&& (inter_float || inter_unsignedp == inside_unsignedp)
|
&& (inter_float || inter_vec
|
||||||
|
|| inter_unsignedp == inside_unsignedp)
|
||||||
&& ! (final_prec != GET_MODE_BITSIZE (TYPE_MODE (type))
|
&& ! (final_prec != GET_MODE_BITSIZE (TYPE_MODE (type))
|
||||||
&& TYPE_MODE (type) == TYPE_MODE (inter_type))
|
&& TYPE_MODE (type) == TYPE_MODE (inter_type))
|
||||||
&& ! final_ptr)
|
&& ! final_ptr
|
||||||
|
&& (! final_vec || inter_prec == inside_prec))
|
||||||
return fold_build1 (code, type, TREE_OPERAND (op0, 0));
|
return fold_build1 (code, type, TREE_OPERAND (op0, 0));
|
||||||
|
|
||||||
/* If we have a sign-extension of a zero-extended value, we can
|
/* If we have a sign-extension of a zero-extended value, we can
|
||||||
|
@ -6818,6 +6824,7 @@ fold_unary (enum tree_code code, tree type, tree op0)
|
||||||
|
|
||||||
/* Two conversions in a row are not needed unless:
|
/* Two conversions in a row are not needed unless:
|
||||||
- some conversion is floating-point (overstrict for now), or
|
- some conversion is floating-point (overstrict for now), or
|
||||||
|
- some conversion is a vector (overstrict for now), or
|
||||||
- the intermediate type is narrower than both initial and
|
- the intermediate type is narrower than both initial and
|
||||||
final, or
|
final, or
|
||||||
- the intermediate type and innermost type differ in signedness,
|
- the intermediate type and innermost type differ in signedness,
|
||||||
|
@ -6827,6 +6834,7 @@ fold_unary (enum tree_code code, tree type, tree op0)
|
||||||
- the final type is a pointer type and the precisions of the
|
- the final type is a pointer type and the precisions of the
|
||||||
initial and intermediate types differ. */
|
initial and intermediate types differ. */
|
||||||
if (! inside_float && ! inter_float && ! final_float
|
if (! inside_float && ! inter_float && ! final_float
|
||||||
|
&& ! inside_vec && ! inter_vec && ! final_vec
|
||||||
&& (inter_prec > inside_prec || inter_prec > final_prec)
|
&& (inter_prec > inside_prec || inter_prec > final_prec)
|
||||||
&& ! (inside_int && inter_int
|
&& ! (inside_int && inter_int
|
||||||
&& inter_unsignedp != inside_unsignedp
|
&& inter_unsignedp != inside_unsignedp
|
||||||
|
|
|
@ -1,3 +1,8 @@
|
||||||
|
2005-04-04 Jakub Jelinek <jakub@redhat.com>
|
||||||
|
|
||||||
|
PR rtl-optimization/16104
|
||||||
|
* gcc.c-torture/execute/20050316-1.c: New test.
|
||||||
|
|
||||||
2005-04-04 Nathan Sidwell <nathan@codesourcery.com>
|
2005-04-04 Nathan Sidwell <nathan@codesourcery.com>
|
||||||
|
|
||||||
* g++.dg/template/spec23.C: Fix dg-error text.
|
* g++.dg/template/spec23.C: Fix dg-error text.
|
||||||
|
|
|
@ -0,0 +1,69 @@
|
||||||
|
/* PR rtl-optimization/16104 */
|
||||||
|
|
||||||
|
extern void abort (void);
|
||||||
|
|
||||||
|
typedef int V2SI __attribute__ ((vector_size (8)));
|
||||||
|
typedef unsigned int V2USI __attribute__ ((vector_size (8)));
|
||||||
|
typedef short V2HI __attribute__ ((vector_size (4)));
|
||||||
|
typedef unsigned int V2UHI __attribute__ ((vector_size (4)));
|
||||||
|
|
||||||
|
int
|
||||||
|
test1 (void)
|
||||||
|
{
|
||||||
|
return (long long) (V2SI) 0LL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
test2 (V2SI x)
|
||||||
|
{
|
||||||
|
return (long long) x;
|
||||||
|
}
|
||||||
|
|
||||||
|
V2SI
|
||||||
|
test3 (void)
|
||||||
|
{
|
||||||
|
return (V2SI) (long long) (int) (V2HI) 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
V2SI
|
||||||
|
test4 (V2HI x)
|
||||||
|
{
|
||||||
|
return (V2SI) (long long) (int) x;
|
||||||
|
}
|
||||||
|
|
||||||
|
V2SI
|
||||||
|
test5 (V2USI x)
|
||||||
|
{
|
||||||
|
return (V2SI) x;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main (void)
|
||||||
|
{
|
||||||
|
if (sizeof (short) != 2 || sizeof (int) != 4 || sizeof (long long) != 8)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (test1 () != 0)
|
||||||
|
abort ();
|
||||||
|
|
||||||
|
V2SI x = { 2, 2 };
|
||||||
|
if (test2 (x) != 2)
|
||||||
|
abort ();
|
||||||
|
|
||||||
|
union { V2SI x; int y[2]; V2USI z; long long l; } u;
|
||||||
|
u.x = test3 ();
|
||||||
|
if (u.y[0] != 0 || u.y[1] != 0)
|
||||||
|
abort ();
|
||||||
|
|
||||||
|
V2HI y = { 4, 4 };
|
||||||
|
union { V2SI x; long long y; } v;
|
||||||
|
v.x = test4 (y);
|
||||||
|
if (v.y != 0x40004)
|
||||||
|
abort ();
|
||||||
|
|
||||||
|
V2USI z = { 6, 6 };
|
||||||
|
u.x = test5 (z);
|
||||||
|
if (u.y[0] != 6 || u.y[1] != 6)
|
||||||
|
abort ();
|
||||||
|
return 0;
|
||||||
|
}
|
Loading…
Reference in New Issue