| ... | ... | @@ -17036,30 +17036,41 @@ fn cmpNumeric( |
| 17036 | 17036 | if (try sema.resolveMaybeUndefVal(block, lhs_src, lhs)) |lhs_val| { |
| 17037 | 17037 | if (lhs_val.isUndef()) |
| 17038 | 17038 | return sema.addConstUndef(Type.bool); |
| 17039 | | const is_unsigned = if (lhs_is_float) x: { |
| 17039 | if (!rhs_is_signed) { |
| 17040 | switch (lhs_val.orderAgainstZero()) { |
| 17041 | .gt => {}, |
| 17042 | .eq => switch (op) { // LHS = 0, RHS is unsigned |
| 17043 | .lte => return Air.Inst.Ref.bool_true, |
| 17044 | .gt => return Air.Inst.Ref.bool_false, |
| 17045 | else => {}, |
| 17046 | }, |
| 17047 | .lt => switch (op) { // LHS < 0, RHS is unsigned |
| 17048 | .neq, .lt, .lte => return Air.Inst.Ref.bool_true, |
| 17049 | .eq, .gt, .gte => return Air.Inst.Ref.bool_false, |
| 17050 | }, |
| 17051 | } |
| 17052 | } |
| 17053 | if (lhs_is_float) { |
| 17040 | 17054 | var bigint_space: Value.BigIntSpace = undefined; |
| 17041 | 17055 | var bigint = try lhs_val.toBigInt(&bigint_space).toManaged(sema.gpa); |
| 17042 | 17056 | defer bigint.deinit(); |
| 17043 | | const zcmp = lhs_val.orderAgainstZero(); |
| 17044 | 17057 | if (lhs_val.floatHasFraction()) { |
| 17045 | 17058 | switch (op) { |
| 17046 | 17059 | .eq => return Air.Inst.Ref.bool_false, |
| 17047 | 17060 | .neq => return Air.Inst.Ref.bool_true, |
| 17048 | 17061 | else => {}, |
| 17049 | 17062 | } |
| 17050 | | if (zcmp == .lt) { |
| 17063 | if (lhs_is_signed) { |
| 17051 | 17064 | try bigint.addScalar(bigint.toConst(), -1); |
| 17052 | 17065 | } else { |
| 17053 | 17066 | try bigint.addScalar(bigint.toConst(), 1); |
| 17054 | 17067 | } |
| 17055 | 17068 | } |
| 17056 | 17069 | lhs_bits = bigint.toConst().bitCountTwosComp(); |
| 17057 | | break :x (zcmp != .lt); |
| 17058 | | } else x: { |
| 17070 | } else { |
| 17059 | 17071 | lhs_bits = lhs_val.intBitCountTwosComp(target); |
| 17060 | | break :x (lhs_val.orderAgainstZero() != .lt); |
| 17061 | | }; |
| 17062 | | lhs_bits += @boolToInt(is_unsigned and dest_int_is_signed); |
| 17072 | } |
| 17073 | lhs_bits += @boolToInt(!lhs_is_signed and dest_int_is_signed); |
| 17063 | 17074 | } else if (lhs_is_float) { |
| 17064 | 17075 | dest_float_type = lhs_ty; |
| 17065 | 17076 | } else { |
| ... | ... | @@ -17071,30 +17082,41 @@ fn cmpNumeric( |
| 17071 | 17082 | if (try sema.resolveMaybeUndefVal(block, rhs_src, rhs)) |rhs_val| { |
| 17072 | 17083 | if (rhs_val.isUndef()) |
| 17073 | 17084 | return sema.addConstUndef(Type.bool); |
| 17074 | | const is_unsigned = if (rhs_is_float) x: { |
| 17085 | if (!lhs_is_signed) { |
| 17086 | switch (rhs_val.orderAgainstZero()) { |
| 17087 | .gt => {}, |
| 17088 | .eq => switch (op) { // RHS = 0, LHS is unsigned |
| 17089 | .gte => return Air.Inst.Ref.bool_true, |
| 17090 | .lt => return Air.Inst.Ref.bool_false, |
| 17091 | else => {}, |
| 17092 | }, |
| 17093 | .lt => switch (op) { // RHS < 0, LHS is unsigned |
| 17094 | .neq, .gt, .gte => return Air.Inst.Ref.bool_true, |
| 17095 | .eq, .lt, .lte => return Air.Inst.Ref.bool_false, |
| 17096 | }, |
| 17097 | } |
| 17098 | } |
| 17099 | if (rhs_is_float) { |
| 17075 | 17100 | var bigint_space: Value.BigIntSpace = undefined; |
| 17076 | 17101 | var bigint = try rhs_val.toBigInt(&bigint_space).toManaged(sema.gpa); |
| 17077 | 17102 | defer bigint.deinit(); |
| 17078 | | const zcmp = rhs_val.orderAgainstZero(); |
| 17079 | 17103 | if (rhs_val.floatHasFraction()) { |
| 17080 | 17104 | switch (op) { |
| 17081 | 17105 | .eq => return Air.Inst.Ref.bool_false, |
| 17082 | 17106 | .neq => return Air.Inst.Ref.bool_true, |
| 17083 | 17107 | else => {}, |
| 17084 | 17108 | } |
| 17085 | | if (zcmp == .lt) { |
| 17109 | if (rhs_is_signed) { |
| 17086 | 17110 | try bigint.addScalar(bigint.toConst(), -1); |
| 17087 | 17111 | } else { |
| 17088 | 17112 | try bigint.addScalar(bigint.toConst(), 1); |
| 17089 | 17113 | } |
| 17090 | 17114 | } |
| 17091 | 17115 | rhs_bits = bigint.toConst().bitCountTwosComp(); |
| 17092 | | break :x (zcmp != .lt); |
| 17093 | | } else x: { |
| 17116 | } else { |
| 17094 | 17117 | rhs_bits = rhs_val.intBitCountTwosComp(target); |
| 17095 | | break :x (rhs_val.orderAgainstZero() != .lt); |
| 17096 | | }; |
| 17097 | | rhs_bits += @boolToInt(is_unsigned and dest_int_is_signed); |
| 17118 | } |
| 17119 | rhs_bits += @boolToInt(!rhs_is_signed and dest_int_is_signed); |
| 17098 | 17120 | } else if (rhs_is_float) { |
| 17099 | 17121 | dest_float_type = rhs_ty; |
| 17100 | 17122 | } else { |