Jakub Jelinek <ja...@redhat.com> writes: > On Mon, Mar 03, 2025 at 12:20:00PM +0000, Richard Sandiford wrote: >> I think we should instead go back to punting on comparisons whose inputs >> are CC modes, as we did (indirectly, via comparison_code_valid_for_mode) >> before r15-6777. Sorry, I'd forgotten/hadn't thought to exclude CC modes >> explicitly when removing that function. > > I believe that is not what was the case before r15-6777. > We punted simply because comparison_to_mask returned for GE 6, for LT it > returned 8, 6 | 8 is not 15, no optimization. > There wasn't this all = 14 vs. 15 thing. > comparison_code_valid_for_mode is actually checking mode which is the mode > in which IOR is performed, e.g. SImode in the testcase.
Ah, right. But like I said in the covering note, that choice of mode seemed to be unintentional (since it should never be a floating-point mode, and even if it were, the mode of the IOR wouldn't affect whether something like ORDERED is valid). So I still think that punting (returning 0) on CC modes would be safer. We just don't have enough information to tell what a CCmode value represents. If that seems too conservative, and in particular if we want to preserve the old "all true" optimisation, then... > So, do you want a simpler > if (GET_MODE (XEXP (op0, 0)) == MODE_CC > || HONOR_NANS (GET_MODE (XEXP (op0, 0)))) > all = 15; > or > if ((!INTEGRAL_MODE_P (GET_MODE (XEXP (op0, 0))) > && !FLOAT_MODE_P (GET_MODE (XEXP (op0, 0))) > && !VECTOR_MODE_P (GET_MODE (XEXP (op0, 0)))) > || HONOR_NANS (GET_MODE (XEXP (op0, 0)))) > all = 15; > or something else? ...how about something like this? Completely untested, and I haven't thought about it much. Just didn't want to hold up the discussion. Thanks, Richard diff --git a/gcc/simplify-rtx.cc b/gcc/simplify-rtx.cc index c478bd060fc..d20aa518a64 100644 --- a/gcc/simplify-rtx.cc +++ b/gcc/simplify-rtx.cc @@ -2655,6 +2655,7 @@ simplify_context::simplify_logical_relational_operation (rtx_code code, enum rtx_code code0 = GET_CODE (op0); enum rtx_code code1 = GET_CODE (op1); + machine_mode cmp_mode = GET_MODE (XEXP (op0, 0)); /* Assume at first that the comparisons are on integers, and that the operands are therefore ordered. */ @@ -2672,8 +2673,10 @@ simplify_context::simplify_logical_relational_operation (rtx_code code, } else { - /* See whether the operands might be unordered. */ - if (HONOR_NANS (GET_MODE (XEXP (op0, 0)))) + /* See whether the operands might be unordered. Assume that all + results are possible for CC modes, and punt later if don't get + an all-true or all-false answer. */ + if (GET_MODE_CLASS (cmp_mode) == MODE_CC || HONOR_NANS (cmp_mode)) all = 15; mask0 = comparison_to_mask (code0) & all; mask1 = comparison_to_mask (code1) & all; @@ -2702,6 +2705,9 @@ simplify_context::simplify_logical_relational_operation (rtx_code code, code = mask_to_unsigned_comparison (mask); else { + if (GET_MODE_CLASS (cmp_mode) == MODE_CC) + return 0; + code = mask_to_comparison (mask); /* LTGT and NE are arithmetically equivalent for ordered operands, with NE being the canonical choice. */