zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

commit 42ddf592dd610dda3371cae2eba63ac3e8502c64 (tree)
parent fd98fc1c5f83224cf1f128df7ba1cd24e4d40808
Author: Stefan Su <stefansu28@gmail.com>
Date:   Fri, 22 Dec 2023 09:51:41 -0500

use `casted_rhs` instead of `rhs` so `icmp` works correctly for `airShlSat`


Diffstat:
Msrc/codegen/llvm.zig | 2+-
Mtest/behavior/bit_shifting.zig | 43+++++++++++++++++++++++++++++++++++++++++++
2 files changed, 44 insertions(+), 1 deletion(-)

diff --git 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 @@ -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); +}