@@ -135,7 +135,8 @@ Z80LegalizerInfo::Z80LegalizerInfo(const Z80Subtarget &STI,
135
135
.clampScalar (1 , s8, s8)
136
136
.clampScalar (0 , s8, s64);
137
137
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})
139
140
.custom ();
140
141
141
142
getActionDefinitionsBuilder ({G_INTRINSIC_TRUNC,
@@ -179,8 +180,6 @@ Z80LegalizerInfo::Z80LegalizerInfo(const Z80Subtarget &STI,
179
180
getActionDefinitionsBuilder (G_INTRINSIC_LRINT)
180
181
.libcallFor ({{s32, s32}, {s32, s64}});
181
182
182
- getActionDefinitionsBuilder (G_FPOWI).lower ();
183
-
184
183
getActionDefinitionsBuilder (G_FCOPYSIGN)
185
184
.libcallFor ({{s32, s32}, {s64, s64}});
186
185
@@ -225,12 +224,26 @@ Z80LegalizerInfo::Z80LegalizerInfo(const Z80Subtarget &STI,
225
224
.legalForCartesianProduct (LegalTypes, {s1})
226
225
.clampScalar (0 , s8, sMax );
227
226
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})
234
247
.lower ();
235
248
236
249
getActionDefinitionsBuilder (G_CTPOP)
@@ -276,6 +289,8 @@ LegalizerHelper::LegalizeResult Z80LegalizerInfo::legalizeCustomMaybeLegal(
276
289
case G_ICMP:
277
290
case G_FCMP:
278
291
return legalizeCompare (Helper, MI);
292
+ case G_UMULO:
293
+ return legalizeMultiplyWithOverflow (Helper, MI);
279
294
case G_MEMCPY:
280
295
case G_MEMMOVE:
281
296
case G_MEMSET:
@@ -554,6 +569,36 @@ Z80LegalizerInfo::legalizeCompare(LegalizerHelper &Helper,
554
569
return LegalizerHelper::Legalized;
555
570
}
556
571
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
+
557
602
LegalizerHelper::LegalizeResult Z80LegalizerInfo::legalizeMemIntrinsic (
558
603
LegalizerHelper &Helper, MachineInstr &MI,
559
604
LostDebugLocObserver &LocObserver) const {
0 commit comments