| author | |
| committer | |
| log | c857959372ec87e3988c2548876d818d92df5f9a |
| tree | 61037a921b8a12c1cd632d73bdd5197fe02b2f14 |
| parent | d761e6cc7d9f1d77af55a4a89bdfe960b0f98608 |
| parent | 716d6a026f468cdb6b84a3e7f1004904b9ac6ecc |
| signature |
llvm: fix `@max`/`@min` of unsupported float types2 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(); |
| 7036 | 7036 | ||
| 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(); |
| 7047 | 7047 | ||
| 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 | } |
| 98 | 98 | ||
| 99 | test "@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 | |||
| 99 | test "@min/@max on lazy values" { | 124 | test "@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 }; |