aboutsummaryrefslogtreecommitdiff
path: root/src/Sema.zig
diff options
context:
space:
mode:
authorkkHAIKE <kkhaike@gmail.com>2022-11-19 04:06:49 +0800
committerGitHub <noreply@github.com>2022-11-18 22:06:49 +0200
commitea590ece4bcc26175d890dd82899ffc9ef64b6c3 (patch)
treeb5d77cc7bbe683e54c9bf2b7d29b4681dc057ba5 /src/Sema.zig
parent04f3067a7921a51bd55870f3138220fd66426e33 (diff)
downloadzig-ea590ece4bcc26175d890dd82899ffc9ef64b6c3.tar.gz
zig-ea590ece4bcc26175d890dd82899ffc9ef64b6c3.zip
Sema: optimize compare comptime float with int
Diffstat (limited to 'src/Sema.zig')
-rw-r--r--src/Sema.zig56
1 files changed, 46 insertions, 10 deletions
diff --git a/src/Sema.zig b/src/Sema.zig
index 3b362d83c4..a6811d37fd 100644
--- a/src/Sema.zig
+++ b/src/Sema.zig
@@ -13896,9 +13896,25 @@ fn analyzeArithmetic(
// because there is a possible value for which the addition would
// overflow (max_int), causing illegal behavior.
// For floats: either operand being undef makes the result undef.
+ // If either of the operands are inf, and the other operand is zero,
+ // the result is nan.
+ // If either of the operands are nan, the result is nan.
if (maybe_lhs_val) |lhs_val| {
if (!lhs_val.isUndef()) {
- if (try lhs_val.compareAllWithZeroAdvanced(.eq, sema)) {
+ if (lhs_val.isNan()) {
+ return sema.addConstant(resolved_type, lhs_val);
+ }
+ if (try lhs_val.compareAllWithZeroAdvanced(.eq, sema)) lz: {
+ if (maybe_rhs_val) |rhs_val| {
+ if (rhs_val.isNan()) {
+ return sema.addConstant(resolved_type, rhs_val);
+ }
+ if (rhs_val.isInf()) {
+ return sema.addConstant(resolved_type, try Value.Tag.float_32.create(sema.arena, std.math.nan_f32));
+ }
+ } else if (resolved_type.isAnyFloat()) {
+ break :lz;
+ }
const zero_val = if (is_vector) b: {
break :b try Value.Tag.repeated.create(sema.arena, Value.zero);
} else Value.zero;
@@ -13918,7 +13934,17 @@ fn analyzeArithmetic(
return sema.addConstUndef(resolved_type);
}
}
- if (try rhs_val.compareAllWithZeroAdvanced(.eq, sema)) {
+ if (rhs_val.isNan()) {
+ return sema.addConstant(resolved_type, rhs_val);
+ }
+ if (try rhs_val.compareAllWithZeroAdvanced(.eq, sema)) rz: {
+ if (maybe_lhs_val) |lhs_val| {
+ if (lhs_val.isInf()) {
+ return sema.addConstant(resolved_type, try Value.Tag.float_32.create(sema.arena, std.math.nan_f32));
+ }
+ } else if (resolved_type.isAnyFloat()) {
+ break :rz;
+ }
const zero_val = if (is_vector) b: {
break :b try Value.Tag.repeated.create(sema.arena, Value.zero);
} else Value.zero;
@@ -28175,8 +28201,10 @@ fn cmpNumeric(
else => return Air.Inst.Ref.bool_false,
};
if (lhs_val.isInf()) switch (op) {
- .gt, .neq => return Air.Inst.Ref.bool_true,
- .lt, .lte, .eq, .gte => return Air.Inst.Ref.bool_false,
+ .neq => return Air.Inst.Ref.bool_true,
+ .eq => return Air.Inst.Ref.bool_false,
+ .gt, .gte => return if (lhs_val.isNegativeInf()) Air.Inst.Ref.bool_false else Air.Inst.Ref.bool_true,
+ .lt, .lte => return if (lhs_val.isNegativeInf()) Air.Inst.Ref.bool_true else Air.Inst.Ref.bool_false,
};
if (!rhs_is_signed) {
switch (lhs_val.orderAgainstZero()) {
@@ -28193,14 +28221,17 @@ fn cmpNumeric(
}
}
if (lhs_is_float) {
- var bigint = try float128IntPartToBigInt(sema.gpa, lhs_val.toFloat(f128));
- defer bigint.deinit();
if (lhs_val.floatHasFraction()) {
switch (op) {
.eq => return Air.Inst.Ref.bool_false,
.neq => return Air.Inst.Ref.bool_true,
else => {},
}
+ }
+
+ var bigint = try float128IntPartToBigInt(sema.gpa, lhs_val.toFloat(f128));
+ defer bigint.deinit();
+ if (lhs_val.floatHasFraction()) {
if (lhs_is_signed) {
try bigint.addScalar(&bigint, -1);
} else {
@@ -28228,8 +28259,10 @@ fn cmpNumeric(
else => return Air.Inst.Ref.bool_false,
};
if (rhs_val.isInf()) switch (op) {
- .lt, .neq => return Air.Inst.Ref.bool_true,
- .gt, .lte, .eq, .gte => return Air.Inst.Ref.bool_false,
+ .neq => return Air.Inst.Ref.bool_true,
+ .eq => return Air.Inst.Ref.bool_false,
+ .gt, .gte => return if (rhs_val.isNegativeInf()) Air.Inst.Ref.bool_true else Air.Inst.Ref.bool_false,
+ .lt, .lte => return if (rhs_val.isNegativeInf()) Air.Inst.Ref.bool_false else Air.Inst.Ref.bool_true,
};
if (!lhs_is_signed) {
switch (rhs_val.orderAgainstZero()) {
@@ -28246,14 +28279,17 @@ fn cmpNumeric(
}
}
if (rhs_is_float) {
- var bigint = try float128IntPartToBigInt(sema.gpa, rhs_val.toFloat(f128));
- defer bigint.deinit();
if (rhs_val.floatHasFraction()) {
switch (op) {
.eq => return Air.Inst.Ref.bool_false,
.neq => return Air.Inst.Ref.bool_true,
else => {},
}
+ }
+
+ var bigint = try float128IntPartToBigInt(sema.gpa, rhs_val.toFloat(f128));
+ defer bigint.deinit();
+ if (rhs_val.floatHasFraction()) {
if (rhs_is_signed) {
try bigint.addScalar(&bigint, -1);
} else {