| ... | @@ -1162,12 +1162,13 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO | ... | @@ -1162,12 +1162,13 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO |
| 1162 | | 1162 | |
| 1163 | .slice => try airSlice(f, inst), | 1163 | .slice => try airSlice(f, inst), |
| 1164 | | 1164 | |
| 1165 | .cmp_eq => try airEquality(f, inst, .cmp_eq), | | |
| 1166 | .cmp_gt => try airBinOp(f, inst, " > "), | 1165 | .cmp_gt => try airBinOp(f, inst, " > "), |
| 1167 | .cmp_gte => try airBinOp(f, inst, " >= "), | 1166 | .cmp_gte => try airBinOp(f, inst, " >= "), |
| 1168 | .cmp_lt => try airBinOp(f, inst, " < "), | 1167 | .cmp_lt => try airBinOp(f, inst, " < "), |
| 1169 | .cmp_lte => try airBinOp(f, inst, " <= "), | 1168 | .cmp_lte => try airBinOp(f, inst, " <= "), |
| 1170 | .cmp_neq => try airEquality(f, inst, .cmp_neq), | 1169 | |
| | 1170 | .cmp_eq => try airEquality(f, inst, "((", "=="), |
| | 1171 | .cmp_neq => try airEquality(f, inst, "!((", "!="), |
| 1171 | | 1172 | |
| 1172 | // bool_and and bool_or are non-short-circuit operations | 1173 | // bool_and and bool_or are non-short-circuit operations |
| 1173 | .bool_and => try airBinOp(f, inst, " & "), | 1174 | .bool_and => try airBinOp(f, inst, " & "), |
| ... | @@ -1908,9 +1909,13 @@ fn airBinOp(f: *Function, inst: Air.Inst.Index, operator: [*:0]const u8) !CValue | ... | @@ -1908,9 +1909,13 @@ fn airBinOp(f: *Function, inst: Air.Inst.Index, operator: [*:0]const u8) !CValue |
| 1908 | return local; | 1909 | return local; |
| 1909 | } | 1910 | } |
| 1910 | | 1911 | |
| 1911 | fn airEquality(f: *Function, inst: Air.Inst.Index, op: Air.Inst.Tag) !CValue { | 1912 | fn airEquality( |
| 1912 | if (f.liveness.isUnused(inst)) | 1913 | f: *Function, |
| 1913 | return CValue.none; | 1914 | inst: Air.Inst.Index, |
| | 1915 | negate_prefix: []const u8, |
| | 1916 | eq_op_str: []const u8, |
| | 1917 | ) !CValue { |
| | 1918 | if (f.liveness.isUnused(inst)) return CValue.none; |
| 1914 | | 1919 | |
| 1915 | const bin_op = f.air.instructions.items(.data)[inst].bin_op; | 1920 | const bin_op = f.air.instructions.items(.data)[inst].bin_op; |
| 1916 | const lhs = try f.resolveInst(bin_op.lhs); | 1921 | const lhs = try f.resolveInst(bin_op.lhs); |
| ... | @@ -1927,7 +1932,7 @@ fn airEquality(f: *Function, inst: Air.Inst.Index, op: Air.Inst.Tag) !CValue { | ... | @@ -1927,7 +1932,7 @@ fn airEquality(f: *Function, inst: Air.Inst.Index, op: Air.Inst.Tag) !CValue { |
| 1927 | // (A && B) || (C && (A == B)) | 1932 | // (A && B) || (C && (A == B)) |
| 1928 | // A = lhs.is_null ; B = rhs.is_null ; C = rhs.payload == lhs.payload | 1933 | // A = lhs.is_null ; B = rhs.is_null ; C = rhs.payload == lhs.payload |
| 1929 | | 1934 | |
| 1930 | try writer.writeAll(if (op == .cmp_eq) "((" else "!(("); | 1935 | try writer.writeAll(negate_prefix); |
| 1931 | try f.writeCValue(writer, lhs); | 1936 | try f.writeCValue(writer, lhs); |
| 1932 | try writer.writeAll(".is_null && "); | 1937 | try writer.writeAll(".is_null && "); |
| 1933 | try f.writeCValue(writer, rhs); | 1938 | try f.writeCValue(writer, rhs); |
| ... | @@ -1944,9 +1949,8 @@ fn airEquality(f: *Function, inst: Air.Inst.Index, op: Air.Inst.Tag) !CValue { | ... | @@ -1944,9 +1949,8 @@ fn airEquality(f: *Function, inst: Air.Inst.Index, op: Air.Inst.Tag) !CValue { |
| 1944 | return local; | 1949 | return local; |
| 1945 | } | 1950 | } |
| 1946 | | 1951 | |
| 1947 | const operator = if (op == .cmp_eq) "==" else "!="; | | |
| 1948 | try f.writeCValue(writer, lhs); | 1952 | try f.writeCValue(writer, lhs); |
| 1949 | try writer.print("{s}", .{operator}); | 1953 | try writer.writeAll(eq_op_str); |
| 1950 | try f.writeCValue(writer, rhs); | 1954 | try f.writeCValue(writer, rhs); |
| 1951 | try writer.writeAll(";\n"); | 1955 | try writer.writeAll(";\n"); |
| 1952 | | 1956 | |