diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2022-03-01 14:56:43 -0700 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2022-03-01 14:58:37 -0700 |
| commit | f6aaab9406807305c2b48fcd742449c9e91f1851 (patch) | |
| tree | 2eeae513df72230b216a77c627a612239e7df6e9 /src/codegen | |
| parent | 1b194931b0df08db0f38a284bb10b89cc00a8817 (diff) | |
| download | zig-f6aaab9406807305c2b48fcd742449c9e91f1851.tar.gz zig-f6aaab9406807305c2b48fcd742449c9e91f1851.zip | |
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.
Diffstat (limited to 'src/codegen')
| -rw-r--r-- | src/codegen/llvm.zig | 12 | ||||
| -rw-r--r-- | src/codegen/llvm/bindings.zig | 3 |
2 files changed, 10 insertions, 5 deletions
diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig index 3ce1ab4b14..bb82a80bbb 100644 --- a/src/codegen/llvm.zig +++ b/src/codegen/llvm.zig @@ -1464,9 +1464,8 @@ pub const DeclGen = struct { if (struct_obj.layout == .Packed) { const target = dg.module.getTarget(); - var int_ty_buf: Type.Payload.Bits = undefined; - const int_ty = struct_obj.packedIntegerType(target, &int_ty_buf); - const int_llvm_ty = try dg.llvmType(int_ty); + const big_bits = struct_obj.packedIntegerBits(target); + const int_llvm_ty = dg.context.intType(big_bits); const fields = struct_obj.fields.values(); comptime assert(Type.packed_struct_layout_version == 2); var running_int: *const llvm.Value = int_llvm_ty.constNull(); @@ -1483,7 +1482,10 @@ pub const DeclGen = struct { const small_int_ty = dg.context.intType(ty_bit_size); const small_int_val = non_int_val.constBitCast(small_int_ty); const shift_rhs = int_llvm_ty.constInt(running_bits, .False); - const extended_int_val = small_int_val.constZExt(int_llvm_ty); + // If the field is as large as the entire packed struct, this + // zext would go from, e.g. i16 to i16. This is legal with + // constZExtOrBitCast but not legal with constZExt. + const extended_int_val = small_int_val.constZExtOrBitCast(int_llvm_ty); const shifted = extended_int_val.constShl(shift_rhs); running_int = running_int.constOr(shifted); running_bits += ty_bit_size; @@ -4830,7 +4832,7 @@ pub const FuncGen = struct { index_type.constInt(@boolToInt(layout.tag_align < layout.payload_align), .False), }; const field_ptr = self.builder.buildInBoundsGEP(casted_ptr, &indices, indices.len, ""); - const llvm_tag = union_llvm_ty.constInt(extra.field_index, .False); + const llvm_tag = tag_llvm_ty.constInt(extra.field_index, .False); const store_inst = self.builder.buildStore(llvm_tag, field_ptr); store_inst.setAlignment(union_obj.tag_ty.abiAlignment(target)); } diff --git a/src/codegen/llvm/bindings.zig b/src/codegen/llvm/bindings.zig index fa285bd291..a9eea39c67 100644 --- a/src/codegen/llvm/bindings.zig +++ b/src/codegen/llvm/bindings.zig @@ -157,6 +157,9 @@ pub const Value = opaque { pub const constZExt = LLVMConstZExt; extern fn LLVMConstZExt(ConstantVal: *const Value, ToType: *const Type) *const Value; + pub const constZExtOrBitCast = LLVMConstZExtOrBitCast; + extern fn LLVMConstZExtOrBitCast(ConstantVal: *const Value, ToType: *const Type) *const Value; + pub const constNot = LLVMConstNot; extern fn LLVMConstNot(ConstantVal: *const Value) *const Value; |
