Commit 0c30799d40

Andrew Kelley <andrew@ziglang.org>
2022-01-30 23:23:40
Sema: fix comptime shl for fixed-width integers
1 parent 91ad96b
Changed files (3)
src
test
behavior
src/Sema.zig
@@ -7474,11 +7474,17 @@ fn zirShl(
         }
         const val = switch (air_tag) {
             .shl_exact => return sema.fail(block, lhs_src, "TODO implement Sema for comptime shl_exact", .{}),
+
             .shl_sat => if (lhs_ty.zigTypeTag() == .ComptimeInt)
                 try lhs_val.shl(rhs_val, sema.arena)
             else
                 try lhs_val.shlSat(rhs_val, lhs_ty, sema.arena, sema.mod.getTarget()),
-            .shl => try lhs_val.shl(rhs_val, sema.arena),
+
+            .shl => if (lhs_ty.zigTypeTag() == .ComptimeInt)
+                try lhs_val.shl(rhs_val, sema.arena)
+            else
+                try lhs_val.shlTrunc(rhs_val, lhs_ty, sema.arena, sema.mod.getTarget()),
+
             else => unreachable,
         };
 
src/value.zig
@@ -2883,6 +2883,19 @@ pub const Value = extern union {
         return fromBigInt(arena, result_bigint.toConst());
     }
 
+    pub fn shlTrunc(
+        lhs: Value,
+        rhs: Value,
+        ty: Type,
+        arena: Allocator,
+        target: Target,
+    ) !Value {
+        const shifted = try lhs.shl(rhs, arena);
+        const int_info = ty.intInfo(target);
+        const truncated = try shifted.intTrunc(arena, int_info.signedness, int_info.bits);
+        return truncated;
+    }
+
     pub fn shr(lhs: Value, rhs: Value, allocator: Allocator) !Value {
         // TODO is this a performance issue? maybe we should try the operation without
         // resorting to BigInt first.
test/behavior/math.zig
@@ -632,7 +632,10 @@ test "allow signed integer division/remainder when values are comptime known and
 }
 
 test "quad hex float literal parsing accurate" {
-    if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
+    if (builtin.zig_backend != .stage1) {
+        // TODO https://github.com/ziglang/zig/issues/10737
+        return error.SkipZigTest;
+    }
 
     const a: f128 = 0x1.1111222233334444555566667777p+0;
 
@@ -724,8 +727,6 @@ test "quad hex float literal parsing accurate" {
 }
 
 test "truncating shift left" {
-    if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
-
     try testShlTrunc(maxInt(u16));
     comptime try testShlTrunc(maxInt(u16));
 }