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