Crystal: LLVM4 crash: Cannot select ... & other errors in codegen

Created on 23 May 2017  路  8Comments  路  Source: crystal-lang/crystal

First, version:

$ crystal -v
Crystal 0.22.0 (2017-04-22) LLVM 4.0.0

The faulty code:

Kilobyte = 1024u32
Megabyte = 1024u32 * Kilobyte
Gigabyte = 1024u32 * Megabyte

struct BigStruct
  @some_array : UInt8[Megabyte]?
end

BigStruct.new

sleep 3

Carc-in is broken on this one: https://carc.in/#/r/22nn

I get the output:

Parse:                             00:00:00.0000907 (   0.19MB)
Semantic (top level):              00:00:00.0820709 (  27.11MB)
Semantic (new):                    00:00:00.0006868 (  27.11MB)
Semantic (type declarations):      00:00:00.0100532 (  35.11MB)
Semantic (abstract def check):     00:00:00.0006654 (  35.11MB)
Semantic (ivars initializers):     00:00:00.0007388 (  35.11MB)
Semantic (cvars initializers):     00:00:00.0052621 (  35.11MB)
Semantic (main):                   00:00:00.0713333 (  43.17MB)
Semantic (cleanup):                00:00:00.0005363 (  51.17MB)
Semantic (recursive struct check): 00:00:00.0004676 (  51.17MB)
Codegen (crystal):                 00:00:00.1255013 (  51.29MB)
Codegen (bc+obj):                 LLVM ERROR: Cannot select: 0x7ecc960: ch,glue = callseq_end 0x7ecd388, TargetConstant:i64<0>, TargetConstant:i64<0>, 0x7ecd388:1
  0x7edc950: i64 = TargetConstant<0>
  0x7edc950: i64 = TargetConstant<0>
  0x7ecd388: ch,glue = X86ISD::CALL 0x7edd310, TargetGlobalAddress:i64<%BigStruct ()* @"*BigStruct::new:BigStruct"> 0 [TF=6], Register:i64 %RDI, RegisterMask:Untyped, 0x7edd310:1
    0x7edcc28: i64 = TargetGlobalAddress<%BigStruct ()* @"*BigStruct::new:BigStruct"> 0 [TF=6]
    0x7eded18: i64 = Register %RDI
    0x7eccdd8: Untyped = RegisterMask
    0x7edd310: ch,glue = CopyToReg 0x7ecd3f0, Register:i64 %RDI, FrameIndex:i64<7>
      0x7eded18: i64 = Register %RDI
      0x7ecc7c0: i64 = FrameIndex<7>
In function: __crystal_main

^C

There where an infinite loop at the end, I needed to Ctrl-C it..

  • If I remove the sleep 3, the LLVM error goes away, but not the infinite loop (the sleep's time doesn't change anything)
  • If I remove the BigStruct.new line, no error (but the program does nothing obviously!)
  • If I use numbers instead of constants (in UInt8[1048576]?) doesn't change anything

  • If I change Megabyte to Gigabyte in UInt8[Gigabyte]?, I get a completely different error (still in codegen though):

Parse:                             00:00:00.0001064 (   0.19MB)
Semantic (top level):              00:00:00.0830904 (  27.10MB)
Semantic (new):                    00:00:00.0006906 (  27.10MB)
Semantic (type declarations):      00:00:00.0096108 (  35.10MB)
Semantic (abstract def check):     00:00:00.0006449 (  35.10MB)
Semantic (ivars initializers):     00:00:00.0007385 (  35.10MB)
Semantic (cvars initializers):     00:00:00.0053483 (  35.10MB)
Semantic (main):                   00:00:00.0730416 (  51.16MB)
Semantic (cleanup):                00:00:00.0005108 (  51.16MB)
Semantic (recursive struct check): 00:00:00.0004811 (  51.16MB)
Codegen (crystal):                 00:00:00.1198496 (  51.29MB)
Codegen (bc+obj):                 Invalid memory access (signal 11) at address 0x1dffffd0
[0x43cebf] __crystal_sigfault_handler +63
[0x7f8d68cfdfe0] ???
[0x7f8d6a5b319f] _ZN4llvm13GetReturnInfoEPNS_4TypeENS_12AttributeSetERNS_15SmallVectorImplINS_3ISD9OutputArgEEERKNS_14TargetLoweringERKNS_10DataLayoutE +735
[0x7f8d6a648dcd] _ZN4llvm20FunctionLoweringInfo3setERKNS_8FunctionERNS_15MachineFunctionEPNS_12SelectionDAGE +269
[0x7f8d6a76ac2e] _ZN4llvm16SelectionDAGISel20runOnMachineFunctionERNS_15MachineFunctionE +926
[0x7f8d6b9a1e74] ???
[0x7f8d6a446841] _ZN4llvm19MachineFunctionPass13runOnFunctionERNS_8FunctionE +145
[0x7f8d6a2c6b32] _ZN4llvm13FPPassManager13runOnFunctionERNS_8FunctionE +642
[0x7f8d6a2c6bd3] _ZN4llvm13FPPassManager11runOnModuleERNS_6ModuleE +51
[0x7f8d6a2c7584] _ZN4llvm6legacy15PassManagerImpl3runERNS_6ModuleE +772
[0x7f8d6b164c45] ???
[0x7f8d6b164f64] LLVMTargetMachineEmitToFile +244
[0x13d26ca] ???
[0x13d6d53] ???
[0x411668] ???
[0x0] ???
Invalid memory access (signal 11) at address 0x3bffffd0
[0x43cebf] __crystal_sigfault_handler +63
[0x7f8d68cfdfe0] ???
[0x7f8d6a5b319f] _ZN4llvm13GetReturnInfoEPNS_4TypeENS_12AttributeSetERNS_15SmallVectorImplINS_3ISD9OutputArgEEERKNS_14TargetLoweringERKNS_10DataLayoutE +735
[0x7f8d6a63b6eb] _ZN4llvm8FastISel11lowerCallToERNS0_16CallLoweringInfoE +363
[0x7f8d6a63d14f] _ZN4llvm8FastISel9lowerCallEPKNS_8CallInstE +1391
[0x7f8d6a640b84] _ZN4llvm8FastISel10selectCallEPKNS_4UserE +100
[0x7f8d6a63df8d] _ZN4llvm8FastISel14selectOperatorEPKNS_4UserEj +413
[0x7f8d6a643333] _ZN4llvm8FastISel17selectInstructionEPKNS_11InstructionE +883
[0x7f8d6a768e68] _ZN4llvm16SelectionDAGISel20SelectAllBasicBlocksERKNS_8FunctionE +696
[0x7f8d6a76ad49] _ZN4llvm16SelectionDAGISel20runOnMachineFunctionERNS_15MachineFunctionE +1209
[0x7f8d6b9a1e74] ???
[0x7f8d6a446841] _ZN4llvm19MachineFunctionPass13runOnFunctionERNS_8FunctionE +145
[0x7f8d6a2c6b32] _ZN4llvm13FPPassManager13runOnFunctionERNS_8FunctionE +642
[0x7f8d6a2c6bd3] _ZN4llvm13FPPassManager11runOnModuleERNS_6ModuleE +51
[0x7f8d6a2c7584] _ZN4llvm6legacy15PassManagerImpl3runERNS_6ModuleE +772
[0x7f8d6b164c45] ???
[0x7f8d6b164f64] LLVMTargetMachineEmitToFile +244
[0x13d26ca] ???
[0x13d6d53] ???
[0x411668] ???
[0x0] ???
 00:00:04.0648193 (  51.29MB)
Codegen (linking):                _main.o: file not recognized: File truncated
collect2: error: ld returned 1 exit status
Error: execution of command failed with code: 1: `cc -o "/home/lesell_b/tests/crystal/fork_on_oom/fork_and_stack" "${@}"  -rdynamic  -lpcre -lgc -lpthread /usr/lib/crystal/ext/libcrystal.a -levent -lrt -ldl -L/usr/lib -L/usr/local/lib`

This last error seams to be LLVM that violently crash, I don't know how I could report this to LLVM team..

Note: Is it just me ? (carcin can't comfirm, and I have only one computer to test right now)

bug discussion compiler

Most helpful comment

As far as I know, LLVM doesn't handle well big arrays (array being an LLVM type that we use to represent static arrays). And the bigger they are, the longer it takes to compile a program, and much more to optimize it.

I think the compiler should disallow static arrays bigger than, say, 10K or 20K. There's no reason to use them instead of a regular Array.

All 8 comments

Is it just me ?

I can confirm this on Crystal 0.22.0 (2017-04-22) LLVM 4.0.0, I'm also getting the same error as you are

If you use --release flag error disappear.

crystal build -s --release g4452.cr
Parse:                             00:00:00.0001905 (   0.19MB)
Semantic (top level):              00:00:00.2001953 (  27.20MB)
Semantic (new):                    00:00:00.0013384 (  27.20MB)
Semantic (type declarations):      00:00:00.0172932 (  27.20MB)
Semantic (abstract def check):     00:00:00.0014872 (  27.20MB)
Semantic (ivars initializers):     00:00:00.0011554 (  27.20MB)
Semantic (cvars initializers):     00:00:00.0124931 (  35.20MB)
Semantic (main):                   00:00:00.1674670 (  43.26MB)
Semantic (cleanup):                00:00:00.0009177 (  43.26MB)
Semantic (recursive struct check): 00:00:00.0011832 (  43.26MB)
Codegen (crystal):                 00:00:00.1593567 (  51.26MB)
Codegen (bc+obj):                  00:00:09.0689940 (  51.26MB)
Codegen (linking):                 00:00:00.0604327 (  51.26MB)

Codegen (bc+obj):
 - no previous .o files were reused

As far as I know, LLVM doesn't handle well big arrays (array being an LLVM type that we use to represent static arrays). And the bigger they are, the longer it takes to compile a program, and much more to optimize it.

I think the compiler should disallow static arrays bigger than, say, 10K or 20K. There's no reason to use them instead of a regular Array.

LLVM must have a hard time dealing with a huge gap on the stack. The program may crash randomly, too, since the stack has a limited size. I agree we should limit the maximum size of structs to an acceptable limit. If I recall correctly, HTTP/2 uses a 16KB frame size by default. It would be nice to keep a 16KB buffer on the stack (or maybe twice that, 32KB), if it's acceptable.

StaticArray(UInt8, 32000).new crashes in carc.in, and 16000 too, so the limit is smaller, like a 10000.

Should we keep this issue open or can I close it?

Let's leave this open for now

Tried this in

$ crystal --version
Crystal 0.31.1 (2019-10-02)

LLVM: 8.0.1
Default target: x86_64-apple-macosx

Maybe I didn't wait long enough but this is the only thing I get after quite a while:

$ crystal test.cr
^C
Was this page helpful?
0 / 5 - 0 ratings

Related issues

RX14 picture RX14  路  62Comments

rdp picture rdp  路  112Comments

malte-v picture malte-v  路  77Comments

xtagon picture xtagon  路  132Comments

farleyknight picture farleyknight  路  64Comments