@@ -1162,12 +1162,12 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO
1162
1162
1163
1163
.slice = > try airSlice (f , inst ),
1164
1164
1165
- .cmp_eq = > try airBinOp (f , inst , " == " ),
1165
+ .cmp_eq = > try airEquality (f , inst , .cmp_eq ),
1166
1166
.cmp_gt = > try airBinOp (f , inst , " > " ),
1167
1167
.cmp_gte = > try airBinOp (f , inst , " >= " ),
1168
1168
.cmp_lt = > try airBinOp (f , inst , " < " ),
1169
1169
.cmp_lte = > try airBinOp (f , inst , " <= " ),
1170
- .cmp_neq = > try airBinOp (f , inst , " != " ),
1170
+ .cmp_neq = > try airEquality (f , inst , .cmp_neq ),
1171
1171
1172
1172
// bool_and and bool_or are non-short-circuit operations
1173
1173
.bool_and = > try airBinOp (f , inst , " & " ),
@@ -1257,9 +1257,9 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO
1257
1257
.slice_elem_ptr = > try airSliceElemPtr (f , inst ),
1258
1258
.array_elem_val = > try airArrayElemVal (f , inst ),
1259
1259
1260
- .unwrap_errunion_payload = > try airUnwrapErrUnionPay (f , inst ),
1260
+ .unwrap_errunion_payload = > try airUnwrapErrUnionPay (f , inst , "" ),
1261
1261
.unwrap_errunion_err = > try airUnwrapErrUnionErr (f , inst ),
1262
- .unwrap_errunion_payload_ptr = > try airUnwrapErrUnionPay (f , inst ),
1262
+ .unwrap_errunion_payload_ptr = > try airUnwrapErrUnionPay (f , inst , "&" ),
1263
1263
.unwrap_errunion_err_ptr = > try airUnwrapErrUnionErr (f , inst ),
1264
1264
.wrap_errunion_payload = > try airWrapErrUnionPay (f , inst ),
1265
1265
.wrap_errunion_err = > try airWrapErrUnionErr (f , inst ),
@@ -1908,6 +1908,51 @@ fn airBinOp(f: *Function, inst: Air.Inst.Index, operator: [*:0]const u8) !CValue
1908
1908
return local ;
1909
1909
}
1910
1910
1911
+ fn airEquality (f : * Function , inst : Air.Inst.Index , op : Air.Inst.Tag ) ! CValue {
1912
+ if (f .liveness .isUnused (inst ))
1913
+ return CValue .none ;
1914
+
1915
+ const bin_op = f .air .instructions .items (.data )[inst ].bin_op ;
1916
+ const lhs = try f .resolveInst (bin_op .lhs );
1917
+ const rhs = try f .resolveInst (bin_op .rhs );
1918
+
1919
+ const writer = f .object .writer ();
1920
+ const inst_ty = f .air .typeOfIndex (inst );
1921
+ const local = try f .allocLocal (inst_ty , .Const );
1922
+
1923
+ try writer .writeAll (" = " );
1924
+
1925
+ const lhs_ty = f .air .typeOf (bin_op .lhs );
1926
+ if (lhs_ty .tag () == .optional ) {
1927
+ // (A && B) || (C && (A == B))
1928
+ // A = lhs.is_null ; B = rhs.is_null ; C = rhs.payload == lhs.payload
1929
+
1930
+ try writer .writeAll (if (op == .cmp_eq ) "((" else "!((" );
1931
+ try f .writeCValue (writer , lhs );
1932
+ try writer .writeAll (".is_null && " );
1933
+ try f .writeCValue (writer , rhs );
1934
+ try writer .writeAll (".is_null) || (" );
1935
+ try f .writeCValue (writer , lhs );
1936
+ try writer .writeAll (".payload == " );
1937
+ try f .writeCValue (writer , rhs );
1938
+ try writer .writeAll (".payload && " );
1939
+ try f .writeCValue (writer , lhs );
1940
+ try writer .writeAll (".is_null == " );
1941
+ try f .writeCValue (writer , rhs );
1942
+ try writer .writeAll (".is_null));\n " );
1943
+
1944
+ return local ;
1945
+ }
1946
+
1947
+ const operator = if (op == .cmp_eq ) "==" else "!=" ;
1948
+ try f .writeCValue (writer , lhs );
1949
+ try writer .print ("{s}" , .{operator });
1950
+ try f .writeCValue (writer , rhs );
1951
+ try writer .writeAll (";\n " );
1952
+
1953
+ return local ;
1954
+ }
1955
+
1911
1956
fn airPtrAddSub (f : * Function , inst : Air.Inst.Index , operator : [* :0 ]const u8 ) ! CValue {
1912
1957
if (f .liveness .isUnused (inst ))
1913
1958
return CValue .none ;
@@ -2104,8 +2149,8 @@ fn airBitcast(f: *Function, inst: Air.Inst.Index) !CValue {
2104
2149
2105
2150
const writer = f .object .writer ();
2106
2151
const inst_ty = f .air .typeOfIndex (inst );
2107
- if (inst_ty .zigTypeTag () == .Pointer and
2108
- f .air .typeOf (ty_op .operand ).zigTypeTag () == .Pointer )
2152
+ if (inst_ty .isPtrAtRuntime () and
2153
+ f .air .typeOf (ty_op .operand ).isPtrAtRuntime () )
2109
2154
{
2110
2155
const local = try f .allocLocal (inst_ty , .Const );
2111
2156
try writer .writeAll (" = (" );
@@ -2503,7 +2548,7 @@ fn airUnwrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue {
2503
2548
return local ;
2504
2549
}
2505
2550
2506
- fn airUnwrapErrUnionPay (f : * Function , inst : Air.Inst.Index ) ! CValue {
2551
+ fn airUnwrapErrUnionPay (f : * Function , inst : Air.Inst.Index , maybe_addrof : [] const u8 ) ! CValue {
2507
2552
if (f .liveness .isUnused (inst ))
2508
2553
return CValue .none ;
2509
2554
@@ -2519,7 +2564,6 @@ fn airUnwrapErrUnionPay(f: *Function, inst: Air.Inst.Index) !CValue {
2519
2564
2520
2565
const inst_ty = f .air .typeOfIndex (inst );
2521
2566
const maybe_deref = if (operand_ty .zigTypeTag () == .Pointer ) "->" else "." ;
2522
- const maybe_addrof = if (inst_ty .zigTypeTag () == .Pointer ) "&" else "" ;
2523
2567
2524
2568
const local = try f .allocLocal (inst_ty , .Const );
2525
2569
try writer .print (" = {s}(" , .{maybe_addrof });
0 commit comments