diff --git a/include/llvm/IR/DiagnosticInfo.h b/include/llvm/IR/DiagnosticInfo.h index 78d7de27b43..9e5bb2b8a3a 100644 --- a/include/llvm/IR/DiagnosticInfo.h +++ b/include/llvm/IR/DiagnosticInfo.h @@ -34,7 +34,7 @@ class Module; class SMDiagnostic; /// \brief Defines the different supported severity of a diagnostic. -enum DiagnosticSeverity { +enum DiagnosticSeverity : char { DS_Error, DS_Warning, DS_Remark, diff --git a/include/llvm/IR/LLVMContext.h b/include/llvm/IR/LLVMContext.h index 8f13171f962..c1999184722 100644 --- a/include/llvm/IR/LLVMContext.h +++ b/include/llvm/IR/LLVMContext.h @@ -29,6 +29,7 @@ class MDString; class DICompositeType; class SMDiagnostic; class DiagnosticInfo; +enum DiagnosticSeverity : char; template class SmallVectorImpl; class Function; class DebugLoc; @@ -172,6 +173,10 @@ public: /// setDiagnosticContext. void *getDiagnosticContext() const; + /// \brief Get the prefix that should be printed in front of a diagnostic of + /// the given \p Severity + static const char *getDiagnosticMessagePrefix(DiagnosticSeverity Severity); + /// \brief Report a message to the currently installed diagnostic handler. /// /// This function returns, in particular in the case of error reporting diff --git a/lib/IR/LLVMContext.cpp b/lib/IR/LLVMContext.cpp index 9369cbd6a08..9f8680cf6c0 100644 --- a/lib/IR/LLVMContext.cpp +++ b/lib/IR/LLVMContext.cpp @@ -231,7 +231,8 @@ static bool isDiagnosticEnabled(const DiagnosticInfo &DI) { return true; } -static const char *getDiagnosticMessagePrefix(DiagnosticSeverity Severity) { +const char * +LLVMContext::getDiagnosticMessagePrefix(DiagnosticSeverity Severity) { switch (Severity) { case DS_Error: return "error"; diff --git a/test/CodeGen/AArch64/arm64-inline-asm-error-I.ll b/test/CodeGen/AArch64/arm64-inline-asm-error-I.ll index a7aaf9e55d1..ec4934a29fe 100644 --- a/test/CodeGen/AArch64/arm64-inline-asm-error-I.ll +++ b/test/CodeGen/AArch64/arm64-inline-asm-error-I.ll @@ -1,4 +1,4 @@ -; RUN: not llc -march=arm64 < %s 2> %t +; RUN: not llc -march=arm64 -exit-on-error < %s 2> %t ; RUN: FileCheck --check-prefix=CHECK-ERRORS < %t %s ; Check for at least one invalid constant. diff --git a/test/CodeGen/AArch64/arm64-inline-asm-error-J.ll b/test/CodeGen/AArch64/arm64-inline-asm-error-J.ll index 077e1b80d93..a155c144b3a 100644 --- a/test/CodeGen/AArch64/arm64-inline-asm-error-J.ll +++ b/test/CodeGen/AArch64/arm64-inline-asm-error-J.ll @@ -1,4 +1,4 @@ -; RUN: not llc -march=arm64 < %s 2> %t +; RUN: not llc -march=arm64 -exit-on-error < %s 2> %t ; RUN: FileCheck --check-prefix=CHECK-ERRORS < %t %s ; Check for at least one invalid constant. diff --git a/test/CodeGen/AArch64/arm64-inline-asm-error-K.ll b/test/CodeGen/AArch64/arm64-inline-asm-error-K.ll index 2a7f9619de5..99b88b88c34 100644 --- a/test/CodeGen/AArch64/arm64-inline-asm-error-K.ll +++ b/test/CodeGen/AArch64/arm64-inline-asm-error-K.ll @@ -1,4 +1,4 @@ -; RUN: not llc -march=arm64 < %s 2> %t +; RUN: not llc -march=arm64 -exit-on-error < %s 2> %t ; RUN: FileCheck --check-prefix=CHECK-ERRORS < %t %s ; Check for at least one invalid constant. diff --git a/test/CodeGen/AArch64/arm64-inline-asm-error-L.ll b/test/CodeGen/AArch64/arm64-inline-asm-error-L.ll index 17019434195..b8afc9bf1d7 100644 --- a/test/CodeGen/AArch64/arm64-inline-asm-error-L.ll +++ b/test/CodeGen/AArch64/arm64-inline-asm-error-L.ll @@ -1,4 +1,4 @@ -; RUN: not llc -march=arm64 < %s 2> %t +; RUN: not llc -march=arm64 -exit-on-error < %s 2> %t ; RUN: FileCheck --check-prefix=CHECK-ERRORS < %t %s ; Check for at least one invalid constant. diff --git a/test/CodeGen/AArch64/arm64-inline-asm-error-M.ll b/test/CodeGen/AArch64/arm64-inline-asm-error-M.ll index 952bf6042c2..75867504541 100644 --- a/test/CodeGen/AArch64/arm64-inline-asm-error-M.ll +++ b/test/CodeGen/AArch64/arm64-inline-asm-error-M.ll @@ -1,4 +1,4 @@ -; RUN: not llc -march=arm64 < %s 2> %t +; RUN: not llc -march=arm64 -exit-on-error < %s 2> %t ; RUN: FileCheck --check-prefix=CHECK-ERRORS < %t %s ; Check for at least one invalid constant. diff --git a/test/CodeGen/AArch64/arm64-inline-asm-error-N.ll b/test/CodeGen/AArch64/arm64-inline-asm-error-N.ll index b4a199f160a..32c7d32a8ef 100644 --- a/test/CodeGen/AArch64/arm64-inline-asm-error-N.ll +++ b/test/CodeGen/AArch64/arm64-inline-asm-error-N.ll @@ -1,4 +1,4 @@ -; RUN: not llc -march=arm64 < %s 2> %t +; RUN: not llc -march=arm64 -exit-on-error < %s 2> %t ; RUN: FileCheck --check-prefix=CHECK-ERRORS < %t %s ; Check for at least one invalid constant. diff --git a/test/CodeGen/AMDGPU/call.ll b/test/CodeGen/AMDGPU/call.ll index 82e77350ab2..168952ca0f1 100644 --- a/test/CodeGen/AMDGPU/call.ll +++ b/test/CodeGen/AMDGPU/call.ll @@ -1,6 +1,6 @@ -; RUN: not llc -march=amdgcn -mcpu=SI -verify-machineinstrs< %s 2>&1 | FileCheck %s -; RUN: not llc -march=amdgcn -mcpu=tonga -verify-machineinstrs< %s 2>&1 | FileCheck %s -; RUN: not llc -march=r600 -mcpu=cypress < %s 2>&1 | FileCheck %s +; RUN: not llc -march=amdgcn -mcpu=SI -verify-machineinstrs -exit-on-error < %s 2>&1 | FileCheck %s +; RUN: not llc -march=amdgcn -mcpu=tonga -verify-machineinstrs -exit-on-error < %s 2>&1 | FileCheck %s +; RUN: not llc -march=r600 -mcpu=cypress -exit-on-error < %s 2>&1 | FileCheck %s ; CHECK: in function test_call_external{{.*}}: unsupported call to function external_function diff --git a/test/CodeGen/AMDGPU/dynamic_stackalloc.ll b/test/CodeGen/AMDGPU/dynamic_stackalloc.ll index 580dc00f935..5d2305600fb 100644 --- a/test/CodeGen/AMDGPU/dynamic_stackalloc.ll +++ b/test/CodeGen/AMDGPU/dynamic_stackalloc.ll @@ -1,6 +1,6 @@ -; RUN: not llc -march=amdgcn -mcpu=tahiti -mattr=+promote-alloca -verify-machineinstrs < %s 2>&1 | FileCheck %s -; RUN: not llc -march=amdgcn -mcpu=tahiti -mattr=-promote-alloca -verify-machineinstrs < %s 2>&1 | FileCheck %s -; RUN: not llc -march=r600 -mcpu=cypress < %s 2>&1 | FileCheck %s +; RUN: not llc -march=amdgcn -mcpu=tahiti -mattr=+promote-alloca -verify-machineinstrs -exit-on-error < %s 2>&1 | FileCheck %s +; RUN: not llc -march=amdgcn -mcpu=tahiti -mattr=-promote-alloca -verify-machineinstrs -exit-on-error < %s 2>&1 | FileCheck %s +; RUN: not llc -march=r600 -mcpu=cypress -exit-on-error < %s 2>&1 | FileCheck %s ; CHECK: in function test_dynamic_stackalloc{{.*}}: unsupported dynamic alloca diff --git a/test/CodeGen/AMDGPU/no-hsa-graphics-shaders.ll b/test/CodeGen/AMDGPU/no-hsa-graphics-shaders.ll index 0a7cd57a38e..e6f51fad6a0 100644 --- a/test/CodeGen/AMDGPU/no-hsa-graphics-shaders.ll +++ b/test/CodeGen/AMDGPU/no-hsa-graphics-shaders.ll @@ -1,4 +1,4 @@ -; RUN: not llc -march=amdgcn -mtriple=amdgcn-unknown-amdhsa < %s 2>&1 | FileCheck %s +; RUN: not llc -march=amdgcn -mtriple=amdgcn-unknown-amdhsa -exit-on-error < %s 2>&1 | FileCheck %s ; CHECK: in function pixel_s{{.*}}: unsupported non-compute shaders with HSA define amdgpu_ps void @pixel_shader() #0 { diff --git a/test/CodeGen/AMDGPU/private-memory-broken.ll b/test/CodeGen/AMDGPU/private-memory-broken.ll index 6b18a19f195..17a54c70fcf 100644 --- a/test/CodeGen/AMDGPU/private-memory-broken.ll +++ b/test/CodeGen/AMDGPU/private-memory-broken.ll @@ -1,5 +1,5 @@ -; RUN: not llc -verify-machineinstrs -march=amdgcn -mcpu=SI %s -o /dev/null 2>&1 | FileCheck %s -; RUN: not llc -verify-machineinstrs -march=amdgcn -mcpu=tonga %s -o /dev/null 2>&1 | FileCheck %s +; RUN: not llc -verify-machineinstrs -march=amdgcn -mcpu=SI -exit-on-error %s -o /dev/null 2>&1 | FileCheck %s +; RUN: not llc -verify-machineinstrs -march=amdgcn -mcpu=tonga -exit-on-error %s -o /dev/null 2>&1 | FileCheck %s ; Make sure promote alloca pass doesn't crash diff --git a/test/CodeGen/AMDGPU/promote-alloca-bitcast-function.ll b/test/CodeGen/AMDGPU/promote-alloca-bitcast-function.ll index 609001733b7..095996d8e10 100644 --- a/test/CodeGen/AMDGPU/promote-alloca-bitcast-function.ll +++ b/test/CodeGen/AMDGPU/promote-alloca-bitcast-function.ll @@ -1,4 +1,4 @@ -; RUN: not llc -march=amdgcn < %s 2>&1 | FileCheck %s +; RUN: not llc -march=amdgcn -exit-on-error < %s 2>&1 | FileCheck %s ; Make sure that AMDGPUPromoteAlloca doesn't crash if the called ; function is a constantexpr cast of a function. diff --git a/test/CodeGen/ARM/2012-09-25-InlineAsmScalarToVectorConv2.ll b/test/CodeGen/ARM/2012-09-25-InlineAsmScalarToVectorConv2.ll index b47247c5454..170c09fc141 100644 --- a/test/CodeGen/ARM/2012-09-25-InlineAsmScalarToVectorConv2.ll +++ b/test/CodeGen/ARM/2012-09-25-InlineAsmScalarToVectorConv2.ll @@ -1,4 +1,4 @@ -; RUN: not llc -mtriple=arm-eabi -mcpu=cortex-a8 %s -o - 2>&1 | FileCheck %s +; RUN: not llc -mtriple=arm-eabi -mcpu=cortex-a8 -exit-on-error %s -o - 2>&1 | FileCheck %s ; Check for error message: ; CHECK: scalar-to-vector conversion failed, possible invalid constraint for vector type diff --git a/test/CodeGen/BPF/many_args1.ll b/test/CodeGen/BPF/many_args1.ll index 08218f452d0..a5500dad1ed 100644 --- a/test/CodeGen/BPF/many_args1.ll +++ b/test/CodeGen/BPF/many_args1.ll @@ -1,4 +1,4 @@ -; RUN: not llc -march=bpf < %s 2> %t1 +; RUN: not llc -march=bpf -exit-on-error < %s 2> %t1 ; RUN: FileCheck %s < %t1 ; CHECK: too many args diff --git a/test/CodeGen/BPF/many_args2.ll b/test/CodeGen/BPF/many_args2.ll index a69886c2b20..08a1179bc5e 100644 --- a/test/CodeGen/BPF/many_args2.ll +++ b/test/CodeGen/BPF/many_args2.ll @@ -1,4 +1,4 @@ -; RUN: not llc -march=bpf < %s 2> %t1 +; RUN: not llc -march=bpf -exit-on-error < %s 2> %t1 ; RUN: FileCheck %s < %t1 ; CHECK: too many args diff --git a/test/CodeGen/BPF/struct_ret1.ll b/test/CodeGen/BPF/struct_ret1.ll index 29486b56a27..c6d3f89b9a9 100644 --- a/test/CodeGen/BPF/struct_ret1.ll +++ b/test/CodeGen/BPF/struct_ret1.ll @@ -1,4 +1,4 @@ -; RUN: not llc -march=bpf < %s 2> %t1 +; RUN: not llc -march=bpf -exit-on-error < %s 2> %t1 ; RUN: FileCheck %s < %t1 ; CHECK: only integer returns diff --git a/test/CodeGen/BPF/struct_ret2.ll b/test/CodeGen/BPF/struct_ret2.ll index 90461205f7c..5266efed776 100644 --- a/test/CodeGen/BPF/struct_ret2.ll +++ b/test/CodeGen/BPF/struct_ret2.ll @@ -1,4 +1,4 @@ -; RUN: not llc -march=bpf < %s 2> %t1 +; RUN: not llc -march=bpf -exit-on-error < %s 2> %t1 ; RUN: FileCheck %s < %t1 ; CHECK: only small returns diff --git a/test/CodeGen/MIR/Generic/invalid-jump-table-kind.mir b/test/CodeGen/MIR/Generic/invalid-jump-table-kind.mir index 576de4bd9dc..04e5606e87f 100644 --- a/test/CodeGen/MIR/Generic/invalid-jump-table-kind.mir +++ b/test/CodeGen/MIR/Generic/invalid-jump-table-kind.mir @@ -1,4 +1,4 @@ -# RUN: not llc -start-after branch-folder -stop-after branch-folder -o /dev/null %s 2>&1 | FileCheck %s +# RUN: not llc -start-after branch-folder -stop-after branch-folder -exit-on-error -o /dev/null %s 2>&1 | FileCheck %s --- | diff --git a/test/CodeGen/MIR/Generic/llvm-ir-error-reported.mir b/test/CodeGen/MIR/Generic/llvm-ir-error-reported.mir index 3508c341c44..e404b26b687 100644 --- a/test/CodeGen/MIR/Generic/llvm-ir-error-reported.mir +++ b/test/CodeGen/MIR/Generic/llvm-ir-error-reported.mir @@ -1,4 +1,4 @@ -# RUN: not llc -start-after branch-folder -stop-after branch-folder -o /dev/null %s 2>&1 | FileCheck %s +# RUN: not llc -start-after branch-folder -stop-after branch-folder -exit-on-error -o /dev/null %s 2>&1 | FileCheck %s # This test ensures an error is reported if the embedded LLVM IR contains an # error. diff --git a/test/CodeGen/MIR/Generic/machine-function-missing-function.mir b/test/CodeGen/MIR/Generic/machine-function-missing-function.mir index 6800f872432..128a98720c2 100644 --- a/test/CodeGen/MIR/Generic/machine-function-missing-function.mir +++ b/test/CodeGen/MIR/Generic/machine-function-missing-function.mir @@ -1,4 +1,4 @@ -# RUN: not llc -start-after branch-folder -stop-after branch-folder -o /dev/null %s 2>&1 | FileCheck %s +# RUN: not llc -start-after branch-folder -stop-after branch-folder -exit-on-error -o /dev/null %s 2>&1 | FileCheck %s # This test ensures that an error is reported when the mir file has LLVM IR and # one of the machine functions has a name that doesn't match any function in # the LLVM IR. diff --git a/test/CodeGen/MIR/Generic/machine-function-missing-name.mir b/test/CodeGen/MIR/Generic/machine-function-missing-name.mir index f65b77880e9..150b923c424 100644 --- a/test/CodeGen/MIR/Generic/machine-function-missing-name.mir +++ b/test/CodeGen/MIR/Generic/machine-function-missing-name.mir @@ -1,4 +1,4 @@ -# RUN: not llc -start-after branch-folder -stop-after branch-folder -o /dev/null %s 2>&1 | FileCheck %s +# RUN: not llc -start-after branch-folder -stop-after branch-folder -exit-on-error -o /dev/null %s 2>&1 | FileCheck %s # This test ensures that an error is reported when a machine function doesn't # have a name attribute. diff --git a/test/CodeGen/MIR/Generic/machine-function-redefinition-error.mir b/test/CodeGen/MIR/Generic/machine-function-redefinition-error.mir index be84161b563..57f3834f29f 100644 --- a/test/CodeGen/MIR/Generic/machine-function-redefinition-error.mir +++ b/test/CodeGen/MIR/Generic/machine-function-redefinition-error.mir @@ -1,4 +1,4 @@ -# RUN: not llc -start-after branch-folder -stop-after branch-folder -o /dev/null %s 2>&1 | FileCheck %s +# RUN: not llc -start-after branch-folder -stop-after branch-folder -exit-on-error -o /dev/null %s 2>&1 | FileCheck %s # This test ensures that the machine function errors are reported correctly. --- diff --git a/test/CodeGen/MIR/X86/spill-slot-fixed-stack-object-aliased.mir b/test/CodeGen/MIR/X86/spill-slot-fixed-stack-object-aliased.mir index b62cd755fec..f0bb16d5183 100644 --- a/test/CodeGen/MIR/X86/spill-slot-fixed-stack-object-aliased.mir +++ b/test/CodeGen/MIR/X86/spill-slot-fixed-stack-object-aliased.mir @@ -1,4 +1,4 @@ -# RUN: not llc -march=x86-64 -start-after branch-folder -stop-after branch-folder -o /dev/null %s 2>&1 | FileCheck %s +# RUN: not llc -march=x86-64 -start-after branch-folder -stop-after branch-folder -exit-on-error -o /dev/null %s 2>&1 | FileCheck %s --- | diff --git a/test/CodeGen/MIR/X86/spill-slot-fixed-stack-object-immutable.mir b/test/CodeGen/MIR/X86/spill-slot-fixed-stack-object-immutable.mir index c89216bea67..b07a961d640 100644 --- a/test/CodeGen/MIR/X86/spill-slot-fixed-stack-object-immutable.mir +++ b/test/CodeGen/MIR/X86/spill-slot-fixed-stack-object-immutable.mir @@ -1,4 +1,4 @@ -# RUN: not llc -march=x86-64 -start-after branch-folder -stop-after branch-folder -o /dev/null %s 2>&1 | FileCheck %s +# RUN: not llc -march=x86-64 -start-after branch-folder -stop-after branch-folder -exit-on-error -o /dev/null %s 2>&1 | FileCheck %s --- | diff --git a/test/CodeGen/MIR/X86/variable-sized-stack-object-size-error.mir b/test/CodeGen/MIR/X86/variable-sized-stack-object-size-error.mir index e6a9ef8d4c8..d348cbeffed 100644 --- a/test/CodeGen/MIR/X86/variable-sized-stack-object-size-error.mir +++ b/test/CodeGen/MIR/X86/variable-sized-stack-object-size-error.mir @@ -1,4 +1,4 @@ -# RUN: not llc -march=x86-64 -start-after branch-folder -stop-after branch-folder -o /dev/null %s 2>&1 | FileCheck %s +# RUN: not llc -march=x86-64 -start-after branch-folder -stop-after branch-folder -exit-on-error -o /dev/null %s 2>&1 | FileCheck %s --- | define i32 @test(i32 %a) { diff --git a/test/CodeGen/PowerPC/crbit-asm-disabled.ll b/test/CodeGen/PowerPC/crbit-asm-disabled.ll index 56ec8ecb85d..e05b09f8c64 100644 --- a/test/CodeGen/PowerPC/crbit-asm-disabled.ll +++ b/test/CodeGen/PowerPC/crbit-asm-disabled.ll @@ -1,4 +1,4 @@ -; RUN: not llc -mcpu=pwr7 -o /dev/null %s 2>&1 | FileCheck %s +; RUN: not llc -mcpu=pwr7 -exit-on-error -o /dev/null %s 2>&1 | FileCheck %s target datalayout = "E-m:e-i64:64-n32:64" target triple = "powerpc64-unknown-linux-gnu" diff --git a/test/CodeGen/PowerPC/vec-asm-disabled.ll b/test/CodeGen/PowerPC/vec-asm-disabled.ll index 333ccce6b89..6e4176ef3cd 100644 --- a/test/CodeGen/PowerPC/vec-asm-disabled.ll +++ b/test/CodeGen/PowerPC/vec-asm-disabled.ll @@ -1,4 +1,4 @@ -; RUN: not llc -mcpu=pwr7 -o /dev/null %s 2>&1 | FileCheck %s +; RUN: not llc -mcpu=pwr7 -exit-on-error -o /dev/null %s 2>&1 | FileCheck %s target datalayout = "E-m:e-i64:64-n32:64" target triple = "powerpc64-unknown-linux-gnu" diff --git a/test/CodeGen/X86/asm-reject-reg-type-mismatch.ll b/test/CodeGen/X86/asm-reject-reg-type-mismatch.ll index c7e86f565ee..77f8ac4f717 100644 --- a/test/CodeGen/X86/asm-reject-reg-type-mismatch.ll +++ b/test/CodeGen/X86/asm-reject-reg-type-mismatch.ll @@ -1,4 +1,4 @@ -; RUN: not llc -o /dev/null %s 2>&1 | FileCheck %s +; RUN: not llc -exit-on-error -o /dev/null %s 2>&1 | FileCheck %s target triple = "x86_64--" ; CHECK: error: couldn't allocate output register for constraint '{ax}' diff --git a/tools/llc/llc.cpp b/tools/llc/llc.cpp index e219c948d26..00b20009244 100644 --- a/tools/llc/llc.cpp +++ b/tools/llc/llc.cpp @@ -25,6 +25,8 @@ #include "llvm/CodeGen/MachineModuleInfo.h" #include "llvm/CodeGen/TargetPassConfig.h" #include "llvm/IR/DataLayout.h" +#include "llvm/IR/DiagnosticInfo.h" +#include "llvm/IR/DiagnosticPrinter.h" #include "llvm/IR/IRPrintingPasses.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/LegacyPassManager.h" @@ -111,6 +113,11 @@ static cl::opt DiscardValueNames( cl::desc("Discard names from Value (other than GlobalValue)."), cl::init(false), cl::Hidden); +static cl::opt ExitOnError( + "exit-on-error", + cl::desc("Exit as soon as an error is encountered."), + cl::init(false), cl::Hidden); + static int compileModule(char **, LLVMContext &); static std::unique_ptr @@ -181,6 +188,17 @@ GetOutputStream(const char *TargetName, Triple::OSType OS, return FDOut; } +static void DiagnosticHandler(const DiagnosticInfo &DI, void *Context) { + bool *HasError = static_cast(Context); + if (DI.getSeverity() == DS_Error) + *HasError = true; + + DiagnosticPrinterRawOStream DP(errs()); + errs() << LLVMContext::getDiagnosticMessagePrefix(DI.getSeverity()) << ": "; + DI.print(DP); + errs() << "\n"; +} + // main - Entry point for the llc compiler. // int main(int argc, char **argv) { @@ -215,6 +233,11 @@ int main(int argc, char **argv) { Context.setDiscardValueNames(DiscardValueNames); + // Set a diagnostic handler that doesn't exit on the first error + bool HasError = false; + if (!ExitOnError) + Context.setDiagnosticHandler(DiagnosticHandler, &HasError); + // Compile the module TimeCompilations times to give better compile time // metrics. for (unsigned I = TimeCompilations; I; --I) @@ -441,6 +464,12 @@ static int compileModule(char **argv, LLVMContext &Context) { PM.run(*M); + if (!ExitOnError) { + auto HasError = *static_cast(Context.getDiagnosticContext()); + if (HasError) + return 1; + } + // Compare the two outputs and make sure they're the same if (CompileTwice) { if (Buffer.size() != CompileTwiceBuffer.size() ||