Skip to content

Commit

Permalink
Fixed fmin/fmax/dmin/dmax node simplifier for const 0s:
Browse files Browse the repository at this point in the history
- now folds to +0 for fmax/dmax(+0, -0), and -0 for fmin/dmin(+0, -0)
- before it folded to the second arg for max and first arg for min when args were equal

Signed-off-by: Matthew Hall <[email protected]>
  • Loading branch information
matthewhall2 committed Sep 25, 2024
1 parent 9b3e65e commit 0aa4f79
Showing 1 changed file with 38 additions and 10 deletions.
48 changes: 38 additions & 10 deletions compiler/optimizer/OMRSimplifierHandlers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17762,15 +17762,29 @@ TR::Node *fmaxminSimplifier(TR::Node * node, TR::Block * block, TR::Simplifier *
fmin = fmax = secondChild->getFloat();
else
{
if (firstChild->getFloat() <= secondChild->getFloat())
float first = firstChild->getFloat();
float second = secondChild->getFloat();
int32_t firstBits = *reinterpret_cast<int32_t *>(&first);
int32_t secondBits = *reinterpret_cast<int32_t *>(&second);
int32_t nZeroBits = 0x80000000;
int32_t pZeroBits = 0;

// compare int32_t bits to avoid compiler simplifying zeros (just in case it treats -0.0 literal as +0.0)
if ((firstBits == pZeroBits || firstBits == nZeroBits) && (secondBits == pZeroBits || secondBits == nZeroBits))
{
int32_t sign = firstBits & nZeroBits;
fmin = sign < 0 ? first : second;
fmax = sign < 0 ? second : first;
}
else if (first <= second)
{
fmin = firstChild->getFloat();
fmax = secondChild->getFloat();
fmin = first;
fmax = second;
}
else
{
fmin = secondChild->getFloat();
fmax = firstChild->getFloat();
fmin = second;
fmax = first;
}
}
foldFloatConstant(node, maxOpcode ? fmax : fmin, s);
Expand All @@ -17797,15 +17811,29 @@ TR::Node *dmaxminSimplifier(TR::Node * node, TR::Block * block, TR::Simplifier *
min = max = secondChild->getDouble();
else
{
if (firstChild->getDouble() <= secondChild->getDouble())
double first = firstChild->getDouble();
double second = secondChild->getDouble();
int64_t firstBits = *reinterpret_cast<int64_t *>(&first);
int64_t secondBits = *reinterpret_cast<int64_t *>(&first);
int64_t nZeroBits = 0x8000000000000000L;
int64_t pZeroBits = 0L;

// compare int64 bits to avoid compiler simplifying zeros (just in case it treats -0.0 literal as +0.0)
if ((firstBits == pZeroBits || firstBits == nZeroBits) && (secondBits == pZeroBits || secondBits == nZeroBits))
{
int64_t sign = firstBits & nZeroBits;
min = sign < 0 ? first : second;
max = sign < 0 ? second : first;
}
else if (first <= second)
{
min = firstChild->getDouble();
max = secondChild->getDouble();
min = first;
max = second;
}
else
{
min = secondChild->getDouble();
max = firstChild->getDouble();
min = second;
max = first;
}
}
foldDoubleConstant(node, maxOpcode ? max : min, s);
Expand Down

0 comments on commit 0aa4f79

Please sign in to comment.