ldc-developers / ldc

The LLVM-based D Compiler.
http://wiki.dlang.org/LDC
Other
1.21k stars 261 forks source link

Unhandled type error when targeting xtensa without -betterC #3943

Closed MoonlightSentinel closed 2 years ago

MoonlightSentinel commented 2 years ago

Preface: Currently trying to use LDC built against Espressif's LLVM fork to target an ESP32 (because their patches are yet to be accepted into the upstream repository...). AFAICT xtensa isn't officially supported, so feel free to close this issue.


The following reduced example fails to compile without -betterC:

Formal argument #1 has unhandled type i32
UNREACHABLE executed at ldc-esp32/source/llvm-xtensa/lib/CodeGen/CallingConvLower.cpp:99!
#0 0x000055f2838e0413 llvm::sys::PrintStackTrace(llvm::raw_ostream&) ldc-esp32/source/llvm-xtensa/lib/Support/Unix/Signals.inc:398:22
#1 0x000055f2838e04af PrintStackTraceSignalHandler(void*) ldc-esp32/source/llvm-xtensa/lib/Support/Unix/Signals.inc:462:1
#2 0x000055f2838de5f8 llvm::sys::RunSignalHandlers() ldc-esp32/source/llvm-xtensa/lib/Support/Signals.cpp:49:19
#3 0x000055f2838dfc64 SignalHandler(int) ldc-esp32/source/llvm-xtensa/lib/Support/Unix/Signals.inc:252:1
#4 0x00007fcb374db560 __restore_rt libc_sigaction.c:0:0
#5 0x00007fcb3752834c __pthread_kill_implementation pthread_kill.c:0:0
#6 0x00007fcb374db4b8 gsignal (/usr/lib/libc.so.6+0x424b8)
#7 0x00007fcb374c5534 abort (/usr/lib/libc.so.6+0x2c534)
#8 0x000055f28383d189 bindingsErrorHandler(void*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, bool) ldc-esp32/source/llvm-xtensa/lib/Support/ErrorHandling.cpp:198:55
#9 0x000055f282676d1c llvm::CCState::AnalyzeFormalArguments(llvm::SmallVectorImpl<llvm::ISD::InputArg> const&, bool (*)(unsigned int, llvm::MVT, llvm::MVT, llvm::CCValAssign::LocInfo, llvm::ISD::ArgFlagsTy, llvm::CCState&)) ldc-esp32/source/llvm-xtensa/lib/CodeGen/CallingConvLower.cpp:91:3
#10 0x000055f2822090e4 llvm::XtensaTargetLowering::LowerFormalArguments(llvm::SDValue, unsigned int, bool, llvm::SmallVectorImpl<llvm::ISD::InputArg> const&, llvm::SDLoc const&, llvm::SelectionDAG&, llvm::SmallVectorImpl<llvm::SDValue>&) const ldc-esp32/source/llvm-xtensa/lib/Target/Xtensa/XtensaISelLowering.cpp:726:17
#11 0x000055f28226336a llvm::SelectionDAGISel::LowerArguments(llvm::Function const&) ldc-esp32/source/llvm-xtensa/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp:8727:46
#12 0x000055f2823069ee llvm::SelectionDAGISel::SelectAllBasicBlocks(llvm::Function const&) ldc-esp32/source/llvm-xtensa/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1402:19
#13 0x000055f282300c3f llvm::SelectionDAGISel::runOnMachineFunction(llvm::MachineFunction&) ldc-esp32/source/llvm-xtensa/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:467:7
#14 0x000055f282202d83 (anonymous namespace)::XtensaDAGToDAGISel::runOnMachineFunction(llvm::MachineFunction&) ldc-esp32/source/llvm-xtensa/lib/Target/Xtensa/XtensaISelDAGToDAG.cpp:262:52
#15 0x000055f2827f2361 llvm::MachineFunctionPass::runOnFunction(llvm::Function&) ldc-esp32/source/llvm-xtensa/lib/CodeGen/MachineFunctionPass.cpp:62:33
#16 0x000055f28368c751 llvm::FPPassManager::runOnFunction(llvm::Function&) ldc-esp32/source/llvm-xtensa/lib/IR/LegacyPassManager.cpp:1520:20
#17 0x000055f28368c90e llvm::FPPassManager::runOnModule(llvm::Module&) ldc-esp32/source/llvm-xtensa/lib/IR/LegacyPassManager.cpp:1541:13
#18 0x000055f28368cccb (anonymous namespace)::MPPassManager::runOnModule(llvm::Module&) ldc-esp32/source/llvm-xtensa/lib/IR/LegacyPassManager.cpp:1597:20
#19 0x000055f28368d458 llvm::legacy::PassManagerImpl::run(llvm::Module&) ldc-esp32/source/llvm-xtensa/lib/IR/LegacyPassManager.cpp:1700:13
#20 0x000055f28368d66f llvm::legacy::PassManager::run(llvm::Module&) ldc-esp32/source/llvm-xtensa/lib/IR/LegacyPassManager.cpp:1732:1
#21 0x000055f281df8bd0 (anonymous namespace)::codegenModule(llvm::TargetMachine&, llvm::Module&, char const*, llvm::TargetMachine::CodeGenFileType) ldc-esp32/source/ldc/driver/toobj.cpp:131:1
#22 0x000055f281df9758 (anonymous namespace)::writeObjectFile(llvm::Module*, char const*) ldc-esp32/source/ldc/driver/toobj.cpp:280:1
#23 0x000055f281dfa8a9 writeModule(llvm::Module*, char const*) ldc-esp32/source/ldc/driver/toobj.cpp:466:5
#24 0x000055f281df72e2 ldc::CodeGenerator::writeAndFreeLLModule(char const*) ldc-esp32/source/ldc/driver/codegenerator.cpp:305:28
#25 0x000055f281df7037 ldc::CodeGenerator::finishLLModule(Module*) ldc-esp32/source/ldc/driver/codegenerator.cpp:269:23
#26 0x000055f281df74bb ldc::CodeGenerator::emit(Module*) ldc-esp32/source/ldc/driver/codegenerator.cpp:336:10
#27 0x000055f281dc0bb9 codegenModules(Array<Module*>&) ldc-esp32/source/ldc/driver/main.cpp:1199:7
#28 0x000055f281adc678 mars_mainBody(Param&, Array<char const*>&, Array<char const*>&) ldc-esp32/source/ldc/dmd/mars.d:727:5
#29 0x000055f281dc07b9 cppmain() ldc-esp32/source/ldc/driver/main.cpp:1138:27
#30 0x000055f2819eaf45 _Dmain ldc-esp32/source/ldc/driver/main.d:27:5
#31 0x00007fcb37ad617d _D2rt6dmain212_d_run_main2UAAamPUQgZiZ6runAllMFZ9__lambda2MFZv /build/ldc/src/ldc/runtime/druntime/src/rt/dmain2.d:500:31
#32 0x00007fcb37ad5f93 _D2rt6dmain212_d_run_main2UAAamPUQgZiZ7tryExecMFMDFZvZv /build/ldc/src/ldc/runtime/druntime/src/rt/dmain2.d:461:17
#33 0x00007fcb37ad609b _D2rt6dmain212_d_run_main2UAAamPUQgZiZ6runAllMFZv /build/ldc/src/ldc/runtime/druntime/src/rt/dmain2.d:500:21
#34 0x00007fcb37ad5f93 _D2rt6dmain212_d_run_main2UAAamPUQgZiZ7tryExecMFMDFZvZv /build/ldc/src/ldc/runtime/druntime/src/rt/dmain2.d:461:17
#35 0x00007fcb37ad5e4f _d_run_main2 /build/ldc/src/ldc/runtime/druntime/src/rt/dmain2.d:523:5
#36 0x00007fcb37ad5b2b _d_run_main /build/ldc/src/ldc/runtime/druntime/src/rt/dmain2.d:320:5
#37 0x000055f281deeebe args::forwardToDruntime(int, char const**) ldc-esp32/source/ldc/driver/args.cpp:82:1
#38 0x000055f281dbfea1 main ldc-esp32/source/ldc/driver/main.cpp:1028:33
#39 0x00007fcb374c6310 __libc_start_call_main libc-start.c:0:0
#40 0x00007fcb374c63c1 __libc_start_main@GLIBC_2.2.5 (/usr/lib/libc.so.6+0x2d3c1)
#41 0x000055f2819c77d5 _start (build/ldc/bin/ldc2+0x1bc7d5)
Error: Error executing build/ldc/bin/ldc2: Aborted (core dumped)
module object;

class TypeInfo_Class
{
}

struct ModuleInfo
{
    uint _flags;
    uint _index;

    void opAssign(ModuleInfo)
    {
    }
}

With -betterC

; ModuleID = './object.d'
source_filename = "./object.d"
target datalayout = "e-m:e-p:32:32-i1:8:32-i8:8:32-i16:16:32-i64:64-f64:64-a:0:32-n32"
target triple = "xtensa-esp32--elf"

%object.TypeInfo_Class = type { [1 x i8*]*, i8* }
%object.ModuleInfo = type { i32, i32 }

@_D14TypeInfo_Class6__initZ = global %object.TypeInfo_Class { [1 x i8*]* @_D14TypeInfo_Class6__vtblZ, i8* null }, align 4 ; [#uses = 0]
@_D14TypeInfo_Class6__vtblZ = constant [1 x i8*] zeroinitializer ; [#uses = 1]

; [#uses = 0]
define void @_D6object10ModuleInfo8opAssignMFSQBfQBbZv(%object.ModuleInfo* nonnull %.this_arg, %object.ModuleInfo* byval align 4 %_param_0) #0 {
  ret void
}

attributes #0 = { "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "target-cpu"="esp32" "unsafe-fp-math"="false" }

!llvm.ident = !{!0}

!0 = !{!"ldc version 1.29.0-git-4349388-dirty"}

Without -betterC

; ModuleID = './object.d'
source_filename = "./object.d"
target datalayout = "e-m:e-p:32:32-i1:8:32-i8:8:32-i16:16:32-i64:64-f64:64-a:0:32-n32"
target triple = "xtensa-esp32--elf"

%0 = type { i32, i32, i32, [1 x %object.TypeInfo_Class*], [7 x i8] }
%object.TypeInfo_Class = type { [1 x i8*]*, i8* }
%ModuleReference = type { %ModuleReference*, %object.ModuleInfo* }
%object.ModuleInfo = type { i32, i32 }

@_D14TypeInfo_Class6__initZ = global %object.TypeInfo_Class { [1 x i8*]* @_D14TypeInfo_Class6__vtblZ, i8* null }, align 4 ; [#uses = 0]
@_D14TypeInfo_Class6__vtblZ = constant [1 x i8*] zeroinitializer ; [#uses = 1]
@_D14TypeInfo_Class7__ClassZ = external global %object.TypeInfo_Class ; [#uses = 1]
@_D6object12__ModuleInfoZ = global %0 { i32 -2147481596, i32 0, i32 1, [1 x %object.TypeInfo_Class*] [%object.TypeInfo_Class* @_D14TypeInfo_Class7__ClassZ], [7 x i8] c"object\00" } ; [#uses = 1]
@_D6object11__moduleRefZ = internal global %ModuleReference { %ModuleReference* null, %object.ModuleInfo* bitcast (%0* @_D6object12__ModuleInfoZ to %object.ModuleInfo*) } ; [#uses = 2]
@_Dmodule_ref = external global %ModuleReference* ; [#uses = 2]
@llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @_D6object16__moduleinfoCtorZ, i8* null }] ; [#uses = 0]

; [#uses = 0]
define void @_D6object10ModuleInfo8opAssignMFSQBfQBbZv(%object.ModuleInfo* nonnull %.this_arg, %object.ModuleInfo* byval align 4 %_param_0) #0 {
  ret void
}

; [#uses = 1]
define internal void @_D6object16__moduleinfoCtorZ() {
moduleinfoCtorEntry:
  %current = load %ModuleReference*, %ModuleReference** @_Dmodule_ref ; [#uses = 1]
  store %ModuleReference* %current, %ModuleReference** getelementptr inbounds (%ModuleReference, %ModuleReference* @_D6object11__moduleRefZ, i32 0, i32 0)
  store %ModuleReference* @_D6object11__moduleRefZ, %ModuleReference** @_Dmodule_ref
  ret void
}

attributes #0 = { "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "target-cpu"="esp32" "unsafe-fp-math"="false" }

!llvm.ldc.typeinfo._D14TypeInfo_Class7__ClassZ = !{!0}
!llvm.ldc.classinfo._D14TypeInfo_Class7__ClassZ = !{!1}
!llvm.ident = !{!2}

!0 = !{%object.TypeInfo_Class* undef}
!1 = !{%object.TypeInfo_Class undef, i1 false}
!2 = !{!"ldc version 1.29.0-git-4349388-dirty"}

Diff:

diff --git a/object-betterc.ll b/object-full.ll
index e9a92a4..753cfc2 100755
--- a/object-betterc.ll
+++ b/object-full.ll
@@ -3,19 +3,39 @@ source_filename = "./object.d"
 target datalayout = "e-m:e-p:32:32-i1:8:32-i8:8:32-i16:16:32-i64:64-f64:64-a:0:32-n32"
 target triple = "xtensa-esp32--elf"

+%0 = type { i32, i32, i32, [1 x %object.TypeInfo_Class*], [7 x i8] }
 %object.TypeInfo_Class = type { [1 x i8*]*, i8* }
+%ModuleReference = type { %ModuleReference*, %object.ModuleInfo* }
 %object.ModuleInfo = type { i32, i32 }

 @_D14TypeInfo_Class6__initZ = global %object.TypeInfo_Class { [1 x i8*]* @_D14TypeInfo_Class6__vtblZ, i8* null }, align 4 ; [#uses = 0]
 @_D14TypeInfo_Class6__vtblZ = constant [1 x i8*] zeroinitializer ; [#uses = 1]
+@_D14TypeInfo_Class7__ClassZ = external global %object.TypeInfo_Class ; [#uses = 1]
+@_D6object12__ModuleInfoZ = global %0 { i32 -2147481596, i32 0, i32 1, [1 x %object.TypeInfo_Class*] [%object.TypeInfo_Class* @_D14TypeInfo_Class7__ClassZ], [7 x i8] c"object\00" } ; [#uses = 1]
+@_D6object11__moduleRefZ = internal global %ModuleReference { %ModuleReference* null, %object.ModuleInfo* bitcast (%0* @_D6object12__ModuleInfoZ to %object.ModuleInfo*) } ; [#uses = 2]
+@_Dmodule_ref = external global %ModuleReference* ; [#uses = 2]
+@llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @_D6object16__moduleinfoCtorZ, i8* null }] ; [#uses = 0]

 ; [#uses = 0]
 define void @_D6object10ModuleInfo8opAssignMFSQBfQBbZv(%object.ModuleInfo* nonnull %.this_arg, %object.ModuleInfo* byval align 4 %_param_0) #0 {
   ret void
 }

+; [#uses = 1]
+define internal void @_D6object16__moduleinfoCtorZ() {
+moduleinfoCtorEntry:
+  %current = load %ModuleReference*, %ModuleReference** @_Dmodule_ref ; [#uses = 1]
+  store %ModuleReference* %current, %ModuleReference** getelementptr inbounds (%ModuleReference, %ModuleReference* @_D6object11__moduleRefZ, i32 0, i32 0)
+  store %ModuleReference* @_D6object11__moduleRefZ, %ModuleReference** @_Dmodule_ref
+  ret void
+}
+
 attributes #0 = { "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "target-cpu"="esp32" "unsafe-fp-math"="false" }

-!llvm.ident = !{!0}
+!llvm.ldc.typeinfo._D14TypeInfo_Class7__ClassZ = !{!0}
+!llvm.ldc.classinfo._D14TypeInfo_Class7__ClassZ = !{!1}
+!llvm.ident = !{!2}

-!0 = !{!"ldc version 1.29.0-git-4349388-dirty"}
+!0 = !{%object.TypeInfo_Class* undef}
+!1 = !{%object.TypeInfo_Class undef, i1 false}
+!2 = !{!"ldc version 1.29.0-git-4349388-dirty"}

Not sure if this is an issue with LDC or Espressif's fork...

thewilsonator commented 2 years ago

I would suspect its an issue with Espressif's LLVM fork.

Have you tried doing a minimisation of the .ll file to see exactly what crashes? e.g. I suspect the metadata (!llvm.ident, etc ,!0, etc) can be removed and still reproduce the crash.

MoonlightSentinel commented 2 years ago

Reduced LL file:

; ModuleID = './object.d'
source_filename = "./object.d"
target datalayout = "e-m:e-p:32:32-i1:8:32-i8:8:32-i16:16:32-i64:64-f64:64-a:0:32-n32"
target triple = "xtensa-esp32--elf"

%object.ModuleInfo = type {}

define void @func(%object.ModuleInfo* byval align 4 %_param_0) {
  ret void
}
llvm-xtensa/bin/llc -mcpu=esp32 object-full.ll 
Formal argument #0 has unhandled type i32
UNREACHABLE executed at ldc-esp32/source/llvm-xtensa/lib/CodeGen/CallingConvLower.cpp:99!
[...]
thewilsonator commented 2 years ago

That looks like a perfectly reasonable thing to compile. Best file it upstream.

kinke commented 2 years ago

Yep, looks like an issue of that fork to me too - does it work without the align 4? Also looks like you're not using the latest version: https://github.com/espressif/llvm-project/blob/xtensa_release_13.0.0/llvm/lib/CodeGen/CallingConvLower.cpp#L98

MoonlightSentinel commented 2 years ago

You're right, apparently built LDC against an outdated version. The current HEAD works AFAICT. Thanks!