Closed a-siva closed 10 months ago
//cc @alexmarkov
Small repro:
@pragma('vm:never-inline')
void foo(int port) {
try {
print('hi');
} catch (e) {
if (port != 0) rethrow;
bar(port);
}
}
@pragma('vm:never-inline')
void bar(int x) {
print(x);
}
void main() {
foo(int.parse('2'));
bar(int.parse('3'));
}
DART_CONFIGURATION=DebugX64 pkg/vm/tool/precompiler2 --print-environments foo.dart foo.snapshot
../../runtime/vm/compiler/backend/flow_graph_checker.cc: 547: error: expected: (arg_def == env_def) || (arg_def->IsConstant() && env_def->IsConstant() && arg_def->AsConstant()->value().ptr() == env_def->AsConstant()->value().ptr()) (arg_def=v30 <- UnboxedConstant(#0) int64, env_def=v2 <- Parameter(0) T{*?~})
version=3.3.0-edge.dd6c961bf0582b94a578ede5a6767988d0f78aed (main) (Tue Nov 21 18:55:01 2023 +0000) on "linux_x64"
pid=1631311, thread=1631311, isolate_group=isolate(0x55b55f186830), isolate=(nil)((nil))
os=linux, arch=x64, comp=no, sim=no
isolate_instructions=0, vm_instructions=0
fp=7fff3020c2a0, sp=7fff3020c168, pc=55b55e71cd9c
pc 0x000055b55e71cd9c fp 0x00007fff3020c2a0 dart::Profiler::DumpStackTrace+0x7c
pc 0x000055b55e45ebb4 fp 0x00007fff3020c380 dart::Assert::Fail+0x84
pc 0x000055b55eb279b8 fp 0x00007fff3020c3f0 dart::FlowGraphChecker::AssertArgumentsInEnv+0x298
pc 0x000055b55eb26175 fp 0x00007fff3020c470 dart::FlowGraphChecker::VisitInstruction+0x2b5
pc 0x000055b55eb25aa5 fp 0x00007fff3020c4d0 dart::FlowGraphChecker::VisitInstructions+0x305
pc 0x000055b55eb254cc fp 0x00007fff3020c550 dart::FlowGraphChecker::VisitBlocks+0x38c
pc 0x000055b55ec2491e fp 0x00007fff3020c620 dart::CompilerPass::Run+0x21e
pc 0x000055b55ec24e76 fp 0x00007fff3020c640 dart::CompilerPass::RunPipeline+0x1f6
pc 0x000055b55ead0bbb fp 0x00007fff3020cd20 dart::PrecompileParsedFunctionHelper::Compile+0x4cb
pc 0x000055b55ead19a7 fp 0x00007fff3020d5e0 dart::PrecompileFunctionHelper+0x397
pc 0x000055b55eacbf8c fp 0x00007fff3020d700 dart::Precompiler::CompileFunction+0x1ac
pc 0x000055b55eaca94e fp 0x00007fff3020d7a0 dart::Precompiler::ProcessFunction+0x1ae
pc 0x000055b55eac4f24 fp 0x00007fff3020d7f0 dart::Precompiler::Iterate+0x94
pc 0x000055b55eac176c fp 0x00007fff3020e100 dart::Precompiler::DoCompileAll+0x192c
pc 0x000055b55eabfd96 fp 0x00007fff3020e590 dart::Precompiler::CompileAll+0xb6
pc 0x000055b55ecffaef fp 0x00007fff3020e6f0 Dart_Precompile+0x1bf
pc 0x000055b55e4309f4 fp 0x00007fff3020e880 dart::bin::main+0x8e4
-- End of DumpStackTrace
=== Crash occurred when compiling file:///.../foo.dart_::_foo in AOT mode in OptimizeBranches pass
*** BEGIN CFG
OptimizeBranches
==== file:///.../foo.dart_::_foo (RegularFunction)
B0[graph]:0 {
v0 <- Constant(#null) T{Null?}
v1 <- Constant(#<optimized out>) T{Sentinel~}
v8 <- Constant(#0) [0, 0] T{_Smi}
v18 <- Constant(#hi) T{_OneByteString}
v30 <- UnboxedConstant(#0) int64
} env={ v1, v0, v0, v0, v0, v0 }
B1[function entry]:2 {
v17 <- Parameter(0) [-9223372036854775808, 9223372036854775807] int64
} env={ v17, v0, v0, v0, v0, v0 }
CheckStackOverflow:8(stack=0, loop=0)
goto:14 B3 env={ v17, v0, v0, v0, v0, v0 }
B3[join try_idx 0]:12 pred(B1) env={ v17, v0, v0, v0, v0, v0 }
StaticCall:16( printToConsole<0> v18 T{_OneByteString}) env={ v18, v0, v18 T{_OneByteString}, v0, v18 T{_OneByteString} } env={ v17, v0, v0, v0, v0, v0 }
goto:20 B4 env={ v17, v0, v0, v0, v0, v0 }
B5[target catch try_idx -1 catch_try_idx 0] {
v2 <- Parameter(0) T{*?~}
v3 <- Parameter(1) T{*?~}
v4 <- Parameter(2) T{*?~}
v5 <- SpecialParameter(Exception) T{*}
v6 <- SpecialParameter(StackTrace) T{*?}
v7 <- Parameter(5) T{*?~}
} env={ v2, v3, v4, v5, v6, v7 }
Branch if StrictCompare(!==, v2 T{int??}, v8) T{bool} goto (6, 7) env={ v2, v4, v1, v5, v6, v1, v2, v8 }
B6[target]:32 env={ v1, v4, v1, v5, v6, v1 }
ReThrow:36(v5, v6) env={ v1, v4, v1, v1, v1, v1, v5, v6 }
B7[target]:38 env={ v2, v4, v1, v1, v1, v1 }
StaticCall:40( bar<0> v30) env={ v1, v4, v1, v1, v1, v1, v2 }
goto:42 B4 env={ v1, v4, v1, v1, v1, v1 }
B4[join]:16 pred(B3, B7) {
v12 <- phi(v0, v4) alive T{*?~}
} env={ v1, v12, v1, v1, v1, v1 }
Return:46(v0) env={ v1, v12, v1, v1, v1, v1, v0 }
*** END CFG
Constant propagator replaces only input uses of port
with constant 0, leaving env uses as is.
Should we replace all uses including environment uses? Or maybe just relax flow graph checker to allow this discrepancy? @mraleph WDYT?
It turns out changing conditional constant propagation to update environments is not enough, as it may replace a use of redefinition with a constant while environment references an original definition. For this to work we need to consistently update environments when inserting all sorts of redefinitions and boxing/unboxing. This seems like an overkill, so I'm leaning towards relaxing flow graph checker: https://dart-review.googlesource.com/c/sdk/+/338941.