| 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 | 7034 | const rhs = try self.resolveInst(bin_op.rhs); |
| 7035 | 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 | 7038 | if (scalar_ty.isSignedInt()) return self.builder.buildSMin(lhs, rhs, ""); |
| 7039 | 7039 | return self.builder.buildUMin(lhs, rhs, ""); |
| 7040 | 7040 | } |
| ... | ... | @@ -7045,7 +7045,7 @@ pub const FuncGen = struct { |
| 7045 | 7045 | const rhs = try self.resolveInst(bin_op.rhs); |
| 7046 | 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 | 7049 | if (scalar_ty.isSignedInt()) return self.builder.buildSMax(lhs, rhs, ""); |
| 7050 | 7050 | return self.builder.buildUMax(lhs, rhs, ""); |
| 7051 | 7051 | } |
test/behavior/maximum_minimum.zig+25| ... | ... | @@ -96,6 +96,31 @@ test "@min for vectors" { |
| 96 | 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 | 124 | test "@min/@max on lazy values" { |
| 100 | 125 | const A = extern struct { u8_4: [4]u8 }; |
| 101 | 126 | const B = extern struct { u8_16: [16]u8 }; |