@@ -89,14 +89,17 @@ WebAssemblyLegalizerInfo::WebAssemblyLegalizerInfo(
89
89
.clampScalar (0 , s32, s64);
90
90
91
91
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})
94
93
.legalFor ({{s32, s32}, {s64, s64}})
95
94
.widenScalarToNextPow2 (0 )
96
95
.clampScalar (0 , s32, s64)
97
96
.minScalarSameAs (1 , 0 )
98
97
.maxScalarSameAs (1 , 0 );
99
98
99
+ getActionDefinitionsBuilder ({G_FSHL, G_FSHR})
100
+ .legalFor ({{s32, s32}, {s64, s64}})
101
+ .lower ();
102
+
100
103
getActionDefinitionsBuilder ({G_SCMP, G_UCMP}).lower ();
101
104
102
105
getActionDefinitionsBuilder ({G_AND, G_OR, G_XOR})
@@ -123,6 +126,12 @@ WebAssemblyLegalizerInfo::WebAssemblyLegalizerInfo(
123
126
.libcallFor ({s32, s64})
124
127
.minScalar (0 , s32);
125
128
129
+ getActionDefinitionsBuilder (G_LROUND).libcallForCartesianProduct ({s32},
130
+ {s32, s64});
131
+
132
+ getActionDefinitionsBuilder (G_LLROUND).libcallForCartesianProduct ({s64},
133
+ {s32, s64});
134
+
126
135
getActionDefinitionsBuilder (G_FCOPYSIGN)
127
136
.legalFor ({s32, s64})
128
137
.minScalar (0 , s32)
@@ -154,9 +163,8 @@ WebAssemblyLegalizerInfo::WebAssemblyLegalizerInfo(
154
163
{s64, p0, s8, 1 },
155
164
{s64, p0, s16, 1 },
156
165
{s64, p0, s32, 1 }})
157
- .widenScalarToNextPow2 (0 )
158
- .lowerIfMemSizeNotByteSizePow2 ()
159
- .clampScalar (0 , s32, s64);
166
+ .clampScalar (0 , s32, s64)
167
+ .lowerIfMemSizeNotByteSizePow2 ();
160
168
161
169
getActionDefinitionsBuilder (G_STORE)
162
170
.legalForTypesWithMemDesc (
@@ -167,9 +175,8 @@ WebAssemblyLegalizerInfo::WebAssemblyLegalizerInfo(
167
175
{s64, p0, s8, 1 },
168
176
{s64, p0, s16, 1 },
169
177
{s64, p0, s32, 1 }})
170
- .widenScalarToNextPow2 (0 )
171
- .lowerIfMemSizeNotByteSizePow2 ()
172
- .clampScalar (0 , s32, s64);
178
+ .clampScalar (0 , s32, s64)
179
+ .lowerIfMemSizeNotByteSizePow2 ();
173
180
174
181
getActionDefinitionsBuilder ({G_ZEXTLOAD, G_SEXTLOAD})
175
182
.legalForTypesWithMemDesc ({{s32, p0, s8, 1 },
@@ -178,10 +185,8 @@ WebAssemblyLegalizerInfo::WebAssemblyLegalizerInfo(
178
185
{s64, p0, s8, 1 },
179
186
{s64, p0, s16, 1 },
180
187
{s64, p0, s32, 1 }})
181
- .widenScalarToNextPow2 (0 )
182
- .lowerIfMemSizeNotByteSizePow2 ()
183
188
.clampScalar (0 , s32, s64)
184
- .lower ();
189
+ .lowerIfMemSizeNotByteSizePow2 ();
185
190
186
191
if (ST.hasBulkMemoryOpt ()) {
187
192
getActionDefinitionsBuilder (G_BZERO).unsupported ();
@@ -204,7 +209,7 @@ WebAssemblyLegalizerInfo::WebAssemblyLegalizerInfo(
204
209
205
210
// TODO: figure out how to combine G_ANYEXT of G_ASSERT_{S|Z}EXT (or
206
211
// 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
208
213
// instruction anyway).
209
214
210
215
getActionDefinitionsBuilder (G_ANYEXT)
@@ -221,8 +226,7 @@ WebAssemblyLegalizerInfo::WebAssemblyLegalizerInfo(
221
226
if (ST.hasSignExt ()) {
222
227
getActionDefinitionsBuilder (G_SEXT_INREG)
223
228
.clampScalar (0 , s32, s64)
224
- .customFor ({s32, s64})
225
- .lower ();
229
+ .customFor ({s32, s64});
226
230
} else {
227
231
getActionDefinitionsBuilder (G_SEXT_INREG).lower ();
228
232
}
@@ -242,23 +246,42 @@ WebAssemblyLegalizerInfo::WebAssemblyLegalizerInfo(
242
246
.legalForCartesianProduct ({s32, s64}, {p0})
243
247
.clampScalar (0 , s32, s64);
244
248
249
+ getActionDefinitionsBuilder (G_DYN_STACKALLOC).lowerFor ({{p0, p0s}});
250
+
251
+ getActionDefinitionsBuilder ({G_STACKSAVE, G_STACKRESTORE}).lower ();
252
+
245
253
getLegacyLegalizerInfo ().computeTables ();
246
254
}
247
255
248
256
bool WebAssemblyLegalizerInfo::legalizeCustom (
249
257
LegalizerHelper &Helper, MachineInstr &MI,
250
258
LostDebugLocObserver &LocObserver) const {
259
+ auto &MRI = *Helper.MIRBuilder .getMRI ();
260
+ auto &MIRBuilder = Helper.MIRBuilder ;
261
+
251
262
switch (MI.getOpcode ()) {
252
263
case TargetOpcode::G_SEXT_INREG: {
264
+ assert (MI.getOperand (2 ).isImm () && " Expected immediate" );
265
+
253
266
// 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);
255
269
auto ExtFromWidth = MI.getOperand (2 ).getImm ();
256
270
257
271
if (ExtFromWidth == 8 || ExtFromWidth == 16 ||
258
272
(DstType.getScalarSizeInBits () == 64 && ExtFromWidth == 32 )) {
259
273
return true ;
260
274
}
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 ;
262
285
}
263
286
case TargetOpcode::G_MEMSET: {
264
287
// Anyext the value being set to 32 bit (only the bottom 8 bits are read by
0 commit comments