diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig index 3684237cb2..156b3ac36e 100644 --- a/src/codegen/llvm.zig +++ b/src/codegen/llvm.zig @@ -9775,10 +9775,8 @@ pub const FuncGen = struct { else try self.wip.cast(.bitcast, non_int_val, small_int_ty, ""); const shift_rhs = try o.builder.intValue(int_ty, running_bits); - // 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 = try self.wip.conv(.unsigned, small_int_val, int_ty, ""); + const extended_int_val = + try self.wip.conv(.unsigned, small_int_val, int_ty, ""); const shifted = try self.wip.bin(.shl, extended_int_val, shift_rhs, ""); running_int = try self.wip.bin(.@"or", running_int, shifted, ""); running_bits += ty_bit_size; diff --git a/src/codegen/llvm/Builder.zig b/src/codegen/llvm/Builder.zig index 396580a664..aa78381ee7 100644 --- a/src/codegen/llvm/Builder.zig +++ b/src/codegen/llvm/Builder.zig @@ -6894,6 +6894,7 @@ pub const Constant = enum(u32) { @"and", @"or", xor, + select, @"asm", @"asm sideeffect", @"asm alignstack", @@ -7005,6 +7006,12 @@ pub const Constant = enum(u32) { rhs: Constant, }; + pub const Select = extern struct { + cond: Constant, + lhs: Constant, + rhs: Constant, + }; + pub const Assembly = extern struct { type: Type, assembly: String, @@ -7136,6 +7143,7 @@ pub const Constant = enum(u32) { .@"or", .xor, => builder.constantExtraData(Binary, item.data).lhs.typeOf(builder), + .select => builder.constantExtraData(Select, item.data).lhs.typeOf(builder), .@"asm", .@"asm sideeffect", .@"asm alignstack", @@ -7500,6 +7508,15 @@ pub const Constant = enum(u32) { extra.rhs.fmt(data.builder), }); }, + .select => |tag| { + const extra = data.builder.constantExtraData(Select, item.data); + try writer.print("{s} ({%}, {%}, {%})", .{ + @tagName(tag), + extra.cond.fmt(data.builder), + extra.lhs.fmt(data.builder), + extra.rhs.fmt(data.builder), + }); + }, .@"asm", .@"asm sideeffect", .@"asm alignstack", @@ -8802,6 +8819,20 @@ pub fn binValue(self: *Builder, tag: Constant.Tag, lhs: Constant, rhs: Constant) return (try self.binConst(tag, lhs, rhs)).toValue(); } +pub fn selectConst( + self: *Builder, + cond: Constant, + lhs: Constant, + rhs: Constant, +) Allocator.Error!Constant { + try self.ensureUnusedConstantCapacity(1, Constant.Select, 0); + return self.selectConstAssumeCapacity(cond, lhs, rhs); +} + +pub fn selectValue(self: *Builder, cond: Constant, lhs: Constant, rhs: Constant) Allocator.Error!Value { + return (try self.selectConst(cond, lhs, rhs)).toValue(); +} + pub fn asmConst( self: *Builder, ty: Type, @@ -11063,6 +11094,42 @@ fn binConstAssumeCapacity( return @enumFromInt(gop.index); } +comptime { + _ = &selectValue; +} + +fn selectConstAssumeCapacity(self: *Builder, cond: Constant, lhs: Constant, rhs: Constant) Constant { + const Adapter = struct { + builder: *const Builder, + pub fn hash(_: @This(), key: Constant.Select) u32 { + return @truncate(std.hash.Wyhash.hash( + std.hash.uint32(@intFromEnum(Constant.Tag.select)), + std.mem.asBytes(&key), + )); + } + pub fn eql(ctx: @This(), lhs_key: Constant.Select, _: void, rhs_index: usize) bool { + if (ctx.builder.constant_items.items(.tag)[rhs_index] != .select) return false; + const rhs_data = ctx.builder.constant_items.items(.data)[rhs_index]; + const rhs_extra = ctx.builder.constantExtraData(Constant.Select, rhs_data); + return std.meta.eql(lhs_key, rhs_extra); + } + }; + const data = Constant.Select{ .cond = cond, .lhs = lhs, .rhs = rhs }; + const gop = self.constant_map.getOrPutAssumeCapacityAdapted(data, Adapter{ .builder = self }); + if (!gop.found_existing) { + gop.key_ptr.* = {}; + gop.value_ptr.* = {}; + self.constant_items.appendAssumeCapacity(.{ + .tag = .select, + .data = self.addConstantExtraAssumeCapacity(data), + }); + if (self.useLibLlvm()) self.llvm.constants.appendAssumeCapacity( + cond.toLlvm(self).constSelect(lhs.toLlvm(self), rhs.toLlvm(self)), + ); + } + return @enumFromInt(gop.index); +} + fn asmConstAssumeCapacity( self: *Builder, ty: Type, diff --git a/src/codegen/llvm/bindings.zig b/src/codegen/llvm/bindings.zig index ccfdd9407c..a756be784b 100644 --- a/src/codegen/llvm/bindings.zig +++ b/src/codegen/llvm/bindings.zig @@ -93,17 +93,6 @@ pub const Context = opaque { pub const constString = LLVMConstStringInContext; extern fn LLVMConstStringInContext(C: *Context, Str: [*]const u8, Length: c_uint, DontNullTerminate: Bool) *Value; - pub const constStruct = LLVMConstStructInContext; - extern fn LLVMConstStructInContext( - C: *Context, - ConstantVals: [*]const *Value, - Count: c_uint, - Packed: Bool, - ) *Value; - - pub const createBasicBlock = LLVMCreateBasicBlockInContext; - extern fn LLVMCreateBasicBlockInContext(C: *Context, Name: [*:0]const u8) *BasicBlock; - pub const appendBasicBlock = LLVMAppendBasicBlockInContext; extern fn LLVMAppendBasicBlockInContext(C: *Context, Fn: *Value, Name: [*:0]const u8) *BasicBlock; @@ -127,9 +116,6 @@ pub const Value = opaque { pub const getFirstBasicBlock = LLVMGetFirstBasicBlock; extern fn LLVMGetFirstBasicBlock(Fn: *Value) ?*BasicBlock; - pub const appendExistingBasicBlock = LLVMAppendExistingBasicBlock; - extern fn LLVMAppendExistingBasicBlock(Fn: *Value, BB: *BasicBlock) void; - pub const addIncoming = LLVMAddIncoming; extern fn LLVMAddIncoming( PhiNode: *Value, @@ -138,9 +124,6 @@ pub const Value = opaque { Count: c_uint, ) void; - pub const getNextInstruction = LLVMGetNextInstruction; - extern fn LLVMGetNextInstruction(Inst: *Value) ?*Value; - pub const setGlobalConstant = LLVMSetGlobalConstant; extern fn LLVMSetGlobalConstant(GlobalVar: *Value, IsConstant: Bool) void; @@ -162,30 +145,9 @@ pub const Value = opaque { pub const deleteGlobal = LLVMDeleteGlobal; extern fn LLVMDeleteGlobal(GlobalVar: *Value) void; - pub const getNextGlobalAlias = LLVMGetNextGlobalAlias; - extern fn LLVMGetNextGlobalAlias(GA: *Value) *Value; - - pub const getAliasee = LLVMAliasGetAliasee; - extern fn LLVMAliasGetAliasee(Alias: *Value) *Value; - pub const setAliasee = LLVMAliasSetAliasee; extern fn LLVMAliasSetAliasee(Alias: *Value, Aliasee: *Value) void; - pub const constZExtOrBitCast = LLVMConstZExtOrBitCast; - extern fn LLVMConstZExtOrBitCast(ConstantVal: *Value, ToType: *Type) *Value; - - pub const constNeg = LLVMConstNeg; - extern fn LLVMConstNeg(ConstantVal: *Value) *Value; - - pub const constNSWNeg = LLVMConstNSWNeg; - extern fn LLVMConstNSWNeg(ConstantVal: *Value) *Value; - - pub const constNUWNeg = LLVMConstNUWNeg; - extern fn LLVMConstNUWNeg(ConstantVal: *Value) *Value; - - pub const constNot = LLVMConstNot; - extern fn LLVMConstNot(ConstantVal: *Value) *Value; - pub const constAdd = LLVMConstAdd; extern fn LLVMConstAdd(LHSConstant: *Value, RHSConstant: *Value) *Value; @@ -309,9 +271,6 @@ pub const Value = opaque { pub const setVolatile = LLVMSetVolatile; extern fn LLVMSetVolatile(MemoryAccessInst: *Value, IsVolatile: Bool) void; - pub const setAtomicSingleThread = LLVMSetAtomicSingleThread; - extern fn LLVMSetAtomicSingleThread(AtomicInst: *Value, SingleThread: Bool) void; - pub const setAlignment = LLVMSetAlignment; extern fn LLVMSetAlignment(V: *Value, Bytes: c_uint) void; @@ -366,9 +325,6 @@ pub const Value = opaque { pub const getAlignment = LLVMGetAlignment; extern fn LLVMGetAlignment(V: *Value) c_uint; - pub const addByValAttr = ZigLLVMAddByValAttr; - extern fn ZigLLVMAddByValAttr(Fn: *Value, ArgNo: c_uint, type: *Type) void; - pub const attachMetaData = ZigLLVMAttachMetaData; extern fn ZigLLVMAttachMetaData(GlobalVar: *Value, DIG: *DIGlobalVariableExpression) void; @@ -380,9 +336,6 @@ pub const Type = opaque { pub const constNull = LLVMConstNull; extern fn LLVMConstNull(Ty: *Type) *Value; - pub const constAllOnes = LLVMConstAllOnes; - extern fn LLVMConstAllOnes(Ty: *Type) *Value; - pub const constInt = LLVMConstInt; extern fn LLVMConstInt(IntTy: *Type, N: c_ulonglong, SignExtend: Bool) *Value; @@ -476,9 +429,6 @@ pub const Module = opaque { pub const addFunctionInAddressSpace = ZigLLVMAddFunctionInAddressSpace; extern fn ZigLLVMAddFunctionInAddressSpace(*Module, Name: [*:0]const u8, FunctionTy: *Type, AddressSpace: c_uint) *Value; - pub const getNamedFunction = LLVMGetNamedFunction; - extern fn LLVMGetNamedFunction(*Module, Name: [*:0]const u8) ?*Value; - pub const printToString = LLVMPrintModuleToString; extern fn LLVMPrintModuleToString(*Module) [*:0]const u8; @@ -488,18 +438,9 @@ pub const Module = opaque { pub const addGlobalInAddressSpace = LLVMAddGlobalInAddressSpace; extern fn LLVMAddGlobalInAddressSpace(M: *Module, Ty: *Type, Name: [*:0]const u8, AddressSpace: c_uint) *Value; - pub const getNamedGlobal = LLVMGetNamedGlobal; - extern fn LLVMGetNamedGlobal(M: *Module, Name: [*:0]const u8) ?*Value; - pub const dump = LLVMDumpModule; extern fn LLVMDumpModule(M: *Module) void; - pub const getFirstGlobalAlias = LLVMGetFirstGlobalAlias; - extern fn LLVMGetFirstGlobalAlias(M: *Module) *Value; - - pub const getLastGlobalAlias = LLVMGetLastGlobalAlias; - extern fn LLVMGetLastGlobalAlias(M: *Module) *Value; - pub const addAlias = LLVMAddAlias2; extern fn LLVMAddAlias2( M: *Module, @@ -541,9 +482,6 @@ pub const Module = opaque { extern fn LLVMWriteBitcodeToFile(M: *Module, Path: [*:0]const u8) c_int; }; -pub const lookupIntrinsicID = LLVMLookupIntrinsicID; -extern fn LLVMLookupIntrinsicID(Name: [*]const u8, NameLen: usize) c_uint; - pub const disposeMessage = LLVMDisposeMessage; extern fn LLVMDisposeMessage(Message: [*:0]const u8) void; @@ -604,12 +542,6 @@ pub const Builder = opaque { Instr: ?*Value, ) void; - pub const positionBuilderAtEnd = LLVMPositionBuilderAtEnd; - extern fn LLVMPositionBuilderAtEnd(Builder: *Builder, Block: *BasicBlock) void; - - pub const getInsertBlock = LLVMGetInsertBlock; - extern fn LLVMGetInsertBlock(Builder: *Builder) *BasicBlock; - pub const buildZExt = LLVMBuildZExt; extern fn LLVMBuildZExt( *Builder, @@ -618,14 +550,6 @@ pub const Builder = opaque { Name: [*:0]const u8, ) *Value; - pub const buildZExtOrBitCast = LLVMBuildZExtOrBitCast; - extern fn LLVMBuildZExtOrBitCast( - *Builder, - Val: *Value, - DestTy: *Type, - Name: [*:0]const u8, - ) *Value; - pub const buildSExt = LLVMBuildSExt; extern fn LLVMBuildSExt( *Builder, @@ -634,14 +558,6 @@ pub const Builder = opaque { Name: [*:0]const u8, ) *Value; - pub const buildSExtOrBitCast = LLVMBuildSExtOrBitCast; - extern fn LLVMBuildSExtOrBitCast( - *Builder, - Val: *Value, - DestTy: *Type, - Name: [*:0]const u8, - ) *Value; - pub const buildCall = LLVMBuildCall2; extern fn LLVMBuildCall2( *Builder, @@ -670,12 +586,6 @@ pub const Builder = opaque { pub const buildLoad = LLVMBuildLoad2; extern fn LLVMBuildLoad2(*Builder, Ty: *Type, PointerVal: *Value, Name: [*:0]const u8) *Value; - pub const buildNeg = LLVMBuildNeg; - extern fn LLVMBuildNeg(*Builder, V: *Value, Name: [*:0]const u8) *Value; - - pub const buildNot = LLVMBuildNot; - extern fn LLVMBuildNot(*Builder, V: *Value, Name: [*:0]const u8) *Value; - pub const buildFAdd = LLVMBuildFAdd; extern fn LLVMBuildFAdd(*Builder, LHS: *Value, RHS: *Value, Name: [*:0]const u8) *Value;