Skip to content

Commit

Permalink
Support NaN values w.r.t fmax/fmin/dmax/dmin opcodes on S390
Browse files Browse the repository at this point in the history
This commit adds support to the S390 MaxMin evaluator to handle NaN operands for [fd]min/max opcodes.

- Add NaN checks for f/d operands and set return register to NaN if either operands are NaN

Closes: #5157

Signed-off-by: Sarwat Shaheen [email protected]
  • Loading branch information
sarwat12 committed Feb 1, 2024
1 parent 4574b93 commit 104d0d3
Showing 1 changed file with 19 additions and 2 deletions.
21 changes: 19 additions & 2 deletions compiler/z/codegen/ControlFlowEvaluator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -338,21 +338,38 @@ xmaxxminHelper(TR::Node* node, TR::CodeGenerator* cg, TR::InstOpCode::Mnemonic c
generateS390LabelInstruction(cg, TR::InstOpCode::label, node, cFlowRegionStart);
cFlowRegionStart->setStartInternalControlFlow();

//Checking common Condition Code and branching to cFlowRegionEnd
generateRREInstruction(cg, compareRROp, node, lhsReg, rhsReg);
generateS390BranchInstruction(cg, TR::InstOpCode::BRC, branchCond, node, cFlowRegionEnd);

//Check for NaN operands for float and double
if (node->getOpCode().isDouble() || node->getOpCode().isFloat())
{
if (node->getOpCode().isDouble())
{
// If first operand is NaN, then we are done, otherwise fallthrough to move second operand as result
generateRREInstruction(cg, TR::InstOpCode::LTDBR, node, lhsReg, lhsReg);
generateS390BranchInstruction(cg, TR::InstOpCode::BRC, TR::InstOpCode::COND_CC3, node, cFlowRegionEnd);
}
else if (node->getOpCode().isFloat())
{
// If first operand is NaN, then we are done, otherwise fallthrough to move second operand as result
generateRREInstruction(cg, TR::InstOpCode::LTEBR, node, lhsReg, lhsReg);
generateS390BranchInstruction(cg, TR::InstOpCode::BRC, TR::InstOpCode::COND_CC3, node, cFlowRegionEnd);
}
}

//Move resulting operand to lhsReg as fallthrough for alternate Condition Code
generateRREInstruction(cg, moveRROp, node, lhsReg, rhsReg);

TR::RegisterDependencyConditions* deps = new (cg->trHeapMemory()) TR::RegisterDependencyConditions(0, 2, cg);

deps->addPostConditionIfNotAlreadyInserted(lhsReg, TR::RealRegister::AssignAny);
deps->addPostConditionIfNotAlreadyInserted(rhsReg, TR::RealRegister::AssignAny);

generateS390LabelInstruction(cg, TR::InstOpCode::label, node, cFlowRegionEnd, deps);
cFlowRegionEnd->setEndInternalControlFlow();

node->setRegister(lhsReg);

cg->decReferenceCount(lhsNode);
cg->decReferenceCount(rhsNode);

Expand Down

0 comments on commit 104d0d3

Please sign in to comment.