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.
This commit is contained in:
Andrew Kelley 2021-09-29 15:33:45 -07:00
parent ea6706b6f4
commit bdbedff910
3 changed files with 28 additions and 7 deletions

View File

@ -264,6 +264,11 @@ pub const Object = struct {
);
errdefer target_machine.dispose();
const target_data = target_machine.createTargetDataLayout();
defer target_data.dispose();
llvm_module.setModuleDataLayout(target_data);
return Object{
.llvm_module = llvm_module,
.context = context,
@ -1589,13 +1594,17 @@ pub const FuncGen = struct {
return null;
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const operand = try self.resolveInst(ty_op.operand);
const array_len = self.air.typeOf(ty_op.operand).elemType().arrayLen();
const usize_llvm_ty = try self.dg.llvmType(Type.initTag(.usize));
const len = usize_llvm_ty.constInt(array_len, .False);
const operand_ty = self.air.typeOf(ty_op.operand);
const array_ty = operand_ty.childType();
const llvm_usize = try self.dg.llvmType(Type.usize);
const len = llvm_usize.constInt(array_ty.arrayLen(), .False);
const slice_llvm_ty = try self.dg.llvmType(self.air.typeOfIndex(inst));
if (!array_ty.hasCodeGenBits()) {
return self.builder.buildInsertValue(slice_llvm_ty.getUndef(), len, 1, "");
}
const operand = try self.resolveInst(ty_op.operand);
const indices: [2]*const llvm.Value = .{
usize_llvm_ty.constNull(), usize_llvm_ty.constNull(),
llvm_usize.constNull(), llvm_usize.constNull(),
};
const ptr = self.builder.buildInBoundsGEP(operand, &indices, indices.len, "");
const partial = self.builder.buildInsertValue(slice_llvm_ty.getUndef(), ptr, 0, "");
@ -2454,12 +2463,12 @@ pub const FuncGen = struct {
}
fn airAlloc(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value {
if (self.liveness.isUnused(inst))
return null;
if (self.liveness.isUnused(inst)) return null;
// buildAlloca expects the pointee type, not the pointer type, so assert that
// a Payload.PointerSimple is passed to the alloc instruction.
const ptr_ty = self.air.typeOfIndex(inst);
const pointee_type = ptr_ty.elemType();
if (!pointee_type.hasCodeGenBits()) return null;
const pointee_llvm_ty = try self.dg.llvmType(pointee_type);
const target = self.dg.module.getTarget();
const alloca_inst = self.buildAlloca(pointee_llvm_ty);

View File

@ -219,6 +219,9 @@ pub const Module = opaque {
pub const verify = LLVMVerifyModule;
extern fn LLVMVerifyModule(*const Module, Action: VerifierFailureAction, OutMessage: *[*:0]const u8) Bool;
pub const setModuleDataLayout = LLVMSetModuleDataLayout;
extern fn LLVMSetModuleDataLayout(*const Module, *const TargetData) void;
pub const addFunction = LLVMAddFunction;
extern fn LLVMAddFunction(*const Module, Name: [*:0]const u8, FunctionTy: *const Type) *const Value;
@ -766,6 +769,14 @@ pub const TargetMachine = opaque {
llvm_ir_filename: ?[*:0]const u8,
bitcode_filename: ?[*:0]const u8,
) bool;
pub const createTargetDataLayout = LLVMCreateTargetDataLayout;
extern fn LLVMCreateTargetDataLayout(*const TargetMachine) *const TargetData;
};
pub const TargetData = opaque {
pub const dispose = LLVMDisposeTargetData;
extern fn LLVMDisposeTargetData(*const TargetData) void;
};
pub const CodeModel = enum(c_int) {

View File

@ -3868,6 +3868,7 @@ pub const Type = extern union {
};
pub const @"bool" = initTag(.bool);
pub const @"usize" = initTag(.usize);
pub const @"comptime_int" = initTag(.comptime_int);
pub fn ptr(arena: *Allocator, d: Payload.Pointer.Data) !Type {