From a2f80471345960c971825a053d22ec886a2ab514 Mon Sep 17 00:00:00 2001 From: Evan Cheng Date: Wed, 14 Oct 2009 23:39:27 +0000 Subject: [PATCH] When LiveVariables is adding implicit-def to model "partial dead", add the earlyclobber marker if the superreg def has it. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@84153 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/LiveVariables.cpp | 13 ++++++++++++- test/CodeGen/X86/2009-10-14-LiveVariablesBug.ll | 15 +++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) create mode 100644 test/CodeGen/X86/2009-10-14-LiveVariablesBug.ll diff --git a/lib/CodeGen/LiveVariables.cpp b/lib/CodeGen/LiveVariables.cpp index 139e0291ea7..96c655c1a9b 100644 --- a/lib/CodeGen/LiveVariables.cpp +++ b/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/test/CodeGen/X86/2009-10-14-LiveVariablesBug.ll b/test/CodeGen/X86/2009-10-14-LiveVariablesBug.ll new file mode 100644 index 00000000000..c1aa17ce870 --- /dev/null +++ b/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 ; [#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 ; [#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 ; [#uses=0] + ret void +}