diff --git a/llvm/lib/CodeGen/LiveVariables.cpp b/llvm/lib/CodeGen/LiveVariables.cpp --- a/llvm/lib/CodeGen/LiveVariables.cpp +++ b/llvm/lib/CodeGen/LiveVariables.cpp @@ -610,6 +610,15 @@ } } + // INLINEASM_BR's define physical registers are live, though we don't see + // their uses in the split copy block. + for (const MachineInstr &MI : MBB->terminators()) + if (MI.getOpcode() == TargetOpcode::INLINEASM_BR) + for (const MachineOperand &MO : MI.operands()) + if (MO.isReg() && Register::isPhysicalRegister(MO.getReg()) && + MO.isDef() && !MO.isDead() && !MO.isEarlyClobber()) + LiveOuts.insert(MO.getReg()); + // Loop over PhysRegDef / PhysRegUse, killing any registers that are // available at the end of the basic block. for (unsigned i = 0; i != NumRegs; ++i) 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,5 +1,6 @@ ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ; RUN: llc -mtriple=i686-- -verify-machineinstrs < %s | FileCheck %s +; RUN: llc -mtriple=i686-- -print-after=livevars -stop-after=livevars < %s 2>&1 | FileCheck --check-prefix=LIVE-CHECK %s ; A test for asm-goto output @@ -81,10 +82,17 @@ %0 = callbr { i32, i32 } asm sideeffect "testl $0, $0; testl $1, $2; jne ${3:l}", "={si},={di},r,X,X,0,1,~{dirflag},~{fpsr},~{flags}"(i32 %out1, i8* blockaddress(@test2, %label_true), i8* blockaddress(@test2, %return), i32 %out1, i32 %out2) to label %if.end [label %label_true, label %return] +; Test that these physical registers are not `implicit-def dead`, i.e. both +; defined by this instruction, and yet dead/no users. + +; LIVE-CHECK: INLINEASM_BR{{.*}}implicit-def $esi,{{.*}}implicit-def $edi, + if.else: ; preds = %entry %1 = callbr { i32, i32 } asm sideeffect "testl $0, $1; testl $2, $3; jne ${5:l}", "={si},={di},r,r,X,X,0,1,~{dirflag},~{fpsr},~{flags}"(i32 %out1, i32 %out2, i8* blockaddress(@test2, %label_true), i8* blockaddress(@test2, %return), i32 %out1, i32 %out2) to label %if.end [label %label_true, label %return] +; LIVE-CHECK: INLINEASM_BR{{.*}}implicit-def $esi,{{.*}}implicit-def $edi, + if.end: ; preds = %if.else, %if.then %.sink11 = phi { i32, i32 } [ %0, %if.then ], [ %1, %if.else ] %asmresult3 = extractvalue { i32, i32 } %.sink11, 0