authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-01-02 14:11:37-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-01-02 14:11:37-07:00
logb4d6e85a339e971829404dc1a260bde4062735f8
tree7debe384b184d4b8c24f3d35e2ec8a32b9da8cd0
parent6b14c58f63a177c26ed7ac51c25738ecb115462d

Sema: implement peer type resolution of signed and unsigned ints

This allows stage2 to build more of compiler-rt. I also changed `-%` to `-` for comptime ints in the div and mul implementations of compiler-rt. This is clearer code and also happens to work around a bug in stage2.

9 files changed, 58 insertions(+), 61 deletions(-)

lib/std/special/compiler_rt.zig+31-35
......@@ -221,21 +221,19 @@ comptime {
221221 const __subtf3 = @import("compiler_rt/addXf3.zig").__subtf3;
222222 @export(__subtf3, .{ .name = "__subtf3", .linkage = linkage });
223223
224 if (!builtin.zig_is_stage2) {
225 const __mulsf3 = @import("compiler_rt/mulXf3.zig").__mulsf3;
226 @export(__mulsf3, .{ .name = "__mulsf3", .linkage = linkage });
227 const __muldf3 = @import("compiler_rt/mulXf3.zig").__muldf3;
228 @export(__muldf3, .{ .name = "__muldf3", .linkage = linkage });
229 const __multf3 = @import("compiler_rt/mulXf3.zig").__multf3;
230 @export(__multf3, .{ .name = "__multf3", .linkage = linkage });
231
232 const __divsf3 = @import("compiler_rt/divsf3.zig").__divsf3;
233 @export(__divsf3, .{ .name = "__divsf3", .linkage = linkage });
234 const __divdf3 = @import("compiler_rt/divdf3.zig").__divdf3;
235 @export(__divdf3, .{ .name = "__divdf3", .linkage = linkage });
236 const __divtf3 = @import("compiler_rt/divtf3.zig").__divtf3;
237 @export(__divtf3, .{ .name = "__divtf3", .linkage = linkage });
238 }
224 const __mulsf3 = @import("compiler_rt/mulXf3.zig").__mulsf3;
225 @export(__mulsf3, .{ .name = "__mulsf3", .linkage = linkage });
226 const __muldf3 = @import("compiler_rt/mulXf3.zig").__muldf3;
227 @export(__muldf3, .{ .name = "__muldf3", .linkage = linkage });
228 const __multf3 = @import("compiler_rt/mulXf3.zig").__multf3;
229 @export(__multf3, .{ .name = "__multf3", .linkage = linkage });
230
231 const __divsf3 = @import("compiler_rt/divsf3.zig").__divsf3;
232 @export(__divsf3, .{ .name = "__divsf3", .linkage = linkage });
233 const __divdf3 = @import("compiler_rt/divdf3.zig").__divdf3;
234 @export(__divdf3, .{ .name = "__divdf3", .linkage = linkage });
235 const __divtf3 = @import("compiler_rt/divtf3.zig").__divtf3;
236 @export(__divtf3, .{ .name = "__divtf3", .linkage = linkage });
239237
240238 // Integral bit manipulation
241239 const __ashldi3 = @import("compiler_rt/shift.zig").__ashldi3;
......@@ -251,26 +249,24 @@ comptime {
251249 const __lshrti3 = @import("compiler_rt/shift.zig").__lshrti3;
252250 @export(__lshrti3, .{ .name = "__lshrti3", .linkage = linkage });
253251
254 if (!builtin.zig_is_stage2) {
255 const __clzsi2 = @import("compiler_rt/count0bits.zig").__clzsi2;
256 @export(__clzsi2, .{ .name = "__clzsi2", .linkage = linkage });
257 const __clzdi2 = @import("compiler_rt/count0bits.zig").__clzdi2;
258 @export(__clzdi2, .{ .name = "__clzdi2", .linkage = linkage });
259 const __clzti2 = @import("compiler_rt/count0bits.zig").__clzti2;
260 @export(__clzti2, .{ .name = "__clzti2", .linkage = linkage });
261 const __ctzsi2 = @import("compiler_rt/count0bits.zig").__ctzsi2;
262 @export(__ctzsi2, .{ .name = "__ctzsi2", .linkage = linkage });
263 const __ctzdi2 = @import("compiler_rt/count0bits.zig").__ctzdi2;
264 @export(__ctzdi2, .{ .name = "__ctzdi2", .linkage = linkage });
265 const __ctzti2 = @import("compiler_rt/count0bits.zig").__ctzti2;
266 @export(__ctzti2, .{ .name = "__ctzti2", .linkage = linkage });
267 const __ffssi2 = @import("compiler_rt/count0bits.zig").__ffssi2;
268 @export(__ffssi2, .{ .name = "__ffssi2", .linkage = linkage });
269 const __ffsdi2 = @import("compiler_rt/count0bits.zig").__ffsdi2;
270 @export(__ffsdi2, .{ .name = "__ffsdi2", .linkage = linkage });
271 const __ffsti2 = @import("compiler_rt/count0bits.zig").__ffsti2;
272 @export(__ffsti2, .{ .name = "__ffsti2", .linkage = linkage });
273 }
252 const __clzsi2 = @import("compiler_rt/count0bits.zig").__clzsi2;
253 @export(__clzsi2, .{ .name = "__clzsi2", .linkage = linkage });
254 const __clzdi2 = @import("compiler_rt/count0bits.zig").__clzdi2;
255 @export(__clzdi2, .{ .name = "__clzdi2", .linkage = linkage });
256 const __clzti2 = @import("compiler_rt/count0bits.zig").__clzti2;
257 @export(__clzti2, .{ .name = "__clzti2", .linkage = linkage });
258 const __ctzsi2 = @import("compiler_rt/count0bits.zig").__ctzsi2;
259 @export(__ctzsi2, .{ .name = "__ctzsi2", .linkage = linkage });
260 const __ctzdi2 = @import("compiler_rt/count0bits.zig").__ctzdi2;
261 @export(__ctzdi2, .{ .name = "__ctzdi2", .linkage = linkage });
262 const __ctzti2 = @import("compiler_rt/count0bits.zig").__ctzti2;
263 @export(__ctzti2, .{ .name = "__ctzti2", .linkage = linkage });
264 const __ffssi2 = @import("compiler_rt/count0bits.zig").__ffssi2;
265 @export(__ffssi2, .{ .name = "__ffssi2", .linkage = linkage });
266 const __ffsdi2 = @import("compiler_rt/count0bits.zig").__ffsdi2;
267 @export(__ffsdi2, .{ .name = "__ffsdi2", .linkage = linkage });
268 const __ffsti2 = @import("compiler_rt/count0bits.zig").__ffsti2;
269 @export(__ffsti2, .{ .name = "__ffsti2", .linkage = linkage });
274270
275271 const __paritysi2 = @import("compiler_rt/parity.zig").__paritysi2;
276272 @export(__paritysi2, .{ .name = "__paritysi2", .linkage = linkage });
lib/std/special/compiler_rt/divdf3.zig+1-1
......@@ -35,7 +35,7 @@ pub fn __divdf3(a: f64, b: f64) callconv(.C) f64 {
3535 var scale: i32 = 0;
3636
3737 // Detect if a or b is zero, denormal, infinity, or NaN.
38 if (aExponent -% 1 >= maxExponent -% 1 or bExponent -% 1 >= maxExponent -% 1) {
38 if (aExponent -% 1 >= maxExponent - 1 or bExponent -% 1 >= maxExponent - 1) {
3939 const aAbs: Z = @bitCast(Z, a) & absMask;
4040 const bAbs: Z = @bitCast(Z, b) & absMask;
4141
lib/std/special/compiler_rt/divsf3.zig+1-1
......@@ -34,7 +34,7 @@ pub fn __divsf3(a: f32, b: f32) callconv(.C) f32 {
3434 var scale: i32 = 0;
3535
3636 // Detect if a or b is zero, denormal, infinity, or NaN.
37 if (aExponent -% 1 >= maxExponent -% 1 or bExponent -% 1 >= maxExponent -% 1) {
37 if (aExponent -% 1 >= maxExponent - 1 or bExponent -% 1 >= maxExponent - 1) {
3838 const aAbs: Z = @bitCast(Z, a) & absMask;
3939 const bAbs: Z = @bitCast(Z, b) & absMask;
4040
lib/std/special/compiler_rt/divtf3.zig+1-1
......@@ -33,7 +33,7 @@ pub fn __divtf3(a: f128, b: f128) callconv(.C) f128 {
3333 var scale: i32 = 0;
3434
3535 // Detect if a or b is zero, denormal, infinity, or NaN.
36 if (aExponent -% 1 >= maxExponent -% 1 or bExponent -% 1 >= maxExponent -% 1) {
36 if (aExponent -% 1 >= maxExponent - 1 or bExponent -% 1 >= maxExponent - 1) {
3737 const aAbs: Z = @bitCast(Z, a) & absMask;
3838 const bAbs: Z = @bitCast(Z, b) & absMask;
3939
lib/std/special/compiler_rt/mulXf3.zig+1-1
......@@ -56,7 +56,7 @@ fn mulXf3(comptime T: type, a: T, b: T) T {
5656 var scale: i32 = 0;
5757
5858 // Detect if a or b is zero, denormal, infinity, or NaN.
59 if (aExponent -% 1 >= maxExponent -% 1 or bExponent -% 1 >= maxExponent -% 1) {
59 if (aExponent -% 1 >= maxExponent - 1 or bExponent -% 1 >= maxExponent - 1) {
6060 const aAbs: Z = @bitCast(Z, a) & absMask;
6161 const bAbs: Z = @bitCast(Z, b) & absMask;
6262
src/Sema.zig+12-11
......@@ -14634,11 +14634,11 @@ fn resolvePeerTypes(
1463414634 instructions: []Air.Inst.Ref,
1463514635 candidate_srcs: Module.PeerTypeCandidateSrc,
1463614636) !Type {
14637 if (instructions.len == 0)
14638 return Type.initTag(.noreturn);
14639
14640 if (instructions.len == 1)
14641 return sema.typeOf(instructions[0]);
14637 switch (instructions.len) {
14638 0 => return Type.initTag(.noreturn),
14639 1 => return sema.typeOf(instructions[0]),
14640 else => {},
14641 }
1464214642
1464314643 const target = sema.mod.getTarget();
1464414644
......@@ -14668,13 +14668,14 @@ fn resolvePeerTypes(
1466814668 continue;
1466914669 },
1467014670 .Int => {
14671 if (chosen_ty.isSignedInt() == candidate_ty.isSignedInt()) {
14672 if (chosen_ty.intInfo(target).bits < candidate_ty.intInfo(target).bits) {
14673 chosen = candidate;
14674 chosen_i = candidate_i + 1;
14675 }
14676 continue;
14671 const chosen_info = chosen_ty.intInfo(target);
14672 const candidate_info = candidate_ty.intInfo(target);
14673
14674 if (chosen_info.bits < candidate_info.bits) {
14675 chosen = candidate;
14676 chosen_i = candidate_i + 1;
1467714677 }
14678 continue;
1467814679 },
1467914680 .Pointer => if (chosen_ty.ptrSize() == .C) continue,
1468014681 else => {},
src/type.zig+2-2
......@@ -3106,9 +3106,9 @@ pub const Type = extern union {
31063106 .c_ulonglong => return .{ .signedness = .unsigned, .bits = CType.ulonglong.sizeInBits(target) },
31073107
31083108 .enum_full, .enum_nonexhaustive => ty = ty.cast(Payload.EnumFull).?.data.tag_ty,
3109 .enum_numbered => ty = self.castTag(.enum_numbered).?.data.tag_ty,
3109 .enum_numbered => ty = ty.castTag(.enum_numbered).?.data.tag_ty,
31103110 .enum_simple => {
3111 const enum_obj = self.castTag(.enum_simple).?.data;
3111 const enum_obj = ty.castTag(.enum_simple).?.data;
31123112 const field_count = enum_obj.fields.count();
31133113 if (field_count == 0) return .{ .signedness = .unsigned, .bits = 0 };
31143114 return .{ .signedness = .unsigned, .bits = smallestUnsignedBits(field_count - 1) };
test/behavior/cast.zig+9
......@@ -295,3 +295,12 @@ test "cast from ?[*]T to ??[*]T" {
295295 const a: ??[*]u8 = @as(?[*]u8, null);
296296 try expect(a != null and a.? == null);
297297}
298
299test "peer type unsigned int to signed" {
300 var w: u31 = 5;
301 var x: u8 = 7;
302 var y: i32 = -5;
303 var a = w + y + x;
304 comptime try expect(@TypeOf(a) == i32);
305 try expect(a == 7);
306}
test/behavior/cast_stage1.zig-9
......@@ -383,15 +383,6 @@ test "peer type resolve string lit with sentinel-terminated mutable slice" {
383383 comptime try expect(@TypeOf("hi", slice) == [:0]const u8);
384384}
385385
386test "peer type unsigned int to signed" {
387 var w: u31 = 5;
388 var x: u8 = 7;
389 var y: i32 = -5;
390 var a = w + y + x;
391 comptime try expect(@TypeOf(a) == i32);
392 try expect(a == 7);
393}
394
395386test "peer type resolve array pointers, one of them const" {
396387 var array1: [4]u8 = undefined;
397388 const array2: [5]u8 = undefined;