-
Notifications
You must be signed in to change notification settings - Fork 397
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix how overflow property is set for arithmetic operations during ValuePropagation #7574
base: master
Are you sure you want to change the base?
Conversation
For arithmetic operations that have an int range constraint, it is because one or both of the operands are not known and therefore cannot be determined as cannotOverflow. While the result of the arithmetic operation would be in a known range of 32bit signed int values, it may have been achieved by intentionally causing an overflow. Signed-off-by: Nazim Bhuiyan <[email protected]>
For arithmetic operations that have a long range constraint, it is because one or both of the operands are not known and therefore cannot be determined as cannotOverflow. While the result of the arithmetic operation would be in a known range of 64bit signed long values, it may have been achieved by intentionally causing an overflow. Signed-off-by: Nazim Bhuiyan <[email protected]>
For arithmetic operations that have a short range constraint, it is because one or both of the operands are not known and therefore cannot be determined as cannotOverflow. While the result of the arithmetic operation would be in a known range of 16bit signed short values, it may have been achieved by intentionally causing an overflow. Signed-off-by: Nazim Bhuiyan <[email protected]>
Signed-off-by: Nazim Bhuiyan <[email protected]>
@hzongaro requesting review |
else if (node->getOpCode().isArithmetic()) | ||
{ | ||
node->setCannotOverflow(false); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Although this change will definitely avoid the problem, I think it's going to be too heavy-handed. Consider this example:
public class Experiment {
public static final int sub(int i, int j) {
if (i > 0 && i < 100 && j > 0 && j < 100) {
return i*j + i/j;
}
return 0;
}
public static final void main(String[] args) {
sub(1, 2);
sub(1, 2);
}
}
Global Value Propagation is able to determine the ranges of the arithmetic operations, and it ought to be able to determine from that that they cannot overflow.
n32n idiv gets new constraint: value 5 is (0 to 99)I
n29n imul gets new constraint: value 6 is (1 to 9801)I
n34n iadd gets new constraint: value 7 is (1 to 9900)I
The existing code here is testing whether range->canOverflow() != TR_yes
. I'm wondering whether the constraint that's associated with the imul
can have its range->canOverflow()
return TR_yes
. I think the fix will likely be a bit more involved to make that happen.
In
checkForNonNegativeAndOverflowProperties
, an arithmetic operation node with a constraint that's a range rather than a constant constraint means that one or both the operands are not known. Therefore, it is not possible to determine that an arithmetic operation would not result in an overflow. While the result of the operation would be within the range, it may be achieved through intentionally causing an overflow.Issue: eclipse-openj9/openj9#19139