From 42ddf592dd610dda3371cae2eba63ac3e8502c64 Mon Sep 17 00:00:00 2001 From: Stefan Su Date: Fri, 22 Dec 2023 09:51:41 -0500 Subject: [PATCH] use `casted_rhs` instead of `rhs` so `icmp` works correctly for `airShlSat` --- src/codegen/llvm.zig | 2 +- test/behavior/bit_shifting.zig | 43 ++++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig index 6dfcf55307..43cda63f43 100644 --- a/src/codegen/llvm.zig +++ b/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, ""); } diff --git a/test/behavior/bit_shifting.zig b/test/behavior/bit_shifting.zig index b47dfa23c1..a25506efc6 100644 --- a/test/behavior/bit_shifting.zig +++ b/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); +}