summaryrefslogtreecommitdiff
path: root/gcc/fold-const.c
diff options
context:
space:
mode:
authorrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>2014-11-09 11:27:00 +0000
committerrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>2014-11-09 11:27:00 +0000
commitc434260f696108b748a69fbc9bae8a0826492d6f (patch)
tree7253af53d7de307a8f840ca8e90e5e0acc5fa293 /gcc/fold-const.c
parentec9bdbf76d1c412a3b8e3afb8ff9347665ff53f1 (diff)
downloadgcc-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.c88
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. */