roc-lang / roc

A fast, friendly, functional language.
https://roc-lang.org
Universal Permissive License v1.0
4.45k stars 312 forks source link

Compiler crash about "call parameter type does not match" and/or "failed LLVM verification" #3603

Closed JanCVanB closed 2 years ago

JanCVanB commented 2 years ago

I don't know what's happening here, but I'm proud to have caused a šŸ˜±-level compiler crash! šŸ˜†

Sorry for these walls of text:

Crash

[jan@framey roc-random]$ export RUST_BACKTRACE=full
[jan@framey roc-random]$
[jan@framey roc-random]$
[jan@framey roc-random]$ (cd roc && cargo run check ../example_complex_with_backpassing.roc)
    Finished dev [unoptimized + debuginfo] target(s) in 0.48s
     Running `target/debug/roc check ../example_complex_with_backpassing.roc`
0 errors and 0 warnings found in 695 ms.
[jan@framey roc-random]$
[jan@framey roc-random]$
[jan@framey roc-random]$ (cd roc && cargo run ../example_complex_with_backpassing.roc)
    Finished dev [unoptimized + debuginfo] target(s) in 0.48s
     Running `target/debug/roc ../example_complex_with_backpassing.roc`
šŸ”Ø Rebuilding host...
Call parameter type does not match function signature!
  %struct_field_access_record_0 = extractvalue { i64, i64, i32, i32 } %"#arg_closure", 0, !dbg !1799
 i32  %call3 = call fastcc { i64, { i32, i32, i32 }, i32 } @RandomB_i32_46f83e3adcc4f4f3eecc56ca777afc551ff50c61ae15f1486e3497cd51bfb(i64 %struct_field_access_record_0, i64 %struct_field_access_record_1, { i32, i32, i32 } %insert_record_field2), !dbg !1799

Function "#UserApp_35_66a0b53312c1d72c6bdc384d5a7e6a470c8a118c9599f59efe112a66cf85c37" failed LLVM verification in NON-OPTIMIZED build. Its content was:

define internal fastcc { i64, { i32, i32, i32 }, i32 } @"#UserApp_35_66a0b53312c1d72c6bdc384d5a7e6a470c8a118c9599f59efe112a66cf85c37"(i32 %z, { i64, i64, i32, i32 } %"#arg_closure") !dbg !1798 {
entry:
  %struct_field_access_record_3 = extractvalue { i64, i64, i32, i32 } %"#arg_closure", 3, !dbg !1799
  %struct_field_access_record_2 = extractvalue { i64, i64, i32, i32 } %"#arg_closure", 2, !dbg !1799
  %struct_field_access_record_1 = extractvalue { i64, i64, i32, i32 } %"#arg_closure", 1, !dbg !1799
  %struct_field_access_record_0 = extractvalue { i64, i64, i32, i32 } %"#arg_closure", 0, !dbg !1799
  %insert_record_field = insertvalue { i32, i32, i32 } zeroinitializer, i32 %struct_field_access_record_2, 0, !dbg !1799
  %insert_record_field1 = insertvalue { i32, i32, i32 } %insert_record_field, i32 %struct_field_access_record_3, 1, !dbg !1799
  %insert_record_field2 = insertvalue { i32, i32, i32 } %insert_record_field1, i32 %z, 2, !dbg !1799
  %call = call fastcc {} @RandomB_int_d23f96d836ebed25ad1d3d2b9d92362252cc8a347a98312a75284f7f6d8bd2(), !dbg !1799
  %call3 = call fastcc { i64, { i32, i32, i32 }, i32 } @RandomB_i32_46f83e3adcc4f4f3eecc56ca777afc551ff50c61ae15f1486e3497cd51bfb(i64 %struct_field_access_record_0, i64 %struct_field_access_record_1, { i32, i32, i32 } %insert_record_field2), !dbg !1799
  ret { i64, { i32, i32, i32 }, i32 } %call3, !dbg !1799
}
thread 'main' panicked at 'šŸ˜± LLVM errors when defining function "#UserApp_35_66a0b53312c1d72c6bdc384d5a7e6a470c8a118c9599f59efe112a66cf85c37"; I wrote the full LLVM IR to "/home/jan/_code/_roc/roc-random/example_complex_with_backpassing.ll"', crates/compiler/gen_llvm/src/llvm/build.rs:4565:21
stack backtrace:
   0:     0x5609e9b3ae4d - std::backtrace_rs::backtrace::libunwind::trace::h22893a5306c091b4
                               at /rustc/fe5b13d681f25ee6474be29d748c65adcd91f69e/library/std/src/../../backtrace/src/backtrace/libunwind.rs:93:5
   1:     0x5609e9b3ae4d - std::backtrace_rs::backtrace::trace_unsynchronized::h29c3bc6f9e91819d
                               at /rustc/fe5b13d681f25ee6474be29d748c65adcd91f69e/library/std/src/../../backtrace/src/backtrace/mod.rs:66:5
   2:     0x5609e9b3ae4d - std::sys_common::backtrace::_print_fmt::he497d8a0ec903793
                               at /rustc/fe5b13d681f25ee6474be29d748c65adcd91f69e/library/std/src/sys_common/backtrace.rs:66:5
   3:     0x5609e9b3ae4d - <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt::h9c2a9d2774d81873
                               at /rustc/fe5b13d681f25ee6474be29d748c65adcd91f69e/library/std/src/sys_common/backtrace.rs:45:22
   4:     0x5609e9b62fec - core::fmt::write::hba4337c43d992f49
                               at /rustc/fe5b13d681f25ee6474be29d748c65adcd91f69e/library/core/src/fmt/mod.rs:1194:17
   5:     0x5609e9b35af1 - std::io::Write::write_fmt::heb73de6e02cfabed
                               at /rustc/fe5b13d681f25ee6474be29d748c65adcd91f69e/library/std/src/io/mod.rs:1655:15
   6:     0x5609e9b3caf5 - std::sys_common::backtrace::_print::h63c8b24acdd8e8ce
                               at /rustc/fe5b13d681f25ee6474be29d748c65adcd91f69e/library/std/src/sys_common/backtrace.rs:48:5
   7:     0x5609e9b3caf5 - std::sys_common::backtrace::print::h426700d6240cdcc2
                               at /rustc/fe5b13d681f25ee6474be29d748c65adcd91f69e/library/std/src/sys_common/backtrace.rs:35:9
   8:     0x5609e9b3caf5 - std::panicking::default_hook::{{closure}}::hc9a76eed0b18f82b
                               at /rustc/fe5b13d681f25ee6474be29d748c65adcd91f69e/library/std/src/panicking.rs:295:22
   9:     0x5609e9b3c7a9 - std::panicking::default_hook::h2e88d02087fae196
                               at /rustc/fe5b13d681f25ee6474be29d748c65adcd91f69e/library/std/src/panicking.rs:314:9
  10:     0x5609e9b3d042 - std::panicking::rust_panic_with_hook::habfdcc2e90f9fd4c
                               at /rustc/fe5b13d681f25ee6474be29d748c65adcd91f69e/library/std/src/panicking.rs:698:17
  11:     0x5609e9b3cf27 - std::panicking::begin_panic_handler::{{closure}}::he054b2a83a51d2cd
                               at /rustc/fe5b13d681f25ee6474be29d748c65adcd91f69e/library/std/src/panicking.rs:588:13
  12:     0x5609e9b3b304 - std::sys_common::backtrace::__rust_end_short_backtrace::ha48b94ab49b30915
                               at /rustc/fe5b13d681f25ee6474be29d748c65adcd91f69e/library/std/src/sys_common/backtrace.rs:138:18
  13:     0x5609e9b3cc59 - rust_begin_unwind
                               at /rustc/fe5b13d681f25ee6474be29d748c65adcd91f69e/library/std/src/panicking.rs:584:5
  14:     0x5609e5228fe3 - core::panicking::panic_fmt::h366d3a309ae17c94
                               at /rustc/fe5b13d681f25ee6474be29d748c65adcd91f69e/library/core/src/panicking.rs:143:14
  15:     0x5609e6ef291d - roc_gen_llvm::llvm::build::build_procedures_help::hb3a7e1afb1670671
                               at /home/jan/_code/_roc/roc-random/roc/crates/compiler/gen_llvm/src/llvm/build.rs:4565:21
  16:     0x5609e6ef043c - roc_gen_llvm::llvm::build::build_procedures::ha6fe4c9cf5343731
                               at /home/jan/_code/_roc/roc-random/roc/crates/compiler/gen_llvm/src/llvm/build.rs:4391:5
  17:     0x5609e69a2df7 - roc_build::program::gen_from_mono_module_llvm::h07a5e4f111eedaf5
                               at /home/jan/_code/_roc/roc-random/roc/crates/compiler/build/src/program.rs:262:5
  18:     0x5609e69a1c80 - roc_build::program::gen_from_mono_module::h7b67544813dd30fe
                               at /home/jan/_code/_roc/roc-random/roc/crates/compiler/build/src/program.rs:169:67
  19:     0x5609e646791b - roc_cli::build::build_file::hf8a0769fa5c7299d
                               at /home/jan/_code/_roc/roc-random/roc/crates/cli/src/build.rs:235:27
  20:     0x5609e64716f0 - roc_cli::build::hdefdb7a350b8fb32
                               at /home/jan/_code/_roc/roc-random/roc/crates/cli/src/lib.rs:559:27
  21:     0x5609e52f7917 - roc::main::h423c1fb84af910cd
                               at /home/jan/_code/_roc/roc-random/roc/crates/cli/src/main.rs:32:17
  22:     0x5609e52f45cb - core::ops::function::FnOnce::call_once::h7c77ac6a58d31fd4
                               at /rustc/fe5b13d681f25ee6474be29d748c65adcd91f69e/library/core/src/ops/function.rs:227:5
  23:     0x5609e52f3ace - std::sys_common::backtrace::__rust_begin_short_backtrace::h996f56a0f696e8be
                               at /rustc/fe5b13d681f25ee6474be29d748c65adcd91f69e/library/std/src/sys_common/backtrace.rs:122:18
  24:     0x5609e52f3c21 - std::rt::lang_start::{{closure}}::h60650cadf439ea7a
                               at /rustc/fe5b13d681f25ee6474be29d748c65adcd91f69e/library/std/src/rt.rs:145:18
  25:     0x5609e9b2dcae - core::ops::function::impls::<impl core::ops::function::FnOnce<A> for &F>::call_once::had4f69b3aefb47a8
                               at /rustc/fe5b13d681f25ee6474be29d748c65adcd91f69e/library/core/src/ops/function.rs:259:13
  26:     0x5609e9b2dcae - std::panicking::try::do_call::hf2ad5355fcafe775
                               at /rustc/fe5b13d681f25ee6474be29d748c65adcd91f69e/library/std/src/panicking.rs:492:40
  27:     0x5609e9b2dcae - std::panicking::try::h0a63ac363423e61e
                               at /rustc/fe5b13d681f25ee6474be29d748c65adcd91f69e/library/std/src/panicking.rs:456:19
  28:     0x5609e9b2dcae - std::panic::catch_unwind::h18088edcecb8693a
                               at /rustc/fe5b13d681f25ee6474be29d748c65adcd91f69e/library/std/src/panic.rs:137:14
  29:     0x5609e9b2dcae - std::rt::lang_start_internal::{{closure}}::ha7dad166dc711761
                               at /rustc/fe5b13d681f25ee6474be29d748c65adcd91f69e/library/std/src/rt.rs:128:48
  30:     0x5609e9b2dcae - std::panicking::try::do_call::hda0c61bf3a57d6e6
                               at /rustc/fe5b13d681f25ee6474be29d748c65adcd91f69e/library/std/src/panicking.rs:492:40
  31:     0x5609e9b2dcae - std::panicking::try::hbc940e68560040a9
                               at /rustc/fe5b13d681f25ee6474be29d748c65adcd91f69e/library/std/src/panicking.rs:456:19
  32:     0x5609e9b2dcae - std::panic::catch_unwind::haed0df2aeb3fa368
                               at /rustc/fe5b13d681f25ee6474be29d748c65adcd91f69e/library/std/src/panic.rs:137:14
  33:     0x5609e9b2dcae - std::rt::lang_start_internal::h9c06694362b5b80c
                               at /rustc/fe5b13d681f25ee6474be29d748c65adcd91f69e/library/std/src/rt.rs:128:20
  34:     0x5609e52f3bf0 - std::rt::lang_start::hc2eba1e5550ccad0
                               at /rustc/fe5b13d681f25ee6474be29d748c65adcd91f69e/library/std/src/rt.rs:144:17
  35:     0x5609e52f830c - main
  36:     0x7f48aece8237 - __libc_start_call_main
  37:     0x7f48aece82f5 - __libc_start_main_impl
  38:     0x5609e52f1cf1 - _start
                               at /build/glibc-2.34/csu/../sysdeps/x86_64/start.S:116
  39:                0x0 - <unknown>
[jan@framey roc-random]$ 

App (a work in progress)

app "example_complex_with_backpassing"
    packages { pf: "roc/examples/interactive/cli-platform/main.roc" }
    imports [pf.Stdout.{ line }, pf.Task.{ await }, RandomB]
    provides [main] to pf

main =
    a = point (RandomB.seed 36)
    b = a |> RandomB.next point

    _ <- await (line (Num.toStr a.value.x |> \s -> "a.x ==   24 ==   \(s)"))
    _ <- await (line (Num.toStr a.value.y |> \s -> "a.y ==   37 ==   \(s)"))
    _ <- await (line (Num.toStr a.value.z |> \s -> "a.z ==   61 ==   \(s)"))
    _ <- await (line (Num.toStr a.value.t |> \s -> "a.t ==  -47 ==  \(s)"))
    _ <- await (line (Num.toStr b.value.x |> \s -> "b.x ==   90 ==   \(s)"))
    _ <- await (line (Num.toStr b.value.y |> \s -> "b.y == -100 == \(s)"))
    _ <- await (line (Num.toStr b.value.z |> \s -> "b.z ==   44 ==   \(s)"))
    _ <- await (line (Num.toStr b.value.t |> \s -> "b.t ==    6 ==    \(s)"))
    line "These values will be the same on every run, because we use a constant seed."

# Complex `Generator`s can be created by chaining primitive `Generator`s.
Point a : { x : a, y : a, z : a, t : a }
point : RandomB.Generator (Point I32) (RandomB.State U32)
point =
    min = -100
    max = 100

    # Primitive generator constructors are included in `Random`.
    x <- RandomB.int min max
    y <- RandomB.int min max
    z <- RandomB.int min max
    t <- RandomB.int min max
    \state -> { value: { x, y, z, t }, state }

Library (a work in progress, mid-refactor)

interface RandomB
    exposes [
        Generation,
        Generator,
        State,
        i8,
        i16,
        i32,
        int,
        next,
        seed,
        seedVariant,
        seed8,
        seed8Variant,
        seed16,
        seed16Variant,
        seed32,
        seed32Variant,
        step,
        u8,
        u16,
        u32,
    ]
    imports []

## # Types

## A psuedorandom value generator
Generator value state : state -> Generation value state

## A psuedorandom value, paired with its [Generator]'s output state (for chaining)
Generation value state : { value : value, state : state }

## Internal state for [Generator]s
State seed := { value : seed, constants : AlgorithmConstants seed }
AlgorithmConstants seed : {
    permuteMultiplier : seed,
    permuteRandomXorShift : seed,
    permuteRandomXorShiftIncrement : seed,
    permuteXorShift : seed,
    updateIncrement : seed,
    updateMultiplier : seed }

## # [State] constructors

Seeder seedType : seedType -> State seedType
VariantSeeder seedType : seedType, seedType -> State seedType

## Initialize a [State] for [Generator]s.
##
## This is an alias for [seed32].
seed : Seeder U32
seed = seed32

## Initialize a specific variant of a [State] for [Generator]s.
##
## For each seed value with N bits of noise, there are N "variants" of an initial [State]
## for each possible value of `updateIncrement` in the [AlgorithmConstants].
## No two variants of the same [State] will share any two consecutive internal/external values.
## Therefore, variants are useful for generating multiple distinct sequences from one initial sample of noise.
##
## Odd numbers are recommended for the update increment,
## to double the repetition period of sequences (by hitting both even & odd values).
##
## This is an alias for [seed32Variant].
seedVariant : VariantSeeder U32
seedVariant = seed32Variant

## Construct an initial [State] from 8 bits of noise
seed8 : Seeder U8
seed8 = \seedValue -> seed8Variant seedValue defaultU8UpdateIncrement

## Construct an initial [State] from 8 bits of noise and a specific increment for updating
seed8Variant : VariantSeeder U8
seed8Variant = \seedValue, updateIncrement ->
    @State {
        value: seedValue,
        constants: {
            permuteMultiplier: defaultU8PermuteMultiplier,
            permuteRandomXorShift: defaultU8PermuteRandomXorShift,
            permuteRandomXorShiftIncrement: defaultU8PermuteRandomXorShiftIncrement,
            permuteXorShift: defaultU8PermuteXorShift,
            updateIncrement,
            updateMultiplier: defaultU8UpdateMultiplier } }

## Construct an initial [State] from 16 bits of noise
seed16 : Seeder U16
seed16 = \seedValue -> seed16Variant seedValue defaultU16UpdateIncrement

## Construct an initial [State] from 16 bits of noise and a specific increment for updating
seed16Variant : VariantSeeder U16
seed16Variant = \seedValue, updateIncrement ->
    @State {
        value: seedValue,
        constants: {
            permuteMultiplier: defaultU16PermuteMultiplier,
            permuteRandomXorShift: defaultU16PermuteRandomXorShift,
            permuteRandomXorShiftIncrement: defaultU16PermuteRandomXorShiftIncrement,
            permuteXorShift: defaultU16PermuteXorShift,
            updateIncrement,
            updateMultiplier: defaultU16UpdateMultiplier } }

## Construct an initial [State] from 32 bits of noise
seed32 : Seeder U32
seed32 = \seedValue -> seed32Variant seedValue defaultU32UpdateIncrement

## Construct an initial [State] from 32 bits of noise and a specific increment for updating
seed32Variant : VariantSeeder U32
seed32Variant = \seedValue, updateIncrement ->
    @State {
        value: seedValue,
        constants: {
            permuteMultiplier: defaultU32PermuteMultiplier,
            permuteRandomXorShift: defaultU32PermuteRandomXorShift,
            permuteRandomXorShiftIncrement: defaultU32PermuteRandomXorShiftIncrement,
            permuteXorShift: defaultU32PermuteXorShift,
            updateIncrement,
            updateMultiplier: defaultU32UpdateMultiplier } }

## # [Generator] helpers

## Generate a new [Generation] from an old [Generation]'s state
next : Generation * state, Generator value state -> Generation value state
next = \generation, generator -> generator generation.state

## Generate a [Generation] from a state
step : state, Generator value state -> Generation value state
step = \state, generator -> generator state

## # Primitive [Generator] constructors

## This is an alias for [i32].
int = i32

## Construct a [Generator] for 8-bit signed integers between two boundaries (inclusive)
i8 : I8, I8, (I8 -> Generator a (State U8)) -> Generator a (State U8)
i8 = \x, y, yield ->
    Pair minimum maximum = sort x y
    # TODO: Remove these `I64` dependencies.
    range = maximum - minimum + 1 |> Num.toI64
    \state ->
        # TODO: Analyze this. The mod-ing might be biased towards a smaller offset!
        offset = permute state |> mapToI8 |> Num.toI64 |> Num.sub (Num.toI64 Num.minI8) |> modWithNonzero range
        value = minimum |> Num.toI64 |> Num.add offset |> Num.toI8
        (yield value) (update state)

## Construct a [Generator] for 16-bit signed integers between two boundaries (inclusive)
i16 : I16, I16, (I16 -> Generator a (State U16)) -> Generator a (State U16)
i16 = \x, y, yield ->
    Pair minimum maximum = sort x y
    # TODO: Remove these `I64` dependencies.
    range = maximum - minimum + 1 |> Num.toI64
    \state ->
        # TODO: Analyze this. The mod-ing might be biased towards a smaller offset!
        offset = permute state |> mapToI16 |> Num.toI64 |> Num.sub (Num.toI64 Num.minI16) |> modWithNonzero range
        value = minimum |> Num.toI64 |> Num.add offset |> Num.toI16
        (yield value) (update state)

## Construct a [Generator] for 32-bit signed integers between two boundaries (inclusive)
i32 : I32, I32, (I32 -> Generator a (State U32)) -> Generator a (State U32)
i32 = \x, y, yield ->
    Pair minimum maximum = sort x y
    # TODO: Remove these `I64` dependencies.
    range = maximum - minimum + 1 |> Num.toI64
    \state ->
        # TODO: Analyze this. The mod-ing might be biased towards a smaller offset!
        offset = permute state |> mapToI32 |> Num.toI64 |> Num.sub (Num.toI64 Num.minI32) |> modWithNonzero range
        value = minimum |> Num.toI64 |> Num.add offset |> Num.toI32
        (yield value) (update state)

## Construct a [Generator] for 8-bit unsigned integers between two boundaries (inclusive)
u8 : U8, U8 -> Generator U8 (State U8)
u8 = \x, y -> betweenUnsigned x y

## Construct a [Generator] for 16-bit unsigned integers between two boundaries (inclusive)
u16 : U16, U16 -> Generator U16 (State U16)
u16 = \x, y -> betweenUnsigned x y

## Construct a [Generator] for 32-bit unsigned integers between two boundaries (inclusive)
u32 : U32, U32 -> Generator U32 (State U32)
u32 = \x, y -> betweenUnsigned x y

#### Helpers for the above constructors

betweenUnsigned = \x, y ->
    Pair minimum maximum = sort x y
    range = maximum - minimum + 1
    \state ->
        # TODO: Analyze this. The mod-ing might be biased towards a smaller offset!
        value = minimum + modWithNonzero (permute state) range
        { value, state: update state }

mapToI8 : U8 -> I8
mapToI8 = \x ->
    middle = Num.toU8 Num.maxI8
    if x <= middle then
        Num.minI8 + Num.toI8 x
    else
        Num.toI8 (x - middle - 1)

mapToI16 : U16 -> I16
mapToI16 = \x ->
    middle = Num.toU16 Num.maxI16
    if x <= middle then
        Num.minI16 + Num.toI16 x
    else
        Num.toI16 (x - middle - 1)

mapToI32 : U32 -> I32
mapToI32 = \x ->
    middle = Num.toU32 Num.maxI32
    if x <= middle then
        Num.minI32 + Num.toI32 x
    else
        Num.toI32 (x - middle - 1)

# Warning: y must never equal 0. The `123` fallback is nonsense for typechecking only.
modWithNonzero = \x, y -> x % y

sort = \x, y ->
    if x < y then
        Pair x y
    else
        Pair y x

#### PCG algorithms, constants, and wrappers
#
# Based on this paper: https://www.pcg-random.org/pdf/hmc-cs-2014-0905.pdf
# Based on this C++ header: https://github.com/imneme/pcg-c/blob/master/include/pcg_variants.h
# Abbreviations:
#     M = Multiplication (see section 6.3.4 on page 45 in the paper)
#     PCG = Permuted Congruential Generator
#     RXS = Random XorShift (see section 5.5.1 on page 36 in the paper)
#     XS = XorShift (see section 5.5 on page 34 in the paper)

# See `RXS M XS` constants (line 168?)
# and `_DEFAULT_` constants (line 276?)
# in the PCG C++ header (see link above).
defaultU8PermuteMultiplier = 217
defaultU8PermuteRandomXorShift = 6
defaultU8PermuteRandomXorShiftIncrement = 2
defaultU8PermuteXorShift = 6
defaultU8UpdateIncrement = 77
defaultU8UpdateMultiplier = 141
defaultU16PermuteMultiplier = 62169
defaultU16PermuteRandomXorShift = 13
defaultU16PermuteRandomXorShiftIncrement = 3
defaultU16PermuteXorShift = 11
defaultU16UpdateIncrement = 47989
defaultU16UpdateMultiplier = 12829
defaultU32PermuteMultiplier = 277_803_737
defaultU32PermuteRandomXorShift = 28
defaultU32PermuteRandomXorShiftIncrement = 4
defaultU32PermuteXorShift = 22
defaultU32UpdateIncrement = 2_891_336_453
defaultU32UpdateMultiplier = 747_796_405
# TODO: These are waiting on 64-bit generators.
#       and literals > Num.maxI64 (https://github.com/rtfeldman/roc/issues/2332).
# defaultU64PermuteMultiplier = 12_605_985_483_714_917_081
# defaultU64PermuteRandomXorShift = 59
# defaultU64PermuteRandomXorShiftIncrement = 5
# defaultU64PermuteXorShift = 43
# defaultU64UpdateIncrement = 1_442_695_040_888_963_407
# defaultU64UpdateMultiplier = 6_364_136_223_846_793_005
# TODO: These are waiting on 128-bit generators.
#       and literals > Num.maxI64 (https://github.com/rtfeldman/roc/issues/2332).
# defaultU128PermuteMultiplier = (Num.shiftLeftBy 64 17_766_728_186_571_221_404) + 12_605_985_483_714_917_081
# defaultU128PermuteRandomXorShift = 122
# defaultU128PermuteRandomXorShiftIncrement = 6
# defaultU128PermuteXorShift = 86
# defaultU128UpdateIncrement = (Num.shiftLeftBy 64 6_364_136_223_846_793_005) + 1_442_695_040_888_963_407
# defaultU128UpdateMultiplier = (Num.shiftLeftBy 64 2_549_297_995_355_413_924) + 4_865_540_595_714_422_341

# See section 6.3.4 on page 45 in the PCG paper (see link above).
pcgRxsMXs = \stateValue, randomXorShift, randomXorShiftIncrement, multiplier, xorShift ->
    partial = Num.mulWrap multiplier (
        Num.bitwiseXor stateValue (
            Num.shiftRightZfBy (
                Num.addWrap (Num.shiftRightZfBy randomXorShift stateValue) randomXorShiftIncrement
            ) stateValue
        ))
    Num.bitwiseXor partial (Num.shiftRightZfBy xorShift partial)

# See section 4.1 on page 20 in the PCG paper (see link above).
pcgStep = \stateValue, multiplier, increment ->
    Num.addWrap (Num.mulWrap stateValue multiplier) increment

# See `pcg_output_rxs_m_xs_8_8` (on line 170?) in the PCG C++ header (see link above).
permute = \@State { value, constants } ->
    pcgRxsMXs value constants.permuteRandomXorShift constants.permuteRandomXorShiftIncrement constants.permuteMultiplier constants.permuteXorShift

# See `pcg_oneseq_8_step_r` (line 409?) in the PCG C++ header (see link above).
update = \@State { value, constants } ->
    @State { value: pcgStep value constants.updateMultiplier constants.updateIncrement, constants }
JanCVanB commented 2 years ago

Let me know if you'd like the full LLVM IR, it's rather large.

ayazhafiz commented 2 years ago

@JanCVanB could you minimize the reproduction here?

JanCVanB commented 2 years ago

After forgetting about this issue for a month and then returning to test it with the nightly build (instead of cargo run-ing from the source dir), this crash doesn't happen anymore. I'm going to close this issue and re-open if it resurfaces!