diff --git a/src/Liveness.zig b/src/Liveness.zig index 8033b28fe5..56b70be317 100644 --- a/src/Liveness.zig +++ b/src/Liveness.zig @@ -599,7 +599,7 @@ pub fn categorizeOperand( .br => { const br = air_datas[@intFromEnum(inst)].br; - if (br.operand == operand_ref) return matchOperandSmallIndex(l, inst, 0, .noret); + if (br.operand == operand_ref) return matchOperandSmallIndex(l, operand, 0, .noret); return .noret; }, .assembly => { diff --git a/test/behavior/if.zig b/test/behavior/if.zig index c4dfd04f71..bef02fd1ce 100644 --- a/test/behavior/if.zig +++ b/test/behavior/if.zig @@ -167,3 +167,36 @@ test "if-@as-if chain" { try expect(num_frames == 4); } + +fn returnTrue() bool { + return true; +} + +test "if value shouldn't be load-elided if used later (structs)" { + const Foo = struct { x: i32 }; + + var a = Foo{ .x = 1 }; + var b = Foo{ .x = 1 }; + + const c = if (@call(.never_inline, returnTrue, .{})) a else b; + // The second variable is superfluous with the current + // state of codegen optimizations, but in future + // "if (smthg) a else a" may be optimized simply into "a". + + a.x = 2; + b.x = 3; + + try std.testing.expectEqual(c.x, 1); +} + +test "if value shouldn't be load-elided if used later (optionals)" { + var a: ?i32 = 1; + var b: ?i32 = 1; + + const c = if (@call(.never_inline, returnTrue, .{})) a else b; + + a = 2; + b = 3; + + try std.testing.expectEqual(c, 1); +}