From 0e6b590b91fcf6d49d2c25196f5053ce285e17f5 Mon Sep 17 00:00:00 2001 From: Evan Cheng Date: Mon, 28 Sep 2009 05:28:43 +0000 Subject: [PATCH] Coalescer should not delete extract_subreg, insert_subreg, and subreg_to_reg of physical registers. This is especially critical for the later two since they start the live interval of a super-register. e.g. %DO = INSERT_SUBREG %D0, %S0, 1 If this instruction is eliminated, the register scavenger will not be happy as D0 is not defined previously. This fixes PR5055. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@82968 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/SimpleRegisterCoalescing.cpp | 19 ++++++++++++--- test/CodeGen/ARM/2009-09-27-CoalescerBug.ll | 24 +++++++++++++++++++ .../Blackfin/2009-08-15-LiveIn-SubReg.ll | 1 - test/CodeGen/X86/sink-hoist.ll | 2 +- 4 files changed, 41 insertions(+), 5 deletions(-) create mode 100644 test/CodeGen/ARM/2009-09-27-CoalescerBug.ll diff --git a/lib/CodeGen/SimpleRegisterCoalescing.cpp b/lib/CodeGen/SimpleRegisterCoalescing.cpp index b77e7b4c471..ac7089337f8 100644 --- a/lib/CodeGen/SimpleRegisterCoalescing.cpp +++ b/lib/CodeGen/SimpleRegisterCoalescing.cpp @@ -2692,21 +2692,34 @@ bool SimpleRegisterCoalescing::runOnMachineFunction(MachineFunction &fn) { unsigned SrcReg, DstReg, SrcSubIdx, DstSubIdx; if (JoinedCopies.count(MI)) { // Delete all coalesced copies. + bool DoDelete = true; if (!tii_->isMoveInstr(*MI, SrcReg, DstReg, SrcSubIdx, DstSubIdx)) { assert((MI->getOpcode() == TargetInstrInfo::EXTRACT_SUBREG || MI->getOpcode() == TargetInstrInfo::INSERT_SUBREG || MI->getOpcode() == TargetInstrInfo::SUBREG_TO_REG) && "Unrecognized copy instruction"); DstReg = MI->getOperand(0).getReg(); + if (TargetRegisterInfo::isPhysicalRegister(DstReg)) + // Do not delete extract_subreg, insert_subreg of physical + // registers unless the definition is dead. e.g. + // %DO = INSERT_SUBREG %D0, %S0, 1 + // or else the scavenger may complain. LowerSubregs will + // change this to an IMPLICIT_DEF later. + DoDelete = false; } if (MI->registerDefIsDead(DstReg)) { LiveInterval &li = li_->getInterval(DstReg); if (!ShortenDeadCopySrcLiveRange(li, MI)) ShortenDeadCopyLiveRange(li, MI); + DoDelete = true; + } + if (!DoDelete) + mii = next(mii); + else { + li_->RemoveMachineInstrFromMaps(MI); + mii = mbbi->erase(mii); + ++numPeep; } - li_->RemoveMachineInstrFromMaps(MI); - mii = mbbi->erase(mii); - ++numPeep; continue; } diff --git a/test/CodeGen/ARM/2009-09-27-CoalescerBug.ll b/test/CodeGen/ARM/2009-09-27-CoalescerBug.ll new file mode 100644 index 00000000000..ea2693ac2e4 --- /dev/null +++ b/test/CodeGen/ARM/2009-09-27-CoalescerBug.ll @@ -0,0 +1,24 @@ +; RUN: llc < %s -mtriple=armv7-eabi -mcpu=cortex-a8 +; PR5055 + +module asm ".globl\09__aeabi_f2lz" +module asm ".set\09__aeabi_f2lz, __fixsfdi" +module asm "" + +define arm_aapcs_vfpcc i64 @__fixsfdi(float %a) nounwind { +entry: + %0 = fcmp olt float %a, 0.000000e+00 ; [#uses=1] + br i1 %0, label %bb, label %bb1 + +bb: ; preds = %entry + %1 = fsub float -0.000000e+00, %a ; [#uses=1] + %2 = tail call arm_aapcs_vfpcc i64 @__fixunssfdi(float %1) nounwind ; [#uses=1] + %3 = sub i64 0, %2 ; [#uses=1] + ret i64 %3 + +bb1: ; preds = %entry + %4 = tail call arm_aapcs_vfpcc i64 @__fixunssfdi(float %a) nounwind ; [#uses=1] + ret i64 %4 +} + +declare arm_aapcs_vfpcc i64 @__fixunssfdi(float) diff --git a/test/CodeGen/Blackfin/2009-08-15-LiveIn-SubReg.ll b/test/CodeGen/Blackfin/2009-08-15-LiveIn-SubReg.ll index 412c66913b2..0b731dccd19 100644 --- a/test/CodeGen/Blackfin/2009-08-15-LiveIn-SubReg.ll +++ b/test/CodeGen/Blackfin/2009-08-15-LiveIn-SubReg.ll @@ -1,5 +1,4 @@ ; RUN: llc < %s -march=bfin -verify-machineinstrs -; XFAIL: * ; When joining live intervals of sub-registers, an MBB live-in list is not ; updated properly. The register scavenger asserts on an undefined register. diff --git a/test/CodeGen/X86/sink-hoist.ll b/test/CodeGen/X86/sink-hoist.ll index 24f2f94d7b2..66582ecd832 100644 --- a/test/CodeGen/X86/sink-hoist.ll +++ b/test/CodeGen/X86/sink-hoist.ll @@ -7,7 +7,7 @@ ; CHECK: foo: ; CHECK-NEXT: divsd -; CHECK-NEXT: testb $1, %dil +; CHECK: testb $1, %dil ; CHECK-NEXT: jne define double @foo(double %x, double %y, i1 %c) nounwind {