Commit 42ddf592dd

Stefan Su <stefansu28@gmail.com>
2023-12-22 15:51:41
use `casted_rhs` instead of `rhs` so `icmp` works correctly for `airShlSat`
1 parent fd98fc1
Changed files (2)
src
codegen
test
src/codegen/llvm.zig
@@ -8433,7 +8433,7 @@ pub const FuncGen = struct {
             llvm_lhs_ty,
             try o.builder.intConst(llvm_lhs_scalar_ty, -1),
         );
-        const in_range = try self.wip.icmp(.ult, rhs, bits, "");
+        const in_range = try self.wip.icmp(.ult, casted_rhs, bits, "");
         return self.wip.select(.normal, in_range, result, lhs_max, "");
     }
 
test/behavior/bit_shifting.zig
@@ -109,3 +109,46 @@ test "comptime shr of BigInt" {
 test "comptime shift safety check" {
     _ = @as(usize, 42) << @sizeOf(usize);
 }
+
+test "Saturating Shift Left where lhs is of a computed type" {
+    if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
+    if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
+    if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
+    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
+    if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
+
+    const S = struct {
+        fn getIntShiftType(comptime T: type) type {
+            var unsigned_shift_type = @typeInfo(std.math.Log2Int(T)).Int;
+            unsigned_shift_type.signedness = .signed;
+
+            return @Type(.{
+                .Int = unsigned_shift_type,
+            });
+        }
+
+        pub fn FixedPoint(comptime value_type: type) type {
+            return struct {
+                value: value_type,
+                exponent: ShiftType,
+
+                const ShiftType: type = getIntShiftType(value_type);
+
+                pub fn shiftExponent(self: @This(), shift: ShiftType) @This() {
+                    const shiftAbs = @abs(shift);
+                    return .{ .value = if (shift >= 0) self.value >> shiftAbs else self.value <<| shiftAbs, .exponent = self.exponent + shift };
+                }
+            };
+        }
+    };
+
+    const FP = S.FixedPoint(i32);
+
+    const value = (FP{
+        .value = 1,
+        .exponent = 1,
+    }).shiftExponent(-1);
+
+    try expect(value.value == 2);
+    try expect(value.exponent == 0);
+}