This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Reverting r278411


Richard Sandiford <richard.sandiford@arm.com> writes:
> Segher Boessenkool <segher@kernel.crashing.org> writes:
>>> find_sets_in_insn has:
>>> 
>>>       /* Don't count call-insns, (set (reg 0) (call ...)), as a set.
>>> 	 The hard function value register is used only once, to copy to
>>> 	 someplace else, so it isn't worth cse'ing.  */
>>>       else if (GET_CODE (SET_SRC (x)) == CALL)
>>> 	;
>>> 
>>> So n_sets == 1 can be true if we have a single SET in parallel
>>> with a call.  Unsurprising, I guess no-one had MEM sets in
>>> parallel with a call, so it didn't matter until now.
>>> 
>>> I'm retesting with a !CALL_P check added to make sure that was
>>> the only problem.
>>> 
>>> Before I resubmit, why is the simplify-rtx.c part all wrong?
>>
>> It was nice and simple, and it isn't anymore.  8 4 2 1 for the four of
>> lt gt eq un are hardly worth documenting or making symbolic constants
>> for, because a) they are familiar to all powerpc users anyway (the
>> assembler has those as predefined constants!), admittedly this isn't a
>> strong argument for most people;
>
> Ah, OK.  I was totally unaware of the connection.
>
>> but also b) they were only used in two short and obvious routines.
>> After your patch the routines are no longer short or obvious.
>>
>> A comparison result is exactly one of four things: lt, gt, eq, or un.
>> So we can express testing for any subset of those with just an OR of
>> the masks for the individual conditions.  Whether a comparison is
>> floating point, floating point no-nans, signed, or unsigned, is just
>> a property of the comparison, not of the result, in this representation.
>
> Yeah, this works for OR because we never lose the unorderdness.
>
> There were two aspects to my patch.  One was adding AND, and had:
>
>   /* We only handle AND if we can ignore unordered cases.  */
>   bool honor_nans_p = HONOR_NANS (GET_MODE (op0));
>   if (code != IOR && (code != AND || honor_nans_p))
>     return 0;
>
> This is needed because e.g. UNLT & ORDERED -> LT is only conditionally
> valid.  It doesn't sound like you're objecting to that bit, is that right?
> Or was this what you had in mind with the reference to no-nans?
>
> As mentioned in the covering note, I punted for this because handling
> trapping FP comparisons correctly for AND would need its own set of
> testcases.  The current code punts for AND and for unsigned comparisons,
> so continuing to punt for ANDs on this case seemed fair game.
>
>> If you do not mix signed and unsigned comparisons (they make not much
>> sense mixed anyway(*)), you need no changes at all: just translate
>> ltu/gtu/leu/geu to/from lt/gt/le/ge on the way in and out of this
>> function (there already are helper functions for that, signed_condition
>> and unsigned_condition).
>
> So this all seems to come down to whether unsigned comparisons are handled
> as separate mask bits or whether they're dealt with by removing the
> unsignedness and then adding it back.  ISTM both are legitimate ways
> of doing it.  I don't think one of them is "all wrong".
>
> FWIW, I'd posted a patch to do the IOR/AND thing in July:
>
>   https://gcc.gnu.org/ml/gcc-patches/2019-07/msg00933.html
>
> But it turns out I'd got the signalling NaN behaviour wrong:
>
>   https://gcc.gnu.org/ml/gcc-patches/2019-08/msg01006.html
>
> (hence punting above :-)).
>
> I was very belatedly getting around to dealing with Joseph's comment
> when you sent your patch and had it approved.  Since that patch seemed
> to be more favourably received in general, I was trying to work within
> the existing style of your version.  And without the powerpc background,
> I just assumed that the mask values were "documented" by the first block
> of case statements:
>
>     case LT:
>       return 8;
>     case GT:
>       return 4;
>     case EQ:
>       return 2;
>     case UNORDERED:
>       return 1;
>
> Adding two more cases here didn't seem to make things any more unclear.
> But maybe it is more jarring if you've memorised the powerpc mapping.
>
> I'd actually considered converting to signed and back instead of adding
> extra cases, but I thought that would be rejected as too inefficient.
> (That was a concern with my patch above.)  It seemed like one of the selling
> points of doing it your way was that everything was handled by one switch
> statement "in" and one switch statement "out", and I was trying to
> preserve that.
>
> signed_condition and unsigned_condition assert on unordered comparisons,
> so if we're going to go that route, we either need to filter them out
> first or add maybe_* versions of the routines that return UNKNOWN.
> We also have to deal with the neutrality of EQ and NE.  E.g. something
> like:
>
>   rtx_code signed_code0 = maybe_signed_condition (code0);
>   rtx_code signed_code1 = maybe_signed_condition (code1);
>   if (signed_code0 != UNKNOWN && signed_code1 != UNKNOWN)
>     code0 = signed_code0, code1 = signed_code1;
>   else if (signed_code0 != UNKNOWN || signed_code1 != UNKNOWN)
>     return 0;
>
>   ...
>
>   if (signed_code0 == UNKNOWN)
>     code = unsigned_condition (code);
>
> Or (without the maybe_* versions) something like:
>
>   bool unsigned0_p
>     = (code0 == LTU || code0 == GTU || code0 == LEU || code0 == GEU);
>   bool unsigned1_p
>     = (code1 == LTU || code1 == GTU || code1 == LEU || code1 == GEU);
>   if (unsigned0_p || unsigned1_p)
>     {
>       if ((!unsigned0_p && code0 != EQ && code0 != NE)
> 	  || (!unsigned1_p && code1 != EQ && code1 != NE))
> 	return 0;
>       code0 = unsigned_condition (code0);
>       code1 = unsigned_condition (code1);

Of course I meant signed_condition here :-)

>     }
>
>   ...
>
>   if (unsigned0_p)
>     code = unsigned_condition (code);
>
> Which do you prefer?  Or would your prefer a different way?
>
> Another alternative would be to resurrect my patch above and try to make
> the mask-to-condition conversion more efficient.  Should easily be doable,
> since Joseph's correction makes things simpler.
>
> Thanks,
> Richard


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]