From 3013a2068421335304dce861dd5977e8cf43cbca Mon Sep 17 00:00:00 2001 From: Jakob Stoklund Olesen Date: Wed, 9 Jun 2010 20:05:00 +0000 Subject: [PATCH] Mark physregs defined by inline asm as implicit. This is a bit of a hack to make inline asm look more like call instructions. It would be better to produce correct dead flags during isel. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@105749 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/SelectionDAG/InstrEmitter.cpp | 8 ++++++-- .../X86/2010-06-09-FastAllocRegisters.ll | 17 +++++++++++++++++ 2 files changed, 23 insertions(+), 2 deletions(-) create mode 100644 test/CodeGen/X86/2010-06-09-FastAllocRegisters.ll diff --git a/lib/CodeGen/SelectionDAG/InstrEmitter.cpp b/lib/CodeGen/SelectionDAG/InstrEmitter.cpp index 1febdb511ca..1c53dbd1b2b 100644 --- a/lib/CodeGen/SelectionDAG/InstrEmitter.cpp +++ b/lib/CodeGen/SelectionDAG/InstrEmitter.cpp @@ -821,14 +821,18 @@ EmitSpecialNode(SDNode *Node, bool IsClone, bool IsCloned, case InlineAsm::Kind_RegDef: for (; NumVals; --NumVals, ++i) { unsigned Reg = cast(Node->getOperand(i))->getReg(); - MI->addOperand(MachineOperand::CreateReg(Reg, true)); + // FIXME: Add dead flags for physical and virtual registers defined. + // For now, mark physical register defs as implicit to help fast + // regalloc. This makes inline asm look a lot like calls. + MI->addOperand(MachineOperand::CreateReg(Reg, true, + /*isImp=*/ TargetRegisterInfo::isPhysicalRegister(Reg))); } break; case InlineAsm::Kind_RegDefEarlyClobber: for (; NumVals; --NumVals, ++i) { unsigned Reg = cast(Node->getOperand(i))->getReg(); MI->addOperand(MachineOperand::CreateReg(Reg, /*isDef=*/ true, - /*isImp=*/ false, + /*isImp=*/ TargetRegisterInfo::isPhysicalRegister(Reg), /*isKill=*/ false, /*isDead=*/ false, /*isUndef=*/false, diff --git a/test/CodeGen/X86/2010-06-09-FastAllocRegisters.ll b/test/CodeGen/X86/2010-06-09-FastAllocRegisters.ll new file mode 100644 index 00000000000..7c7792ac65a --- /dev/null +++ b/test/CodeGen/X86/2010-06-09-FastAllocRegisters.ll @@ -0,0 +1,17 @@ +; RUN: llc < %s -O0 -disable-fp-elim -relocation-model=pic +; PR7313 +; +; The inline asm in this function clobbers almost all allocatable registers. +; Make sure that the register allocator recovers. +; +target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" +target triple = "x86_64-unknown-linux-gnu" + +declare void @snapshot() + +define void @test_too_many_longs() nounwind { +entry: + call void asm sideeffect "xor %rax, %rax\0A\09xor %rbx, %rbx\0A\09xor %rcx, %rcx\0A\09xor %rdx, %rdx\0A\09xor %rsi, %rsi\0A\09xor %rdi, %rdi\0A\09xor %r8, %r8\0A\09xor %r9, %r9\0A\09xor %r10, %r10\0A\09xor %r11, %r11\0A\09xor %r12, %r12\0A\09xor %r13, %r13\0A\09xor %r14, %r14\0A\09xor %r15, %r15\0A\09", "~{fpsr},~{flags},~{r15},~{r14},~{r13},~{r12},~{r11},~{r10},~{r9},~{r8},~{rdi},~{rsi},~{rdx},~{rcx},~{rbx},~{rax}"() nounwind + call void bitcast (void ()* @snapshot to void (i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64)*)(i64 32, i64 33, i64 34, i64 35, i64 36, i64 37, i64 38, i64 39, i64 40, i64 41, i64 42, i64 43) nounwind + ret void +}