From 0c6d17eca1ca73e0b3799d75c28aadac9adaeb85 Mon Sep 17 00:00:00 2001 From: Roger Sayle Date: Tue, 16 Sep 2003 17:16:25 +0000 Subject: [PATCH] re PR bootstrap/12269 (Mainline failed to bootstrap on Linux/ia64) PR bootstrap/12269 * simplify-rtx.c (simplify_gen_relational): Allow the cmp_mode argument to be VOIDmode, taking the mode of the comparison from the operands. Only call simplify_relational_operation if we know the mode of the comparison. Honor FLOAT_STORE_FLAG_VALUE if comparison has a floating point result. Ensure that the result is always of the specified mode. (simplify_replace_rtx): Simplify call to simplify_gen_relational. (simplify_unary_operation): Ensure the correct mode and cmp_mode are always passed to simplify_gen_relational. Simplify NOT of comparison operator in any mode, not just BImode. (simplify_ternary_operation): Correct tests on the return value of simplify_relational_operation to use const_true_rtx, not const1_rtx. Abort if it ever returns a non-constant result. * cfgloopanal.c (count_strange_loop_iterations): Use the function simplify_relational_operation, not simplify_gen_relational, if we're only interested in constant comparisons and will ignore non-constant results. From-SVN: r71439 --- gcc/ChangeLog | 22 +++++++++++ gcc/cfgloopanal.c | 4 +- gcc/simplify-rtx.c | 97 +++++++++++++++++++++++++--------------------- 3 files changed, 76 insertions(+), 47 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index cce3c91bff5..679fcfd8a2b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,25 @@ +2003-09-16 Roger Sayle + + PR bootstrap/12269 + * simplify-rtx.c (simplify_gen_relational): Allow the cmp_mode + argument to be VOIDmode, taking the mode of the comparison from + the operands. Only call simplify_relational_operation if we + know the mode of the comparison. Honor FLOAT_STORE_FLAG_VALUE + if comparison has a floating point result. Ensure that the + result is always of the specified mode. + (simplify_replace_rtx): Simplify call to simplify_gen_relational. + (simplify_unary_operation): Ensure the correct mode and cmp_mode + are always passed to simplify_gen_relational. Simplify NOT of + comparison operator in any mode, not just BImode. + (simplify_ternary_operation): Correct tests on the return value + of simplify_relational_operation to use const_true_rtx, not + const1_rtx. Abort if it ever returns a non-constant result. + + * cfgloopanal.c (count_strange_loop_iterations): Use the function + simplify_relational_operation, not simplify_gen_relational, if + we're only interested in constant comparisons and will ignore + non-constant results. + 2003-09-16 Roger Sayle * fold-const.c (tree_swap_operands_p): New function to determine diff --git a/gcc/cfgloopanal.c b/gcc/cfgloopanal.c index 68dd9282333..57c3baceff4 100644 --- a/gcc/cfgloopanal.c +++ b/gcc/cfgloopanal.c @@ -470,7 +470,7 @@ count_strange_loop_iterations (rtx init, rtx lim, enum rtx_code cond, /* If we are able to prove that we don't pass the first test, we are done. */ - rqmt = simplify_gen_relational (cond, SImode, mode, init, lim); + rqmt = simplify_relational_operation (cond, mode, init, lim); if (rqmt == const0_rtx) return const0_rtx; @@ -560,7 +560,7 @@ count_strange_loop_iterations (rtx init, rtx lim, enum rtx_code cond, /* If this is const_true_rtx and we did not take a conservative approximation of after_wrap above, we might iterate the calculation (but of course we would have to take care about infinite cases). Ignore this for now. */ - rqmt = simplify_gen_relational (cond, SImode, mode, after_wrap, lim); + rqmt = simplify_relational_operation (cond, mode, after_wrap, lim); if (rqmt != const0_rtx) return NULL_RTX; diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c index aa16af820f9..f2da9eef4d0 100644 --- a/gcc/simplify-rtx.c +++ b/gcc/simplify-rtx.c @@ -197,38 +197,62 @@ simplify_gen_relational (enum rtx_code code, enum machine_mode mode, { rtx tem; - if ((tem = simplify_relational_operation (code, cmp_mode, op0, op1)) != 0) - return tem; + if (cmp_mode == VOIDmode) + cmp_mode = GET_MODE (op0); + if (cmp_mode == VOIDmode) + cmp_mode = GET_MODE (op1); + + if (cmp_mode != VOIDmode) + { + tem = simplify_relational_operation (code, cmp_mode, op0, op1); + + if (tem) + { +#ifdef FLOAT_STORE_FLAG_VALUE + if (GET_MODE_CLASS (mode) == MODE_FLOAT) + { + REAL_VALUE_TYPE val; + if (tem == const0_rtx) + return CONST0_RTX (mode); + if (tem != const_true_rtx) + abort (); + val = FLOAT_STORE_FLAG_VALUE (mode); + return CONST_DOUBLE_FROM_REAL_VALUE (val, mode); + } +#endif + return tem; + } + } /* For the following tests, ensure const0_rtx is op1. */ - if (op0 == const0_rtx && swap_commutative_operands_p (op0, op1)) + if (swap_commutative_operands_p (op0, op1) + || (op0 == const0_rtx && op1 != const0_rtx)) tem = op0, op0 = op1, op1 = tem, code = swap_condition (code); /* If op0 is a compare, extract the comparison arguments from it. */ if (GET_CODE (op0) == COMPARE && op1 == const0_rtx) - op1 = XEXP (op0, 1), op0 = XEXP (op0, 0); + return simplify_gen_relational (code, mode, VOIDmode, + XEXP (op0, 0), XEXP (op0, 1)); /* If op0 is a comparison, extract the comparison arguments form it. */ - if (code == NE && op1 == const0_rtx - && GET_RTX_CLASS (GET_CODE (op0)) == '<') - return op0; - else if (code == EQ && op1 == const0_rtx) + if (GET_RTX_CLASS (GET_CODE (op0)) == '<' && op1 == const0_rtx) { - /* The following tests GET_RTX_CLASS (GET_CODE (op0)) == '<'. */ - enum rtx_code new = reversed_comparison_code (op0, NULL_RTX); - if (new != UNKNOWN) - { - code = new; - mode = cmp_mode; - op1 = XEXP (op0, 1); - op0 = XEXP (op0, 0); + if (code == NE) + { + if (GET_MODE (op0) == mode) + return op0; + return simplify_gen_relational (GET_CODE (op0), mode, VOIDmode, + XEXP (op0, 0), XEXP (op0, 1)); + } + else if (code == EQ) + { + enum rtx_code new = reversed_comparison_code (op0, NULL_RTX); + if (new != UNKNOWN) + return simplify_gen_relational (new, mode, VOIDmode, + XEXP (op0, 0), XEXP (op0, 1)); } } - /* Put complex operands first and constants second. */ - if (swap_commutative_operands_p (op0, op1)) - tem = op0, op0 = op1, op1 = tem, code = swap_condition (code); - return gen_rtx_fmt_ee (code, mode, op0, op1); } @@ -272,24 +296,7 @@ simplify_replace_rtx (rtx x, rtx old, rtx new) : GET_MODE (XEXP (x, 1))); rtx op0 = simplify_replace_rtx (XEXP (x, 0), old, new); rtx op1 = simplify_replace_rtx (XEXP (x, 1), old, new); - rtx temp = simplify_gen_relational (code, mode, - (op_mode != VOIDmode - ? op_mode - : GET_MODE (op0) != VOIDmode - ? GET_MODE (op0) - : GET_MODE (op1)), - op0, op1); -#ifdef FLOAT_STORE_FLAG_VALUE - if (GET_MODE_CLASS (mode) == MODE_FLOAT) - { - if (temp == const0_rtx) - temp = CONST0_RTX (mode); - else if (temp == const_true_rtx) - temp = CONST_DOUBLE_FROM_REAL_VALUE (FLOAT_STORE_FLAG_VALUE (mode), - mode); - } -#endif - return temp; + return simplify_gen_relational (code, mode, op_mode, op0, op1); } case '3': @@ -800,10 +807,10 @@ simplify_unary_operation (enum rtx_code code, enum machine_mode mode, return XEXP (op, 0); /* (not (eq X Y)) == (ne X Y), etc. */ - if (mode == BImode && GET_RTX_CLASS (GET_CODE (op)) == '<' + if (GET_RTX_CLASS (GET_CODE (op)) == '<' && ((reversed = reversed_comparison_code (op, NULL_RTX)) != UNKNOWN)) - return simplify_gen_relational (reversed, op_mode, op_mode, + return simplify_gen_relational (reversed, mode, VOIDmode, XEXP (op, 0), XEXP (op, 1)); /* (not (plus X -1)) can become (neg X). */ @@ -842,7 +849,7 @@ simplify_unary_operation (enum rtx_code code, enum machine_mode mode, && GET_RTX_CLASS (GET_CODE (op)) == '<' && (reversed = reversed_comparison_code (op, NULL_RTX)) != UNKNOWN) - return simplify_gen_relational (reversed, op_mode, op_mode, + return simplify_gen_relational (reversed, mode, VOIDmode, XEXP (op, 0), XEXP (op, 1)); /* (not (ashiftrt foo C)) where C is the number of bits in FOO @@ -853,8 +860,8 @@ simplify_unary_operation (enum rtx_code code, enum machine_mode mode, && GET_CODE (op) == ASHIFTRT && GET_CODE (XEXP (op, 1)) == CONST_INT && INTVAL (XEXP (op, 1)) == GET_MODE_BITSIZE (mode) - 1) - return simplify_gen_relational (GE, mode, mode, XEXP (op, 0), - const0_rtx); + return simplify_gen_relational (GE, mode, VOIDmode, + XEXP (op, 0), const0_rtx); break; @@ -2725,10 +2732,10 @@ simplify_ternary_operation (enum rtx_code code, enum machine_mode mode, /* See if any simplifications were possible. */ if (temp == const0_rtx) return op2; - else if (temp == const1_rtx) + else if (temp == const_true_rtx) return op1; else if (temp) - op0 = temp; + abort (); /* Look for happy constants in op1 and op2. */ if (GET_CODE (op1) == CONST_INT && GET_CODE (op2) == CONST_INT)