diff options
author | Renato Golin <renato.golin@linaro.org> | 2016-05-17 19:52:01 +0000 |
---|---|---|
committer | Renato Golin <renato.golin@linaro.org> | 2016-05-17 19:52:01 +0000 |
commit | 38ed8021c748bf8a928a30a97f497eccf0746369 (patch) | |
tree | b16095967140b7bdc7b393d329d0670ea5b67f29 | |
parent | 0a828aa0006e9c054c806d35b1719059c0711ae5 (diff) | |
download | bcm5719-llvm-38ed8021c748bf8a928a30a97f497eccf0746369.tar.gz bcm5719-llvm-38ed8021c748bf8a928a30a97f497eccf0746369.zip |
Fix an assert in SelectionDAGBuilder when processing inline asm
When processing inline asm that contains errors, make sure we can recover
gracefully by creating an UNDEF SDValue for the inline asm statement before
returning from SelectionDAGBuilder::visitInlineAsm. This is necessary for
consumers that don't exit on the first error that is emitted (e.g. clang)
and that would assert later on.
Fixes PR24071.
Patch by Diana Picus.
llvm-svn: 269811
11 files changed, 39 insertions, 34 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp index aa39c7874ac..105a930870f 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -6798,10 +6798,9 @@ void SelectionDAGBuilder::visitInlineAsm(ImmutableCallSite CS) { // Copy the output from the appropriate register. Find a register that // we can use. if (OpInfo.AssignedRegs.Regs.empty()) { - LLVMContext &Ctx = *DAG.getContext(); - Ctx.emitError(CS.getInstruction(), - "couldn't allocate output register for constraint '" + - Twine(OpInfo.ConstraintCode) + "'"); + emitInlineAsmError( + CS, "couldn't allocate output register for constraint '" + + Twine(OpInfo.ConstraintCode) + "'"); return; } @@ -6854,10 +6853,9 @@ void SelectionDAGBuilder::visitInlineAsm(ImmutableCallSite CS) { // Add (OpFlag&0xffff)>>3 registers to MatchedRegs. if (OpInfo.isIndirect) { // This happens on gcc/testsuite/gcc.dg/pr8788-1.c - LLVMContext &Ctx = *DAG.getContext(); - Ctx.emitError(CS.getInstruction(), "inline asm not supported yet:" - " don't know how to handle tied " - "indirect register inputs"); + emitInlineAsmError(CS, "inline asm not supported yet:" + " don't know how to handle tied " + "indirect register inputs"); return; } @@ -6871,10 +6869,9 @@ void SelectionDAGBuilder::visitInlineAsm(ImmutableCallSite CS) { if (const TargetRegisterClass *RC = TLI.getRegClassFor(RegVT)) MatchedRegs.Regs.push_back(RegInfo.createVirtualRegister(RC)); else { - LLVMContext &Ctx = *DAG.getContext(); - Ctx.emitError(CS.getInstruction(), - "inline asm error: This value" - " type register class is not natively supported!"); + emitInlineAsmError( + CS, "inline asm error: This value" + " type register class is not natively supported!"); return; } } @@ -6912,10 +6909,8 @@ void SelectionDAGBuilder::visitInlineAsm(ImmutableCallSite CS) { TLI.LowerAsmOperandForConstraint(InOperandVal, OpInfo.ConstraintCode, Ops, DAG); if (Ops.empty()) { - LLVMContext &Ctx = *DAG.getContext(); - Ctx.emitError(CS.getInstruction(), - "invalid operand for inline asm constraint '" + - Twine(OpInfo.ConstraintCode) + "'"); + emitInlineAsmError(CS, "invalid operand for inline asm constraint '" + + Twine(OpInfo.ConstraintCode) + "'"); return; } @@ -6955,20 +6950,17 @@ void SelectionDAGBuilder::visitInlineAsm(ImmutableCallSite CS) { // TODO: Support this. if (OpInfo.isIndirect) { - LLVMContext &Ctx = *DAG.getContext(); - Ctx.emitError(CS.getInstruction(), - "Don't know how to handle indirect register inputs yet " - "for constraint '" + - Twine(OpInfo.ConstraintCode) + "'"); + emitInlineAsmError( + CS, "Don't know how to handle indirect register inputs yet " + "for constraint '" + + Twine(OpInfo.ConstraintCode) + "'"); return; } // Copy the input into the appropriate registers. if (OpInfo.AssignedRegs.Regs.empty()) { - LLVMContext &Ctx = *DAG.getContext(); - Ctx.emitError(CS.getInstruction(), - "couldn't allocate input reg for constraint '" + - Twine(OpInfo.ConstraintCode) + "'"); + emitInlineAsmError(CS, "couldn't allocate input reg for constraint '" + + Twine(OpInfo.ConstraintCode) + "'"); return; } @@ -7066,6 +7058,17 @@ void SelectionDAGBuilder::visitInlineAsm(ImmutableCallSite CS) { DAG.setRoot(Chain); } +void SelectionDAGBuilder::emitInlineAsmError(ImmutableCallSite CS, + const Twine &Message) { + LLVMContext &Ctx = *DAG.getContext(); + Ctx.emitError(CS.getInstruction(), Message); + + // Make sure we leave the DAG in a valid state + const TargetLowering &TLI = DAG.getTargetLoweringInfo(); + auto VT = TLI.getValueType(DAG.getDataLayout(), CS.getType()); + setValue(CS.getInstruction(), DAG.getUNDEF(VT)); +} + void SelectionDAGBuilder::visitVAStart(const CallInst &I) { DAG.setRoot(DAG.getNode(ISD::VASTART, getCurSDLoc(), MVT::Other, getRoot(), diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h index 0f8d8a567ff..4905b8b7d1f 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h @@ -910,6 +910,8 @@ private: void HandlePHINodesInSuccessorBlocks(const BasicBlock *LLVMBB); + void emitInlineAsmError(ImmutableCallSite CS, const Twine &Message); + /// EmitFuncArgumentDbgValue - If V is an function argument then create /// corresponding DBG_VALUE machine instruction for it now. At the end of /// instruction selection, they will be inserted to the entry BB. diff --git a/llvm/test/CodeGen/AArch64/arm64-inline-asm-error-I.ll b/llvm/test/CodeGen/AArch64/arm64-inline-asm-error-I.ll index ec4934a29fe..a7aaf9e55d1 100644 --- a/llvm/test/CodeGen/AArch64/arm64-inline-asm-error-I.ll +++ b/llvm/test/CodeGen/AArch64/arm64-inline-asm-error-I.ll @@ -1,4 +1,4 @@ -; RUN: not llc -march=arm64 -exit-on-error < %s 2> %t +; RUN: not llc -march=arm64 < %s 2> %t ; RUN: FileCheck --check-prefix=CHECK-ERRORS < %t %s ; Check for at least one invalid constant. diff --git a/llvm/test/CodeGen/AArch64/arm64-inline-asm-error-J.ll b/llvm/test/CodeGen/AArch64/arm64-inline-asm-error-J.ll index a155c144b3a..077e1b80d93 100644 --- a/llvm/test/CodeGen/AArch64/arm64-inline-asm-error-J.ll +++ b/llvm/test/CodeGen/AArch64/arm64-inline-asm-error-J.ll @@ -1,4 +1,4 @@ -; RUN: not llc -march=arm64 -exit-on-error < %s 2> %t +; RUN: not llc -march=arm64 < %s 2> %t ; RUN: FileCheck --check-prefix=CHECK-ERRORS < %t %s ; Check for at least one invalid constant. diff --git a/llvm/test/CodeGen/AArch64/arm64-inline-asm-error-K.ll b/llvm/test/CodeGen/AArch64/arm64-inline-asm-error-K.ll index 99b88b88c34..2a7f9619de5 100644 --- a/llvm/test/CodeGen/AArch64/arm64-inline-asm-error-K.ll +++ b/llvm/test/CodeGen/AArch64/arm64-inline-asm-error-K.ll @@ -1,4 +1,4 @@ -; RUN: not llc -march=arm64 -exit-on-error < %s 2> %t +; RUN: not llc -march=arm64 < %s 2> %t ; RUN: FileCheck --check-prefix=CHECK-ERRORS < %t %s ; Check for at least one invalid constant. diff --git a/llvm/test/CodeGen/AArch64/arm64-inline-asm-error-L.ll b/llvm/test/CodeGen/AArch64/arm64-inline-asm-error-L.ll index b8afc9bf1d7..17019434195 100644 --- a/llvm/test/CodeGen/AArch64/arm64-inline-asm-error-L.ll +++ b/llvm/test/CodeGen/AArch64/arm64-inline-asm-error-L.ll @@ -1,4 +1,4 @@ -; RUN: not llc -march=arm64 -exit-on-error < %s 2> %t +; RUN: not llc -march=arm64 < %s 2> %t ; RUN: FileCheck --check-prefix=CHECK-ERRORS < %t %s ; Check for at least one invalid constant. diff --git a/llvm/test/CodeGen/AArch64/arm64-inline-asm-error-M.ll b/llvm/test/CodeGen/AArch64/arm64-inline-asm-error-M.ll index 75867504541..952bf6042c2 100644 --- a/llvm/test/CodeGen/AArch64/arm64-inline-asm-error-M.ll +++ b/llvm/test/CodeGen/AArch64/arm64-inline-asm-error-M.ll @@ -1,4 +1,4 @@ -; RUN: not llc -march=arm64 -exit-on-error < %s 2> %t +; RUN: not llc -march=arm64 < %s 2> %t ; RUN: FileCheck --check-prefix=CHECK-ERRORS < %t %s ; Check for at least one invalid constant. diff --git a/llvm/test/CodeGen/AArch64/arm64-inline-asm-error-N.ll b/llvm/test/CodeGen/AArch64/arm64-inline-asm-error-N.ll index 32c7d32a8ef..b4a199f160a 100644 --- a/llvm/test/CodeGen/AArch64/arm64-inline-asm-error-N.ll +++ b/llvm/test/CodeGen/AArch64/arm64-inline-asm-error-N.ll @@ -1,4 +1,4 @@ -; RUN: not llc -march=arm64 -exit-on-error < %s 2> %t +; RUN: not llc -march=arm64 < %s 2> %t ; RUN: FileCheck --check-prefix=CHECK-ERRORS < %t %s ; Check for at least one invalid constant. diff --git a/llvm/test/CodeGen/PowerPC/crbit-asm-disabled.ll b/llvm/test/CodeGen/PowerPC/crbit-asm-disabled.ll index e05b09f8c64..56ec8ecb85d 100644 --- a/llvm/test/CodeGen/PowerPC/crbit-asm-disabled.ll +++ b/llvm/test/CodeGen/PowerPC/crbit-asm-disabled.ll @@ -1,4 +1,4 @@ -; RUN: not llc -mcpu=pwr7 -exit-on-error -o /dev/null %s 2>&1 | FileCheck %s +; RUN: not llc -mcpu=pwr7 -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/llvm/test/CodeGen/PowerPC/vec-asm-disabled.ll b/llvm/test/CodeGen/PowerPC/vec-asm-disabled.ll index 6e4176ef3cd..333ccce6b89 100644 --- a/llvm/test/CodeGen/PowerPC/vec-asm-disabled.ll +++ b/llvm/test/CodeGen/PowerPC/vec-asm-disabled.ll @@ -1,4 +1,4 @@ -; RUN: not llc -mcpu=pwr7 -exit-on-error -o /dev/null %s 2>&1 | FileCheck %s +; RUN: not llc -mcpu=pwr7 -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/llvm/test/CodeGen/X86/asm-reject-reg-type-mismatch.ll b/llvm/test/CodeGen/X86/asm-reject-reg-type-mismatch.ll index 77f8ac4f717..c7e86f565ee 100644 --- a/llvm/test/CodeGen/X86/asm-reject-reg-type-mismatch.ll +++ b/llvm/test/CodeGen/X86/asm-reject-reg-type-mismatch.ll @@ -1,4 +1,4 @@ -; RUN: not llc -exit-on-error -o /dev/null %s 2>&1 | FileCheck %s +; RUN: not llc -o /dev/null %s 2>&1 | FileCheck %s target triple = "x86_64--" ; CHECK: error: couldn't allocate output register for constraint '{ax}' |