[GlobalIsel][AArch64] Legalize G_SCMP and G_UCMP (#99820)
https://github.com/llvm/llvm-project/pull/91871
https://github.com/llvm/llvm-project/pull/98774
diff --git a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
index 640a425..644dbae 100644
--- a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
@@ -4006,6 +4006,9 @@
case G_UMIN:
case G_UMAX:
return lowerMinMax(MI);
+ case G_SCMP:
+ case G_UCMP:
+ return lowerThreewayCompare(MI);
case G_FCOPYSIGN:
return lowerFCopySign(MI);
case G_FMINNUM:
@@ -7270,6 +7273,36 @@
}
LegalizerHelper::LegalizeResult
+LegalizerHelper::lowerThreewayCompare(MachineInstr &MI) {
+ GSUCmp *Cmp = cast<GSUCmp>(&MI);
+
+ Register Dst = Cmp->getReg(0);
+ LLT DstTy = MRI.getType(Dst);
+ LLT CmpTy = DstTy.changeElementSize(1);
+
+ CmpInst::Predicate LTPredicate = Cmp->isSigned()
+ ? CmpInst::Predicate::ICMP_SLT
+ : CmpInst::Predicate::ICMP_ULT;
+ CmpInst::Predicate GTPredicate = Cmp->isSigned()
+ ? CmpInst::Predicate::ICMP_SGT
+ : CmpInst::Predicate::ICMP_UGT;
+
+ auto One = MIRBuilder.buildConstant(DstTy, 1);
+ auto Zero = MIRBuilder.buildConstant(DstTy, 0);
+ auto IsGT = MIRBuilder.buildICmp(GTPredicate, CmpTy, Cmp->getLHSReg(),
+ Cmp->getRHSReg());
+ auto SelectZeroOrOne = MIRBuilder.buildSelect(DstTy, IsGT, One, Zero);
+
+ auto MinusOne = MIRBuilder.buildConstant(DstTy, -1);
+ auto IsLT = MIRBuilder.buildICmp(LTPredicate, CmpTy, Cmp->getLHSReg(),
+ Cmp->getRHSReg());
+ MIRBuilder.buildSelect(Dst, IsLT, MinusOne, SelectZeroOrOne);
+
+ MI.eraseFromParent();
+ return Legalized;
+}
+
+LegalizerHelper::LegalizeResult
LegalizerHelper::lowerFCopySign(MachineInstr &MI) {
auto [Dst, DstTy, Src0, Src0Ty, Src1, Src1Ty] = MI.getFirst3RegLLTs();
const int Src0Size = Src0Ty.getScalarSizeInBits();