Sema: rewrite analyzeMinMax

I only wanted to fix a bug originally, but this logic was kind of a
rat's nest. But now... okay, it still *is*, but it's now a slightly more
navigable nest, with cute little signs occasionally, painted by adorable
rats desparately trying to follow the specification.

Hopefully #3806 comes along at some point to simplify this logic a
little.

Resolves: #23139
This commit is contained in:
mlugg
2025-05-17 16:59:53 +01:00
committed by Matthew Lugg
parent b77e601342
commit 07a5efd072
2 changed files with 324 additions and 200 deletions

View File

@@ -351,3 +351,44 @@ test "@min resulting in u0" {
const x = S.min(0, 1);
try expect(x == 0);
}
test "@min/@max with runtime signed and unsigned integers of same size" {
const S = struct {
fn min(a: i32, b: u32) i32 {
return @min(a, b);
}
fn max(a: i32, b: u32) u32 {
return @max(a, b);
}
};
const min = S.min(std.math.minInt(i32), std.math.maxInt(u32));
try expect(min == std.math.minInt(i32));
const max = S.max(std.math.minInt(i32), std.math.maxInt(u32));
try expect(max == std.math.maxInt(u32));
}
test "@min/@max with runtime vectors of signed and unsigned integers of same size" {
if (builtin.zig_backend == .stage2_wasm) 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_riscv64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
const S = struct {
fn min(a: @Vector(2, i32), b: @Vector(2, u32)) @Vector(2, i32) {
return @min(a, b);
}
fn max(a: @Vector(2, i32), b: @Vector(2, u32)) @Vector(2, u32) {
return @max(a, b);
}
};
const a: @Vector(2, i32) = .{ std.math.minInt(i32), std.math.maxInt(i32) };
const b: @Vector(2, u32) = .{ std.math.maxInt(u32), std.math.minInt(u32) };
try expectEqual(@Vector(2, i32){ std.math.minInt(i32), std.math.minInt(u32) }, S.min(a, b));
try expectEqual(@Vector(2, u32){ std.math.maxInt(u32), std.math.maxInt(i32) }, S.max(a, b));
}