AnyDSL / thorin

The Higher-Order Intermediate Representation
https://anydsl.github.io
GNU Lesser General Public License v3.0
151 stars 15 forks source link

SegFault in LLVM (BasicBlock has no terminator) when using enums #85

Closed richardmembarth closed 6 years ago

richardmembarth commented 6 years ago

Triggered for jacobi.impala in AnyDSL/stincilla on branch eta_enum_bug when line 13 is uncommented.

Assertion failed: (Val && "isa<> used on a null pointer"), function doit, file llvm/include/llvm/Support/Casting.h, line 95.

Note: this is related to using BoundaryMode::Const.

madmann91 commented 6 years ago

Here is a reproducing example:

enum K {
    K1(int),
    K2(i64)
}

extern "C" {
    fn printf(&[u8], int) -> ();
}

fn test(k : K) -> () {
    let mut i = 0;
    while i < 5 {
        ++i;
    }
    printf("%d\n", i);
    match k {
        K::K1(x) => printf("%d\n", x),
        K::K2(y) => printf("%d\n", y as int)
    }
}

fn main() -> () {
    test(K::K1(1));
    test(K::K2(1i64));
}

The problem is that K::K2(1i64) is seen as a constant by Thorin, and consequently we get this IR:

test_cont_761(mem mem_762)
    test_717(mem_762, (K struct_agg qu32 1, (variant(qs32, qs64) variant qs64 1)), return_767)

However, in order to emit a variant PrimOp, we need to emit allocas in LLVM, so the schedule should actually be:

test_cont_761(mem mem_762)
    variant(qs32, qs64) v = variant qs64 1
    K k = struct_agg qu32 1, v
    test_717(mem_762, k, return_767)
madmann91 commented 6 years ago

A simple but too restrictive solution is to mark any variant as non const (change the implementation of is_const). That has the negative side-effect that some optimizations will not be triggered in Thorin.

madmann91 commented 6 years ago

Fixed by commit d682987.

richardmembarth commented 6 years ago

There is still an issue with the generated code: Segfault!

Here is the output from valgrind:

==13492== Warning: client switching stacks?  SP change: 0x32611530 --> 0x32801868
==13492==          to suppress, use: --max-stackframe=2032440 or greater
==13492== Warning: client switching stacks?  SP change: 0x32611530 --> 0x32801868
==13492==          to suppress, use: --max-stackframe=2032440 or greater
==13492== Warning: client switching stacks?  SP change: 0x32611530 --> 0x32801868
==13492==          to suppress, use: --max-stackframe=2032440 or greater
==13492==          further instances of this message will not be shown.
Timing: 101360 | 101360 | 101360 (median(1) | minimum | maximum) ms
Total timing for cpu / kernel: 101360 / 0 ms
==13492== Stack overflow in thread #1: can't grow stack to 0xffe001000
==13492== Stack overflow in thread #1: can't grow stack to 0xffe001000
==13492== Can't extend stack to 0xffe0010a8 during signal delivery for thread 1:
==13492==   no stack segment
==13492== 
==13492== Process terminating with default action of signal 11 (SIGSEGV): dumping core
==13492==  Access not within mapped region at address 0xFFE0010A8
==13492== Stack overflow in thread #1: can't grow stack to 0xffe001000
==13492==    at 0x409ECE: main (gaussian.impala:176)
==13492==  If you believe this happened as a result of a stack
==13492==  overflow in your program's main thread (unlikely but
==13492==  possible), you can try to increase the size of the
==13492==  main thread stack using the --main-stacksize= flag.
==13492==  The main thread stack size used in this run was 16777216.
==13492== Stack overflow in thread #1: can't grow stack to 0xffe001000
==13492== 
==13492== Process terminating with default action of signal 11 (SIGSEGV)
==13492==  Access not within mapped region at address 0xFFE001F68
==13492== Stack overflow in thread #1: can't grow stack to 0xffe001000
==13492==    at 0x4A286C0: _vgnU_freeres (vg_preloaded.c:59)
==13492==  If you believe this happened as a result of a stack
==13492==  overflow in your program's main thread (unlikely but
==13492==  possible), you can try to increase the size of the
==13492==  main thread stack using the --main-stacksize= flag.
==13492==  The main thread stack size used in this run was 16777216.

Running gaussian using BoundaryMode::Const. Stack size is set to unlimited:

ulimit -s unlimited

There are no warnings when using BoundaryMode::Index.

madmann91 commented 6 years ago

Should be fixed by commit 8ad6765