compilationclangllvm

Custom LLVM backend: error: unable to interface with target machine


Background I am writing a custom, globalISel only, backend for a currently unsupported processor. I have progressed to the point where I can run

> clang -target xxx -emit-llvm file.c

> llc -march=xxx -global-isel -stop-after=irtranslator file.ll -o -

> llc -march=xxx -global-isel -debug-only=instruction-select,xxx-gisel file.ll -o -
 

and it will produce valid target assembly.

Problem However, when I try to run this through the clang driver:

clang -fglobal-isel --target=xxx -S file.c

I get:

error: unable to interface with target machine

Debugging I am not sure how to resolve this. The error comes directly from BackendUtils.cpp, where my target does not seem to implement TargetMachine→addPassesToEmitFile(). And as expected, when I manually override this method, the error goes away, however the assembly file is empty (as no passes have been added). However, other backends do not seem to override this, as I believe the passes (IRTranslator, RegBankSelect, etc…) get called automatically.

One thing I have not done is implement xxx.cpp in clang/lib/CodeGen/Targets/. Am am not confident I understand the purpose of the logic in here. It seems to be defining the ABI and calling conventions. My issue is I think I have already done that in llvm/Target/XXX/XXXCallingConvention.td and llvm/Target/XXX/GlobalISel/XXXCallLowering.cpp

I am not sure if this is a relevant problem, nor if it is necessary for me to do. Is this truly duplicate logic or is it necessary information for both clang and llvm.

Conclusion I understand this is quite a specific question, and I have far-from included all the relevant details. I am happy to provide anything that would be helpful. Any assistance would be greatly appreciated, thank you.


Solution

  • Issue source has been identified as isGlobalISelAbortEnabled being set to disabled for some reason, even though it is initially and by default true. This leads to a fallback SelDAG setup attempt, which is where I (rightfully) crash. Manually enabling this when PassConfig is created resolves this. Still unclear as to why, but it works.