Mathematically correct result from maybe_lt, maybe_le and derivatives (avoiding type traits) #180
No reviewers
Labels
No labels
Compat/Breaking
Frontend/ada
Frontend/c
Frontend/c++
Frontend/rust
General/forge
Kind/Bug
Kind/Documentation
Kind/Enhancement
Kind/Feature
Kind/Security
Kind/Testing
Library/libgcc
Library/libstdc++
Midend/gimple
Midend/rtl
Midend/tree
Priority
Critical
Priority
High
Priority
Low
Priority
Medium
Reviewed
Confirmed
Reviewed
Duplicate
Reviewed
Invalid
Reviewed
Won't Fix
Status
Abandoned
Status
Blocked
Status
Need More Info
Target/aarch64
Target/arm
Target/i386
bug
duplicate
enhancement
help wanted
invalid
question
wontfix
No milestone
No assignees
3 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
gcc/gcc!180
Loading…
Reference in a new issue
No description provided.
Delete branch "chris.bazley/gcc:myforge/comparisons_b"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Most of the poly_int functions don't handle mixed signed/unsigned
parameter types correctly, but it is relatively easy to make
the comparison functions do so:
positive or zero then a < b. This should optimise to nothing
if the first operand is unsigned.
is negative then a > b. This should optimise to nothing if the
second operand is unsigned.
are negative, so cast them to a common type then use the
standard C++ comparison operator.
This approach is potentially less efficient than using type traits
because a < 0 and b < 0 are evaluated as well as a < b (or a <= b)
if both operands have signed types.
It would not be straightforward to make use of existing unsigned
test cases because they rely on implicit conversion of negative
integers to unsigned types, therefore I followed the following
method instead:
coefficient type specified by the user of the template, otherwise
the unsigned coefficient type.
coefficients and do not have operands of types with different
signedness.
modify them such that one version has the first operand of signed
type and the other has the second operand of signed type.
unsigned types have a non-negative value, trying to preserve intent,
ordering, and relative distance between values.
Most of the poly_int functions don't handle mixed signed/unsigned
parameter types correctly, but it is relatively easy to make
the comparison functions do so:
the standard C++ comparison operator.
two types mismatches (1) then the second operand's value is
positive or zero, which is greater than the first operand's value
if the latter is negative.
two types mismatches (1) then the first operand's value is
positive or zero, which is greater than the second operand's value
if the latter is negative.
common type then use the standard C++ comparison operator.
Using type traits is likely to be more efficient than relying
on the fact that unsigned types never have a negative value,
because it avoids unnecessary comparisons in the case where
one or more of the operands has a signed type.
It would not be straightforward to make use of existing unsigned
test cases because they rely on implicit conversion of negative
integers to unsigned types, therefore I followed the following
method instead:
coefficient type specified by the user of the template, otherwise
the unsigned coefficient type.
coefficients and do not have operands types with different
signedness.
modify them such that one version has the first operand of signed
type and the other has the second operand of signed type.
unsigned types have a non-negative value, trying to preserve intent,
ordering, and relative distance between values.
CC: rdsandiford@googlemail.com, tamar.christina@arm.com
Hi @chris.bazley. This bot helps send your PR as a patch series to the mailing list.
Next steps
CC: Reviewer1 <revi.ewer@example.com>, Reviewer2 <an.other@example.com>./preview./submit.Changes since vXsection, and comment with/submitagain.See Submitting Patches and UsingForge.
Consider joining the gcc and gcc-patches mailing lists..
For real time communication, check the gcc irc channels.
Or join
#overseerson Libera Chat, particularly if this automation is not working (stay online to get replies, IRC does not save messages if people are not online).I used these functions as part of my work on gcc/gcc-TEST#176 and found they don't work for mixed signed / unsigned operand types. I think it might be worth fixing that to prevent future surprises.
This approach is an alternative to the one that I used in gcc/gcc-TEST#179 because I was not sure which was more likely to be accepted. The tests are identical. Please state your preference, if any.
1ee378e31fc6a3ddbb71c6a3ddbb71da888bbaedda888bbaed4cc72b71ba@chris.bazley wrote in gcc/gcc-TEST#180 (comment):
As I mentioned in #176, I think it's a feature that
known_ltgives a warning for mismatched signs, since<does the same.I think it's ok for mixed-signedness divisions to trigger a warning as well. That's stricter than C++, but it would force callers to make a choice. The C++ behaviour of silently converting
int64_t / uint64_ttouint64_t / uint64_tdoesn't seem something to cherish.If we did want to make
can_div_away_from_zero_pbehave like C++ division, i.e. convert to the common type before dividing, then the way to do that would be with a cast toPOLY_POLY_RESULT, or similar. But like I say, I think we should avoid that. It just seems like setting a trap for the unwary.So I still prefer the version I suggested above. There again, if you did go with that, I'd no longer be able to approve the patch :-)
@rsandifo wrote in gcc/gcc-TEST#180 (comment):
I can see both sides of the argument. These comparison macros which produce a mathematically correct result are very likely to be part of C2Y: https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3776.pdf
My comments here, on a related proposal for standard min/max macros, also seem relevant:
https://open-std.org/jtc1/sc22/wg14/35823
https://open-std.org/jtc1/sc22/wg14/36744
I feel more strongly against functions that potentially return an unexpected result that is a number, than functions that simply return a Boolean answer (as in the case of maybe_lt). I'm not sure there's any rational reason for that though.
tl;dr: I have argued against the thing I have implemented in this patch, but the wind seems to be blowing in the opposite direction.
Mathematically correct result from maybe_lt, maybe_le and derivativesto Mathematically correct result from maybe_lt, maybe_le and derivatives (avoiding type traits)View command line instructions
Checkout
From your project repository, check out a new branch and test the changes.Merge
Merge the changes and update on Forgejo.