diff options
| author | Cody Tapscott <topolarity@tapscott.me> | 2022-02-27 01:19:02 -0700 |
|---|---|---|
| committer | Cody Tapscott <topolarity@tapscott.me> | 2022-02-27 02:24:28 -0700 |
| commit | a7a508fcd9a961ea9d903f9065556a02b4045b95 (patch) | |
| tree | 32a18d391650f39f4b67bf679fc213b2446a6b21 /src/Sema.zig | |
| parent | b52948444f16c082f0e29bb75b246370c4b11326 (diff) | |
| download | zig-a7a508fcd9a961ea9d903f9065556a02b4045b95.tar.gz zig-a7a508fcd9a961ea9d903f9065556a02b4045b95.zip | |
stage2 sema: Implement comptime result for comparison of uint to comptime value
This adds a comptime result when comparing a comptime value to an
unsigned integer. For example:
( 0 <= (unsigned runtime value)) => true
(-1 < (unsigned runtime value)) => true
((unsigned runtime value) < -15) => false
Diffstat (limited to 'src/Sema.zig')
| -rw-r--r-- | src/Sema.zig | 54 |
1 files changed, 38 insertions, 16 deletions
diff --git a/src/Sema.zig b/src/Sema.zig index 4dad9a6c8c..9b03b4c32e 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -17036,30 +17036,41 @@ fn cmpNumeric( if (try sema.resolveMaybeUndefVal(block, lhs_src, lhs)) |lhs_val| { if (lhs_val.isUndef()) return sema.addConstUndef(Type.bool); - const is_unsigned = if (lhs_is_float) x: { + if (!rhs_is_signed) { + switch (lhs_val.orderAgainstZero()) { + .gt => {}, + .eq => switch (op) { // LHS = 0, RHS is unsigned + .lte => return Air.Inst.Ref.bool_true, + .gt => return Air.Inst.Ref.bool_false, + else => {}, + }, + .lt => switch (op) { // LHS < 0, RHS is unsigned + .neq, .lt, .lte => return Air.Inst.Ref.bool_true, + .eq, .gt, .gte => return Air.Inst.Ref.bool_false, + }, + } + } + if (lhs_is_float) { var bigint_space: Value.BigIntSpace = undefined; var bigint = try lhs_val.toBigInt(&bigint_space).toManaged(sema.gpa); defer bigint.deinit(); - const zcmp = lhs_val.orderAgainstZero(); if (lhs_val.floatHasFraction()) { switch (op) { .eq => return Air.Inst.Ref.bool_false, .neq => return Air.Inst.Ref.bool_true, else => {}, } - if (zcmp == .lt) { + if (lhs_is_signed) { try bigint.addScalar(bigint.toConst(), -1); } else { try bigint.addScalar(bigint.toConst(), 1); } } lhs_bits = bigint.toConst().bitCountTwosComp(); - break :x (zcmp != .lt); - } else x: { + } else { lhs_bits = lhs_val.intBitCountTwosComp(target); - break :x (lhs_val.orderAgainstZero() != .lt); - }; - lhs_bits += @boolToInt(is_unsigned and dest_int_is_signed); + } + lhs_bits += @boolToInt(!lhs_is_signed and dest_int_is_signed); } else if (lhs_is_float) { dest_float_type = lhs_ty; } else { @@ -17071,30 +17082,41 @@ fn cmpNumeric( if (try sema.resolveMaybeUndefVal(block, rhs_src, rhs)) |rhs_val| { if (rhs_val.isUndef()) return sema.addConstUndef(Type.bool); - const is_unsigned = if (rhs_is_float) x: { + if (!lhs_is_signed) { + switch (rhs_val.orderAgainstZero()) { + .gt => {}, + .eq => switch (op) { // RHS = 0, LHS is unsigned + .gte => return Air.Inst.Ref.bool_true, + .lt => return Air.Inst.Ref.bool_false, + else => {}, + }, + .lt => switch (op) { // RHS < 0, LHS is unsigned + .neq, .gt, .gte => return Air.Inst.Ref.bool_true, + .eq, .lt, .lte => return Air.Inst.Ref.bool_false, + }, + } + } + if (rhs_is_float) { var bigint_space: Value.BigIntSpace = undefined; var bigint = try rhs_val.toBigInt(&bigint_space).toManaged(sema.gpa); defer bigint.deinit(); - const zcmp = rhs_val.orderAgainstZero(); if (rhs_val.floatHasFraction()) { switch (op) { .eq => return Air.Inst.Ref.bool_false, .neq => return Air.Inst.Ref.bool_true, else => {}, } - if (zcmp == .lt) { + if (rhs_is_signed) { try bigint.addScalar(bigint.toConst(), -1); } else { try bigint.addScalar(bigint.toConst(), 1); } } rhs_bits = bigint.toConst().bitCountTwosComp(); - break :x (zcmp != .lt); - } else x: { + } else { rhs_bits = rhs_val.intBitCountTwosComp(target); - break :x (rhs_val.orderAgainstZero() != .lt); - }; - rhs_bits += @boolToInt(is_unsigned and dest_int_is_signed); + } + rhs_bits += @boolToInt(!rhs_is_signed and dest_int_is_signed); } else if (rhs_is_float) { dest_float_type = rhs_ty; } else { |
