Jakub Jelinek <[email protected]> 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. */