diff --git a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp --- a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp +++ b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp @@ -2426,8 +2426,11 @@ if (isa(U)) return false; - if (CI.isInlineAsm()) - return translateInlineAsm(CI, MIRBuilder); + if (CI.isInlineAsm()) { + const Instruction& Instr = cast(CI); + auto& TLI = *MF->getSubtarget().getTargetLowering(); + return TLI.fallBackToDAGISel(Instr) ? false : translateInlineAsm(CI, MIRBuilder); + } diagnoseDontCall(CI); diff --git a/llvm/lib/Target/X86/X86ISelLowering.h b/llvm/lib/Target/X86/X86ISelLowering.h --- a/llvm/lib/Target/X86/X86ISelLowering.h +++ b/llvm/lib/Target/X86/X86ISelLowering.h @@ -1455,6 +1455,8 @@ return nullptr; // nothing to do, move along. } + bool fallBackToDAGISel(const Instruction& Inst) const override; + Register getRegisterByName(const char* RegName, LLT VT, const MachineFunction &MF) const override; diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -29397,6 +29397,12 @@ return FrameAddr; } +bool X86TargetLowering::fallBackToDAGISel(const Instruction& Inst) const { + auto* CI = dyn_cast(&Inst); + + return CI && CI->isInlineAsm(); +} + // FIXME? Maybe this could be a TableGen attribute on some registers and // this table could be generated automatically from RegInfo. Register X86TargetLowering::getRegisterByName(const char* RegName, LLT VT, diff --git a/llvm/test/CodeGen/X86/GlobalISel/x86_64-fallback.ll b/llvm/test/CodeGen/X86/GlobalISel/x86_64-fallback.ll --- a/llvm/test/CodeGen/X86/GlobalISel/x86_64-fallback.ll +++ b/llvm/test/CodeGen/X86/GlobalISel/x86_64-fallback.ll @@ -27,3 +27,12 @@ call void @ScaleObjectOverwrite_3(ptr %index, ptr byval(%struct.PointListStruct) %index) ret void } + +; Check that inline assembly lowering falls back to instruction selection. +; FALLBACK-WITH-REPORT-ERR: :0:0: unable to translate instruction: call: ' %2 = tail call i32 asm "and $$3, ${0:k}", "=r,0,~{dirflag},~{fpsr},~{flags}"(i32 %0)' (in function: inline_asm_func) +; FALLBACK-WITH-REPORT-ERR: warning: Instruction selection used fallback path for inline_asm_func +; FALLBACK-WITH-REPORT-OUT-LABEL: inline_asm_func: +define i32 @inline_asm_func(i32 %0) { + %2 = tail call i32 asm "and $$3, ${0:k}", "=r,0,~{dirflag},~{fpsr},~{flags}"(i32 %0) + ret i32 %2 +}