diff options
author | rguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2014-11-09 11:27:00 +0000 |
---|---|---|
committer | rguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2014-11-09 11:27:00 +0000 |
commit | c434260f696108b748a69fbc9bae8a0826492d6f (patch) | |
tree | 7253af53d7de307a8f840ca8e90e5e0acc5fa293 /gcc/fold-const.c | |
parent | ec9bdbf76d1c412a3b8e3afb8ff9347665ff53f1 (diff) | |
download | gcc-c434260f696108b748a69fbc9bae8a0826492d6f.tar.gz |
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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@217260 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/fold-const.c')
-rw-r--r-- | gcc/fold-const.c | 88 |
1 files changed, 0 insertions, 88 deletions
diff --git a/gcc/fold-const.c b/gcc/fold-const.c index c712213444c..13faf0c524a 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -7692,94 +7692,6 @@ fold_unary_loc (location_t loc, enum tree_code code, tree type, tree op0) constant_boolean_node (false, type)); } - /* Handle cases of two conversions in a row. */ - if (CONVERT_EXPR_P (op0)) - { - tree inside_type = TREE_TYPE (TREE_OPERAND (op0, 0)); - 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); - - /* 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 (TYPE_MAIN_VARIANT (inside_type) == TYPE_MAIN_VARIANT (type) - && (((inter_int || inter_ptr) && final_int) - || (inter_float && final_float)) - && inter_prec >= final_prec) - return fold_build1_loc (loc, code, type, TREE_OPERAND (op0, 0)); - - /* 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)) - return fold_build1_loc (loc, code, type, TREE_OPERAND (op0, 0)); - - /* 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)) - return fold_build1_loc (loc, code, type, TREE_OPERAND (op0, 0)); - - /* 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))) - return fold_build1_loc (loc, code, type, TREE_OPERAND (op0, 0)); - } - /* Handle (T *)&A.B.C for A being of type T and B and C living at offset zero. This occurs frequently in C++ upcasting and then accessing the base. */ |