Merge branch 'LemonBoy-fix-4259'
This commit is contained in:
commit
7ebc624a15
91
src/ir.cpp
91
src/ir.cpp
@ -11161,6 +11161,38 @@ void float_read_ieee597(ZigValue *val, uint8_t *buf, bool is_big_endian) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void value_to_bigfloat(BigFloat *out, ZigValue *val) {
|
||||||
|
switch (val->type->id) {
|
||||||
|
case ZigTypeIdInt:
|
||||||
|
case ZigTypeIdComptimeInt:
|
||||||
|
bigfloat_init_bigint(out, &val->data.x_bigint);
|
||||||
|
return;
|
||||||
|
case ZigTypeIdComptimeFloat:
|
||||||
|
*out = val->data.x_bigfloat;
|
||||||
|
return;
|
||||||
|
case ZigTypeIdFloat: switch (val->type->data.floating.bit_count) {
|
||||||
|
case 16:
|
||||||
|
bigfloat_init_16(out, val->data.x_f16);
|
||||||
|
return;
|
||||||
|
case 32:
|
||||||
|
bigfloat_init_32(out, val->data.x_f32);
|
||||||
|
return;
|
||||||
|
case 64:
|
||||||
|
bigfloat_init_64(out, val->data.x_f64);
|
||||||
|
return;
|
||||||
|
case 80:
|
||||||
|
zig_panic("TODO");
|
||||||
|
case 128:
|
||||||
|
bigfloat_init_128(out, val->data.x_f128);
|
||||||
|
return;
|
||||||
|
default:
|
||||||
|
zig_unreachable();
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
zig_unreachable();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static bool ir_num_lit_fits_in_other_type(IrAnalyze *ira, IrInstGen *instruction, ZigType *other_type,
|
static bool ir_num_lit_fits_in_other_type(IrAnalyze *ira, IrInstGen *instruction, ZigType *other_type,
|
||||||
bool explicit_cast)
|
bool explicit_cast)
|
||||||
{
|
{
|
||||||
@ -15815,33 +15847,44 @@ never_mind_just_calculate_it_normally:
|
|||||||
bool op1_is_int = op1_val->type->id == ZigTypeIdInt || op1_val->type->id == ZigTypeIdComptimeInt;
|
bool op1_is_int = op1_val->type->id == ZigTypeIdInt || op1_val->type->id == ZigTypeIdComptimeInt;
|
||||||
bool op2_is_int = op2_val->type->id == ZigTypeIdInt || op2_val->type->id == ZigTypeIdComptimeInt;
|
bool op2_is_int = op2_val->type->id == ZigTypeIdInt || op2_val->type->id == ZigTypeIdComptimeInt;
|
||||||
|
|
||||||
BigInt *op1_bigint;
|
if (op1_is_int && op2_is_int) {
|
||||||
BigInt *op2_bigint;
|
Cmp cmp_result = bigint_cmp(&op1_val->data.x_bigint, &op2_val->data.x_bigint);
|
||||||
bool need_to_free_op1_bigint = false;
|
out_val->special = ConstValSpecialStatic;
|
||||||
bool need_to_free_op2_bigint = false;
|
out_val->data.x_bool = resolve_cmp_op_id(op_id, cmp_result);
|
||||||
if (op1_is_float) {
|
|
||||||
op1_bigint = allocate<BigInt>(1, "BigInt");
|
return nullptr;
|
||||||
need_to_free_op1_bigint = true;
|
}
|
||||||
float_init_bigint(op1_bigint, op1_val);
|
|
||||||
} else {
|
// Handle the case where one of the two operands is a fp value and the other
|
||||||
assert(op1_is_int);
|
// is an integer value
|
||||||
op1_bigint = &op1_val->data.x_bigint;
|
ZigValue *float_val;
|
||||||
}
|
if (op1_is_int && op2_is_float) {
|
||||||
if (op2_is_float) {
|
float_val = op2_val;
|
||||||
op2_bigint = allocate<BigInt>(1, "BigInt");
|
} else if (op1_is_float && op2_is_int) {
|
||||||
need_to_free_op2_bigint = true;
|
float_val = op1_val;
|
||||||
float_init_bigint(op2_bigint, op2_val);
|
} else {
|
||||||
} else {
|
zig_unreachable();
|
||||||
assert(op2_is_int);
|
}
|
||||||
op2_bigint = &op2_val->data.x_bigint;
|
|
||||||
}
|
// They can never be equal if the fp value has a non-zero decimal part
|
||||||
|
if (op_id == IrBinOpCmpEq || op_id == IrBinOpCmpNotEq) {
|
||||||
Cmp cmp_result = bigint_cmp(op1_bigint, op2_bigint);
|
if (float_has_fraction(float_val)) {
|
||||||
|
out_val->special = ConstValSpecialStatic;
|
||||||
|
out_val->data.x_bool = op_id == IrBinOpCmpNotEq;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cast the integer operand into a fp value to perform the comparison
|
||||||
|
BigFloat op1_bigfloat;
|
||||||
|
BigFloat op2_bigfloat;
|
||||||
|
value_to_bigfloat(&op1_bigfloat, op1_val);
|
||||||
|
value_to_bigfloat(&op2_bigfloat, op2_val);
|
||||||
|
|
||||||
|
Cmp cmp_result = bigfloat_cmp(&op1_bigfloat, &op2_bigfloat);
|
||||||
out_val->special = ConstValSpecialStatic;
|
out_val->special = ConstValSpecialStatic;
|
||||||
out_val->data.x_bool = resolve_cmp_op_id(op_id, cmp_result);
|
out_val->data.x_bool = resolve_cmp_op_id(op_id, cmp_result);
|
||||||
|
|
||||||
if (need_to_free_op1_bigint) destroy(op1_bigint, "BigInt");
|
|
||||||
if (need_to_free_op2_bigint) destroy(op2_bigint, "BigInt");
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,7 +36,7 @@ fn testSqrt() void {
|
|||||||
// expect(@sqrt(a) == 7);
|
// expect(@sqrt(a) == 7);
|
||||||
//}
|
//}
|
||||||
{
|
{
|
||||||
var v: @Vector(4, f32) = [_]f32{1.1, 2.2, 3.3, 4.4};
|
var v: @Vector(4, f32) = [_]f32{ 1.1, 2.2, 3.3, 4.4 };
|
||||||
var result = @sqrt(v);
|
var result = @sqrt(v);
|
||||||
expect(math.approxEq(f32, @sqrt(@as(f32, 1.1)), result[0], epsilon));
|
expect(math.approxEq(f32, @sqrt(@as(f32, 1.1)), result[0], epsilon));
|
||||||
expect(math.approxEq(f32, @sqrt(@as(f32, 2.2)), result[1], epsilon));
|
expect(math.approxEq(f32, @sqrt(@as(f32, 2.2)), result[1], epsilon));
|
||||||
@ -86,7 +86,7 @@ fn testSin() void {
|
|||||||
expect(@sin(a) == 0);
|
expect(@sin(a) == 0);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
var v: @Vector(4, f32) = [_]f32{1.1, 2.2, 3.3, 4.4};
|
var v: @Vector(4, f32) = [_]f32{ 1.1, 2.2, 3.3, 4.4 };
|
||||||
var result = @sin(v);
|
var result = @sin(v);
|
||||||
expect(math.approxEq(f32, @sin(@as(f32, 1.1)), result[0], epsilon));
|
expect(math.approxEq(f32, @sin(@as(f32, 1.1)), result[0], epsilon));
|
||||||
expect(math.approxEq(f32, @sin(@as(f32, 2.2)), result[1], epsilon));
|
expect(math.approxEq(f32, @sin(@as(f32, 2.2)), result[1], epsilon));
|
||||||
@ -116,7 +116,7 @@ fn testCos() void {
|
|||||||
expect(@cos(a) == 1);
|
expect(@cos(a) == 1);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
var v: @Vector(4, f32) = [_]f32{1.1, 2.2, 3.3, 4.4};
|
var v: @Vector(4, f32) = [_]f32{ 1.1, 2.2, 3.3, 4.4 };
|
||||||
var result = @cos(v);
|
var result = @cos(v);
|
||||||
expect(math.approxEq(f32, @cos(@as(f32, 1.1)), result[0], epsilon));
|
expect(math.approxEq(f32, @cos(@as(f32, 1.1)), result[0], epsilon));
|
||||||
expect(math.approxEq(f32, @cos(@as(f32, 2.2)), result[1], epsilon));
|
expect(math.approxEq(f32, @cos(@as(f32, 2.2)), result[1], epsilon));
|
||||||
@ -146,7 +146,7 @@ fn testExp() void {
|
|||||||
expect(@exp(a) == 1);
|
expect(@exp(a) == 1);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
var v: @Vector(4, f32) = [_]f32{1.1, 2.2, 0.3, 0.4};
|
var v: @Vector(4, f32) = [_]f32{ 1.1, 2.2, 0.3, 0.4 };
|
||||||
var result = @exp(v);
|
var result = @exp(v);
|
||||||
expect(math.approxEq(f32, @exp(@as(f32, 1.1)), result[0], epsilon));
|
expect(math.approxEq(f32, @exp(@as(f32, 1.1)), result[0], epsilon));
|
||||||
expect(math.approxEq(f32, @exp(@as(f32, 2.2)), result[1], epsilon));
|
expect(math.approxEq(f32, @exp(@as(f32, 2.2)), result[1], epsilon));
|
||||||
@ -176,7 +176,7 @@ fn testExp2() void {
|
|||||||
expect(@exp2(a) == 4);
|
expect(@exp2(a) == 4);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
var v: @Vector(4, f32) = [_]f32{1.1, 2.2, 0.3, 0.4};
|
var v: @Vector(4, f32) = [_]f32{ 1.1, 2.2, 0.3, 0.4 };
|
||||||
var result = @exp2(v);
|
var result = @exp2(v);
|
||||||
expect(math.approxEq(f32, @exp2(@as(f32, 1.1)), result[0], epsilon));
|
expect(math.approxEq(f32, @exp2(@as(f32, 1.1)), result[0], epsilon));
|
||||||
expect(math.approxEq(f32, @exp2(@as(f32, 2.2)), result[1], epsilon));
|
expect(math.approxEq(f32, @exp2(@as(f32, 2.2)), result[1], epsilon));
|
||||||
@ -208,7 +208,7 @@ fn testLog() void {
|
|||||||
expect(@log(a) == 1 or @log(a) == @bitCast(f64, @as(u64, 0x3ff0000000000000)));
|
expect(@log(a) == 1 or @log(a) == @bitCast(f64, @as(u64, 0x3ff0000000000000)));
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
var v: @Vector(4, f32) = [_]f32{1.1, 2.2, 0.3, 0.4};
|
var v: @Vector(4, f32) = [_]f32{ 1.1, 2.2, 0.3, 0.4 };
|
||||||
var result = @log(v);
|
var result = @log(v);
|
||||||
expect(math.approxEq(f32, @log(@as(f32, 1.1)), result[0], epsilon));
|
expect(math.approxEq(f32, @log(@as(f32, 1.1)), result[0], epsilon));
|
||||||
expect(math.approxEq(f32, @log(@as(f32, 2.2)), result[1], epsilon));
|
expect(math.approxEq(f32, @log(@as(f32, 2.2)), result[1], epsilon));
|
||||||
@ -238,7 +238,7 @@ fn testLog2() void {
|
|||||||
expect(@log2(a) == 2);
|
expect(@log2(a) == 2);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
var v: @Vector(4, f32) = [_]f32{1.1, 2.2, 0.3, 0.4};
|
var v: @Vector(4, f32) = [_]f32{ 1.1, 2.2, 0.3, 0.4 };
|
||||||
var result = @log2(v);
|
var result = @log2(v);
|
||||||
expect(math.approxEq(f32, @log2(@as(f32, 1.1)), result[0], epsilon));
|
expect(math.approxEq(f32, @log2(@as(f32, 1.1)), result[0], epsilon));
|
||||||
expect(math.approxEq(f32, @log2(@as(f32, 2.2)), result[1], epsilon));
|
expect(math.approxEq(f32, @log2(@as(f32, 2.2)), result[1], epsilon));
|
||||||
@ -268,7 +268,7 @@ fn testLog10() void {
|
|||||||
expect(@log10(a) == 3);
|
expect(@log10(a) == 3);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
var v: @Vector(4, f32) = [_]f32{1.1, 2.2, 0.3, 0.4};
|
var v: @Vector(4, f32) = [_]f32{ 1.1, 2.2, 0.3, 0.4 };
|
||||||
var result = @log10(v);
|
var result = @log10(v);
|
||||||
expect(math.approxEq(f32, @log10(@as(f32, 1.1)), result[0], epsilon));
|
expect(math.approxEq(f32, @log10(@as(f32, 1.1)), result[0], epsilon));
|
||||||
expect(math.approxEq(f32, @log10(@as(f32, 2.2)), result[1], epsilon));
|
expect(math.approxEq(f32, @log10(@as(f32, 2.2)), result[1], epsilon));
|
||||||
@ -304,7 +304,7 @@ fn testFabs() void {
|
|||||||
expect(@fabs(b) == 2.5);
|
expect(@fabs(b) == 2.5);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
var v: @Vector(4, f32) = [_]f32{1.1, -2.2, 0.3, -0.4};
|
var v: @Vector(4, f32) = [_]f32{ 1.1, -2.2, 0.3, -0.4 };
|
||||||
var result = @fabs(v);
|
var result = @fabs(v);
|
||||||
expect(math.approxEq(f32, @fabs(@as(f32, 1.1)), result[0], epsilon));
|
expect(math.approxEq(f32, @fabs(@as(f32, 1.1)), result[0], epsilon));
|
||||||
expect(math.approxEq(f32, @fabs(@as(f32, -2.2)), result[1], epsilon));
|
expect(math.approxEq(f32, @fabs(@as(f32, -2.2)), result[1], epsilon));
|
||||||
@ -334,7 +334,7 @@ fn testFloor() void {
|
|||||||
expect(@floor(a) == 3);
|
expect(@floor(a) == 3);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
var v: @Vector(4, f32) = [_]f32{1.1, -2.2, 0.3, -0.4};
|
var v: @Vector(4, f32) = [_]f32{ 1.1, -2.2, 0.3, -0.4 };
|
||||||
var result = @floor(v);
|
var result = @floor(v);
|
||||||
expect(math.approxEq(f32, @floor(@as(f32, 1.1)), result[0], epsilon));
|
expect(math.approxEq(f32, @floor(@as(f32, 1.1)), result[0], epsilon));
|
||||||
expect(math.approxEq(f32, @floor(@as(f32, -2.2)), result[1], epsilon));
|
expect(math.approxEq(f32, @floor(@as(f32, -2.2)), result[1], epsilon));
|
||||||
@ -364,7 +364,7 @@ fn testCeil() void {
|
|||||||
expect(@ceil(a) == 4);
|
expect(@ceil(a) == 4);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
var v: @Vector(4, f32) = [_]f32{1.1, -2.2, 0.3, -0.4};
|
var v: @Vector(4, f32) = [_]f32{ 1.1, -2.2, 0.3, -0.4 };
|
||||||
var result = @ceil(v);
|
var result = @ceil(v);
|
||||||
expect(math.approxEq(f32, @ceil(@as(f32, 1.1)), result[0], epsilon));
|
expect(math.approxEq(f32, @ceil(@as(f32, 1.1)), result[0], epsilon));
|
||||||
expect(math.approxEq(f32, @ceil(@as(f32, -2.2)), result[1], epsilon));
|
expect(math.approxEq(f32, @ceil(@as(f32, -2.2)), result[1], epsilon));
|
||||||
@ -394,7 +394,7 @@ fn testTrunc() void {
|
|||||||
expect(@trunc(a) == -3);
|
expect(@trunc(a) == -3);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
var v: @Vector(4, f32) = [_]f32{1.1, -2.2, 0.3, -0.4};
|
var v: @Vector(4, f32) = [_]f32{ 1.1, -2.2, 0.3, -0.4 };
|
||||||
var result = @trunc(v);
|
var result = @trunc(v);
|
||||||
expect(math.approxEq(f32, @trunc(@as(f32, 1.1)), result[0], epsilon));
|
expect(math.approxEq(f32, @trunc(@as(f32, 1.1)), result[0], epsilon));
|
||||||
expect(math.approxEq(f32, @trunc(@as(f32, -2.2)), result[1], epsilon));
|
expect(math.approxEq(f32, @trunc(@as(f32, -2.2)), result[1], epsilon));
|
||||||
@ -403,6 +403,36 @@ fn testTrunc() void {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test "floating point comparisons" {
|
||||||
|
testFloatComparisons();
|
||||||
|
comptime testFloatComparisons();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn testFloatComparisons() void {
|
||||||
|
inline for ([_]type{ f16, f32, f64, f128 }) |ty| {
|
||||||
|
// No decimal part
|
||||||
|
{
|
||||||
|
const x: ty = 1.0;
|
||||||
|
expect(x == 1);
|
||||||
|
expect(x != 0);
|
||||||
|
expect(x > 0);
|
||||||
|
expect(x < 2);
|
||||||
|
expect(x >= 1);
|
||||||
|
expect(x <= 1);
|
||||||
|
}
|
||||||
|
// Non-zero decimal part
|
||||||
|
{
|
||||||
|
const x: ty = 1.5;
|
||||||
|
expect(x != 1);
|
||||||
|
expect(x != 2);
|
||||||
|
expect(x > 1);
|
||||||
|
expect(x < 2);
|
||||||
|
expect(x >= 1);
|
||||||
|
expect(x <= 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// TODO This is waiting on library support for the Windows build (not sure why the other's don't need it)
|
// TODO This is waiting on library support for the Windows build (not sure why the other's don't need it)
|
||||||
//test "@nearbyint" {
|
//test "@nearbyint" {
|
||||||
// comptime testNearbyInt();
|
// comptime testNearbyInt();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user