aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/fold-const.c39
1 files changed, 22 insertions, 17 deletions
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index 3aafbc9..e2110b6 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -126,7 +126,8 @@ static tree range_binop (enum tree_code, tree, tree, int, tree, int);
static tree range_predecessor (tree);
static tree range_successor (tree);
static tree fold_range_test (location_t, enum tree_code, tree, tree, tree);
-static tree fold_cond_expr_with_comparison (location_t, tree, tree, tree, tree);
+static tree fold_cond_expr_with_comparison (location_t, tree, enum tree_code,
+ tree, tree, tree, tree);
static tree unextend (tree, int, int, tree);
static tree extract_muldiv (tree, tree, enum tree_code, tree, bool *);
static tree extract_muldiv_1 (tree, tree, enum tree_code, tree, bool *);
@@ -5734,20 +5735,19 @@ merge_ranges (int *pin_p, tree *plow, tree *phigh, int in0_p, tree low0,
/* Subroutine of fold, looking inside expressions of the form
- A op B ? A : C, where ARG0, ARG1 and ARG2 are the three operands
- of the COND_EXPR. This function is being used also to optimize
- A op B ? C : A, by reversing the comparison first.
+ A op B ? A : C, where (ARG00, COMP_CODE, ARG01), ARG1 and ARG2
+ are the three operands of the COND_EXPR. This function is
+ being used also to optimize A op B ? C : A, by reversing the
+ comparison first.
Return a folded expression whose code is not a COND_EXPR
anymore, or NULL_TREE if no folding opportunity is found. */
static tree
fold_cond_expr_with_comparison (location_t loc, tree type,
- tree arg0, tree arg1, tree arg2)
+ enum tree_code comp_code,
+ tree arg00, tree arg01, tree arg1, tree arg2)
{
- enum tree_code comp_code = TREE_CODE (arg0);
- tree arg00 = TREE_OPERAND (arg0, 0);
- tree arg01 = TREE_OPERAND (arg0, 1);
tree arg1_type = TREE_TYPE (arg1);
tree tem;
@@ -12821,7 +12821,10 @@ fold_ternary_loc (location_t loc, enum tree_code code, tree type,
&& operand_equal_for_comparison_p (TREE_OPERAND (arg0, 0), op1)
&& !HONOR_SIGNED_ZEROS (element_mode (op1)))
{
- tem = fold_cond_expr_with_comparison (loc, type, arg0, op1, op2);
+ tem = fold_cond_expr_with_comparison (loc, type, TREE_CODE (arg0),
+ TREE_OPERAND (arg0, 0),
+ TREE_OPERAND (arg0, 1),
+ op1, op2);
if (tem)
return tem;
}
@@ -12830,14 +12833,16 @@ fold_ternary_loc (location_t loc, enum tree_code code, tree type,
&& operand_equal_for_comparison_p (TREE_OPERAND (arg0, 0), op2)
&& !HONOR_SIGNED_ZEROS (element_mode (op2)))
{
- location_t loc0 = expr_location_or (arg0, loc);
- tem = fold_invert_truthvalue (loc0, arg0);
- if (tem && COMPARISON_CLASS_P (tem))
- {
- tem = fold_cond_expr_with_comparison (loc, type, tem, op2, op1);
- if (tem)
- return tem;
- }
+ enum tree_code comp_code = TREE_CODE (arg0);
+ tree arg00 = TREE_OPERAND (arg0, 0);
+ tree arg01 = TREE_OPERAND (arg0, 1);
+ comp_code = invert_tree_comparison (comp_code, HONOR_NANS (arg00));
+ tem = fold_cond_expr_with_comparison (loc, type, comp_code,
+ arg00,
+ arg01,
+ op2, op1);
+ if (tem)
+ return tem;
}
/* If the second operand is simpler than the third, swap them