aboutsummaryrefslogtreecommitdiff
path: root/gcc/fold-const.c
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@gcc.gnu.org>2005-04-04 10:50:35 +0200
committerJakub Jelinek <jakub@gcc.gnu.org>2005-04-04 10:50:35 +0200
commit4b8d544bc69dca9cd1afe0905a2f7816aa0cdbe3 (patch)
tree1b181db21b4c2c7cc2de3a1c480cc3fa88cec9ef /gcc/fold-const.c
parentedc3676fb0a275db10df71dd63f040e2f2a7f1b6 (diff)
downloadgcc-4b8d544bc69dca9cd1afe0905a2f7816aa0cdbe3.zip
gcc-4b8d544bc69dca9cd1afe0905a2f7816aa0cdbe3.tar.gz
gcc-4b8d544bc69dca9cd1afe0905a2f7816aa0cdbe3.tar.bz2
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
Diffstat (limited to 'gcc/fold-const.c')
-rw-r--r--gcc/fold-const.c14
1 files changed, 11 insertions, 3 deletions
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index 0b9a71f..efbf8ed 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -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