authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-05-11 08:35:08-07:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2023-05-11 08:35:08-07:00
logc857959372ec87e3988c2548876d818d92df5f9a
tree61037a921b8a12c1cd632d73bdd5197fe02b2f14
parentd761e6cc7d9f1d77af55a4a89bdfe960b0f98608
parent716d6a026f468cdb6b84a3e7f1004904b9ac6ecc
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #15640 from jacobly0/min-max

llvm: fix `@max`/`@min` of unsupported float types

2 files changed, 27 insertions(+), 2 deletions(-)

src/codegen/llvm.zig+2-2
...@@ -7034,7 +7034,7 @@ pub const FuncGen = struct {...@@ -7034,7 +7034,7 @@ pub const FuncGen = struct {
7034 const rhs = try self.resolveInst(bin_op.rhs);7034 const rhs = try self.resolveInst(bin_op.rhs);
7035 const scalar_ty = self.air.typeOfIndex(inst).scalarType();7035 const scalar_ty = self.air.typeOfIndex(inst).scalarType();
70367036
7037 if (scalar_ty.isAnyFloat()) return self.builder.buildMinNum(lhs, rhs, "");7037 if (scalar_ty.isAnyFloat()) return self.buildFloatOp(.fmin, scalar_ty, 2, .{ lhs, rhs });
7038 if (scalar_ty.isSignedInt()) return self.builder.buildSMin(lhs, rhs, "");7038 if (scalar_ty.isSignedInt()) return self.builder.buildSMin(lhs, rhs, "");
7039 return self.builder.buildUMin(lhs, rhs, "");7039 return self.builder.buildUMin(lhs, rhs, "");
7040 }7040 }
...@@ -7045,7 +7045,7 @@ pub const FuncGen = struct {...@@ -7045,7 +7045,7 @@ pub const FuncGen = struct {
7045 const rhs = try self.resolveInst(bin_op.rhs);7045 const rhs = try self.resolveInst(bin_op.rhs);
7046 const scalar_ty = self.air.typeOfIndex(inst).scalarType();7046 const scalar_ty = self.air.typeOfIndex(inst).scalarType();
70477047
7048 if (scalar_ty.isAnyFloat()) return self.builder.buildMaxNum(lhs, rhs, "");7048 if (scalar_ty.isAnyFloat()) return self.buildFloatOp(.fmax, scalar_ty, 2, .{ lhs, rhs });
7049 if (scalar_ty.isSignedInt()) return self.builder.buildSMax(lhs, rhs, "");7049 if (scalar_ty.isSignedInt()) return self.builder.buildSMax(lhs, rhs, "");
7050 return self.builder.buildUMax(lhs, rhs, "");7050 return self.builder.buildUMax(lhs, rhs, "");
7051 }7051 }
test/behavior/maximum_minimum.zig+25
...@@ -96,6 +96,31 @@ test "@min for vectors" {...@@ -96,6 +96,31 @@ test "@min for vectors" {
96 comptime try S.doTheTest();96 comptime try S.doTheTest();
97}97}
9898
99test "@min/max for floats" {
100 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
101 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
102 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
103 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
104 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
105
106 const S = struct {
107 fn doTheTest(comptime T: type) !void {
108 var x: T = -3.14;
109 var y: T = 5.27;
110 try expectEqual(x, @min(x, y));
111 try expectEqual(x, @min(y, x));
112 try expectEqual(y, @max(x, y));
113 try expectEqual(y, @max(y, x));
114 }
115 };
116
117 inline for (.{ f16, f32, f64, f80, f128, c_longdouble }) |T| {
118 try S.doTheTest(T);
119 comptime try S.doTheTest(T);
120 }
121 comptime try S.doTheTest(comptime_float);
122}
123
99test "@min/@max on lazy values" {124test "@min/@max on lazy values" {
100 const A = extern struct { u8_4: [4]u8 };125 const A = extern struct { u8_4: [4]u8 };
101 const B = extern struct { u8_16: [16]u8 };126 const B = extern struct { u8_16: [16]u8 };