Index: llvm/lib/Target/X86/X86ISelLowering.h =================================================================== --- llvm/lib/Target/X86/X86ISelLowering.h +++ 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; Index: llvm/lib/Target/X86/X86ISelLowering.cpp =================================================================== --- llvm/lib/Target/X86/X86ISelLowering.cpp +++ 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, Index: llvm/test/CodeGen/X86/GlobalISel/x86_64-fallback.ll =================================================================== --- llvm/test/CodeGen/X86/GlobalISel/x86_64-fallback.ll +++ 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 +}