diff --git a/lib/std/math/big/int.zig b/lib/std/math/big/int.zig index a5463ed8e7f1..09c7f0237d05 100644 --- a/lib/std/math/big/int.zig +++ b/lib/std/math/big/int.zig @@ -1741,7 +1741,7 @@ pub const Mutable = struct { assert(mask.positive); r.positive = true; - std.mem.set(Limb, r.limbs, 0); + @memset(r.limbs, 0); var mask_limb: Limb = mask.limbs[0]; var mask_limb_index: Limb = 0; @@ -1787,7 +1787,7 @@ pub const Mutable = struct { assert(mask.positive); r.positive = true; - std.mem.set(Limb, r.limbs, 0); + @memset(r.limbs, 0); var mask_limb: Limb = mask.limbs[0]; var mask_limb_index: Limb = 0; diff --git a/src/Air.zig b/src/Air.zig index ecb1e99393ed..791a09f7b870 100644 --- a/src/Air.zig +++ b/src/Air.zig @@ -1751,6 +1751,8 @@ pub fn mustLower(air: Air, inst: Air.Inst.Index, ip: *const InternPool) bool { .work_item_id, .work_group_size, .work_group_id, + .deposit_bits, + .extract_bits, => false, .assembly => @truncate(u1, air.extraData(Air.Asm, data.ty_pl.payload).data.flags >> 31) != 0, diff --git a/src/Liveness/Verify.zig b/src/Liveness/Verify.zig index a5fc59289422..073e467c5f31 100644 --- a/src/Liveness/Verify.zig +++ b/src/Liveness/Verify.zig @@ -261,6 +261,8 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void { .memset, .memset_safe, .memcpy, + .deposit_bits, + .extract_bits, => { const bin_op = data[inst].bin_op; try self.verifyInstOperands(inst, .{ bin_op.lhs, bin_op.rhs, .none }); diff --git a/src/Sema.zig b/src/Sema.zig index 70667c764f62..bc71ad9d8f39 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -24153,7 +24153,7 @@ fn zirDepositExtractBits( extended: Zir.Inst.Extended.InstData, air_tag: Air.Inst.Tag, ) CompileError!Air.Inst.Ref { - const target = sema.mod.getTarget(); + const mod = sema.mod; const extra = sema.code.extraData(Zir.Inst.BinNode, extended.operand).data; const src = LazySrcLoc.nodeOffset(extra.node); @@ -24166,12 +24166,12 @@ fn zirDepositExtractBits( const lhs_ty = sema.typeOf(uncasted_lhs); const rhs_ty = sema.typeOf(uncasted_rhs); - if (!lhs_ty.isUnsignedInt() and lhs_ty.zigTypeTag() != .ComptimeInt) { - return sema.fail(block, lhs_src, "expected unsigned integer or 'comptime_int', found '{}'", .{lhs_ty.fmt(sema.mod)}); + if (!lhs_ty.isUnsignedInt(mod) and lhs_ty.zigTypeTag(mod) != .ComptimeInt) { + return sema.fail(block, lhs_src, "expected unsigned integer or 'comptime_int', found '{}'", .{lhs_ty.fmt(mod)}); } - if (!rhs_ty.isUnsignedInt() and rhs_ty.zigTypeTag() != .ComptimeInt) { - return sema.fail(block, rhs_src, "expected unsigned integer or 'comptime_int', found '{}'", .{rhs_ty.fmt(sema.mod)}); + if (!rhs_ty.isUnsignedInt(mod) and rhs_ty.zigTypeTag(mod) != .ComptimeInt) { + return sema.fail(block, rhs_src, "expected unsigned integer or 'comptime_int', found '{}'", .{rhs_ty.fmt(mod)}); } const instructions = &[_]Air.Inst.Ref{ uncasted_lhs, uncasted_rhs }; @@ -24190,7 +24190,7 @@ fn zirDepositExtractBits( error.AnalysisFail => { const msg = sema.err orelse return err; const val = (try sema.resolveMaybeUndefVal(uncasted_lhs)).?; - if (val.compareHetero(.lt, Value.zero, target)) { + if (val.orderAgainstZero(mod) == .lt) { try sema.errNote(block, src, msg, "parameters to {s} must be positive", .{builtin_name}); } return err; @@ -24202,7 +24202,7 @@ fn zirDepositExtractBits( error.AnalysisFail => { const msg = sema.err orelse return err; const val = (try sema.resolveMaybeUndefVal(uncasted_rhs)).?; - if (val.compareHetero(.lt, Value.zero, target)) { + if (val.orderAgainstZero(mod) == .lt) { try sema.errNote(block, src, msg, "parameters to {s} must be positive", .{builtin_name}); } return err; @@ -24215,18 +24215,18 @@ fn zirDepositExtractBits( // We check for negative values here only if the type is a comptime_int, as negative values // would have otherwise been filtered out by coercion and the unsigned type restriction - if (dest_ty.zigTypeTag() == .ComptimeInt) { + if (dest_ty.zigTypeTag(mod) == .ComptimeInt) { if (maybe_lhs_val) |lhs_val| { - if (!lhs_val.isUndef() and lhs_val.compareHetero(.lt, Value.zero, target)) { - const err = try sema.errMsg(block, lhs_src, "use of negative value '{}'", .{lhs_val.fmtValue(lhs_ty, sema.mod)}); + if (!lhs_val.isUndef(mod) and lhs_val.orderAgainstZero(mod) == .lt) { + const err = try sema.errMsg(block, lhs_src, "use of negative value '{}'", .{lhs_val.fmtValue(lhs_ty, mod)}); try sema.errNote(block, src, err, "parameters to {s} must be positive", .{builtin_name}); return sema.failWithOwnedErrorMsg(err); } } if (maybe_rhs_val) |rhs_val| { - if (!rhs_val.isUndef() and rhs_val.compareHetero(.lt, Value.zero, target)) { - const err = try sema.errMsg(block, rhs_src, "use of negative value '{}'", .{rhs_val.fmtValue(rhs_ty, sema.mod)}); + if (!rhs_val.isUndef(mod) and rhs_val.orderAgainstZero(mod) == .lt) { + const err = try sema.errMsg(block, rhs_src, "use of negative value '{}'", .{rhs_val.fmtValue(rhs_ty, mod)}); try sema.errNote(block, src, err, "parameters to {s} must be positive", .{builtin_name}); return sema.failWithOwnedErrorMsg(err); } @@ -24236,19 +24236,19 @@ fn zirDepositExtractBits( // If either of the operands are zero, the result is zero // If either of the operands are undefined, the result is undefined if (maybe_lhs_val) |lhs_val| { - if (try lhs_val.compareAllWithZeroAdvanced(.eq, sema)) return sema.addConstant(dest_ty, Value.zero); - if (lhs_val.isUndef()) return sema.addConstUndef(dest_ty); + if (lhs_val.orderAgainstZero(mod) == .eq) return sema.addConstant(dest_ty, try mod.intValue(dest_ty, 0)); + if (lhs_val.isUndef(mod)) return sema.addConstUndef(dest_ty); } if (maybe_rhs_val) |rhs_val| { - if (try rhs_val.compareAllWithZeroAdvanced(.eq, sema)) return sema.addConstant(dest_ty, Value.zero); - if (rhs_val.isUndef()) return sema.addConstUndef(dest_ty); + if (rhs_val.orderAgainstZero(mod) == .lt) return sema.addConstant(dest_ty, try mod.intValue(dest_ty, 0)); + if (rhs_val.isUndef(mod)) return sema.addConstUndef(dest_ty); } if (maybe_lhs_val) |lhs_val| { if (maybe_rhs_val) |rhs_val| { const dest_val = switch (air_tag) { - .deposit_bits => try sema.intDepositBits(lhs_val, rhs_val), - .extract_bits => try sema.intExtractBits(lhs_val, rhs_val), + .deposit_bits => try sema.intDepositBits(lhs_val, rhs_val, dest_ty), + .extract_bits => try sema.intExtractBits(lhs_val, rhs_val, dest_ty), else => unreachable, }; @@ -36375,16 +36375,17 @@ fn intDepositBits( sema: *Sema, lhs: Value, rhs: Value, + ty: Type, ) !Value { // TODO is this a performance issue? maybe we should try the operation without // resorting to BigInt first. For non-bigints, @intDeposit could be used? - const target = sema.mod.getTarget(); + const mod = sema.mod; const arena = sema.arena; var lhs_space: Value.BigIntSpace = undefined; var rhs_space: Value.BigIntSpace = undefined; - const source = lhs.toBigInt(&lhs_space, target); - const mask = rhs.toBigInt(&rhs_space, target); + const source = lhs.toBigInt(&lhs_space, mod); + const mask = rhs.toBigInt(&rhs_space, mod); const result_limbs = try arena.alloc( std.math.big.Limb, @@ -36394,7 +36395,7 @@ fn intDepositBits( var result = std.math.big.int.Mutable{ .limbs = result_limbs, .positive = undefined, .len = undefined }; result.depositBits(source, mask); - return Value.fromBigInt(arena, result.toConst()); + return mod.intValue_big(ty, result.toConst()); } /// Asserts that the values are positive @@ -36402,16 +36403,17 @@ fn intExtractBits( sema: *Sema, lhs: Value, rhs: Value, + ty: Type, ) !Value { // TODO is this a performance issue? maybe we should try the operation without // resorting to BigInt first. For non-bigints, @intExtract could be used? - const target = sema.mod.getTarget(); + const mod = sema.mod; const arena = sema.arena; var lhs_space: Value.BigIntSpace = undefined; var rhs_space: Value.BigIntSpace = undefined; - const source = lhs.toBigInt(&lhs_space, target); - const mask = rhs.toBigInt(&rhs_space, target); + const source = lhs.toBigInt(&lhs_space, mod); + const mask = rhs.toBigInt(&rhs_space, mod); const result_limbs = try arena.alloc( std.math.big.Limb, @@ -36421,7 +36423,7 @@ fn intExtractBits( var result = std.math.big.int.Mutable{ .limbs = result_limbs, .positive = undefined, .len = undefined }; result.extractBits(source, mask); - return Value.fromBigInt(arena, result.toConst()); + return mod.intValue_big(ty, result.toConst()); } /// Asserts the values are comparable. Both operands have type `ty`. diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig index 154b59b66c23..6f03108d8cd7 100644 --- a/src/codegen/llvm.zig +++ b/src/codegen/llvm.zig @@ -9456,7 +9456,7 @@ pub const FuncGen = struct { const bin_op = self.air.instructions.items(.data)[inst].bin_op; const lhs = try self.resolveInst(bin_op.lhs); const rhs = try self.resolveInst(bin_op.rhs); - const inst_ty = self.air.typeOfIndex(inst); + const inst_ty = self.typeOfIndex(inst); const target = self.dg.module.getTarget(); const params = [2]*llvm.Value{ lhs, rhs }; @@ -9465,7 +9465,7 @@ pub const FuncGen = struct { // Doesn't have pdep if (!std.Target.x86.featureSetHas(target.cpu.features, .bmi2)) break :blk; - const bits = inst_ty.intInfo(target).bits; + const bits = inst_ty.intInfo(self.dg.module).bits; const supports_64 = tag == .x86_64; // Integer size doesn't match the available instruction(s) if (!(bits <= 32 or (bits <= 64 and supports_64))) break :blk; @@ -9488,7 +9488,7 @@ pub const FuncGen = struct { assert(target.cpu.arch.isX86()); assert(std.Target.x86.featureSetHas(target.cpu.features, .bmi2)); - const bits = ty.intInfo(target).bits; + const bits = ty.intInfo(self.dg.module).bits; const intrinsic_name = switch (bits) { 1...32 => "llvm.x86.bmi.pdep.32", 33...64 => "llvm.x86.bmi.pdep.64", @@ -9603,7 +9603,7 @@ pub const FuncGen = struct { const bin_op = self.air.instructions.items(.data)[inst].bin_op; const lhs = try self.resolveInst(bin_op.lhs); const rhs = try self.resolveInst(bin_op.rhs); - const inst_ty = self.air.typeOfIndex(inst); + const inst_ty = self.typeOfIndex(inst); const target = self.dg.module.getTarget(); const params = [2]*llvm.Value{ lhs, rhs }; @@ -9612,7 +9612,7 @@ pub const FuncGen = struct { // Doesn't have pext if (!std.Target.x86.featureSetHas(target.cpu.features, .bmi2)) break :blk; - const bits = inst_ty.intInfo(target).bits; + const bits = inst_ty.intInfo(self.dg.module).bits; const supports_64 = tag == .x86_64; // Integer size doesn't match the available instruction(s) if (!(bits <= 32 or (bits <= 64 and supports_64))) break :blk; @@ -9635,7 +9635,7 @@ pub const FuncGen = struct { assert(target.cpu.arch.isX86()); assert(std.Target.x86.featureSetHas(target.cpu.features, .bmi2)); - const bits = ty.intInfo(target).bits; + const bits = ty.intInfo(self.dg.module).bits; const intrinsic_name = switch (bits) { 1...32 => "llvm.x86.bmi.pext.32", 33...64 => "llvm.x86.bmi.pext.64",