diff options
| -rw-r--r-- | llvm/lib/CodeGen/LiveVariables.cpp | 13 | ||||
| -rw-r--r-- | llvm/test/CodeGen/X86/2009-10-14-LiveVariablesBug.ll | 15 | 
2 files changed, 27 insertions, 1 deletions
diff --git a/llvm/lib/CodeGen/LiveVariables.cpp b/llvm/lib/CodeGen/LiveVariables.cpp index 139e0291ea7..96c655c1a9b 100644 --- a/llvm/lib/CodeGen/LiveVariables.cpp +++ b/llvm/lib/CodeGen/LiveVariables.cpp @@ -323,10 +323,21 @@ bool LiveVariables::HandlePhysRegKill(unsigned Reg, MachineInstr *MI) {        // The last partial def kills the register.        LastPartDef->addOperand(MachineOperand::CreateReg(Reg, false/*IsDef*/,                                                  true/*IsImp*/, true/*IsKill*/)); -    else +    else { +      MachineOperand *MO = +        LastRefOrPartRef->findRegisterDefOperand(Reg, false, TRI); +      bool NeedEC = MO->isEarlyClobber() && MO->getReg() != Reg;        // If the last reference is the last def, then it's not used at all.        // That is, unless we are currently processing the last reference itself.        LastRefOrPartRef->addRegisterDead(Reg, TRI, true); +      if (NeedEC) { +        // If we are adding a subreg def and the superreg def is marked early +        // clobber, add an early clobber marker to the subreg def. +        MO = LastRefOrPartRef->findRegisterDefOperand(Reg); +        if (MO) +          MO->setIsEarlyClobber(); +      } +    }    } else if (!PhysRegUse[Reg]) {      // Partial uses. Mark register def dead and add implicit def of      // sub-registers which are used. diff --git a/llvm/test/CodeGen/X86/2009-10-14-LiveVariablesBug.ll b/llvm/test/CodeGen/X86/2009-10-14-LiveVariablesBug.ll new file mode 100644 index 00000000000..c1aa17ce870 --- /dev/null +++ b/llvm/test/CodeGen/X86/2009-10-14-LiveVariablesBug.ll @@ -0,0 +1,15 @@ +; RUN: llc < %s -mtriple=i386-apple-darwin +; rdar://7299435 + +@i = internal global i32 0                        ; <i32*> [#uses=1] +@llvm.used = appending global [1 x i8*] [i8* bitcast (void (i16)* @foo to i8*)], section "llvm.metadata" ; <[1 x i8*]*> [#uses=0] + +define void @foo(i16 signext %source) nounwind ssp { +entry: +  %source_addr = alloca i16, align 2              ; <i16*> [#uses=2] +  store i16 %source, i16* %source_addr +  store i32 4, i32* @i, align 4 +  call void asm sideeffect "# top of block", "~{dirflag},~{fpsr},~{flags},~{edi},~{esi},~{edx},~{ecx},~{eax}"() nounwind +  %asmtmp = call i16 asm sideeffect "movw $1, $0", "=={ax},*m,~{dirflag},~{fpsr},~{flags},~{memory}"(i16* %source_addr) nounwind ; <i16> [#uses=0] +  ret void +}  | 

