Skip to content

Commit

Permalink
Check for right-hand operand of zero in lrem and irem
Browse files Browse the repository at this point in the history
The constrainIrem and constrainLrem methods guard against a right-hand
operand of zero if the left-hand operand is a constant, but not if the
left-hand operand is a non-constant.  In the latter case, a constraint
in the range [1,-1] results.

This change adds an additional check for a right-hand operand equal to
zero if the left-hand operand is non-constant, avoiding creating an
erroneous constraint for the result.

Signed-off-by:  Henry Zongaro <[email protected]>
  • Loading branch information
hzongaro committed Jan 16, 2023
1 parent 2bb0413 commit 625ff55
Showing 1 changed file with 34 additions and 24 deletions.
58 changes: 34 additions & 24 deletions compiler/optimizer/VPHandlers.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2000, 2022 IBM Corp. and others
* Copyright (c) 2000, 2023 IBM Corp. and others
*
* This program and the accompanying materials are made available under
* the terms of the Eclipse Public License 2.0 which accompanies this
Expand Down Expand Up @@ -6678,18 +6678,23 @@ TR::Node *constrainIrem(OMR::ValuePropagation *vp, TR::Node *node)
int32_t rhsConst = rhs->asIntConst()->getInt();
if (!isUnsigned && rhsConst < 0)
rhsConst *= -1;
rhsConst--; // If the original const was 10, the range is from 0 to 9

if (lhsLow > 0)
constraint = TR::VPIntRange::create(vp, 0, rhsConst);
else if (!isUnsigned && lhsHigh < 0)
constraint = TR::VPIntRange::create(vp, -rhsConst, 0);
else if (!isUnsigned)
constraint = TR::VPIntRange::create(vp, -rhsConst, rhsConst);

if (constraint)
// Guard against division by zero
if (rhsConst != 0)
{
vp->addBlockOrGlobalConstraint(node, constraint ,lhsGlobal);
rhsConst--; // If the original const was 10, the range is from 0 to 9

if (lhsLow > 0)
constraint = TR::VPIntRange::create(vp, 0, rhsConst);
else if (!isUnsigned && lhsHigh < 0)
constraint = TR::VPIntRange::create(vp, -rhsConst, 0);
else if (!isUnsigned)
constraint = TR::VPIntRange::create(vp, -rhsConst, rhsConst);

if (constraint)
{
vp->addBlockOrGlobalConstraint(node, constraint ,lhsGlobal);
}
}
}

Expand Down Expand Up @@ -6736,22 +6741,27 @@ TR::Node *constrainLrem(OMR::ValuePropagation *vp, TR::Node *node)
int64_t rhsConst = rhs->asLongConst()->getLong();
if (rhsConst < 0)
rhsConst *= -1;
rhsConst--; // If the original const was 10, the range is from 0 to 9

if (lhsLow > 0)
constraint = TR::VPLongRange::create(vp, 0, rhsConst);
else if (lhsHigh < 0)
constraint = TR::VPLongRange::create(vp, -rhsConst, 0);
else
constraint = TR::VPLongRange::create(vp, -rhsConst, rhsConst);

if (constraint)
// Guard against division by zero
if (rhsConst != 0)
{
bool didReduction = reduceLongOpToIntegerOp(vp, node, constraint);
vp->addBlockOrGlobalConstraint(node, constraint ,lhsGlobal);
rhsConst--; // If the original const was 10, the range is from 0 to 9

if (didReduction)
return node;
if (lhsLow > 0)
constraint = TR::VPLongRange::create(vp, 0, rhsConst);
else if (lhsHigh < 0)
constraint = TR::VPLongRange::create(vp, -rhsConst, 0);
else
constraint = TR::VPLongRange::create(vp, -rhsConst, rhsConst);

if (constraint)
{
bool didReduction = reduceLongOpToIntegerOp(vp, node, constraint);
vp->addBlockOrGlobalConstraint(node, constraint ,lhsGlobal);

if (didReduction)
return node;
}
}
}

Expand Down

0 comments on commit 625ff55

Please sign in to comment.