This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Factor and export a const_unop, export const_binop
- From: Richard Biener <rguenther at suse dot de>
- To: gcc-patches at gcc dot gnu dot org
- Cc: Jakub Jelinek <jakub at redhat dot com>
- Date: Wed, 19 Nov 2014 15:54:12 +0100 (CET)
- Subject: [PATCH] Factor and export a const_unop, export const_binop
- Authentication-results: sourceware.org; auth=none
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 <rguenther@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;