diff --git a/include/llvm/CodeGen/SelectionDAGISel.h b/include/llvm/CodeGen/SelectionDAGISel.h index c204ce2be06..03b3f9f2d02 100644 --- a/include/llvm/CodeGen/SelectionDAGISel.h +++ b/include/llvm/CodeGen/SelectionDAGISel.h @@ -53,6 +53,7 @@ public: CodeGenOpt::Level OptLevel; const TargetInstrInfo *TII; const TargetLowering *TLI; + bool FastISelFailed; static char ID; diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp index 989c33e0fcb..5525e869786 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -51,6 +51,7 @@ #include "llvm/IR/Constants.h" #include "llvm/IR/DebugInfoMetadata.h" #include "llvm/IR/DebugLoc.h" +#include "llvm/IR/DiagnosticInfo.h" #include "llvm/IR/Function.h" #include "llvm/IR/InlineAsm.h" #include "llvm/IR/InstrTypes.h" @@ -209,6 +210,11 @@ static cl::opt EnableFastISelAbort( "abort for argument lowering, and 3 will never fallback " "to SelectionDAG.")); +static cl::opt EnableFastISelFallbackReport( + "fast-isel-report-on-fallback", cl::Hidden, + cl::desc("Emit a diagnostic when \"fast\" instruction selection " + "falls back to SelectionDAG.")); + static cl::opt UseMBPI("use-mbpi", cl::desc("use Machine Branch Probability Info"), @@ -534,6 +540,10 @@ bool SelectionDAGISel::runOnMachineFunction(MachineFunction &mf) { TLI->initializeSplitCSR(EntryMBB); SelectAllBasicBlocks(Fn); + if (FastISelFailed && EnableFastISelFallbackReport) { + DiagnosticInfoISelFallback DiagFallback(Fn); + Fn.getContext().diagnose(DiagFallback); + } // If the first basic block in the function has live ins that need to be // copied into vregs, emit the copies into the top of the block before @@ -1445,6 +1455,7 @@ static void propagateSwiftErrorVRegs(FunctionLoweringInfo *FuncInfo) { } void SelectionDAGISel::SelectAllBasicBlocks(const Function &Fn) { + FastISelFailed = false; // Initialize the Fast-ISel state, if needed. FastISel *FastIS = nullptr; if (TM.Options.EnableFastISel) @@ -1469,6 +1480,7 @@ void SelectionDAGISel::SelectAllBasicBlocks(const Function &Fn) { // See if fast isel can lower the arguments. FastIS->startNewBlock(); if (!FastIS->lowerArguments()) { + FastISelFailed = true; // Fast isel failed to lower these arguments ++NumFastIselFailLowerArguments; if (EnableFastISelAbort > 1) @@ -1557,6 +1569,7 @@ void SelectionDAGISel::SelectAllBasicBlocks(const Function &Fn) { // Try to select the instruction with FastISel. if (FastIS->selectInstruction(Inst)) { + FastISelFailed = true; --NumFastIselRemaining; ++NumFastIselSuccess; // If fast isel succeeded, skip over all the folded instructions, and diff --git a/test/CodeGen/X86/fast-isel-abort-warm.ll b/test/CodeGen/X86/fast-isel-abort-warm.ll new file mode 100644 index 00000000000..3caa91b11ec --- /dev/null +++ b/test/CodeGen/X86/fast-isel-abort-warm.ll @@ -0,0 +1,14 @@ +; RUN: llc -fast-isel -o - %s -fast-isel-report-on-fallback 2>&1 | FileCheck %s +; Make sure FastISel report a warming when we asked it to do so. +; Note: This test needs to use whatever is not supported by FastISel. +; Thus, this test may fail because inline asm gets supported in FastISel. +; To fix this, use something else that's not supported (e.g., weird types). +target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-apple-macosx" + +; CHECK: warning: Instruction selection used fallback path for foo +define void @foo(){ +entry: + call void asm sideeffect "nop", "~{dirflag},~{fpsr},~{flags}"() + ret void +}