diff --git a/lib/CodeGen/MachineCSE.cpp b/lib/CodeGen/MachineCSE.cpp index 9cfe9ab4b97..0a76f8db0b3 100644 --- a/lib/CodeGen/MachineCSE.cpp +++ b/lib/CodeGen/MachineCSE.cpp @@ -324,6 +324,29 @@ bool MachineCSE::isProfitableToCSE(unsigned CSReg, unsigned Reg, MachineInstr *CSMI, MachineInstr *MI) { // FIXME: Heuristics that works around the lack the live range splitting. + // If CSReg is used at all uses of Reg, CSE should not increase register + // pressure of CSReg. + bool MayIncreasePressure = true; + if (TargetRegisterInfo::isVirtualRegister(CSReg) && + TargetRegisterInfo::isVirtualRegister(Reg)) { + MayIncreasePressure = false; + SmallPtrSet CSUses; + for (MachineRegisterInfo::use_nodbg_iterator I =MRI->use_nodbg_begin(CSReg), + E = MRI->use_nodbg_end(); I != E; ++I) { + MachineInstr *Use = &*I; + CSUses.insert(Use); + } + for (MachineRegisterInfo::use_nodbg_iterator I = MRI->use_nodbg_begin(Reg), + E = MRI->use_nodbg_end(); I != E; ++I) { + MachineInstr *Use = &*I; + if (!CSUses.count(Use)) { + MayIncreasePressure = true; + break; + } + } + } + if (!MayIncreasePressure) return true; + // Heuristics #1: Don't CSE "cheap" computation if the def is not local or in // an immediate predecessor. We don't want to increase register pressure and // end up causing other computation to be spilled. diff --git a/test/CodeGen/X86/block-placement.ll b/test/CodeGen/X86/block-placement.ll index fc7b6383b8b..ab23b88f49e 100644 --- a/test/CodeGen/X86/block-placement.ll +++ b/test/CodeGen/X86/block-placement.ll @@ -634,7 +634,7 @@ define void @test_unnatural_cfg_backwards_inner_loop() { ; ; CHECK: test_unnatural_cfg_backwards_inner_loop ; CHECK: %entry -; CHECK: %body +; CHECK: [[BODY:# BB#[0-9]+]]: ; CHECK: %loop2b ; CHECK: %loop1 ; CHECK: %loop2a diff --git a/test/CodeGen/X86/machine-cse.ll b/test/CodeGen/X86/machine-cse.ll index a757cde6abe..33bef70444a 100644 --- a/test/CodeGen/X86/machine-cse.ll +++ b/test/CodeGen/X86/machine-cse.ll @@ -99,3 +99,38 @@ return: ; preds = %if.end, %entry %retval.0 = phi i32 [ 1, %entry ], [ %., %if.end ] ret i32 %retval.0 } + +; rdar://11393714 +define i8* @bsd_memchr(i8* %s, i32 %a, i32 %c, i64 %n) nounwind ssp { +; CHECK: %entry +; CHECK: xorl +; CHECK: %preheader +; CHECK: %do.body +; CHECK-NOT: xorl +; CHECK: %do.cond +; CHECK-NOT: xorl +; CHECK: %return +entry: + %cmp = icmp eq i64 %n, 0 + br i1 %cmp, label %return, label %preheader + +preheader: + %conv2 = and i32 %c, 255 + br label %do.body + +do.body: + %n.addr.0 = phi i64 [ %dec, %do.cond ], [ %n, %preheader ] + %p.0 = phi i8* [ %incdec.ptr, %do.cond ], [ %s, %preheader ] + %cmp3 = icmp eq i32 %a, %conv2 + br i1 %cmp3, label %return, label %do.cond + +do.cond: + %incdec.ptr = getelementptr inbounds i8* %p.0, i64 1 + %dec = add i64 %n.addr.0, -1 + %cmp6 = icmp eq i64 %dec, 0 + br i1 %cmp6, label %return, label %do.body + +return: + %retval.0 = phi i8* [ null, %entry ], [ null, %do.cond ], [ %p.0, %do.body ] + ret i8* %retval.0 +}