authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-09-29 15:33:45-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-09-29 15:33:45-07:00
logbdbedff910e18e18dc31db84a80607435e9b6ee0
treed0081d6089f09f797662b6f22d05a73895e5aacd
parentea6706b6f406606a7523e35e34e390fb880b607e

stage2: LLVM backend: properly set module target data

Also fix tripping LLVM assert having to do with 0 bit integers. stage2 behavior tests now run clean in a debug build of llvm 12.

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

src/codegen/llvm.zig+16-7
...@@ -264,6 +264,11 @@ pub const Object = struct {...@@ -264,6 +264,11 @@ pub const Object = struct {
264 );264 );
265 errdefer target_machine.dispose();265 errdefer target_machine.dispose();
266266
267 const target_data = target_machine.createTargetDataLayout();
268 defer target_data.dispose();
269
270 llvm_module.setModuleDataLayout(target_data);
271
267 return Object{272 return Object{
268 .llvm_module = llvm_module,273 .llvm_module = llvm_module,
269 .context = context,274 .context = context,
...@@ -1589,13 +1594,17 @@ pub const FuncGen = struct {...@@ -1589,13 +1594,17 @@ pub const FuncGen = struct {
1589 return null;1594 return null;
15901595
1591 const ty_op = self.air.instructions.items(.data)[inst].ty_op;1596 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
1592 const operand = try self.resolveInst(ty_op.operand);1597 const operand_ty = self.air.typeOf(ty_op.operand);
1593 const array_len = self.air.typeOf(ty_op.operand).elemType().arrayLen();1598 const array_ty = operand_ty.childType();
1594 const usize_llvm_ty = try self.dg.llvmType(Type.initTag(.usize));1599 const llvm_usize = try self.dg.llvmType(Type.usize);
1595 const len = usize_llvm_ty.constInt(array_len, .False);1600 const len = llvm_usize.constInt(array_ty.arrayLen(), .False);
1596 const slice_llvm_ty = try self.dg.llvmType(self.air.typeOfIndex(inst));1601 const slice_llvm_ty = try self.dg.llvmType(self.air.typeOfIndex(inst));
1602 if (!array_ty.hasCodeGenBits()) {
1603 return self.builder.buildInsertValue(slice_llvm_ty.getUndef(), len, 1, "");
1604 }
1605 const operand = try self.resolveInst(ty_op.operand);
1597 const indices: [2]*const llvm.Value = .{1606 const indices: [2]*const llvm.Value = .{
1598 usize_llvm_ty.constNull(), usize_llvm_ty.constNull(),1607 llvm_usize.constNull(), llvm_usize.constNull(),
1599 };1608 };
1600 const ptr = self.builder.buildInBoundsGEP(operand, &indices, indices.len, "");1609 const ptr = self.builder.buildInBoundsGEP(operand, &indices, indices.len, "");
1601 const partial = self.builder.buildInsertValue(slice_llvm_ty.getUndef(), ptr, 0, "");1610 const partial = self.builder.buildInsertValue(slice_llvm_ty.getUndef(), ptr, 0, "");
...@@ -2454,12 +2463,12 @@ pub const FuncGen = struct {...@@ -2454,12 +2463,12 @@ pub const FuncGen = struct {
2454 }2463 }
24552464
2456 fn airAlloc(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value {2465 fn airAlloc(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value {
2457 if (self.liveness.isUnused(inst))2466 if (self.liveness.isUnused(inst)) return null;
2458 return null;
2459 // buildAlloca expects the pointee type, not the pointer type, so assert that2467 // buildAlloca expects the pointee type, not the pointer type, so assert that
2460 // a Payload.PointerSimple is passed to the alloc instruction.2468 // a Payload.PointerSimple is passed to the alloc instruction.
2461 const ptr_ty = self.air.typeOfIndex(inst);2469 const ptr_ty = self.air.typeOfIndex(inst);
2462 const pointee_type = ptr_ty.elemType();2470 const pointee_type = ptr_ty.elemType();
2471 if (!pointee_type.hasCodeGenBits()) return null;
2463 const pointee_llvm_ty = try self.dg.llvmType(pointee_type);2472 const pointee_llvm_ty = try self.dg.llvmType(pointee_type);
2464 const target = self.dg.module.getTarget();2473 const target = self.dg.module.getTarget();
2465 const alloca_inst = self.buildAlloca(pointee_llvm_ty);2474 const alloca_inst = self.buildAlloca(pointee_llvm_ty);
src/codegen/llvm/bindings.zig+11
...@@ -219,6 +219,9 @@ pub const Module = opaque {...@@ -219,6 +219,9 @@ pub const Module = opaque {
219 pub const verify = LLVMVerifyModule;219 pub const verify = LLVMVerifyModule;
220 extern fn LLVMVerifyModule(*const Module, Action: VerifierFailureAction, OutMessage: *[*:0]const u8) Bool;220 extern fn LLVMVerifyModule(*const Module, Action: VerifierFailureAction, OutMessage: *[*:0]const u8) Bool;
221221
222 pub const setModuleDataLayout = LLVMSetModuleDataLayout;
223 extern fn LLVMSetModuleDataLayout(*const Module, *const TargetData) void;
224
222 pub const addFunction = LLVMAddFunction;225 pub const addFunction = LLVMAddFunction;
223 extern fn LLVMAddFunction(*const Module, Name: [*:0]const u8, FunctionTy: *const Type) *const Value;226 extern fn LLVMAddFunction(*const Module, Name: [*:0]const u8, FunctionTy: *const Type) *const Value;
224227
...@@ -766,6 +769,14 @@ pub const TargetMachine = opaque {...@@ -766,6 +769,14 @@ pub const TargetMachine = opaque {
766 llvm_ir_filename: ?[*:0]const u8,769 llvm_ir_filename: ?[*:0]const u8,
767 bitcode_filename: ?[*:0]const u8,770 bitcode_filename: ?[*:0]const u8,
768 ) bool;771 ) bool;
772
773 pub const createTargetDataLayout = LLVMCreateTargetDataLayout;
774 extern fn LLVMCreateTargetDataLayout(*const TargetMachine) *const TargetData;
775};
776
777pub const TargetData = opaque {
778 pub const dispose = LLVMDisposeTargetData;
779 extern fn LLVMDisposeTargetData(*const TargetData) void;
769};780};
770781
771pub const CodeModel = enum(c_int) {782pub const CodeModel = enum(c_int) {
src/type.zig+1
...@@ -3868,6 +3868,7 @@ pub const Type = extern union {...@@ -3868,6 +3868,7 @@ pub const Type = extern union {
3868 };3868 };
38693869
3870 pub const @"bool" = initTag(.bool);3870 pub const @"bool" = initTag(.bool);
3871 pub const @"usize" = initTag(.usize);
3871 pub const @"comptime_int" = initTag(.comptime_int);3872 pub const @"comptime_int" = initTag(.comptime_int);
38723873
3873 pub fn ptr(arena: *Allocator, d: Payload.Pointer.Data) !Type {3874 pub fn ptr(arena: *Allocator, d: Payload.Pointer.Data) !Type {