Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 57 additions & 3 deletions src/coreclr/jit/ifconversion.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ class OptIfConversionDsc
GenTree* TrySelectToCnsOpCond(GenTreeConditional* select);
GenTree* TrySelectToLclOpCond(GenTreeConditional* select);
GenTree* TrySelectToCondOpLcl(GenTreeConditional* select);
GenTree* TrySelectToMinMax(GenTreeConditional* select);

#ifdef DEBUG
void IfConvertDump();
Expand Down Expand Up @@ -205,7 +206,7 @@ bool OptIfConversionDsc::IfConvertCheckStmts(BasicBlock* block, IfConvertOperati
}

// Ensure the operation has integer type.
if (!varTypeIsIntegralOrI(tree))
if (!varTypeIsIntegralOrI(tree) && !varTypeIsFloating(tree))
{
return false;
}
Comment on lines 208 to 212
Expand Down Expand Up @@ -636,14 +637,20 @@ bool OptIfConversionDsc::optIfConvert(int* pReachabilityBudget)
}
}

#ifdef TARGET_RISCV64
if (select->OperIs(GT_SELECT))
{
#ifdef TARGET_RISCV64
JITDUMP("Skipping if-conversion that could not be optimized to ordinary operations\n");
return true;
}
#endif
Comment on lines 640 to 645
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

we call gtNewConditionalNode before which counts as change


// We only produce float SELECTs for optimization into non-SELECTs, otherwise bail
if (varTypeIsFloating(select))
{
return true;
Comment thread
BoyBaykiller marked this conversation as resolved.
}
}

// Use the SELECT as the source of the Then STORE/RETURN.
m_thenOperation.node->AddAllEffectsFlags(select);
if (m_mainOper == GT_STORE_LCL_VAR)
Expand Down Expand Up @@ -739,6 +746,12 @@ GenTree* OptIfConversionDsc::TryOptimizeSelect(GenTreeConditional* select)
return opt;
}

opt = TrySelectToMinMax(select);
if (opt != nullptr)
{
return opt;
}

return nullptr;
}

Expand Down Expand Up @@ -960,6 +973,47 @@ GenTree* OptIfConversionDsc::TrySelectToCondOpLcl(GenTreeConditional* select)
return nullptr;
}

GenTree* OptIfConversionDsc::TrySelectToMinMax(GenTreeConditional* select)
{
#ifdef TARGET_XARCH
GenTree* condInput = select->gtCond;
GenTree* trueInput = select->gtOp1;
GenTree* falseInput = select->gtOp2;

if (!varTypeIsFloating(select) || !varTypeIsFloating(condInput->gtGetOp1()) ||
!varTypeIsFloating(condInput->gtGetOp2()))
{
return nullptr;
}

GenCondition cond = GenCondition::FromFloatRelop(condInput);
if (cond.IsUnordered() || !cond.Is(GenCondition::Code::FLT, GenCondition::Code::FGT))
{
return nullptr;
}

bool isMax = cond.Is(GenCondition::Code::FGT);
bool reversed = !GenTree::Compare(trueInput, condInput->gtGetOp1());
if (reversed)
{
// 'return a > b ? b : a;' has a GT but computes the min
isMax = !isMax;
std::swap(trueInput, falseInput);
}

if (GenTree::Compare(trueInput, condInput->gtGetOp1()) &&
GenTree::Compare(falseInput, condInput->gtGetOp2()->gtEffectiveVal()))
{
return m_compiler->gtNewSimdMinMaxNativeNode(select->TypeGet(),
reversed ? condInput->gtGetOp2() : condInput->gtGetOp1(),
reversed ? condInput->gtGetOp1() : condInput->gtGetOp2(),
select->TypeGet(), 0, isMax);
}

#endif
return nullptr;
}

//-----------------------------------------------------------------------------
// optIfConversion: If conversion
//
Expand Down
Loading