Skip to content
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

Support IEEE-754 for fmin/fmax/dmin/dmax nodes #7464

Merged
merged 2 commits into from
Oct 21, 2024

Conversation

matthewhall2
Copy link
Contributor

@matthewhall2 matthewhall2 commented Sep 18, 2024

  • Enables inlining of fmin/fmax/dmin/dmax nodes
  • Implements IEEE-754 standard for the evaluators:
    • if the first arg is a NaN, returns the corresponding quiet NaN, same for if only the second arg is a NaN
  • Refactors xmaxxminhelper to infer correct compare/branch/move instructions based on datatype; helper does not change NaNs, so can be used in other min/max evaluators which can extend the behaviour on NaNs as they see fit
  • Uses vector operations when available, defaults to branching if not
  • Supports inlining for Support Java Behaviour w.r.t Math.max and Math.min for Floating Points eclipse-openj9/openj9#20185

Depends on OMR Simplifier change #7471 (needed for eclipse-openj9/openj9#20185 to pass)

https://hyc-runtimes-jenkins.swg-devops.com/job/jvm.29.personal/34283/

@matthewhall2 matthewhall2 force-pushed the fmin_fmax_dmin_dmax branch 2 times, most recently from 88e0beb to 65d97f3 Compare September 19, 2024 20:32
@matthewhall2 matthewhall2 force-pushed the fmin_fmax_dmin_dmax branch 2 times, most recently from 0c276e5 to 9670bf9 Compare September 25, 2024 16:07
@matthewhall2 matthewhall2 marked this pull request as ready for review September 25, 2024 17:34
@matthewhall2 matthewhall2 force-pushed the fmin_fmax_dmin_dmax branch 3 times, most recently from 2f62f58 to 15a2d2b Compare September 27, 2024 19:18
@matthewhall2 matthewhall2 force-pushed the fmin_fmax_dmin_dmax branch 5 times, most recently from db6022b to ccc837d Compare October 4, 2024 20:42
@matthewhall2 matthewhall2 changed the title Support IEEE-754 w.r.t fmin/fmax/dmin/dmax Support IEEE-754 for fmin/fmax/dmin/dmax nodes Oct 4, 2024
@matthewhall2
Copy link
Contributor Author

can you review please @r30shah ?


TR::Register* lhsReg = cg->gprClobberEvaluate(lhsNode);
TR::Register* rhsReg = cg->evaluate(rhsNode);
TR::Node * lhsNode = node->getChild(0);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we rename lhsNode and rhsNode ?

{
compareRROp = node->getOpCode().isDouble() ? TR::InstOpCode::CDBR : TR::InstOpCode::CEBR;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like you have extra indentation here in the next else block

}

TR::LabelSymbol* cFlowRegionEnd = generateLabelSymbol(cg);
TR::LabelSymbol* swap = generateLabelSymbol(cg);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I may have missed this in initial review, but swapValue or something meaningful name should be used.

if (isFloatingPointOp)
{
/*
Check for NaN operands for float and double
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@@ -253,6 +253,8 @@ class OMR_EXTENSIBLE TreeEvaluator: public OMR::TreeEvaluator
static TR::Register *MethodEnterHookEvaluator(TR::Node *node, TR::CodeGenerator *cg);
static TR::Register *MethodExitHookEvaluator(TR::Node *node, TR::CodeGenerator *cg);
static TR::Register *PassThroughEvaluator(TR::Node *node, TR::CodeGenerator *cg);
static TR::Register *fpMinMaxVectorHelper(TR::Node *node, TR::CodeGenerator *cg);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Either here or where the function is implemented, we should add a doxygen styled comments for function description(Take a look at functions in z/OMRTreeEvaluator.hpp [1])

[1]. https://github.com/eclipse/omr/blob/13d47ea4def377422793a23813b6b25c76bbd56d/compiler/z/codegen/OMRTreeEvaluator.hpp#L924-L951

{
result = OMR::Z::TreeEvaluator::xmaxxminhelper(node, cg);
}
generateRREInstruction(cg, TR::InstOpCode::LTDBR, node, result, result);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should add a brief explanation for these Load Test instructions.

static TR::Register*
xmaxxminHelper(TR::Node* node, TR::CodeGenerator* cg, TR::InstOpCode::Mnemonic compareRROp, TR::InstOpCode::S390BranchCondition branchCond, TR::InstOpCode::Mnemonic moveRROp)
TR::Register *
OMR::Z::TreeEvaluator::xmaxxminhelper(TR::Node * node, TR::CodeGenerator * cg)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the original name xmaxminHelper should be ok (You missed the caps in Helper when refactoring).

Comment on lines 359 to 365
/* Check for NaN operands for float and double
* Support float and double +0/-0 comparisons adhering to IEEE 754 standard
* Checking if operands are equal, then branching to equalRegion, otherwise
* fall through for NaN case handling
*/
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/* Check for NaN operands for float and double
* Support float and double +0/-0 comparisons adhering to IEEE 754 standard
* Checking if operands are equal, then branching to equalRegion, otherwise
* fall through for NaN case handling
*/
/**
* Check for NaN operands for float and double
* Support float and double +0/-0 comparisons adhering to IEEE 754 standard
* Checking if operands are equal, then branching to equalRegion, otherwise
* fall through for NaN case handling
*/

TR::Register *
OMR::Z::TreeEvaluator::fpMinMaxVectorHelper(TR::Node *node, TR::CodeGenerator *cg)
{
TR_ASSERT(node->getNumChildren() >= 1 || node->getNumChildren() <= 2, "node has incorrect number of children");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should combine this two asserts.

Copy link
Contributor

@r30shah r30shah left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Last nitpicks

@@ -254,6 +254,41 @@ class OMR_EXTENSIBLE TreeEvaluator: public OMR::TreeEvaluator
static TR::Register *MethodExitHookEvaluator(TR::Node *node, TR::CodeGenerator *cg);
static TR::Register *PassThroughEvaluator(TR::Node *node, TR::CodeGenerator *cg);

/** \brief
* This is a helper function used for floating point max/min operations
* when SIMD instructions are available. +0.0 compares as strictly
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should mention that it generates Vector Instructions when available for max/min operations.

@r30shah
Copy link
Contributor

r30shah commented Oct 8, 2024

This PR has to be merged first. The only potential issue is that OpenJ9 will follow the IEEE spec and not the Java spec until the openj9 PR is merged

Looking at your openJ9 change, is this statement true? Without OpenJ9 change , Java should not be inlining max and min for floating point types right >?

@matthewhall2
Copy link
Contributor Author

matthewhall2 commented Oct 8, 2024

Looking at your openJ9 change, is this statement true? Without OpenJ9 change , Java should not be inlining max and min for floating point types right >?

ah yes, they won't be inlined without the openj9 change. But the openj9 PR won't compile without this PR, so this one still needs to be merged first.

@matthewhall2
Copy link
Contributor Author

@hzongaro can you review when you get the chance?

@matthewhall2 matthewhall2 force-pushed the fmin_fmax_dmin_dmax branch 3 times, most recently from 3511fe1 to cc9736b Compare October 10, 2024 13:25
Add Math.max/min/F/D to list of recognized Java methods to:
- Disable special aliasing rules since they are intrinsically optimized
- Disable implicit asynchronous checks

Signed-off-by: Sarwat Shaheen <[email protected]>
@hzongaro hzongaro requested review from hzongaro and removed request for fjeremic and vijaysun-omr October 10, 2024 14:03
Copy link
Contributor

@hzongaro hzongaro left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the changes look good overall. Just a few minor comments.

May I also ask you to update the commit comments to indicate that these changes are for inline code for z/Architecture only?

compiler/z/codegen/ControlFlowEvaluator.cpp Outdated Show resolved Hide resolved
compiler/z/codegen/ControlFlowEvaluator.cpp Outdated Show resolved Hide resolved
compiler/z/codegen/ControlFlowEvaluator.cpp Outdated Show resolved Hide resolved
compiler/z/codegen/ControlFlowEvaluator.cpp Outdated Show resolved Hide resolved
compiler/z/codegen/ControlFlowEvaluator.cpp Outdated Show resolved Hide resolved
compiler/z/codegen/ControlFlowEvaluator.cpp Outdated Show resolved Hide resolved
@matthewhall2 matthewhall2 requested a review from hzongaro October 10, 2024 20:47
@matthewhall2 matthewhall2 force-pushed the fmin_fmax_dmin_dmax branch 2 times, most recently from 581db9b to d54e28e Compare October 11, 2024 13:30
@matthewhall2 matthewhall2 force-pushed the fmin_fmax_dmin_dmax branch 2 times, most recently from 9bd6113 to d3aff89 Compare October 11, 2024 18:21
@matthewhall2 matthewhall2 requested a review from hzongaro October 11, 2024 18:22
Copy link
Contributor

@hzongaro hzongaro left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good. Just one further minor comment.

compiler/z/codegen/ControlFlowEvaluator.cpp Outdated Show resolved Hide resolved
- changes are only for the floating point min/max evaluators on
  z/Architecture
- +0.0 compares as strictly greater than -0.0
- Refactored xmaxxminHelper to into a more generic helper function that
  does not change NaNs
- added helper for fmin/fmax/... nodes that uses SIMD instructions when
  available that has same behaviour as xmaxxminHelper on floats
- idea is to enable other evaluators to use these helpers and deal with
  NaNs as they see fit
- omr evaluators support IEEE-754 w.r.t zeros and NaNs (returns the
  quiet NaN corresponding to the first NaN given if present)

Signed-off-by: Matthew Hall <[email protected]>
Copy link
Contributor

@r30shah r30shah left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @matthewhall2 for the changes, it looks good to me, will wait for @hzongaro to approve and merge this before I go on and look at the J9 changes.

@r30shah
Copy link
Contributor

r30shah commented Oct 18, 2024

jenkins build zos,zlinux

Copy link
Contributor

@hzongaro hzongaro left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good. Thanks for addressing the comments!

@hzongaro hzongaro merged commit ad12524 into eclipse-omr:master Oct 21, 2024
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants