@@ -1588,12 +1588,18 @@ fn toWasmBits(bits: u16) ?u16 {
1588
1588
/// Performs a copy of bytes for a given type. Copying all bytes
1589
1589
/// from rhs to lhs.
1590
1590
fn memcpy (cg : * CodeGen , dst : WValue , src : WValue , len : WValue ) ! void {
1591
+ const len_known_neq_0 = switch (len ) {
1592
+ .imm32 = > | val | if (val != 0 ) true else return ,
1593
+ .imm64 = > | val | if (val != 0 ) true else return ,
1594
+ else = > false ,
1595
+ };
1591
1596
// When bulk_memory is enabled, we lower it to wasm's memcpy instruction.
1592
1597
// If not, we lower it ourselves manually
1593
1598
if (std .Target .wasm .featureSetHas (cg .target .cpu .features , .bulk_memory )) {
1594
1599
const len0_ok = std .Target .wasm .featureSetHas (cg .target .cpu .features , .nontrapping_bulk_memory_len0 );
1600
+ const emit_check = ! (len0_ok or len_known_neq_0 );
1595
1601
1596
- if (! len0_ok ) {
1602
+ if (emit_check ) {
1597
1603
try cg .startBlock (.block , .empty );
1598
1604
1599
1605
// Even if `len` is zero, the spec requires an implementation to trap if `src + len` or
@@ -1616,7 +1622,7 @@ fn memcpy(cg: *CodeGen, dst: WValue, src: WValue, len: WValue) !void {
1616
1622
try cg .emitWValue (len );
1617
1623
try cg .addExtended (.memory_copy );
1618
1624
1619
- if (! len0_ok ) {
1625
+ if (emit_check ) {
1620
1626
try cg .endBlock ();
1621
1627
}
1622
1628
@@ -5196,9 +5202,7 @@ fn airAggregateInit(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5196
5202
const result = try cg .allocStack (result_ty );
5197
5203
const elem_ty = result_ty .childType (zcu );
5198
5204
const elem_size = @as (u32 , @intCast (elem_ty .abiSize (zcu )));
5199
- const sentinel = if (result_ty .sentinel (zcu )) | sent | blk : {
5200
- break :blk try cg .lowerConstant (sent , elem_ty );
5201
- } else null ;
5205
+ const sentinel = result_ty .sentinel (zcu );
5202
5206
5203
5207
// When the element type is by reference, we must copy the entire
5204
5208
// value. It is therefore safer to move the offset pointer and store
@@ -5211,12 +5215,13 @@ fn airAggregateInit(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5211
5215
const elem_val = try cg .resolveInst (elem );
5212
5216
try cg .store (offset , elem_val , elem_ty , 0 );
5213
5217
5214
- if (elem_index < elements .len - 1 and sentinel = = null ) {
5218
+ if (elem_index < elements .len - 1 or sentinel ! = null ) {
5215
5219
_ = try cg .buildPointerOffset (offset , elem_size , .modify );
5216
5220
}
5217
5221
}
5218
- if (sentinel ) | sent | {
5219
- try cg .store (offset , sent , elem_ty , 0 );
5222
+ if (sentinel ) | s | {
5223
+ const val = try cg .resolveInst (Air .internedToRef (s .toIntern ()));
5224
+ try cg .store (offset , val , elem_ty , 0 );
5220
5225
}
5221
5226
} else {
5222
5227
var offset : u32 = 0 ;
@@ -5225,8 +5230,9 @@ fn airAggregateInit(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5225
5230
try cg .store (result , elem_val , elem_ty , offset );
5226
5231
offset += elem_size ;
5227
5232
}
5228
- if (sentinel ) | sent | {
5229
- try cg .store (result , sent , elem_ty , offset );
5233
+ if (sentinel ) | s | {
5234
+ const val = try cg .resolveInst (Air .internedToRef (s .toIntern ()));
5235
+ try cg .store (result , val , elem_ty , offset );
5230
5236
}
5231
5237
}
5232
5238
break :result_value result ;
0 commit comments