dart-lang / sdk

The Dart SDK, including the VM, JS and Wasm compilers, analysis, core libraries, and more.
https://dart.dev
BSD 3-Clause "New" or "Revised" License
10.24k stars 1.58k forks source link

True output divergence DebugIA32 vs ReleaseSIMARM #38412

Closed feli-citas closed 5 years ago

feli-citas commented 5 years ago

Isolate (/b/s/w/itxyeKQv/dart_fuzzIDPSFL) NO-FFI FP : JIT-O3-SLOWPATH-DET-ReleaseSIMARM - JIT-OPTCOUNTER-DebugIA32: !DIVERGENCE! 1.45:2969830399 (output)

-- BEGIN REPRODUCE  --

dartfuzz.dart --no-ffi --fp --seed 2969830399 /b/s/w/itxyeKQv/dart_fuzzIDPSFL/fuzz.dart

-- RUN 1 --

/b/s/w/ir/out/ReleaseSIMARM/dart --optimization_level=3 --use-slow-path --deterministic /b/s/w/itxyeKQv/dart_fuzzIDPSFL/fuzz.dart

-- RUN 2 --

/b/s/w/ir/out/DebugIA32/dart --optimization_counter_threshold=1 /b/s/w/itxyeKQv/dart_fuzzIDPSFL/fuzz.dart

-- END REPRODUCE  --
diff simarm.out ia32.out 
26c26
< -9223372028264841225
---
> -9223372028264841224
feli-citas commented 5 years ago

fuzz.dart.txt

feli-citas commented 5 years ago

DebugIA32 output is non deterministic. Sometimes identical to ReleaseSIMARM

feli-citas commented 5 years ago

Below is the relevant line extracted from the output of a handful of IA32 runs, divergences to SIMARM are marked

-9223372028264841225
-9223372028264841225
-9223372028264841225
-9223372028264841225
-9223372028264841225
-9223372028264841224*
-9223372028264841225
-9223372028264841225
-9223372028264841225
-9223372028264841225
-9223372028264841225
-9223372028264841225
-9223372028264841224*
-9223372028264841225
-9223372028264841225
-9223372028264841225
-9223372028264841225
-9223372028264841225
-9223372028264841225
-9223372028264841225
-9223372028264841225
-9223372028264841224*
-9223372028264841225
-9223372028264841225
-9223372028264841225
-9223372028264841224*
-9223372028264841225
-9223372028264841225
bkonyi commented 5 years ago

Is there a minimization of this case by any chance? Also, I'm guessing that it's really the IA32 configuration that's diverging since SIMARM is being consistent with x64 from what I can tell?

feli-citas commented 5 years ago

fuzz_mini.dart.txt

out/DebugIA32/dart --optimization_counter_threshold=1 fuzz_mini.dart.txt | grep 922337202826484
-9223372028264841224
out/DebugX64/dart fuzz_mini.dart.txt  | grep 922337202826484            
-9223372028264841225
bkonyi commented 5 years ago

Confirmed that this doesn't seem to be a platform specific issue but seems to only occur when --optimization_counter_threshold=1.

bkonyi commented 5 years ago

Seems to be OSR related. Minimized reproduction:

import 'dart:async';
import 'dart:convert';

int var1 = -9223372028264841217;
Map<int, String> var8 = {1: "a"};

class X1 {
  List<int> foo1_0(List<int> par1, String par3) {
    return [1];
  }
}

main() {
  print("");
  for (int loc0 = 0; loc0 < 7500; loc0++) {
    "a" == Uri.parse("\u2665");
  }

  print('var8 runtime type: ${var8.runtimeType}');
  X1().foo1_0([for (int i = 0; i < 1; ++i) 0], var8[--var1]);
}

Results in the following exception 25-50% of the time:

var8 runtime type: _InternalLinkedHashMap<int, String>
Unhandled exception:
Invalid argument(s): -9223372028264841218
#0      List.[] (dart:core-patch/growable_array.dart:147:60)
#1      main (file:///usr/local/google/home/bkonyi/sdk/ia32_fuzz.dart:24:52)
#2      _startIsolate.<anonymous closure> (dart:isolate-patch/isolate_patch.dart:305:19)
#3      _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:172:12)

Doesn't seem to happen with --use-osr=false.

aartbik commented 5 years ago

This still happens after stack integrity fix, so must be something else, OSR with regular DebugX64:

Attempting OSR for dart:core_::__scan@0150898 at id=20, count=9
var8 runtime type: _InternalLinkedHashMap<int, String>
Attempting OSR for file:///usr/local/google/home/ajcbik/Repo/DART/fuzz4.dart_::_main at id=62, count=6
Unhandled exception:
Invalid argument(s): -9223372028264841218
#0      List.[] (dart:core-patch/growable_array.dart:147:60)
#1      main (file:///usr/local/google/home/ajcbik/Repo/DART/fuzz4.dart:21:52)
#2      _startIsolate.<anonymous closure> (dart:isolate-patch/isolate_patch.dart:305:19)
#3      _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:172:12)
aartbik commented 5 years ago

The IR looks good after OSR, although the PushArguments (those again!) appear at a slightly difference place. These may confuse something in the code generator, because we seem to access the List on the stack (just constructed by for-loop), not the Map (var8) when calling the [] method for the second argument of foo().

aartbik commented 5 years ago

By replacing the [] call with a user-defined method, I can confirm that when OSR hits with the expression stack non-empty, we seems to have a bookkeeping error, since the just constructed List is passed to "bar" as first argument instead of the map.

String bar(Map<int, String> o1, int o2) {
  Expect.equals(1, o1.length);
  Expect.equals(-9223372028264841218, o2);
  return "not";
}
....
  var x = X1().foo1_0([for (int i = 0; i < 10; ++i) 0], bar(fuzzvar8, --fuzzvar1));