On 6/29/2026 3:22 AM, Christopher Bazley wrote:
> Ping!
>
> Please could someone take over this code review from Richard 
> Sandiford? He wrote (in a comment on the Forge) that he cannot 
> complete the review because he is now a co-author. The relevant 
> comment is
> https://forge.sourceware.org/gcc/gcc-TEST/pulls/180#issuecomment-6403
I would have been comfortable with Richard S. self-approving, even under 
these conditions.   His knowledge in this space far exceeds my own.


>
> Thanks,
> Chris
>
> On 19/06/2026 14:08, Christopher Bazley via Sourceware Forge wrote:
>> From: Christopher Bazley <[email protected]>
>>
>> PR middle-end/125767
>>
>> When the magnitude of the divisor is known to be bigger
>> than that of the dividend, the output quotient should be 1
>> when divisor and dividend have the same sign or -1
>> when they have opposite signs.
>>
>> Previously, can_div_away_from_zero_p was overreliant on
>> can_div_trunc_p: if can_div_trunc_p returned a failure
>> indication then can_div_away_from_zero_p did likewise.
>>
>> This matters because can_div_away_from_zero_p is commonly
>> used to answer questions such as "How many registers does
>> this value occupy?" If the register has a scalable vector
>> type, then the answer should be 1 if the number of bits
>> occupied by the value is known to be not greater than
>> the minimum number of bits in the vector type (as well as
>> if the number of bits occupied by the value is known to be
>> smaller). Previously, can_div_away_from_zero_p had to be
>> used with care to avoid wrongly concluding that a value of
>> type V16QI would not fit in a register of type VNx16QI.
>> That could cause selection of inefficient instruction
>> sequences or even an ICE in cases where V8QI in VNx16QI
>> behaved as expected.
>>
>> Because polynomial division truncated toward zero can
>> fail to produce a constant quotient in cases where
>> polynomial division rounded away from zero can produce a
>> constant quotient, it is not sufficient for the
>> implementation of can_div_away_from_zero_p to simply adjust
>> the quotient produced by can_div_trunc_p.
>>
>> can_div_trunc_p requires |b * Q| <= |a| whereas
>> can_div_away_from_zero_p requires |b * Q| >= |a|. The
>> latter can be proven in cases where the former cannot.
>> For example, when a = 16 + 0i and b = 16 + 16i, |b * Q|
>> cannot be smaller than |a| unless Q = 0, which would
>> violate a common requirement that |a - b * Q| < |b|
>> (because |a| >= 16 and |b| >= 16). In contrast, |b * Q|
>> is bigger than |a| if Q > 1 or i > 0. Crucially, it's
>> impossible to know the value of i at compile time, so
>> can_div_trunc_p must conservatively return false.
>>
>> Another way of looking at it is:
>> Q = (16 + 0i) / (16 + 16i)
>>    = 16 / (16 + 16i)
>>    = 1 / (1 + i)
>>
>> which is not "some constant Q" that these functions must
>> find in order to return true; however, we can be sure that
>> whatever the unknowable value of 1 / (1 + i) is, it lies
>> within the range 0 < Q <= 1. We cannot know whether that
>> answer should be truncated to zero, but we can know that
>> it should be rounded to one.
>>
>> gcc/ChangeLog:
>>
>>     * poly-int.h (can_div_away_from_zero_p):
>>     Exit early if |a| <= |b| instead of calling
>>     can_div_trunc_p and returning false if it
>>     returned false.
>>
>> gcc/testsuite/ChangeLog:
>>
>>     * gcc.dg/plugin/poly-int-tests.h: New test cases.
Thanks for the detailed cover & comments.  It really does help someone 
not intimately familiar with what's going on here.

OK for the trunk.

jeff

Reply via email to