@@ -4258,6 +4258,75 @@ fn validateStructInit(
4258
4258
}
4259
4259
try sema.resolveStructLayout(struct_ty);
4260
4260
4261
+ if (struct_ty.containerLayout() == .Packed) {
4262
+ // Convert stores to ptr into an aggregate init.
4263
+ const element_refs = try sema.arena.alloc(Air.Inst.Ref, struct_ty.structFieldCount());
4264
+
4265
+ var block_index = block.instructions.items.len - 1;
4266
+ var field_ptr_count = instrs.len;
4267
+ while (block_index > 0 and field_ptr_count > 0) : (block_index -= 1) {
4268
+ const store_inst = block.instructions.items[block_index];
4269
+ if (air_tags[store_inst] != .store) continue;
4270
+ const store_index = block_index;
4271
+ const bin_op = air_datas[store_inst].bin_op;
4272
+
4273
+ var lhs_index = Air.refToIndex(bin_op.lhs) orelse continue;
4274
+ var bitcast_index: ?usize = null;
4275
+ {
4276
+ if (air_tags[lhs_index] == .bitcast) {
4277
+ const lhs = air_datas[lhs_index].ty_op.operand;
4278
+ lhs_index = Air.refToIndex(lhs).?;
4279
+ var i = block_index;
4280
+ while (i > 0) : (i -= 1) {
4281
+ if (block.instructions.items[i] == lhs_index) {
4282
+ bitcast_index = i;
4283
+ break;
4284
+ }
4285
+ } else continue;
4286
+ }
4287
+ }
4288
+
4289
+ const index = switch (air_tags[lhs_index]) {
4290
+ .struct_field_ptr_index_0 => 0,
4291
+ .struct_field_ptr_index_1 => 1,
4292
+ .struct_field_ptr_index_2 => 2,
4293
+ .struct_field_ptr_index_3 => 3,
4294
+ .struct_field_ptr => blk: {
4295
+ const ty_pl = air_datas[lhs_index].ty_pl;
4296
+ const struct_field = sema.getTmpAir().extraData(Air.StructField, ty_pl.payload).data;
4297
+ break :blk struct_field.field_index;
4298
+ },
4299
+ else => continue,
4300
+ };
4301
+
4302
+ // Delete dead store, field_ptr and bitcast instructions.
4303
+ _ = block.instructions.orderedRemove(store_index);
4304
+ if (bitcast_index) |some| _ = block.instructions.orderedRemove(some);
4305
+ block_index = block.instructions.items.len - 1;
4306
+ while (block_index > 0) : (block_index -= 1) {
4307
+ if (block.instructions.items[block_index] == lhs_index) {
4308
+ _ = block.instructions.orderedRemove(block_index);
4309
+ break;
4310
+ }
4311
+ }
4312
+
4313
+ field_ptr_count -= 1;
4314
+ element_refs[index] = bin_op.rhs;
4315
+ continue;
4316
+ }
4317
+
4318
+ assert(field_ptr_count == 0); // Unable to eliminate all stores.
4319
+ for (found_fields) |field_ptr, i| {
4320
+ if (field_ptr != 0) continue;
4321
+
4322
+ element_refs[i] = try sema.addConstant(struct_ty.structFieldType(i), field_values[i]);
4323
+ }
4324
+
4325
+ const init = try block.addAggregateInit(struct_ty, element_refs);
4326
+ try sema.storePtr2(block, init_src, struct_ptr, init_src, init, init_src, .store);
4327
+ return;
4328
+ }
4329
+
4261
4330
// Our task is to insert `store` instructions for all the default field values.
4262
4331
for (found_fields) |field_ptr, i| {
4263
4332
if (field_ptr != 0) continue;
0 commit comments