Commit 4aae0b09cf

Andrew Kelley <andrew@ziglang.org>
2022-12-04 03:30:08
CBE and LLVM: handle unused try instructions
In both backends they did not observe the Liveness information for try instructions. Now they do. For the C backend this is necessary for correctness; for the LLVM backend, it improves code generation.
1 parent f2e59e4
Changed files (2)
src
src/codegen/c.zig
@@ -4092,9 +4092,14 @@ fn lowerTry(
         }
     }
 
+    try reap(f, inst, &.{operand});
+
+    if (f.liveness.isUnused(inst)) {
+        return CValue.none;
+    }
+
     const target = f.object.dg.module.getTarget();
     const is_array = lowersToArray(payload_ty, target);
-    try reap(f, inst, &.{operand});
     const local = try f.allocLocal(inst, result_ty);
     if (is_array) {
         try writer.writeAll("memcpy(");
src/codegen/llvm.zig
@@ -5346,7 +5346,8 @@ pub const FuncGen = struct {
         const err_union_ty = self.air.typeOf(pl_op.operand);
         const payload_ty = self.air.typeOfIndex(inst);
         const can_elide_load = if (isByRef(payload_ty)) self.canElideLoad(body_tail) else false;
-        return lowerTry(self, err_union, body, err_union_ty, false, can_elide_load, payload_ty);
+        const is_unused = self.liveness.isUnused(inst);
+        return lowerTry(self, err_union, body, err_union_ty, false, can_elide_load, is_unused, payload_ty);
     }
 
     fn airTryPtr(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
@@ -5356,7 +5357,8 @@ pub const FuncGen = struct {
         const body = self.air.extra[extra.end..][0..extra.data.body_len];
         const err_union_ty = self.air.typeOf(extra.data.ptr).childType();
         const payload_ty = self.air.typeOfIndex(inst);
-        return lowerTry(self, err_union_ptr, body, err_union_ty, true, true, payload_ty);
+        const is_unused = self.liveness.isUnused(inst);
+        return lowerTry(self, err_union_ptr, body, err_union_ty, true, true, is_unused, payload_ty);
     }
 
     fn lowerTry(
@@ -5366,6 +5368,7 @@ pub const FuncGen = struct {
         err_union_ty: Type,
         operand_is_ptr: bool,
         can_elide_load: bool,
+        is_unused: bool,
         result_ty: Type,
     ) !?*llvm.Value {
         const payload_ty = err_union_ty.errorUnionPayload();
@@ -5405,6 +5408,9 @@ pub const FuncGen = struct {
 
             fg.builder.positionBuilderAtEnd(continue_block);
         }
+        if (is_unused) {
+            return null;
+        }
         if (!payload_has_bits) {
             if (!operand_is_ptr) return null;