commit c857959372ec87e3988c2548876d818d92df5f9a (tree)
parent d761e6cc7d9f1d77af55a4a89bdfe960b0f98608
Author: Andrew Kelley <andrew@ziglang.org>
Date: Thu, 11 May 2023 08:35:08 -0700
Merge pull request #15640 from jacobly0/min-max
llvm: fix `@max`/`@min` of unsupported float types
Diffstat:
2 files changed, 27 insertions(+), 2 deletions(-)
diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig
@@ -7034,7 +7034,7 @@ pub const FuncGen = struct {
const rhs = try self.resolveInst(bin_op.rhs);
const scalar_ty = self.air.typeOfIndex(inst).scalarType();
- if (scalar_ty.isAnyFloat()) return self.builder.buildMinNum(lhs, rhs, "");
+ if (scalar_ty.isAnyFloat()) return self.buildFloatOp(.fmin, scalar_ty, 2, .{ lhs, rhs });
if (scalar_ty.isSignedInt()) return self.builder.buildSMin(lhs, rhs, "");
return self.builder.buildUMin(lhs, rhs, "");
}
@@ -7045,7 +7045,7 @@ pub const FuncGen = struct {
const rhs = try self.resolveInst(bin_op.rhs);
const scalar_ty = self.air.typeOfIndex(inst).scalarType();
- if (scalar_ty.isAnyFloat()) return self.builder.buildMaxNum(lhs, rhs, "");
+ if (scalar_ty.isAnyFloat()) return self.buildFloatOp(.fmax, scalar_ty, 2, .{ lhs, rhs });
if (scalar_ty.isSignedInt()) return self.builder.buildSMax(lhs, rhs, "");
return self.builder.buildUMax(lhs, rhs, "");
}
diff --git a/test/behavior/maximum_minimum.zig b/test/behavior/maximum_minimum.zig
@@ -96,6 +96,31 @@ test "@min for vectors" {
comptime try S.doTheTest();
}
+test "@min/max for floats" {
+ if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
+ 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
+
+ const S = struct {
+ fn doTheTest(comptime T: type) !void {
+ var x: T = -3.14;
+ var y: T = 5.27;
+ try expectEqual(x, @min(x, y));
+ try expectEqual(x, @min(y, x));
+ try expectEqual(y, @max(x, y));
+ try expectEqual(y, @max(y, x));
+ }
+ };
+
+ inline for (.{ f16, f32, f64, f80, f128, c_longdouble }) |T| {
+ try S.doTheTest(T);
+ comptime try S.doTheTest(T);
+ }
+ comptime try S.doTheTest(comptime_float);
+}
+
test "@min/@max on lazy values" {
const A = extern struct { u8_4: [4]u8 };
const B = extern struct { u8_16: [16]u8 };