@@ -135,7 +135,8 @@ Z80LegalizerInfo::Z80LegalizerInfo(const Z80Subtarget &STI,
135135 .clampScalar (1 , s8, s8)
136136 .clampScalar (0 , s8, s64);
137137
138- getActionDefinitionsBuilder ({G_FSHL, G_FSHR, G_MEMCPY, G_MEMMOVE, G_MEMSET})
138+ getActionDefinitionsBuilder (
139+ {G_FSHL, G_FSHR, G_UMULO, G_MEMCPY, G_MEMMOVE, G_MEMSET})
139140 .custom ();
140141
141142 getActionDefinitionsBuilder ({G_INTRINSIC_TRUNC,
@@ -179,8 +180,6 @@ Z80LegalizerInfo::Z80LegalizerInfo(const Z80Subtarget &STI,
179180 getActionDefinitionsBuilder (G_INTRINSIC_LRINT)
180181 .libcallFor ({{s32, s32}, {s32, s64}});
181182
182- getActionDefinitionsBuilder (G_FPOWI).lower ();
183-
184183 getActionDefinitionsBuilder (G_FCOPYSIGN)
185184 .libcallFor ({{s32, s32}, {s64, s64}});
186185
@@ -225,12 +224,26 @@ Z80LegalizerInfo::Z80LegalizerInfo(const Z80Subtarget &STI,
225224 .legalForCartesianProduct (LegalTypes, {s1})
226225 .clampScalar (0 , s8, sMax );
227226
228- getActionDefinitionsBuilder ({G_ABS, G_DYN_STACKALLOC, G_SEXT_INREG,
229- G_CTLZ_ZERO_UNDEF, G_CTTZ_ZERO_UNDEF,
230- G_CTLZ, G_CTTZ, G_BSWAP,
231- G_SMULO, G_UMULO, G_SMULH, G_UMULH,
232- G_SMIN, G_SMAX, G_UMIN, G_UMAX,
233- G_UADDSAT, G_SADDSAT, G_USUBSAT, G_SSUBSAT})
227+ getActionDefinitionsBuilder ({G_ABS,
228+ G_DYN_STACKALLOC,
229+ G_SEXT_INREG,
230+ G_CTLZ_ZERO_UNDEF,
231+ G_CTTZ_ZERO_UNDEF,
232+ G_CTLZ,
233+ G_CTTZ,
234+ G_BSWAP,
235+ G_SMULO,
236+ G_SMULH,
237+ G_UMULH,
238+ G_SMIN,
239+ G_SMAX,
240+ G_UMIN,
241+ G_UMAX,
242+ G_UADDSAT,
243+ G_SADDSAT,
244+ G_USUBSAT,
245+ G_SSUBSAT,
246+ G_FPOWI})
234247 .lower ();
235248
236249 getActionDefinitionsBuilder (G_CTPOP)
@@ -276,6 +289,8 @@ LegalizerHelper::LegalizeResult Z80LegalizerInfo::legalizeCustomMaybeLegal(
276289 case G_ICMP:
277290 case G_FCMP:
278291 return legalizeCompare (Helper, MI);
292+ case G_UMULO:
293+ return legalizeMultiplyWithOverflow (Helper, MI);
279294 case G_MEMCPY:
280295 case G_MEMMOVE:
281296 case G_MEMSET:
@@ -554,6 +569,36 @@ Z80LegalizerInfo::legalizeCompare(LegalizerHelper &Helper,
554569 return LegalizerHelper::Legalized;
555570}
556571
572+ LegalizerHelper::LegalizeResult
573+ Z80LegalizerInfo::legalizeMultiplyWithOverflow (LegalizerHelper &Helper,
574+ MachineInstr &MI) const {
575+ MachineIRBuilder &MIRBuilder = Helper.MIRBuilder ;
576+ MIRBuilder.setInstrAndDebugLoc (MI);
577+ MachineRegisterInfo &MRI = *MIRBuilder.getMRI ();
578+
579+ assert (MI.getOpcode () == G_UMULO && " Unexpected opcode" );
580+
581+ Register MulReg = MI.getOperand (0 ).getReg ();
582+ Register OverflowReg = MI.getOperand (1 ).getReg ();
583+ LLT Ty = MRI.getType (MulReg);
584+
585+ Register LHSReg = MI.getOperand (2 ).getReg ();
586+ Register RHSReg = MI.getOperand (3 ).getReg ();
587+
588+ MIRBuilder.buildMul (MulReg, LHSReg, RHSReg);
589+
590+ auto One = MIRBuilder.buildConstant (Ty, 1 );
591+ auto Max =
592+ MIRBuilder.buildConstant (Ty, APInt::getMaxValue (Ty.getSizeInBits ()));
593+ MIRBuilder.buildICmp (
594+ CmpInst::ICMP_UGT, OverflowReg, LHSReg,
595+ MIRBuilder.buildInstr (G_UDIV, {Ty},
596+ {Max, MIRBuilder.buildUMax (Ty, RHSReg, One)}));
597+
598+ MI.eraseFromParent ();
599+ return LegalizerHelper::Legalized;
600+ }
601+
557602LegalizerHelper::LegalizeResult Z80LegalizerInfo::legalizeMemIntrinsic (
558603 LegalizerHelper &Helper, MachineInstr &MI,
559604 LostDebugLocObserver &LocObserver) const {
0 commit comments