The following patch is to avoid needlessly recursing to generic_simplify from fold_unary when we ask to perform constant folding. Similar fold_binary is currently entered to constant fold from gimple/generic_simplify and will do extra work in case it isn't able to fold the constant operation.
To mitigate that (and still missing the fold_ternary case - to be done as followup in case this gets accepted at this point) - I factor and export a const_unop and provide an exported const_binop which also knows to dispatch to fold_relational_const. These API are intended to provide pure constant folding (that is, all-constant operands, not only a constant result). Bootstrapped and tested on x86_64-unknown-linux-gnu, ok at this point? (it should fix a tiny compile-time regression) I'll followup with a const_ternop (better name?) if ok. Thanks, Richard. 2014-11-19 Richard Biener <rguent...@suse.de> * fold-const.h (const_unop): Declare. (const_binop): Likewise. * fold-const.c (const_binop): Export overload that expects a type parameter and dispatches to fold_relational_const as well. Check both operand kinds for guarding the transforms. (const_unop): New function, with constant folding from fold_unary_loc. (fold_unary_loc): Dispatch to const_unop for tcc_constant operand. Remove constant folding done there from the simplifications. (fold_binary_loc): Check for constants using CONSTANT_CLASS_P. (fold_negate_expr): Remove dead code from the REAL_CST case. Avoid building garbage in the COMPLEX_CST case. * gimple-match-head.c (gimple_resimplify1): Dispatch to const_unop. (gimple_resimplify2): Dispatch to const_binop. (gimple_simplify): Likewise. Index: gcc/fold-const.c =================================================================== *** gcc/fold-const.c.orig 2014-11-18 15:16:04.263514898 +0100 --- gcc/fold-const.c 2014-11-19 13:22:24.866032427 +0100 *************** static bool negate_expr_p (tree); *** 115,121 **** static tree negate_expr (tree); static tree split_tree (tree, enum tree_code, tree *, tree *, tree *, int); static tree associate_trees (location_t, tree, tree, enum tree_code, tree); - static tree const_binop (enum tree_code, tree, tree); static enum comparison_code comparison_to_compcode (enum tree_code); static enum tree_code compcode_to_comparison (enum comparison_code); static int operand_equal_for_comparison_p (tree, tree, tree); --- 115,120 ---- *************** static tree fold_negate_const (tree, tre *** 156,161 **** --- 155,163 ---- static tree fold_not_const (const_tree, tree); static tree fold_relational_const (enum tree_code, tree, tree, tree); static tree fold_convert_const (enum tree_code, tree, tree); + static tree fold_view_convert_expr (tree, tree); + static bool vec_cst_ctor_to_array (tree, tree *); + /* Return EXPR_LOCATION of T if it is not UNKNOWN_LOCATION. Otherwise, return LOC. */ *************** fold_negate_expr (location_t loc, tree t *** 561,570 **** case REAL_CST: tem = fold_negate_const (t, type); ! /* Two's complement FP formats, such as c4x, may overflow. */ ! if (!TREE_OVERFLOW (tem) || !flag_trapping_math) ! return tem; ! break; case FIXED_CST: tem = fold_negate_const (t, type); --- 563,569 ---- case REAL_CST: tem = fold_negate_const (t, type); ! return tem; case FIXED_CST: tem = fold_negate_const (t, type); *************** fold_negate_expr (location_t loc, tree t *** 572,584 **** case COMPLEX_CST: { ! tree rpart = negate_expr (TREE_REALPART (t)); ! tree ipart = negate_expr (TREE_IMAGPART (t)); ! ! if ((TREE_CODE (rpart) == REAL_CST ! && TREE_CODE (ipart) == REAL_CST) ! || (TREE_CODE (rpart) == INTEGER_CST ! && TREE_CODE (ipart) == INTEGER_CST)) return build_complex (type, rpart, ipart); } break; --- 571,579 ---- case COMPLEX_CST: { ! tree rpart = fold_negate_expr (loc, TREE_REALPART (t)); ! tree ipart = fold_negate_expr (loc, TREE_IMAGPART (t)); ! if (rpart && ipart) return build_complex (type, rpart, ipart); } break; *************** const_binop (enum tree_code code, tree a *** 1135,1144 **** STRIP_NOPS (arg1); STRIP_NOPS (arg2); ! if (TREE_CODE (arg1) == INTEGER_CST) return int_const_binop (code, arg1, arg2); ! if (TREE_CODE (arg1) == REAL_CST) { machine_mode mode; REAL_VALUE_TYPE d1; --- 1130,1139 ---- STRIP_NOPS (arg1); STRIP_NOPS (arg2); ! if (TREE_CODE (arg1) == INTEGER_CST && TREE_CODE (arg2) == INTEGER_CST) return int_const_binop (code, arg1, arg2); ! if (TREE_CODE (arg1) == REAL_CST && TREE_CODE (arg2) == REAL_CST) { machine_mode mode; REAL_VALUE_TYPE d1; *************** const_binop (enum tree_code code, tree a *** 1216,1222 **** return t; } ! if (TREE_CODE (arg1) == FIXED_CST) { FIXED_VALUE_TYPE f1; FIXED_VALUE_TYPE f2; --- 1211,1217 ---- return t; } ! if (TREE_CODE (arg1) == FIXED_CST && TREE_CODE (arg2) == FIXED_CST) { FIXED_VALUE_TYPE f1; FIXED_VALUE_TYPE f2; *************** const_binop (enum tree_code code, tree a *** 1260,1266 **** return t; } ! if (TREE_CODE (arg1) == COMPLEX_CST) { tree type = TREE_TYPE (arg1); tree r1 = TREE_REALPART (arg1); --- 1255,1261 ---- return t; } ! if (TREE_CODE (arg1) == COMPLEX_CST && TREE_CODE (arg2) == COMPLEX_CST) { tree type = TREE_TYPE (arg1); tree r1 = TREE_REALPART (arg1); *************** const_binop (enum tree_code code, tree a *** 1437,1442 **** --- 1432,1610 ---- return NULL_TREE; } + /* Overload that adds a TYPE parameter to be able to dispatch + to fold_relational_const. */ + + tree + const_binop (enum tree_code code, tree type, tree arg1, tree arg2) + { + if (TREE_CODE_CLASS (code) == tcc_comparison) + return fold_relational_const (code, type, arg1, arg2); + else + return const_binop (code, arg1, arg2); + } + + /* Compute CODE ARG1 with resulting type TYPE with ARG1 being constant. + Return zero if computing the constants is not possible. */ + + tree + const_unop (enum tree_code code, tree type, tree arg0) + { + switch (code) + { + CASE_CONVERT: + case FLOAT_EXPR: + case FIX_TRUNC_EXPR: + case FIXED_CONVERT_EXPR: + return fold_convert_const (code, type, arg0); + + case ADDR_SPACE_CONVERT_EXPR: + if (integer_zerop (arg0)) + return fold_convert_const (code, type, arg0); + break; + + case VIEW_CONVERT_EXPR: + return fold_view_convert_expr (type, arg0); + + case NEGATE_EXPR: + { + /* Can't call fold_negate_const directly here as that doesn't + handle all cases and we might not be able to negate some + constants. */ + tree tem = fold_negate_expr (UNKNOWN_LOCATION, arg0); + if (tem && CONSTANT_CLASS_P (tem)) + return tem; + break; + } + + case ABS_EXPR: + return fold_abs_const (arg0, type); + + case CONJ_EXPR: + if (TREE_CODE (arg0) == COMPLEX_CST) + { + tree ipart = fold_negate_const (TREE_IMAGPART (arg0), + TREE_TYPE (type)); + return build_complex (type, TREE_REALPART (arg0), ipart); + } + break; + + case BIT_NOT_EXPR: + if (TREE_CODE (arg0) == INTEGER_CST) + return fold_not_const (arg0, type); + /* Perform BIT_NOT_EXPR on each element individually. */ + else if (TREE_CODE (arg0) == VECTOR_CST) + { + tree *elements; + tree elem; + unsigned count = VECTOR_CST_NELTS (arg0), i; + + elements = XALLOCAVEC (tree, count); + for (i = 0; i < count; i++) + { + elem = VECTOR_CST_ELT (arg0, i); + elem = const_unop (BIT_NOT_EXPR, TREE_TYPE (type), elem); + if (elem == NULL_TREE) + break; + elements[i] = elem; + } + if (i == count) + return build_vector (type, elements); + } + break; + + case TRUTH_NOT_EXPR: + if (TREE_CODE (arg0) == INTEGER_CST) + return constant_boolean_node (integer_zerop (arg0), type); + break; + + case REALPART_EXPR: + if (TREE_CODE (arg0) == COMPLEX_CST) + return fold_convert (type, TREE_REALPART (arg0)); + break; + + case IMAGPART_EXPR: + if (TREE_CODE (arg0) == COMPLEX_CST) + return fold_convert (type, TREE_IMAGPART (arg0)); + break; + + case VEC_UNPACK_LO_EXPR: + case VEC_UNPACK_HI_EXPR: + case VEC_UNPACK_FLOAT_LO_EXPR: + case VEC_UNPACK_FLOAT_HI_EXPR: + { + unsigned int nelts = TYPE_VECTOR_SUBPARTS (type), i; + tree *elts; + enum tree_code subcode; + + gcc_assert (TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg0)) == nelts * 2); + if (TREE_CODE (arg0) != VECTOR_CST) + return NULL_TREE; + + elts = XALLOCAVEC (tree, nelts * 2); + if (!vec_cst_ctor_to_array (arg0, elts)) + return NULL_TREE; + + if ((!BYTES_BIG_ENDIAN) ^ (code == VEC_UNPACK_LO_EXPR + || code == VEC_UNPACK_FLOAT_LO_EXPR)) + elts += nelts; + + if (code == VEC_UNPACK_LO_EXPR || code == VEC_UNPACK_HI_EXPR) + subcode = NOP_EXPR; + else + subcode = FLOAT_EXPR; + + for (i = 0; i < nelts; i++) + { + elts[i] = fold_convert_const (subcode, TREE_TYPE (type), elts[i]); + if (elts[i] == NULL_TREE || !CONSTANT_CLASS_P (elts[i])) + return NULL_TREE; + } + + return build_vector (type, elts); + } + + case REDUC_MIN_EXPR: + case REDUC_MAX_EXPR: + case REDUC_PLUS_EXPR: + { + unsigned int nelts, i; + tree *elts; + enum tree_code subcode; + + if (TREE_CODE (arg0) != VECTOR_CST) + return NULL_TREE; + nelts = TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg0)); + + elts = XALLOCAVEC (tree, nelts); + if (!vec_cst_ctor_to_array (arg0, elts)) + return NULL_TREE; + + switch (code) + { + case REDUC_MIN_EXPR: subcode = MIN_EXPR; break; + case REDUC_MAX_EXPR: subcode = MAX_EXPR; break; + case REDUC_PLUS_EXPR: subcode = PLUS_EXPR; break; + default: gcc_unreachable (); + } + + for (i = 1; i < nelts; i++) + { + elts[0] = const_binop (subcode, elts[0], elts[i]); + if (elts[0] == NULL_TREE || !CONSTANT_CLASS_P (elts[0])) + return NULL_TREE; + } + + return elts[0]; + } + + default: + break; + } + + return NULL_TREE; + } + /* Create a sizetype INT_CST node with NUMBER sign extended. KIND indicates which particular sizetype to create. */ *************** build_fold_addr_expr_loc (location_t loc *** 7504,7511 **** return build_fold_addr_expr_with_type_loc (loc, t, ptrtype); } - static bool vec_cst_ctor_to_array (tree, tree *); - /* Fold a unary expression of code CODE and type TYPE with operand OP0. Return the folded expression if folding is successful. Otherwise, return NULL_TREE. */ --- 7672,7677 ---- *************** fold_unary_loc (location_t loc, enum tre *** 7520,7529 **** gcc_assert (IS_EXPR_CODE_CLASS (kind) && TREE_CODE_LENGTH (code) == 1); - tem = generic_simplify (loc, code, type, op0); - if (tem) - return tem; - arg0 = op0; if (arg0) { --- 7686,7691 ---- *************** fold_unary_loc (location_t loc, enum tre *** 7549,7556 **** --- 7711,7733 ---- constant folder. */ STRIP_NOPS (arg0); } + + if (CONSTANT_CLASS_P (arg0)) + { + tree tem = const_unop (code, type, arg0); + if (tem) + { + if (TREE_TYPE (tem) != type) + tem = fold_convert_loc (loc, type, tem); + return tem; + } + } } + tem = generic_simplify (loc, code, type, op0); + if (tem) + return tem; + if (TREE_CODE_CLASS (code) == tcc_unary) { if (TREE_CODE (arg0) == COMPOUND_EXPR) *************** fold_unary_loc (location_t loc, enum tre *** 7787,7810 **** } } - tem = fold_convert_const (code, type, arg0); - return tem ? tem : NULL_TREE; - - case ADDR_SPACE_CONVERT_EXPR: - if (integer_zerop (arg0)) - return fold_convert_const (code, type, arg0); return NULL_TREE; - case FIXED_CONVERT_EXPR: - tem = fold_convert_const (code, type, arg0); - return tem ? tem : NULL_TREE; - case VIEW_CONVERT_EXPR: if (TREE_CODE (op0) == MEM_REF) return fold_build2_loc (loc, MEM_REF, type, TREE_OPERAND (op0, 0), TREE_OPERAND (op0, 1)); ! return fold_view_convert_expr (type, op0); case NEGATE_EXPR: tem = fold_negate_expr (loc, arg0); --- 7964,7977 ---- } } return NULL_TREE; case VIEW_CONVERT_EXPR: if (TREE_CODE (op0) == MEM_REF) return fold_build2_loc (loc, MEM_REF, type, TREE_OPERAND (op0, 0), TREE_OPERAND (op0, 1)); ! return NULL_TREE; case NEGATE_EXPR: tem = fold_negate_expr (loc, arg0); *************** fold_unary_loc (location_t loc, enum tre *** 7813,7823 **** return NULL_TREE; case ABS_EXPR: - if (TREE_CODE (arg0) == INTEGER_CST || TREE_CODE (arg0) == REAL_CST) - return fold_abs_const (arg0, type); /* Convert fabs((double)float) into (double)fabsf(float). */ ! else if (TREE_CODE (arg0) == NOP_EXPR ! && TREE_CODE (type) == REAL_TYPE) { tree targ0 = strip_float_extensions (arg0); if (targ0 != arg0) --- 7980,7988 ---- return NULL_TREE; case ABS_EXPR: /* Convert fabs((double)float) into (double)fabsf(float). */ ! if (TREE_CODE (arg0) == NOP_EXPR ! && TREE_CODE (type) == REAL_TYPE) { tree targ0 = strip_float_extensions (arg0); if (targ0 != arg0) *************** fold_unary_loc (location_t loc, enum tre *** 7851,7872 **** return fold_build2_loc (loc, COMPLEX_EXPR, type, rpart, negate_expr (ipart)); } - if (TREE_CODE (arg0) == COMPLEX_CST) - { - tree itype = TREE_TYPE (type); - tree rpart = fold_convert_loc (loc, itype, TREE_REALPART (arg0)); - tree ipart = fold_convert_loc (loc, itype, TREE_IMAGPART (arg0)); - return build_complex (type, rpart, negate_expr (ipart)); - } if (TREE_CODE (arg0) == CONJ_EXPR) return fold_convert_loc (loc, type, TREE_OPERAND (arg0, 0)); return NULL_TREE; case BIT_NOT_EXPR: - if (TREE_CODE (arg0) == INTEGER_CST) - return fold_not_const (arg0, type); /* Convert ~ (-A) to A - 1. */ ! else if (INTEGRAL_TYPE_P (type) && TREE_CODE (arg0) == NEGATE_EXPR) return fold_build2_loc (loc, MINUS_EXPR, type, fold_convert_loc (loc, type, TREE_OPERAND (arg0, 0)), build_int_cst (type, 1)); --- 8016,8028 ---- return fold_build2_loc (loc, COMPLEX_EXPR, type, rpart, negate_expr (ipart)); } if (TREE_CODE (arg0) == CONJ_EXPR) return fold_convert_loc (loc, type, TREE_OPERAND (arg0, 0)); return NULL_TREE; case BIT_NOT_EXPR: /* Convert ~ (-A) to A - 1. */ ! if (INTEGRAL_TYPE_P (type) && TREE_CODE (arg0) == NEGATE_EXPR) return fold_build2_loc (loc, MINUS_EXPR, type, fold_convert_loc (loc, type, TREE_OPERAND (arg0, 0)), build_int_cst (type, 1)); *************** fold_unary_loc (location_t loc, enum tre *** 7894,7918 **** return fold_build2_loc (loc, BIT_XOR_EXPR, type, fold_convert_loc (loc, type, TREE_OPERAND (arg0, 0)), tem); - /* Perform BIT_NOT_EXPR on each element individually. */ - else if (TREE_CODE (arg0) == VECTOR_CST) - { - tree *elements; - tree elem; - unsigned count = VECTOR_CST_NELTS (arg0), i; - - elements = XALLOCAVEC (tree, count); - for (i = 0; i < count; i++) - { - elem = VECTOR_CST_ELT (arg0, i); - elem = fold_unary_loc (loc, BIT_NOT_EXPR, TREE_TYPE (type), elem); - if (elem == NULL_TREE) - break; - elements[i] = elem; - } - if (i == count) - return build_vector (type, elements); - } return NULL_TREE; --- 8050,8055 ---- *************** fold_unary_loc (location_t loc, enum tre *** 7929,7936 **** case REALPART_EXPR: if (TREE_CODE (TREE_TYPE (arg0)) != COMPLEX_TYPE) return fold_convert_loc (loc, type, arg0); - if (TREE_CODE (arg0) == COMPLEX_CST) - return fold_convert_loc (loc, type, TREE_REALPART (arg0)); if (TREE_CODE (arg0) == PLUS_EXPR || TREE_CODE (arg0) == MINUS_EXPR) { tree itype = TREE_TYPE (TREE_TYPE (arg0)); --- 8066,8071 ---- *************** fold_unary_loc (location_t loc, enum tre *** 7969,7976 **** case IMAGPART_EXPR: if (TREE_CODE (TREE_TYPE (arg0)) != COMPLEX_TYPE) return build_zero_cst (type); - if (TREE_CODE (arg0) == COMPLEX_CST) - return fold_convert_loc (loc, type, TREE_IMAGPART (arg0)); if (TREE_CODE (arg0) == PLUS_EXPR || TREE_CODE (arg0) == MINUS_EXPR) { tree itype = TREE_TYPE (TREE_TYPE (arg0)); --- 8104,8109 ---- *************** fold_unary_loc (location_t loc, enum tre *** 8018,8093 **** } return NULL_TREE; - case VEC_UNPACK_LO_EXPR: - case VEC_UNPACK_HI_EXPR: - case VEC_UNPACK_FLOAT_LO_EXPR: - case VEC_UNPACK_FLOAT_HI_EXPR: - { - unsigned int nelts = TYPE_VECTOR_SUBPARTS (type), i; - tree *elts; - enum tree_code subcode; - - gcc_assert (TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg0)) == nelts * 2); - if (TREE_CODE (arg0) != VECTOR_CST) - return NULL_TREE; - - elts = XALLOCAVEC (tree, nelts * 2); - if (!vec_cst_ctor_to_array (arg0, elts)) - return NULL_TREE; - - if ((!BYTES_BIG_ENDIAN) ^ (code == VEC_UNPACK_LO_EXPR - || code == VEC_UNPACK_FLOAT_LO_EXPR)) - elts += nelts; - - if (code == VEC_UNPACK_LO_EXPR || code == VEC_UNPACK_HI_EXPR) - subcode = NOP_EXPR; - else - subcode = FLOAT_EXPR; - - for (i = 0; i < nelts; i++) - { - elts[i] = fold_convert_const (subcode, TREE_TYPE (type), elts[i]); - if (elts[i] == NULL_TREE || !CONSTANT_CLASS_P (elts[i])) - return NULL_TREE; - } - - return build_vector (type, elts); - } - - case REDUC_MIN_EXPR: - case REDUC_MAX_EXPR: - case REDUC_PLUS_EXPR: - { - unsigned int nelts, i; - tree *elts; - enum tree_code subcode; - - if (TREE_CODE (op0) != VECTOR_CST) - return NULL_TREE; - nelts = TYPE_VECTOR_SUBPARTS (TREE_TYPE (op0)); - - elts = XALLOCAVEC (tree, nelts); - if (!vec_cst_ctor_to_array (op0, elts)) - return NULL_TREE; - - switch (code) - { - case REDUC_MIN_EXPR: subcode = MIN_EXPR; break; - case REDUC_MAX_EXPR: subcode = MAX_EXPR; break; - case REDUC_PLUS_EXPR: subcode = PLUS_EXPR; break; - default: gcc_unreachable (); - } - - for (i = 1; i < nelts; i++) - { - elts[0] = const_binop (subcode, elts[0], elts[i]); - if (elts[0] == NULL_TREE || !CONSTANT_CLASS_P (elts[0])) - return NULL_TREE; - } - - return elts[0]; - } - default: return NULL_TREE; } /* switch (code) */ --- 8151,8156 ---- *************** fold_binary_loc (location_t loc, *** 9686,9704 **** /* Note that TREE_CONSTANT isn't enough: static var addresses are constant but we can't do arithmetic on them. */ ! if ((TREE_CODE (arg0) == INTEGER_CST && TREE_CODE (arg1) == INTEGER_CST) ! || (TREE_CODE (arg0) == REAL_CST && TREE_CODE (arg1) == REAL_CST) ! || (TREE_CODE (arg0) == FIXED_CST && TREE_CODE (arg1) == FIXED_CST) ! || (TREE_CODE (arg0) == FIXED_CST && TREE_CODE (arg1) == INTEGER_CST) ! || (TREE_CODE (arg0) == COMPLEX_CST && TREE_CODE (arg1) == COMPLEX_CST) ! || (TREE_CODE (arg0) == VECTOR_CST && TREE_CODE (arg1) == VECTOR_CST) ! || (TREE_CODE (arg0) == VECTOR_CST && TREE_CODE (arg1) == INTEGER_CST)) { if (kind == tcc_binary) { /* Make sure type and arg0 have the same saturating flag. */ ! gcc_assert (TYPE_SATURATING (type) ! == TYPE_SATURATING (TREE_TYPE (arg0))); tem = const_binop (code, arg0, arg1); } else if (kind == tcc_comparison) --- 9749,9761 ---- /* Note that TREE_CONSTANT isn't enough: static var addresses are constant but we can't do arithmetic on them. */ ! if (CONSTANT_CLASS_P (arg0) && CONSTANT_CLASS_P (arg1)) { if (kind == tcc_binary) { /* Make sure type and arg0 have the same saturating flag. */ ! gcc_checking_assert (TYPE_SATURATING (type) ! == TYPE_SATURATING (TREE_TYPE (arg0))); tem = const_binop (code, arg0, arg1); } else if (kind == tcc_comparison) Index: gcc/fold-const.h =================================================================== *** gcc/fold-const.h.orig 2014-11-18 15:16:04.263514898 +0100 --- gcc/fold-const.h 2014-11-19 13:19:18.444040585 +0100 *************** extern bool merge_ranges (int *, tree *, *** 169,173 **** --- 169,175 ---- tree, tree); extern tree sign_bit_p (tree, const_tree); extern tree exact_inverse (tree, tree); + extern tree const_unop (enum tree_code, tree, tree); + extern tree const_binop (enum tree_code, tree, tree, tree); #endif // GCC_FOLD_CONST_H Index: gcc/gimple-match-head.c =================================================================== *** gcc/gimple-match-head.c.orig 2014-11-18 15:16:04.263514898 +0100 --- gcc/gimple-match-head.c 2014-11-19 13:19:18.450040585 +0100 *************** gimple_resimplify1 (gimple_seq *seq, *** 94,100 **** { tree tem = NULL_TREE; if (res_code->is_tree_code ()) ! tem = fold_unary_to_constant (*res_code, type, res_ops[0]); else { tree decl = builtin_decl_implicit (*res_code); --- 94,100 ---- { tree tem = NULL_TREE; if (res_code->is_tree_code ()) ! tem = const_unop (*res_code, type, res_ops[0]); else { tree decl = builtin_decl_implicit (*res_code); *************** gimple_resimplify2 (gimple_seq *seq, *** 150,157 **** { tree tem = NULL_TREE; if (res_code->is_tree_code ()) ! tem = fold_binary_to_constant (*res_code, type, ! res_ops[0], res_ops[1]); else { tree decl = builtin_decl_implicit (*res_code); --- 150,156 ---- { tree tem = NULL_TREE; if (res_code->is_tree_code ()) ! tem = const_binop (*res_code, type, res_ops[0], res_ops[1]); else { tree decl = builtin_decl_implicit (*res_code); *************** gimple_simplify (enum tree_code code, tr *** 386,392 **** { if (constant_for_folding (op0)) { ! tree res = fold_unary_to_constant (code, type, op0); if (res != NULL_TREE && CONSTANT_CLASS_P (res)) return res; --- 385,391 ---- { if (constant_for_folding (op0)) { ! tree res = const_unop (code, type, op0); if (res != NULL_TREE && CONSTANT_CLASS_P (res)) return res; *************** gimple_simplify (enum tree_code code, tr *** 409,415 **** { if (constant_for_folding (op0) && constant_for_folding (op1)) { ! tree res = fold_binary_to_constant (code, type, op0, op1); if (res != NULL_TREE && CONSTANT_CLASS_P (res)) return res; --- 408,414 ---- { if (constant_for_folding (op0) && constant_for_folding (op1)) { ! tree res = const_binop (code, type, op0, op1); if (res != NULL_TREE && CONSTANT_CLASS_P (res)) return res;