diff --git a/include/llvm/Target/TargetInstrInfo.h b/include/llvm/Target/TargetInstrInfo.h index 00f9f5a5220..0ab57ca08e4 100644 --- a/include/llvm/Target/TargetInstrInfo.h +++ b/include/llvm/Target/TargetInstrInfo.h @@ -151,7 +151,7 @@ public: /// specific location targeting a new destination register. virtual void reMaterialize(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, - unsigned DestReg, + unsigned DestReg, unsigned SubIdx, const MachineInstr *Orig) const = 0; /// isInvariantLoad - Return true if the specified instruction (which is @@ -499,7 +499,7 @@ public: const SmallVectorImpl &Pred) const; virtual void reMaterialize(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, - unsigned DestReg, + unsigned DestReg, unsigned SubReg, const MachineInstr *Orig) const; virtual unsigned GetFunctionSizeInBytes(const MachineFunction &MF) const; }; diff --git a/lib/CodeGen/LiveIntervalAnalysis.cpp b/lib/CodeGen/LiveIntervalAnalysis.cpp index 3887fc81d82..873e58e5c7b 100644 --- a/lib/CodeGen/LiveIntervalAnalysis.cpp +++ b/lib/CodeGen/LiveIntervalAnalysis.cpp @@ -1157,6 +1157,11 @@ bool LiveIntervals::isReMaterializable(const LiveInterval &li, if (DisableReMat) return false; + // FIXME: For now, avoid remating instructions whose definition has a subreg + // index. It's just incredibly difficult to get right. + if (MI->findRegisterDefOperand(li.reg)->getSubReg()) + return false; + if (MI->getOpcode() == TargetInstrInfo::IMPLICIT_DEF) return true; @@ -1595,7 +1600,7 @@ rewriteInstructionForSpills(const LiveInterval &li, const VNInfo *VNI, if (CreatedNewVReg) { if (DefIsReMat) { - vrm.setVirtIsReMaterialized(NewVReg, ReMatDefMI/*, CanDelete*/); + vrm.setVirtIsReMaterialized(NewVReg, ReMatDefMI); if (ReMatIds[VNI->id] == VirtRegMap::MAX_STACK_SLOT) { // Each valnum may have its own remat id. ReMatIds[VNI->id] = vrm.assignVirtReMatId(NewVReg); diff --git a/lib/CodeGen/PreAllocSplitting.cpp b/lib/CodeGen/PreAllocSplitting.cpp index c49575bade6..580a6d1d9d8 100644 --- a/lib/CodeGen/PreAllocSplitting.cpp +++ b/lib/CodeGen/PreAllocSplitting.cpp @@ -867,7 +867,7 @@ void PreAllocSplitting::RenumberValno(VNInfo* VN) { NumRenumbers++; } -bool PreAllocSplitting::Rematerialize(unsigned vreg, VNInfo* ValNo, +bool PreAllocSplitting::Rematerialize(unsigned VReg, VNInfo* ValNo, MachineInstr* DefMI, MachineBasicBlock::iterator RestorePt, unsigned RestoreIdx, @@ -884,7 +884,7 @@ bool PreAllocSplitting::Rematerialize(unsigned vreg, VNInfo* ValNo, if (KillPt == DefMI->getParent()->end()) return false; - TII->reMaterialize(MBB, RestorePt, vreg, DefMI); + TII->reMaterialize(MBB, RestorePt, VReg, 0, DefMI); LIs->InsertMachineInstrInMaps(prior(RestorePt), RestoreIdx); ReconstructLiveInterval(CurrLI); diff --git a/lib/CodeGen/SimpleRegisterCoalescing.cpp b/lib/CodeGen/SimpleRegisterCoalescing.cpp index 94a275a21a1..444952f330c 100644 --- a/lib/CodeGen/SimpleRegisterCoalescing.cpp +++ b/lib/CodeGen/SimpleRegisterCoalescing.cpp @@ -590,6 +590,7 @@ SimpleRegisterCoalescing::TrimLiveIntervalToLastUse(unsigned CopyIdx, /// computation, replace the copy by rematerialize the definition. bool SimpleRegisterCoalescing::ReMaterializeTrivialDef(LiveInterval &SrcInt, unsigned DstReg, + unsigned DstSubIdx, MachineInstr *CopyMI) { unsigned CopyIdx = li_->getUseIndex(li_->getInstructionIndex(CopyMI)); LiveInterval::iterator SrcLR = SrcInt.FindLiveRangeContaining(CopyIdx); @@ -647,7 +648,7 @@ bool SimpleRegisterCoalescing::ReMaterializeTrivialDef(LiveInterval &SrcInt, } MachineBasicBlock::iterator MII = next(MachineBasicBlock::iterator(CopyMI)); - tii_->reMaterialize(*MBB, MII, DstReg, DefMI); + tii_->reMaterialize(*MBB, MII, DstReg, DstSubIdx, DefMI); MachineInstr *NewMI = prior(MII); if (checkForDeadDef) { @@ -738,7 +739,8 @@ SimpleRegisterCoalescing::UpdateRegDefsUses(unsigned SrcReg, unsigned DstReg, CopySrcReg == SrcReg && CopyDstReg != UseDstReg) { // If the use is a copy and it won't be coalesced away, and its source // is defined by a trivial computation, try to rematerialize it instead. - if (ReMaterializeTrivialDef(li_->getInterval(SrcReg), CopyDstReg,UseMI)) + if (ReMaterializeTrivialDef(li_->getInterval(SrcReg), CopyDstReg, + CopyDstSubIdx, UseMI)) continue; } @@ -950,10 +952,9 @@ SimpleRegisterCoalescing::ShortenDeadCopySrcLiveRange(LiveInterval &li, if (LR->valno->def == RemoveStart) { // If the def MI defines the val# and this copy is the only kill of the // val#, then propagate the dead marker. - if (li.isOnlyLROfValNo(LR)) { - PropagateDeadness(li, CopyMI, RemoveStart, li_, tri_); - ++numDeadValNo; - } + PropagateDeadness(li, CopyMI, RemoveStart, li_, tri_); + ++numDeadValNo; + if (li.isKill(LR->valno, RemoveEnd)) li.removeKill(LR->valno, RemoveEnd); } @@ -1679,7 +1680,7 @@ bool SimpleRegisterCoalescing::JoinCopy(CopyRec &TheCopy, bool &Again) { // If definition of source is defined by trivial computation, try // rematerializing it. if (!isExtSubReg && !isInsSubReg && !isSubRegToReg && - ReMaterializeTrivialDef(SrcInt, DstInt.reg, CopyMI)) + ReMaterializeTrivialDef(SrcInt, DstReg, DstSubIdx, CopyMI)) return true; // If we can eliminate the copy without merging the live ranges, do so now. diff --git a/lib/CodeGen/SimpleRegisterCoalescing.h b/lib/CodeGen/SimpleRegisterCoalescing.h index d2c55810f60..b1810ed413a 100644 --- a/lib/CodeGen/SimpleRegisterCoalescing.h +++ b/lib/CodeGen/SimpleRegisterCoalescing.h @@ -206,7 +206,7 @@ namespace llvm { /// ReMaterializeTrivialDef - If the source of a copy is defined by a trivial /// computation, replace the copy by rematerialize the definition. bool ReMaterializeTrivialDef(LiveInterval &SrcInt, unsigned DstReg, - MachineInstr *CopyMI); + unsigned DstSubIdx, MachineInstr *CopyMI); /// TurnCopyIntoImpDef - If source of the specified copy is an implicit def, /// turn the copy into an implicit def. diff --git a/lib/CodeGen/TargetInstrInfoImpl.cpp b/lib/CodeGen/TargetInstrInfoImpl.cpp index 97de901f431..0b791e4a71f 100644 --- a/lib/CodeGen/TargetInstrInfoImpl.cpp +++ b/lib/CodeGen/TargetInstrInfoImpl.cpp @@ -130,9 +130,12 @@ bool TargetInstrInfoImpl::PredicateInstruction(MachineInstr *MI, void TargetInstrInfoImpl::reMaterialize(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, unsigned DestReg, + unsigned SubIdx, const MachineInstr *Orig) const { MachineInstr *MI = MBB.getParent()->CloneMachineInstr(Orig); - MI->getOperand(0).setReg(DestReg); + MachineOperand &MO = MI->getOperand(0); + MO.setReg(DestReg); + MO.setSubReg(SubIdx); MBB.insert(I, MI); } diff --git a/lib/CodeGen/TwoAddressInstructionPass.cpp b/lib/CodeGen/TwoAddressInstructionPass.cpp index b67f84b0f94..83468d9273d 100644 --- a/lib/CodeGen/TwoAddressInstructionPass.cpp +++ b/lib/CodeGen/TwoAddressInstructionPass.cpp @@ -798,6 +798,7 @@ bool TwoAddressInstructionPass::runOnMachineFunction(MachineFunction &MF) { // a = a op c unsigned regA = mi->getOperand(ti).getReg(); unsigned regB = mi->getOperand(si).getReg(); + unsigned regASubIdx = mi->getOperand(ti).getSubReg(); assert(TargetRegisterInfo::isVirtualRegister(regB) && "cannot update physical register live information"); @@ -946,7 +947,7 @@ bool TwoAddressInstructionPass::runOnMachineFunction(MachineFunction &MF) { DefMI->isSafeToReMat(TII, regB) && isProfitableToReMat(regB, rc, mi, DefMI, mbbi, Dist)){ DEBUG(cerr << "2addr: REMATTING : " << *DefMI << "\n"); - TII->reMaterialize(*mbbi, mi, regA, DefMI); + TII->reMaterialize(*mbbi, mi, regA, regASubIdx, DefMI); ReMatRegs.set(regB); ++NumReMats; } else { diff --git a/lib/CodeGen/VirtRegRewriter.cpp b/lib/CodeGen/VirtRegRewriter.cpp index 69f640ea11f..800cdd625f9 100644 --- a/lib/CodeGen/VirtRegRewriter.cpp +++ b/lib/CodeGen/VirtRegRewriter.cpp @@ -490,7 +490,7 @@ static void ReMaterialize(MachineBasicBlock &MBB, const TargetInstrInfo *TII, const TargetRegisterInfo *TRI, VirtRegMap &VRM) { - TII->reMaterialize(MBB, MII, DestReg, VRM.getReMaterializedMI(Reg)); + TII->reMaterialize(MBB, MII, DestReg, 0, VRM.getReMaterializedMI(Reg)); MachineInstr *NewMI = prior(MII); for (unsigned i = 0, e = NewMI->getNumOperands(); i != e; ++i) { MachineOperand &MO = NewMI->getOperand(i); diff --git a/lib/Target/ARM/ARMBaseRegisterInfo.cpp b/lib/Target/ARM/ARMBaseRegisterInfo.cpp index 37ba0efae73..55db6c9e7d9 100644 --- a/lib/Target/ARM/ARMBaseRegisterInfo.cpp +++ b/lib/Target/ARM/ARMBaseRegisterInfo.cpp @@ -887,7 +887,7 @@ void ARMBaseRegisterInfo:: emitLoadConstPool(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, DebugLoc dl, - unsigned DestReg, int Val, + unsigned DestReg, unsigned SubIdx, int Val, ARMCC::CondCodes Pred, unsigned PredReg) const { MachineFunction &MF = *MBB.getParent(); @@ -896,7 +896,8 @@ emitLoadConstPool(MachineBasicBlock &MBB, MF.getFunction()->getContext()->getConstantInt(Type::Int32Ty, Val); unsigned Idx = ConstantPool->getConstantPoolIndex(C, 4); - BuildMI(MBB, MBBI, dl, TII.get(ARM::LDRcp), DestReg) + BuildMI(MBB, MBBI, dl, TII.get(ARM::LDRcp)) + .addReg(DestReg, getDefRegState(true), SubIdx) .addConstantPoolIndex(Idx) .addReg(0).addImm(0).addImm(Pred).addReg(PredReg); } diff --git a/lib/Target/ARM/ARMBaseRegisterInfo.h b/lib/Target/ARM/ARMBaseRegisterInfo.h index f427b97cc8b..92ecc783c7f 100644 --- a/lib/Target/ARM/ARMBaseRegisterInfo.h +++ b/lib/Target/ARM/ARMBaseRegisterInfo.h @@ -112,7 +112,8 @@ public: virtual void emitLoadConstPool(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, DebugLoc dl, - unsigned DestReg, int Val, + unsigned DestReg, unsigned SubIdx, + int Val, ARMCC::CondCodes Pred = ARMCC::AL, unsigned PredReg = 0) const; diff --git a/lib/Target/ARM/ARMInstrInfo.cpp b/lib/Target/ARM/ARMInstrInfo.cpp index ab0a39177ab..688dc31c139 100644 --- a/lib/Target/ARM/ARMInstrInfo.cpp +++ b/lib/Target/ARM/ARMInstrInfo.cpp @@ -117,12 +117,12 @@ BlockHasNoFallThrough(const MachineBasicBlock &MBB) const { void ARMInstrInfo:: reMaterialize(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, - unsigned DestReg, + unsigned DestReg, unsigned SubIdx, const MachineInstr *Orig) const { DebugLoc dl = Orig->getDebugLoc(); if (Orig->getOpcode() == ARM::MOVi2pieces) { RI.emitLoadConstPool(MBB, I, dl, - DestReg, + DestReg, SubIdx, Orig->getOperand(1).getImm(), (ARMCC::CondCodes)Orig->getOperand(2).getImm(), Orig->getOperand(3).getReg()); diff --git a/lib/Target/ARM/ARMInstrInfo.h b/lib/Target/ARM/ARMInstrInfo.h index 286b5b702f5..3e9f0204fe0 100644 --- a/lib/Target/ARM/ARMInstrInfo.h +++ b/lib/Target/ARM/ARMInstrInfo.h @@ -45,7 +45,8 @@ public: const ARMRegisterInfo &getRegisterInfo() const { return RI; } void reMaterialize(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, - unsigned DestReg, const MachineInstr *Orig) const; + unsigned DestReg, unsigned SubIdx, + const MachineInstr *Orig) const; }; } diff --git a/lib/Target/ARM/Thumb1RegisterInfo.cpp b/lib/Target/ARM/Thumb1RegisterInfo.cpp index 8374090bd3f..9c933063230 100644 --- a/lib/Target/ARM/Thumb1RegisterInfo.cpp +++ b/lib/Target/ARM/Thumb1RegisterInfo.cpp @@ -62,7 +62,8 @@ const MachineInstrBuilder &AddDefaultCC(const MachineInstrBuilder &MIB) { void Thumb1RegisterInfo::emitLoadConstPool(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, DebugLoc dl, - unsigned DestReg, int Val, + unsigned DestReg, unsigned SubIdx, + int Val, ARMCC::CondCodes Pred, unsigned PredReg) const { MachineFunction &MF = *MBB.getParent(); @@ -71,8 +72,9 @@ void Thumb1RegisterInfo::emitLoadConstPool(MachineBasicBlock &MBB, MF.getFunction()->getContext()->getConstantInt(Type::Int32Ty, Val); unsigned Idx = ConstantPool->getConstantPoolIndex(C, 4); - BuildMI(MBB, MBBI, dl, TII.get(ARM::tLDRcp), DestReg) - .addConstantPoolIndex(Idx).addImm(Pred).addReg(PredReg); + BuildMI(MBB, MBBI, dl, TII.get(ARM::tLDRcp)) + .addReg(DestReg, getDefRegState(true), SubIdx) + .addConstantPoolIndex(Idx).addImm(Pred).addReg(PredReg); } const TargetRegisterClass* @@ -149,7 +151,7 @@ void emitThumbRegPlusImmInReg(MachineBasicBlock &MBB, AddDefaultCC(BuildMI(MBB, MBBI, dl, TII.get(ARM::tRSB), LdReg)) .addReg(LdReg, RegState::Kill); } else - MRI.emitLoadConstPool(MBB, MBBI, dl, LdReg, NumBytes); + MRI.emitLoadConstPool(MBB, MBBI, dl, LdReg, 0, NumBytes); // Emit add / sub. int Opc = (isSub) ? ARM::tSUBrr : (isHigh ? ARM::tADDhirr : ARM::tADDrr); @@ -570,7 +572,7 @@ void Thumb1RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, emitThumbRegPlusImmInReg(MBB, II, TmpReg, FrameReg, Offset, false, TII, *this, dl); else { - emitLoadConstPool(MBB, II, dl, TmpReg, Offset); + emitLoadConstPool(MBB, II, dl, TmpReg, 0, Offset); UseRR = true; } } else { @@ -610,7 +612,7 @@ void Thumb1RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, emitThumbRegPlusImmInReg(MBB, II, TmpReg, FrameReg, Offset, false, TII, *this, dl); else { - emitLoadConstPool(MBB, II, dl, TmpReg, Offset); + emitLoadConstPool(MBB, II, dl, TmpReg, 0, Offset); UseRR = true; } } else diff --git a/lib/Target/ARM/Thumb1RegisterInfo.h b/lib/Target/ARM/Thumb1RegisterInfo.h index 6e8dd3d6dab..31e0df23503 100644 --- a/lib/Target/ARM/Thumb1RegisterInfo.h +++ b/lib/Target/ARM/Thumb1RegisterInfo.h @@ -32,7 +32,7 @@ public: void emitLoadConstPool(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, DebugLoc dl, - unsigned DestReg, int Val, + unsigned DestReg, unsigned SubIdx, int Val, ARMCC::CondCodes Pred = ARMCC::AL, unsigned PredReg = 0) const; diff --git a/lib/Target/ARM/Thumb2RegisterInfo.cpp b/lib/Target/ARM/Thumb2RegisterInfo.cpp index bf7149722ec..482fdce519e 100644 --- a/lib/Target/ARM/Thumb2RegisterInfo.cpp +++ b/lib/Target/ARM/Thumb2RegisterInfo.cpp @@ -46,7 +46,8 @@ Thumb2RegisterInfo::Thumb2RegisterInfo(const ARMBaseInstrInfo &tii, void Thumb2RegisterInfo::emitLoadConstPool(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, DebugLoc dl, - unsigned DestReg, int Val, + unsigned DestReg, unsigned SubIdx, + int Val, ARMCC::CondCodes Pred, unsigned PredReg) const { MachineFunction &MF = *MBB.getParent(); @@ -55,7 +56,8 @@ void Thumb2RegisterInfo::emitLoadConstPool(MachineBasicBlock &MBB, MF.getFunction()->getContext()->getConstantInt(Type::Int32Ty, Val); unsigned Idx = ConstantPool->getConstantPoolIndex(C, 4); - BuildMI(MBB, MBBI, dl, TII.get(ARM::t2LDRpci), DestReg) + BuildMI(MBB, MBBI, dl, TII.get(ARM::t2LDRpci)) + .addReg(DestReg, getDefRegState(true), SubIdx) .addConstantPoolIndex(Idx).addImm((int64_t)ARMCC::AL).addReg(0); } diff --git a/lib/Target/ARM/Thumb2RegisterInfo.h b/lib/Target/ARM/Thumb2RegisterInfo.h index 61ee531c76a..0a9a15aa1ee 100644 --- a/lib/Target/ARM/Thumb2RegisterInfo.h +++ b/lib/Target/ARM/Thumb2RegisterInfo.h @@ -32,7 +32,7 @@ public: void emitLoadConstPool(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, DebugLoc dl, - unsigned DestReg, int Val, + unsigned DestReg, unsigned SubIdx, int Val, ARMCC::CondCodes Pred = ARMCC::AL, unsigned PredReg = 0) const; diff --git a/lib/Target/X86/X86InstrInfo.cpp b/lib/Target/X86/X86InstrInfo.cpp index 6f5e717384f..6e1d0791ec3 100644 --- a/lib/Target/X86/X86InstrInfo.cpp +++ b/lib/Target/X86/X86InstrInfo.cpp @@ -916,14 +916,11 @@ static bool isSafeToClobberEFLAGS(MachineBasicBlock &MBB, void X86InstrInfo::reMaterialize(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, - unsigned DestReg, + unsigned DestReg, unsigned SubIdx, const MachineInstr *Orig) const { DebugLoc DL = DebugLoc::getUnknownLoc(); if (I != MBB.end()) DL = I->getDebugLoc(); - unsigned SubIdx = Orig->getOperand(0).isReg() - ? Orig->getOperand(0).getSubReg() : 0; - bool ChangeSubIdx = SubIdx != 0; if (SubIdx && TargetRegisterInfo::isPhysicalRegister(DestReg)) { DestReg = RI.getSubReg(DestReg, SubIdx); SubIdx = 0; @@ -931,37 +928,36 @@ void X86InstrInfo::reMaterialize(MachineBasicBlock &MBB, // MOV32r0 etc. are implemented with xor which clobbers condition code. // Re-materialize them as movri instructions to avoid side effects. - bool Emitted = false; - switch (Orig->getOpcode()) { + bool Clone = true; + unsigned Opc = Orig->getOpcode(); + switch (Opc) { default: break; case X86::MOV8r0: case X86::MOV16r0: case X86::MOV32r0: { if (!isSafeToClobberEFLAGS(MBB, I)) { - unsigned Opc = 0; - switch (Orig->getOpcode()) { + switch (Opc) { default: break; case X86::MOV8r0: Opc = X86::MOV8ri; break; case X86::MOV16r0: Opc = X86::MOV16ri; break; case X86::MOV32r0: Opc = X86::MOV32ri; break; } - BuildMI(MBB, I, DL, get(Opc), DestReg).addImm(0); - Emitted = true; + Clone = false; } break; } } - if (!Emitted) { + if (Clone) { MachineInstr *MI = MBB.getParent()->CloneMachineInstr(Orig); MI->getOperand(0).setReg(DestReg); MBB.insert(I, MI); + } else { + BuildMI(MBB, I, DL, get(Opc), DestReg).addImm(0); } - if (ChangeSubIdx) { - MachineInstr *NewMI = prior(I); - NewMI->getOperand(0).setSubReg(SubIdx); - } + MachineInstr *NewMI = prior(I); + NewMI->getOperand(0).setSubReg(SubIdx); } /// isInvariantLoad - Return true if the specified instruction (which is marked diff --git a/lib/Target/X86/X86InstrInfo.h b/lib/Target/X86/X86InstrInfo.h index 5ad52cff3a4..0fb20522027 100644 --- a/lib/Target/X86/X86InstrInfo.h +++ b/lib/Target/X86/X86InstrInfo.h @@ -456,7 +456,8 @@ public: bool isReallyTriviallyReMaterializable(const MachineInstr *MI) const; void reMaterialize(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, - unsigned DestReg, const MachineInstr *Orig) const; + unsigned DestReg, unsigned SubIdx, + const MachineInstr *Orig) const; bool isInvariantLoad(const MachineInstr *MI) const; diff --git a/test/CodeGen/X86/2008-08-23-X86-64AsmBug.ll b/test/CodeGen/X86/2008-08-23-X86-64AsmBug.ll index 4e3533287db..518e8ccd5dc 100644 --- a/test/CodeGen/X86/2008-08-23-X86-64AsmBug.ll +++ b/test/CodeGen/X86/2008-08-23-X86-64AsmBug.ll @@ -1,7 +1,11 @@ -; RUN: llvm-as < %s | llc -mtriple=x86_64-apple-darwin | grep movd | count 1 ; RUN: llvm-as < %s | llc -mtriple=x86_64-apple-darwin | grep movq ; PR2677 +; FIXME: llvm-as < %s | llc -mtriple=x86_64-apple-darwin | grep movd | count 1 +; We now no longer allow instruction whose def has a sub-reg index to be +; rematerialized. + + %struct.Bigint = type { %struct.Bigint*, i32, i32, i32, i32, [1 x i32] } define double @_Z7qstrtodPKcPS0_Pb(i8* %s00, i8** %se, i8* %ok) nounwind { diff --git a/test/CodeGen/X86/2009-07-16-CoalescerBug.ll b/test/CodeGen/X86/2009-07-16-CoalescerBug.ll new file mode 100644 index 00000000000..f79b3da2971 --- /dev/null +++ b/test/CodeGen/X86/2009-07-16-CoalescerBug.ll @@ -0,0 +1,210 @@ +; RUN: llvm-as < %s | llc -mtriple=x86_64-apple-darwin10 +; rdar://7059496 + + %struct.brinfo = type <{ %struct.brinfo*, %struct.brinfo*, i8*, i32, i32, i32, i8, i8, i8, i8 }> + %struct.cadata = type <{ i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i32, i32, %struct.cmatcher*, i8*, i8*, i8*, i8*, i8*, i8*, i32, i8, i8, i8, i8 }> + %struct.cline = type <{ %struct.cline*, i32, i8, i8, i8, i8, i8*, i32, i8, i8, i8, i8, i8*, i32, i8, i8, i8, i8, i8*, i32, i32, %struct.cline*, %struct.cline*, i32, i32 }> + %struct.cmatch = type <{ i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i32, i8, i8, i8, i8, i32*, i32*, i8*, i8*, i32, i32, i32, i32, i16, i8, i8, i16, i8, i8 }> + %struct.cmatcher = type <{ i32, i8, i8, i8, i8, %struct.cmatcher*, i32, i8, i8, i8, i8, %struct.cpattern*, i32, i8, i8, i8, i8, %struct.cpattern*, i32, i8, i8, i8, i8, %struct.cpattern*, i32, i8, i8, i8, i8, %struct.cpattern*, i32, i8, i8, i8, i8 }> + %struct.cpattern = type <{ %struct.cpattern*, i32, i8, i8, i8, i8, %union.anon }> + %struct.patprog = type <{ i64, i64, i64, i64, i32, i32, i32, i32, i8, i8, i8, i8, i8, i8, i8, i8 }> + %union.anon = type <{ [8 x i8] }> + +define i32 @addmatches(%struct.cadata* %dat, i8** nocapture %argv) nounwind ssp { +entry: + br i1 undef, label %if.else, label %if.then91 + +if.then91: ; preds = %entry + br label %if.end96 + +if.else: ; preds = %entry + br label %if.end96 + +if.end96: ; preds = %if.else, %if.then91 + br i1 undef, label %lor.lhs.false, label %if.then105 + +lor.lhs.false: ; preds = %if.end96 + br i1 undef, label %if.else139, label %if.then105 + +if.then105: ; preds = %lor.lhs.false, %if.end96 + unreachable + +if.else139: ; preds = %lor.lhs.false + br i1 undef, label %land.end, label %land.rhs + +land.rhs: ; preds = %if.else139 + unreachable + +land.end: ; preds = %if.else139 + br i1 undef, label %land.lhs.true285, label %if.then315 + +land.lhs.true285: ; preds = %land.end + br i1 undef, label %if.end324, label %if.then322 + +if.then315: ; preds = %land.end + unreachable + +if.then322: ; preds = %land.lhs.true285 + unreachable + +if.end324: ; preds = %land.lhs.true285 + br i1 undef, label %if.end384, label %if.then358 + +if.then358: ; preds = %if.end324 + unreachable + +if.end384: ; preds = %if.end324 + br i1 undef, label %if.end394, label %land.lhs.true387 + +land.lhs.true387: ; preds = %if.end384 + unreachable + +if.end394: ; preds = %if.end384 + br i1 undef, label %if.end498, label %land.lhs.true399 + +land.lhs.true399: ; preds = %if.end394 + br i1 undef, label %if.end498, label %if.then406 + +if.then406: ; preds = %land.lhs.true399 + unreachable + +if.end498: ; preds = %land.lhs.true399, %if.end394 + br i1 undef, label %if.end514, label %if.then503 + +if.then503: ; preds = %if.end498 + unreachable + +if.end514: ; preds = %if.end498 + br i1 undef, label %if.end585, label %if.then520 + +if.then520: ; preds = %if.end514 + br i1 undef, label %lor.lhs.false547, label %if.then560 + +lor.lhs.false547: ; preds = %if.then520 + unreachable + +if.then560: ; preds = %if.then520 + br i1 undef, label %if.end585, label %land.lhs.true566 + +land.lhs.true566: ; preds = %if.then560 + br i1 undef, label %if.end585, label %if.then573 + +if.then573: ; preds = %land.lhs.true566 + unreachable + +if.end585: ; preds = %land.lhs.true566, %if.then560, %if.end514 + br i1 undef, label %cond.true593, label %cond.false599 + +cond.true593: ; preds = %if.end585 + unreachable + +cond.false599: ; preds = %if.end585 + br i1 undef, label %if.end647, label %if.then621 + +if.then621: ; preds = %cond.false599 + br i1 undef, label %cond.true624, label %cond.false630 + +cond.true624: ; preds = %if.then621 + br label %if.end647 + +cond.false630: ; preds = %if.then621 + unreachable + +if.end647: ; preds = %cond.true624, %cond.false599 + br i1 undef, label %if.end723, label %if.then701 + +if.then701: ; preds = %if.end647 + br label %if.end723 + +if.end723: ; preds = %if.then701, %if.end647 + br i1 undef, label %if.else1090, label %if.then729 + +if.then729: ; preds = %if.end723 + br i1 undef, label %if.end887, label %if.then812 + +if.then812: ; preds = %if.then729 + unreachable + +if.end887: ; preds = %if.then729 + br i1 undef, label %if.end972, label %if.then893 + +if.then893: ; preds = %if.end887 + br i1 undef, label %if.end919, label %if.then903 + +if.then903: ; preds = %if.then893 + unreachable + +if.end919: ; preds = %if.then893 + br label %if.end972 + +if.end972: ; preds = %if.end919, %if.end887 + %sline.0 = phi %struct.cline* [ undef, %if.end919 ], [ null, %if.end887 ] ; <%struct.cline*> [#uses=5] + %bcs.0 = phi i32 [ undef, %if.end919 ], [ 0, %if.end887 ] ; [#uses=5] + br i1 undef, label %if.end1146, label %land.lhs.true975 + +land.lhs.true975: ; preds = %if.end972 + br i1 undef, label %if.end1146, label %if.then980 + +if.then980: ; preds = %land.lhs.true975 + br i1 undef, label %cond.false1025, label %cond.false1004 + +cond.false1004: ; preds = %if.then980 + unreachable + +cond.false1025: ; preds = %if.then980 + br i1 undef, label %if.end1146, label %if.then1071 + +if.then1071: ; preds = %cond.false1025 + br i1 undef, label %if.then1074, label %if.end1081 + +if.then1074: ; preds = %if.then1071 + br label %if.end1081 + +if.end1081: ; preds = %if.then1074, %if.then1071 + %call1083 = call %struct.patprog* @patcompile(i8* undef, i32 0, i8** null) nounwind ssp ; <%struct.patprog*> [#uses=2] + br i1 undef, label %if.end1146, label %if.then1086 + +if.then1086: ; preds = %if.end1081 + br label %if.end1146 + +if.else1090: ; preds = %if.end723 + br i1 undef, label %if.end1146, label %land.lhs.true1093 + +land.lhs.true1093: ; preds = %if.else1090 + br i1 undef, label %if.end1146, label %if.then1098 + +if.then1098: ; preds = %land.lhs.true1093 + unreachable + +if.end1146: ; preds = %land.lhs.true1093, %if.else1090, %if.then1086, %if.end1081, %cond.false1025, %land.lhs.true975, %if.end972 + %cp.0 = phi %struct.patprog* [ %call1083, %if.then1086 ], [ null, %if.end972 ], [ null, %land.lhs.true975 ], [ null, %cond.false1025 ], [ %call1083, %if.end1081 ], [ null, %if.else1090 ], [ null, %land.lhs.true1093 ] ; <%struct.patprog*> [#uses=1] + %sline.1 = phi %struct.cline* [ %sline.0, %if.then1086 ], [ %sline.0, %if.end972 ], [ %sline.0, %land.lhs.true975 ], [ %sline.0, %cond.false1025 ], [ %sline.0, %if.end1081 ], [ null, %if.else1090 ], [ null, %land.lhs.true1093 ] ; <%struct.cline*> [#uses=1] + %bcs.1 = phi i32 [ %bcs.0, %if.then1086 ], [ %bcs.0, %if.end972 ], [ %bcs.0, %land.lhs.true975 ], [ %bcs.0, %cond.false1025 ], [ %bcs.0, %if.end1081 ], [ 0, %if.else1090 ], [ 0, %land.lhs.true1093 ] ; [#uses=1] + br i1 undef, label %if.end1307, label %do.body1270 + +do.body1270: ; preds = %if.end1146 + unreachable + +if.end1307: ; preds = %if.end1146 + br i1 undef, label %if.end1318, label %if.then1312 + +if.then1312: ; preds = %if.end1307 + unreachable + +if.end1318: ; preds = %if.end1307 + br i1 undef, label %for.cond1330.preheader, label %if.then1323 + +if.then1323: ; preds = %if.end1318 + unreachable + +for.cond1330.preheader: ; preds = %if.end1318 + %call1587 = call i8* @comp_match(i8* undef, i8* undef, i8* undef, %struct.patprog* %cp.0, %struct.cline** undef, i32 0, %struct.brinfo** undef, i32 0, %struct.brinfo** undef, i32 %bcs.1, i32* undef) nounwind ssp ; [#uses=0] + %call1667 = call %struct.cmatch* @add_match_data(i32 0, i8* undef, i8* undef, %struct.cline* undef, i8* undef, i8* null, i8* undef, i8* undef, i8* undef, i8* undef, %struct.cline* null, i8* undef, %struct.cline* %sline.1, i8* undef, i32 undef, i32 undef) ssp ; <%struct.cmatch*> [#uses=0] + unreachable +} + +declare %struct.patprog* @patcompile(i8*, i32, i8**) ssp + +declare i8* @comp_match(i8*, i8*, i8*, %struct.patprog*, %struct.cline**, i32, %struct.brinfo**, i32, %struct.brinfo**, i32, i32*) ssp + +declare %struct.cmatch* @add_match_data(i32, i8*, i8*, %struct.cline*, i8*, i8*, i8*, i8*, i8*, i8*, %struct.cline*, i8*, %struct.cline*, i8*, i32, i32) nounwind ssp