Commit 4b8d544b by Jakub Jelinek

re PR rtl-optimization/16104 (ICE in reload_cse_simplify_operands, at…

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
parent edc3676f
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>
* 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_ptr = POINTER_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);
int inside_unsignedp = TYPE_UNSIGNED (inside_type);
int inter_int = INTEGRAL_TYPE_P (inter_type);
int inter_ptr = POINTER_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);
int inter_unsignedp = TYPE_UNSIGNED (inter_type);
int final_int = INTEGRAL_TYPE_P (type);
int final_ptr = POINTER_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);
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
the outer has a precision not equal to the size of its mode. */
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_float || inter_unsignedp == inside_unsignedp)
&& (inter_float || inter_vec
|| inter_unsignedp == inside_unsignedp)
&& ! (final_prec != GET_MODE_BITSIZE (TYPE_MODE (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));
/* 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:
- 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
final, or
- 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
initial and intermediate types differ. */
if (! inside_float && ! inter_float && ! final_float
&& ! inside_vec && ! inter_vec && ! final_vec
&& (inter_prec > inside_prec || inter_prec > final_prec)
&& ! (inside_int && inter_int
&& inter_unsignedp != inside_unsignedp
......
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>
* g++.dg/template/spec23.C: Fix dg-error text.
......
/* 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;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment