@@ -89,14 +89,17 @@ WebAssemblyLegalizerInfo::WebAssemblyLegalizerInfo(
8989 .clampScalar (0 , s32, s64);
9090
9191 getActionDefinitionsBuilder ({G_ASHR, G_LSHR, G_SHL, G_CTLZ, G_CTLZ_ZERO_UNDEF,
92- G_CTTZ, G_CTTZ_ZERO_UNDEF, G_CTPOP, G_FSHL,
93- G_FSHR})
92+ G_CTTZ, G_CTTZ_ZERO_UNDEF, G_CTPOP})
9493 .legalFor ({{s32, s32}, {s64, s64}})
9594 .widenScalarToNextPow2 (0 )
9695 .clampScalar (0 , s32, s64)
9796 .minScalarSameAs (1 , 0 )
9897 .maxScalarSameAs (1 , 0 );
9998
99+ getActionDefinitionsBuilder ({G_FSHL, G_FSHR})
100+ .legalFor ({{s32, s32}, {s64, s64}})
101+ .lower ();
102+
100103 getActionDefinitionsBuilder ({G_SCMP, G_UCMP}).lower ();
101104
102105 getActionDefinitionsBuilder ({G_AND, G_OR, G_XOR})
@@ -123,6 +126,12 @@ WebAssemblyLegalizerInfo::WebAssemblyLegalizerInfo(
123126 .libcallFor ({s32, s64})
124127 .minScalar (0 , s32);
125128
129+ getActionDefinitionsBuilder (G_LROUND).libcallForCartesianProduct ({s32},
130+ {s32, s64});
131+
132+ getActionDefinitionsBuilder (G_LLROUND).libcallForCartesianProduct ({s64},
133+ {s32, s64});
134+
126135 getActionDefinitionsBuilder (G_FCOPYSIGN)
127136 .legalFor ({s32, s64})
128137 .minScalar (0 , s32)
@@ -154,9 +163,8 @@ WebAssemblyLegalizerInfo::WebAssemblyLegalizerInfo(
154163 {s64, p0, s8, 1 },
155164 {s64, p0, s16, 1 },
156165 {s64, p0, s32, 1 }})
157- .widenScalarToNextPow2 (0 )
158- .lowerIfMemSizeNotByteSizePow2 ()
159- .clampScalar (0 , s32, s64);
166+ .clampScalar (0 , s32, s64)
167+ .lowerIfMemSizeNotByteSizePow2 ();
160168
161169 getActionDefinitionsBuilder (G_STORE)
162170 .legalForTypesWithMemDesc (
@@ -167,9 +175,8 @@ WebAssemblyLegalizerInfo::WebAssemblyLegalizerInfo(
167175 {s64, p0, s8, 1 },
168176 {s64, p0, s16, 1 },
169177 {s64, p0, s32, 1 }})
170- .widenScalarToNextPow2 (0 )
171- .lowerIfMemSizeNotByteSizePow2 ()
172- .clampScalar (0 , s32, s64);
178+ .clampScalar (0 , s32, s64)
179+ .lowerIfMemSizeNotByteSizePow2 ();
173180
174181 getActionDefinitionsBuilder ({G_ZEXTLOAD, G_SEXTLOAD})
175182 .legalForTypesWithMemDesc ({{s32, p0, s8, 1 },
@@ -178,10 +185,8 @@ WebAssemblyLegalizerInfo::WebAssemblyLegalizerInfo(
178185 {s64, p0, s8, 1 },
179186 {s64, p0, s16, 1 },
180187 {s64, p0, s32, 1 }})
181- .widenScalarToNextPow2 (0 )
182- .lowerIfMemSizeNotByteSizePow2 ()
183188 .clampScalar (0 , s32, s64)
184- .lower ();
189+ .lowerIfMemSizeNotByteSizePow2 ();
185190
186191 if (ST.hasBulkMemoryOpt ()) {
187192 getActionDefinitionsBuilder (G_BZERO).unsupported ();
@@ -204,7 +209,7 @@ WebAssemblyLegalizerInfo::WebAssemblyLegalizerInfo(
204209
205210 // TODO: figure out how to combine G_ANYEXT of G_ASSERT_{S|Z}EXT (or
206211 // appropriate G_AND and G_SEXT_IN_REG?) to a G_{S|Z}EXT + G_ASSERT_{S|Z}EXT
207- // for better optimization (since G_ANYEXT lowers to a ZEXT or SEXT
212+ // for better optimization (since G_ANYEXT will lower to a ZEXT or SEXT
208213 // instruction anyway).
209214
210215 getActionDefinitionsBuilder (G_ANYEXT)
@@ -221,8 +226,7 @@ WebAssemblyLegalizerInfo::WebAssemblyLegalizerInfo(
221226 if (ST.hasSignExt ()) {
222227 getActionDefinitionsBuilder (G_SEXT_INREG)
223228 .clampScalar (0 , s32, s64)
224- .customFor ({s32, s64})
225- .lower ();
229+ .customFor ({s32, s64});
226230 } else {
227231 getActionDefinitionsBuilder (G_SEXT_INREG).lower ();
228232 }
@@ -242,23 +246,42 @@ WebAssemblyLegalizerInfo::WebAssemblyLegalizerInfo(
242246 .legalForCartesianProduct ({s32, s64}, {p0})
243247 .clampScalar (0 , s32, s64);
244248
249+ getActionDefinitionsBuilder (G_DYN_STACKALLOC).lowerFor ({{p0, p0s}});
250+
251+ getActionDefinitionsBuilder ({G_STACKSAVE, G_STACKRESTORE}).lower ();
252+
245253 getLegacyLegalizerInfo ().computeTables ();
246254}
247255
248256bool WebAssemblyLegalizerInfo::legalizeCustom (
249257 LegalizerHelper &Helper, MachineInstr &MI,
250258 LostDebugLocObserver &LocObserver) const {
259+ auto &MRI = *Helper.MIRBuilder .getMRI ();
260+ auto &MIRBuilder = Helper.MIRBuilder ;
261+
251262 switch (MI.getOpcode ()) {
252263 case TargetOpcode::G_SEXT_INREG: {
264+ assert (MI.getOperand (2 ).isImm () && " Expected immediate" );
265+
253266 // Mark only 8/16/32-bit SEXT_INREG as legal
254- auto [DstType, SrcType] = MI.getFirst2LLTs ();
267+ auto [DstReg, SrcReg] = MI.getFirst2Regs ();
268+ auto DstType = MRI.getType (DstReg);
255269 auto ExtFromWidth = MI.getOperand (2 ).getImm ();
256270
257271 if (ExtFromWidth == 8 || ExtFromWidth == 16 ||
258272 (DstType.getScalarSizeInBits () == 64 && ExtFromWidth == 32 )) {
259273 return true ;
260274 }
261- return false ;
275+
276+ Register TmpRes = MRI.createGenericVirtualRegister (DstType);
277+
278+ auto MIBSz = MIRBuilder.buildConstant (
279+ DstType, DstType.getScalarSizeInBits () - ExtFromWidth);
280+ MIRBuilder.buildShl (TmpRes, SrcReg, MIBSz->getOperand (0 ));
281+ MIRBuilder.buildAShr (DstReg, TmpRes, MIBSz->getOperand (0 ));
282+ MI.eraseFromParent ();
283+
284+ return true ;
262285 }
263286 case TargetOpcode::G_MEMSET: {
264287 // Anyext the value being set to 32 bit (only the bottom 8 bits are read by
0 commit comments