diff options
author | Richard Biener <rguenther@suse.de> | 2014-11-09 11:27:00 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2014-11-09 11:27:00 +0000 |
commit | 1e51d0a29dbfebe6c0df58739562644c1a50f3c3 (patch) | |
tree | 7253af53d7de307a8f840ca8e90e5e0acc5fa293 /gcc/tree-ssa-forwprop.c | |
parent | 8dcd07febcafc7fd8a62d86f88aca1f6724f8a24 (diff) | |
download | gcc-1e51d0a29dbfebe6c0df58739562644c1a50f3c3.zip gcc-1e51d0a29dbfebe6c0df58739562644c1a50f3c3.tar.gz gcc-1e51d0a29dbfebe6c0df58739562644c1a50f3c3.tar.bz2 |
match.pd: Add patterns convering two conversions in a row from fold-const.c.
2014-11-09 Richard Biener <rguenther@suse.de>
* match.pd: Add patterns convering two conversions in a row
from fold-const.c.
* fold-const.c (fold_unary_loc): Remove them here.
* tree-ssa-forwprop.c (combine_conversions): Likewise.
* genmatch.c (dt_node::gen_kids): Check whether we may
follow SSA use-def chains.
* g++.dg/cpp0x/constexpr-reinterpret1.C: XFAIL.
* gcc.dg/tree-ssa/pr21031.c: XFAIL.
From-SVN: r217260
Diffstat (limited to 'gcc/tree-ssa-forwprop.c')
-rw-r--r-- | gcc/tree-ssa-forwprop.c | 89 |
1 files changed, 0 insertions, 89 deletions
diff --git a/gcc/tree-ssa-forwprop.c b/gcc/tree-ssa-forwprop.c index 58f3898..2f4998c 100644 --- a/gcc/tree-ssa-forwprop.c +++ b/gcc/tree-ssa-forwprop.c @@ -2386,109 +2386,20 @@ combine_conversions (gimple_stmt_iterator *gsi) tree inside_type = TREE_TYPE (defop0); tree inter_type = TREE_TYPE (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); /* Don't propagate ssa names that occur in abnormal phis. */ if (TREE_CODE (defop0) == SSA_NAME && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (defop0)) return 0; - /* In addition to the cases of two conversions in a row - handled below, if we are converting something to its own - type via an object of identical or wider precision, neither - conversion is needed. */ - if (useless_type_conversion_p (type, inside_type) - && (((inter_int || inter_ptr) && final_int) - || (inter_float && final_float)) - && inter_prec >= final_prec) - { - gimple_assign_set_rhs1 (stmt, unshare_expr (defop0)); - gimple_assign_set_rhs_code (stmt, TREE_CODE (defop0)); - update_stmt (stmt); - return remove_prop_source_from_use (op0) ? 2 : 1; - } - - /* Likewise, if the intermediate and initial types are either both - float or both integer, we don't need the middle conversion if the - former is wider than the latter and doesn't change the signedness - (for integers). Avoid this if the final type is a pointer since - then we sometimes need the middle conversion. Likewise if the - final type has a precision not equal to the size of its mode. */ - if (((inter_int && inside_int) - || (inter_float && inside_float) - || (inter_vec && inside_vec)) - && inter_prec >= inside_prec - && (inter_float || inter_vec - || inter_unsignedp == inside_unsignedp) - && ! (final_prec != GET_MODE_PRECISION (TYPE_MODE (type)) - && TYPE_MODE (type) == TYPE_MODE (inter_type)) - && ! final_ptr - && (! final_vec || inter_prec == inside_prec)) - { - gimple_assign_set_rhs1 (stmt, defop0); - update_stmt (stmt); - return remove_prop_source_from_use (op0) ? 2 : 1; - } - - /* If we have a sign-extension of a zero-extended value, we can - replace that by a single zero-extension. Likewise if the - final conversion does not change precision we can drop the - intermediate conversion. */ - if (inside_int && inter_int && final_int - && ((inside_prec < inter_prec && inter_prec < final_prec - && inside_unsignedp && !inter_unsignedp) - || final_prec == inter_prec)) - { - gimple_assign_set_rhs1 (stmt, defop0); - update_stmt (stmt); - return remove_prop_source_from_use (op0) ? 2 : 1; - } - - /* 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, - and the outermost type is wider than the intermediate, or - - the initial type is a pointer type and the precisions of the - intermediate and final types differ, or - - 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 - && inter_prec < final_prec) - && ((inter_unsignedp && inter_prec > inside_prec) - == (final_unsignedp && final_prec > inter_prec)) - && ! (inside_ptr && inter_prec != final_prec) - && ! (final_ptr && inside_prec != inter_prec) - && ! (final_prec != GET_MODE_PRECISION (TYPE_MODE (type)) - && TYPE_MODE (type) == TYPE_MODE (inter_type))) - { - gimple_assign_set_rhs1 (stmt, defop0); - update_stmt (stmt); - return remove_prop_source_from_use (op0) ? 2 : 1; - } - /* A truncation to an unsigned type should be canonicalized as bitwise and of a mask. */ if (final_int && inter_int && inside_int |