Skip to content

Commit

Permalink
Fix an assert in SelectionDAGBuilder when processing inline asm
Browse files Browse the repository at this point in the history
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.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@269811 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
rengolin committed May 17, 2016
1 parent 0865cea commit cd41a78
Show file tree
Hide file tree
Showing 11 changed files with 39 additions and 34 deletions.
53 changes: 28 additions & 25 deletions lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down Expand Up @@ -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;
}

Expand All @@ -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;
}
}
Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -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(),
Expand Down
2 changes: 2 additions & 0 deletions lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -910,6 +910,8 @@ class SelectionDAGBuilder {

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.
Expand Down
2 changes: 1 addition & 1 deletion test/CodeGen/AArch64/arm64-inline-asm-error-I.ll
Original file line number Diff line number Diff line change
@@ -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.
Expand Down
2 changes: 1 addition & 1 deletion test/CodeGen/AArch64/arm64-inline-asm-error-J.ll
Original file line number Diff line number Diff line change
@@ -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.
Expand Down
2 changes: 1 addition & 1 deletion test/CodeGen/AArch64/arm64-inline-asm-error-K.ll
Original file line number Diff line number Diff line change
@@ -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.
Expand Down
2 changes: 1 addition & 1 deletion test/CodeGen/AArch64/arm64-inline-asm-error-L.ll
Original file line number Diff line number Diff line change
@@ -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.
Expand Down
2 changes: 1 addition & 1 deletion test/CodeGen/AArch64/arm64-inline-asm-error-M.ll
Original file line number Diff line number Diff line change
@@ -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.
Expand Down
2 changes: 1 addition & 1 deletion test/CodeGen/AArch64/arm64-inline-asm-error-N.ll
Original file line number Diff line number Diff line change
@@ -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.
Expand Down
2 changes: 1 addition & 1 deletion test/CodeGen/PowerPC/crbit-asm-disabled.ll
Original file line number Diff line number Diff line change
@@ -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"

Expand Down
2 changes: 1 addition & 1 deletion test/CodeGen/PowerPC/vec-asm-disabled.ll
Original file line number Diff line number Diff line change
@@ -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"

Expand Down
2 changes: 1 addition & 1 deletion test/CodeGen/X86/asm-reject-reg-type-mismatch.ll
Original file line number Diff line number Diff line change
@@ -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}'
Expand Down

0 comments on commit cd41a78

Please sign in to comment.