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