authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-03-01 14:56:43-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-03-01 14:58:37-07:00
logf6aaab9406807305c2b48fcd742449c9e91f1851
tree2eeae513df72230b216a77c627a612239e7df6e9
parent1b194931b0df08db0f38a284bb10b89cc00a8817

LLVM: fix tripping assertions

Packed structs were tripping an LLVM assertion due to calling `LLVMConstZExt` from i16 to i16. Solved by using instead `LLVMConstZExtOrBitCast`. Unions were tripping an LLVM assertion due to a typo using the union llvm type to construct an integer value rather than the tag type.

3 files changed, 12 insertions(+), 7 deletions(-)

src/codegen/llvm.zig+7-5
...@@ -1464,9 +1464,8 @@ pub const DeclGen = struct {...@@ -1464,9 +1464,8 @@ pub const DeclGen = struct {
14641464
1465 if (struct_obj.layout == .Packed) {1465 if (struct_obj.layout == .Packed) {
1466 const target = dg.module.getTarget();1466 const target = dg.module.getTarget();
1467 var int_ty_buf: Type.Payload.Bits = undefined;1467 const big_bits = struct_obj.packedIntegerBits(target);
1468 const int_ty = struct_obj.packedIntegerType(target, &int_ty_buf);1468 const int_llvm_ty = dg.context.intType(big_bits);
1469 const int_llvm_ty = try dg.llvmType(int_ty);
1470 const fields = struct_obj.fields.values();1469 const fields = struct_obj.fields.values();
1471 comptime assert(Type.packed_struct_layout_version == 2);1470 comptime assert(Type.packed_struct_layout_version == 2);
1472 var running_int: *const llvm.Value = int_llvm_ty.constNull();1471 var running_int: *const llvm.Value = int_llvm_ty.constNull();
...@@ -1483,7 +1482,10 @@ pub const DeclGen = struct {...@@ -1483,7 +1482,10 @@ pub const DeclGen = struct {
1483 const small_int_ty = dg.context.intType(ty_bit_size);1482 const small_int_ty = dg.context.intType(ty_bit_size);
1484 const small_int_val = non_int_val.constBitCast(small_int_ty);1483 const small_int_val = non_int_val.constBitCast(small_int_ty);
1485 const shift_rhs = int_llvm_ty.constInt(running_bits, .False);1484 const shift_rhs = int_llvm_ty.constInt(running_bits, .False);
1486 const extended_int_val = small_int_val.constZExt(int_llvm_ty);1485 // If the field is as large as the entire packed struct, this
1486 // zext would go from, e.g. i16 to i16. This is legal with
1487 // constZExtOrBitCast but not legal with constZExt.
1488 const extended_int_val = small_int_val.constZExtOrBitCast(int_llvm_ty);
1487 const shifted = extended_int_val.constShl(shift_rhs);1489 const shifted = extended_int_val.constShl(shift_rhs);
1488 running_int = running_int.constOr(shifted);1490 running_int = running_int.constOr(shifted);
1489 running_bits += ty_bit_size;1491 running_bits += ty_bit_size;
...@@ -4830,7 +4832,7 @@ pub const FuncGen = struct {...@@ -4830,7 +4832,7 @@ pub const FuncGen = struct {
4830 index_type.constInt(@boolToInt(layout.tag_align < layout.payload_align), .False),4832 index_type.constInt(@boolToInt(layout.tag_align < layout.payload_align), .False),
4831 };4833 };
4832 const field_ptr = self.builder.buildInBoundsGEP(casted_ptr, &indices, indices.len, "");4834 const field_ptr = self.builder.buildInBoundsGEP(casted_ptr, &indices, indices.len, "");
4833 const llvm_tag = union_llvm_ty.constInt(extra.field_index, .False);4835 const llvm_tag = tag_llvm_ty.constInt(extra.field_index, .False);
4834 const store_inst = self.builder.buildStore(llvm_tag, field_ptr);4836 const store_inst = self.builder.buildStore(llvm_tag, field_ptr);
4835 store_inst.setAlignment(union_obj.tag_ty.abiAlignment(target));4837 store_inst.setAlignment(union_obj.tag_ty.abiAlignment(target));
4836 }4838 }
src/codegen/llvm/bindings.zig+3
...@@ -157,6 +157,9 @@ pub const Value = opaque {...@@ -157,6 +157,9 @@ pub const Value = opaque {
157 pub const constZExt = LLVMConstZExt;157 pub const constZExt = LLVMConstZExt;
158 extern fn LLVMConstZExt(ConstantVal: *const Value, ToType: *const Type) *const Value;158 extern fn LLVMConstZExt(ConstantVal: *const Value, ToType: *const Type) *const Value;
159159
160 pub const constZExtOrBitCast = LLVMConstZExtOrBitCast;
161 extern fn LLVMConstZExtOrBitCast(ConstantVal: *const Value, ToType: *const Type) *const Value;
162
160 pub const constNot = LLVMConstNot;163 pub const constNot = LLVMConstNot;
161 extern fn LLVMConstNot(ConstantVal: *const Value) *const Value;164 extern fn LLVMConstNot(ConstantVal: *const Value) *const Value;
162165
test/behavior/struct.zig+2-2
...@@ -871,10 +871,10 @@ test "non-packed struct with u128 entry in union" {...@@ -871,10 +871,10 @@ test "non-packed struct with u128 entry in union" {
871871
872 var sx: S = undefined;872 var sx: S = undefined;
873 var s = &sx;873 var s = &sx;
874 try std.testing.expect(@ptrToInt(&s.f2) - @ptrToInt(&s.f1) == @offsetOf(S, "f2"));874 try expect(@ptrToInt(&s.f2) - @ptrToInt(&s.f1) == @offsetOf(S, "f2"));
875 var v2 = U{ .Num = 123 };875 var v2 = U{ .Num = 123 };
876 s.f2 = v2;876 s.f2 = v2;
877 try std.testing.expect(s.f2.Num == 123);877 try expect(s.f2.Num == 123);
878}878}
879879
880test "packed struct field passed to generic function" {880test "packed struct field passed to generic function" {