diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp --- a/llvm/lib/AsmParser/LLParser.cpp +++ b/llvm/lib/AsmParser/LLParser.cpp @@ -6416,9 +6416,6 @@ /*IsCall=*/true)) return true; - if (isa(Callee) && !Ty->getReturnType()->isVoidTy()) - return Error(RetTypeLoc, "asm-goto outputs not supported"); - // Set up the Attribute for the function. SmallVector Args; SmallVector ArgAttrs; diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -2834,6 +2834,7 @@ assert(isa(I.getCalledValue()) && "Only know how to handle inlineasm callbr"); visitInlineAsm(&I); + CopyToExportRegsIfNeeded(&I); // Retrieve successors. MachineBasicBlock *Return = FuncInfo.MBBMap[I.getDefaultDest()]; diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp --- a/llvm/lib/IR/Verifier.cpp +++ b/llvm/lib/IR/Verifier.cpp @@ -2492,8 +2492,6 @@ void Verifier::visitCallBrInst(CallBrInst &CBI) { Assert(CBI.isInlineAsm(), "Callbr is currently only used for asm-goto!", &CBI); - Assert(CBI.getType()->isVoidTy(), "Callbr return value is not supported!", - &CBI); for (unsigned i = 0, e = CBI.getNumSuccessors(); i != e; ++i) Assert(CBI.getSuccessor(i)->getType()->isLabelTy(), "Callbr successors must all have pointer type!", &CBI); diff --git a/llvm/test/CodeGen/X86/callbr-asm-outputs.ll b/llvm/test/CodeGen/X86/callbr-asm-outputs.ll --- a/llvm/test/CodeGen/X86/callbr-asm-outputs.ll +++ b/llvm/test/CodeGen/X86/callbr-asm-outputs.ll @@ -1,18 +1,26 @@ -; RUN: not llc -mtriple=i686-- < %s 2> %t -; RUN: FileCheck %s < %t +; RUN: llc -mtriple=i686-- < %s | FileCheck %s -; CHECK: error: asm-goto outputs not supported +; A test for asm-goto output -; A test for asm-goto output prohibition - -define i32 @test(i32 %a) { +; CHECK-LABEL: test1: +; CHECK: movl 4(%esp), %eax +; CHECK-NEXT: addl $4, %eax +; CHECK-NEXT: #APP +; CHECK-NEXT: xorl %eax, %eax +; CHECK-NEXT: jmp .Ltmp0 +; CHECK-NEXT: #NO_APP +; CHECK-NEXT: .LBB0_1: +; CHECK-NEXT: retl +; CHECK-NEXT: .Ltmp0: +define i32 @test1(i32 %x) { entry: - %0 = add i32 %a, 4 - %1 = callbr i32 asm "xorl $1, $1; jmp ${1:l}", "=&r,r,X,~{dirflag},~{fpsr},~{flags}"(i32 %0, i8* blockaddress(@test, %fail)) to label %normal [label %fail] + %add = add nsw i32 %x, 4 + %ret = callbr i32 asm "xorl $1, $0; jmp ${2:l}", "=r,r,X,~{dirflag},~{fpsr},~{flags}"(i32 %add, i8* blockaddress(@test1, %abnormal)) + to label %normal [label %abnormal] normal: - ret i32 %1 + ret i32 %ret -fail: +abnormal: ret i32 1 }