Skip to content

Commit 9f5f9f5

Browse files
committed
* add all possible SELECT(a < b, a, b) to nativeMin(a, b) transforms
1 parent ff05c8a commit 9f5f9f5

1 file changed

Lines changed: 54 additions & 1 deletion

File tree

src/coreclr/jit/ifconversion.cpp

Lines changed: 54 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ class OptIfConversionDsc
5656
GenTree* TrySelectToCnsOpCond(GenTreeConditional* select);
5757
GenTree* TrySelectToLclOpCond(GenTreeConditional* select);
5858
GenTree* TrySelectToCondOpLcl(GenTreeConditional* select);
59+
GenTree* TrySelectToMinMax(GenTreeConditional* select);
5960

6061
#ifdef DEBUG
6162
void IfConvertDump();
@@ -205,7 +206,7 @@ bool OptIfConversionDsc::IfConvertCheckStmts(BasicBlock* block, IfConvertOperati
205206
}
206207

207208
// Ensure the operation has integer type.
208-
if (!varTypeIsIntegralOrI(tree))
209+
if (!varTypeIsIntegralOrI(tree) && !varTypeIsFloating(tree))
209210
{
210211
return false;
211212
}
@@ -636,6 +637,12 @@ bool OptIfConversionDsc::optIfConvert(int* pReachabilityBudget)
636637
}
637638
}
638639

640+
// We only produce float SELECTs for optimization into non-SELECTs, otherwise bail
641+
if (varTypeIsFloating(select))
642+
{
643+
return true;
644+
}
645+
639646
#ifdef TARGET_RISCV64
640647
if (select->OperIs(GT_SELECT))
641648
{
@@ -739,6 +746,12 @@ GenTree* OptIfConversionDsc::TryOptimizeSelect(GenTreeConditional* select)
739746
return opt;
740747
}
741748

749+
opt = TrySelectToMinMax(select);
750+
if (opt != nullptr)
751+
{
752+
return opt;
753+
}
754+
742755
return nullptr;
743756
}
744757

@@ -960,6 +973,46 @@ GenTree* OptIfConversionDsc::TrySelectToCondOpLcl(GenTreeConditional* select)
960973
return nullptr;
961974
}
962975

976+
GenTree* OptIfConversionDsc::TrySelectToMinMax(GenTreeConditional* select)
977+
{
978+
#ifdef TARGET_XARCH
979+
GenTree* condInput = select->gtCond;
980+
GenTree* trueInput = select->gtOp1;
981+
GenTree* falseInput = select->gtOp2;
982+
983+
if (!varTypeIsFloating(select) || !varTypeIsFloating(condInput->gtGetOp1()) || !varTypeIsFloating(condInput->gtGetOp2()))
984+
{
985+
return nullptr;
986+
}
987+
988+
GenCondition cond = GenCondition::FromFloatRelop(condInput);
989+
if (cond.IsUnordered() || !cond.Is(GenCondition::Code::FLT, GenCondition::Code::FGT))
990+
{
991+
return nullptr;
992+
}
993+
994+
bool isMax = cond.Is(GenCondition::Code::FGT);
995+
bool reversed = !GenTree::Compare(trueInput, condInput->gtGetOp1());
996+
if (reversed)
997+
{
998+
// 'return a > b ? b : a;' has a GT but computes the min
999+
isMax = !isMax;
1000+
std::swap(trueInput, falseInput);
1001+
}
1002+
1003+
if (GenTree::Compare(trueInput, condInput->gtGetOp1()) &&
1004+
GenTree::Compare(falseInput, condInput->gtGetOp2()->gtEffectiveVal()))
1005+
{
1006+
return m_compiler->gtNewSimdMinMaxNativeNode(select->TypeGet(),
1007+
reversed ? condInput->gtGetOp2() : condInput->gtGetOp1(),
1008+
reversed ? condInput->gtGetOp1() : condInput->gtGetOp2(),
1009+
select->TypeGet(), 0, isMax);
1010+
}
1011+
1012+
#endif
1013+
return nullptr;
1014+
}
1015+
9631016
//-----------------------------------------------------------------------------
9641017
// optIfConversion: If conversion
9651018
//

0 commit comments

Comments
 (0)