diff --git a/llvm/lib/CodeGen/RegAllocFast.cpp b/llvm/lib/CodeGen/RegAllocFast.cpp --- a/llvm/lib/CodeGen/RegAllocFast.cpp +++ b/llvm/lib/CodeGen/RegAllocFast.cpp @@ -1237,6 +1237,18 @@ Register Reg = MO.getReg(); if (!Reg) continue; + // Do not free later early-clobbered registers when MI is MSVCInlineAsm + if (MI.isMSInlineAsm()) { + unsigned J = 0; + for (J = I+1; J != MI.getNumOperands(); ++J) { + MachineOperand &LaterMO = MI.getOperand(J); + if (LaterMO.isReg() && LaterMO.getReg() == Reg && + MI.getOperand(J).isEarlyClobber()) + break; + } + if (J != MI.getNumOperands()) + continue; + } assert(Reg.isPhysical()); if (MRI->isReserved(Reg)) continue; diff --git a/llvm/test/CodeGen/X86/phys-msInline-fastregalloc.ll b/llvm/test/CodeGen/X86/phys-msInline-fastregalloc.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/X86/phys-msInline-fastregalloc.ll @@ -0,0 +1,15 @@ +; RUN: llc < %s -O0 -mtriple=i386-unknown-linux-gnu -mcpu=generic -regalloc=fast -optimize-regalloc=0 -no-x86-call-frame-opt | FileCheck %s + +define dso_local i32 @main() { +entry: +; CHECK: movl $1, %eax +; CHECK-NOT: movl %eax, (%eax) + %retval = alloca i32, align 4 + %c = alloca { [4 x i32] }, align 4 + store i32 0, i32* %retval, align 4 + %m32 = bitcast { [4 x i32] }* %c to [4 x i32]* + %0 = call i32 asm sideeffect inteldialect "mov eax,$$1\0A\09mov $0,eax", "=*m,={eax},~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %m32) #1, !srcloc !3 + store i32 %0, i32* %retval, align 4 + ret i32 0 +} +!3 = !{i32 285} \ No newline at end of file