Index: include/llvm/CodeGen/MachineInstrBuilder.h =================================================================== --- include/llvm/CodeGen/MachineInstrBuilder.h +++ include/llvm/CodeGen/MachineInstrBuilder.h @@ -237,6 +237,16 @@ return MachineInstrBuilder(MF, MF.CreateMachineInstr(MCID, DL)); } +inline MachineInstrBuilder BuildMI(MachineFunction &MF, + MachineBasicBlock::iterator I, + DebugLoc DL, + const MCInstrDesc &MCID) { + assert(&MF == I->getParent()->getParent()); + MachineInstr *MI = MF.CreateMachineInstr(MCID, DL); + I->getParent()->insert(I, MI); + return MachineInstrBuilder(MF, MI); +} + /// BuildMI - This version of the builder sets up the first operand as a /// destination virtual register. /// @@ -248,6 +258,18 @@ .addReg(DestReg, RegState::Define); } +inline MachineInstrBuilder BuildMI(MachineFunction &MF, + MachineBasicBlock::iterator I, + DebugLoc DL, + const MCInstrDesc &MCID, + unsigned DestReg) { + assert(&MF == I->getParent()->getParent()); + MachineInstr *MI = MF.CreateMachineInstr(MCID, DL); + I->getParent()->insert(I, MI); + return MachineInstrBuilder(MF, MF.CreateMachineInstr(MCID, DL)) + .addReg(DestReg, RegState::Define); +} + /// BuildMI - This version of the builder inserts the newly-built /// instruction before the given position in the given MachineBasicBlock, and /// sets up the first operand as a destination virtual register. Index: include/llvm/Target/TargetInstrInfo.h =================================================================== --- include/llvm/Target/TargetInstrInfo.h +++ include/llvm/Target/TargetInstrInfo.h @@ -714,9 +714,12 @@ /// foldMemoryOperandImpl - Target-dependent implementation for /// foldMemoryOperand. Target-independent code in foldMemoryOperand will /// take care of adding a MachineMemOperand to the newly created instruction. + /// The instruction and any auxiliary instructions necessary will be inserted + /// at InsertPt. virtual MachineInstr* foldMemoryOperandImpl(MachineFunction &MF, MachineInstr* MI, const SmallVectorImpl &Ops, + MachineBasicBlock::iterator InsertPt, int FrameIndex) const { return nullptr; } @@ -724,10 +727,13 @@ /// foldMemoryOperandImpl - Target-dependent implementation for /// foldMemoryOperand. Target-independent code in foldMemoryOperand will /// take care of adding a MachineMemOperand to the newly created instruction. + /// The instruction and any auxiliary instructions necessary will be inserted + /// at InsertPt. virtual MachineInstr* foldMemoryOperandImpl(MachineFunction &MF, - MachineInstr* MI, + MachineInstr* MI, const SmallVectorImpl &Ops, - MachineInstr* LoadMI) const { + MachineBasicBlock::iterator InsertPt, + MachineInstr* LoadMI) const { return nullptr; } Index: lib/CodeGen/TargetInstrInfo.cpp =================================================================== --- lib/CodeGen/TargetInstrInfo.cpp +++ lib/CodeGen/TargetInstrInfo.cpp @@ -468,11 +468,13 @@ MI->getOpcode() == TargetOpcode::PATCHPOINT) { // Fold stackmap/patchpoint. NewMI = foldPatchpoint(MF, MI, Ops, FI, *this); + if (NewMI) + MBB->insert(MI, NewMI); } else { // Ask the target to do the actual folding. - NewMI =foldMemoryOperandImpl(MF, MI, Ops, FI); + NewMI = foldMemoryOperandImpl(MF, MI, Ops, MI, FI); } - + if (NewMI) { NewMI->setMemRefs(MI->memoperands_begin(), MI->memoperands_end()); // Add a memory operand, foldMemoryOperandImpl doesn't do that. @@ -490,8 +492,7 @@ MFI.getObjectAlignment(FI)); NewMI->addMemOperand(MF, MMO); - // FIXME: change foldMemoryOperandImpl semantics to also insert NewMI. - return MBB->insert(MI, NewMI); + return NewMI; } // Straight COPY may fold as load/store. @@ -537,15 +538,15 @@ isLoadFromStackSlot(LoadMI, FrameIndex)) { // Fold stackmap/patchpoint. NewMI = foldPatchpoint(MF, MI, Ops, FrameIndex, *this); + if (NewMI) + NewMI = MBB.insert(MI, NewMI); } else { // Ask the target to do the actual folding. - NewMI = foldMemoryOperandImpl(MF, MI, Ops, LoadMI); + NewMI = foldMemoryOperandImpl(MF, MI, Ops, MI, LoadMI); } if (!NewMI) return nullptr; - NewMI = MBB.insert(MI, NewMI); - // Copy the memoperands from the load to the folded instruction. if (MI->memoperands_empty()) { NewMI->setMemRefs(LoadMI->memoperands_begin(), Index: lib/Target/AArch64/AArch64InstrInfo.h =================================================================== --- lib/Target/AArch64/AArch64InstrInfo.h +++ lib/Target/AArch64/AArch64InstrInfo.h @@ -132,6 +132,7 @@ MachineInstr * foldMemoryOperandImpl(MachineFunction &MF, MachineInstr *MI, const SmallVectorImpl &Ops, + MachineBasicBlock::iterator InsertPt, int FrameIndex) const override; bool AnalyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, Index: lib/Target/AArch64/AArch64InstrInfo.cpp =================================================================== --- lib/Target/AArch64/AArch64InstrInfo.cpp +++ lib/Target/AArch64/AArch64InstrInfo.cpp @@ -2047,6 +2047,7 @@ MachineInstr * AArch64InstrInfo::foldMemoryOperandImpl(MachineFunction &MF, MachineInstr *MI, const SmallVectorImpl &Ops, + MachineBasicBlock::iterator InsertPt, int FrameIndex) const { // This is a bit of a hack. Consider this instruction: // Index: lib/Target/Hexagon/HexagonInstrInfo.h =================================================================== --- lib/Target/Hexagon/HexagonInstrInfo.h +++ lib/Target/Hexagon/HexagonInstrInfo.h @@ -105,11 +105,13 @@ MachineInstr* foldMemoryOperandImpl(MachineFunction &MF, MachineInstr* MI, const SmallVectorImpl &Ops, + MachineBasicBlock::iterator InsertPt, int FrameIndex) const override; MachineInstr* foldMemoryOperandImpl(MachineFunction &MF, MachineInstr* MI, const SmallVectorImpl &Ops, + MachineBasicBlock::iterator InsertPt, MachineInstr* LoadMI) const override { return nullptr; } Index: lib/Target/Hexagon/HexagonInstrInfo.cpp =================================================================== --- lib/Target/Hexagon/HexagonInstrInfo.cpp +++ lib/Target/Hexagon/HexagonInstrInfo.cpp @@ -558,6 +558,7 @@ MachineInstr *HexagonInstrInfo::foldMemoryOperandImpl(MachineFunction &MF, MachineInstr* MI, const SmallVectorImpl &Ops, + MachineBasicBlock::iterator InsertPt, int FI) const { // Hexagon_TODO: Implement. return nullptr; Index: lib/Target/R600/AMDGPUInstrInfo.h =================================================================== --- lib/Target/R600/AMDGPUInstrInfo.h +++ lib/Target/R600/AMDGPUInstrInfo.h @@ -88,10 +88,12 @@ MachineInstr *foldMemoryOperandImpl(MachineFunction &MF, MachineInstr *MI, const SmallVectorImpl &Ops, + MachineBasicBlock::iterator InsertPt, int FrameIndex) const override; MachineInstr *foldMemoryOperandImpl(MachineFunction &MF, MachineInstr *MI, const SmallVectorImpl &Ops, + MachineBasicBlock::iterator InsertPt, MachineInstr *LoadMI) const override; public: /// \returns the smallest register index that will be accessed by an indirect Index: lib/Target/R600/AMDGPUInstrInfo.cpp =================================================================== --- lib/Target/R600/AMDGPUInstrInfo.cpp +++ lib/Target/R600/AMDGPUInstrInfo.cpp @@ -157,6 +157,7 @@ AMDGPUInstrInfo::foldMemoryOperandImpl(MachineFunction &MF, MachineInstr *MI, const SmallVectorImpl &Ops, + MachineBasicBlock::iterator InsertPt, int FrameIndex) const { // TODO: Implement this function return nullptr; @@ -165,6 +166,7 @@ AMDGPUInstrInfo::foldMemoryOperandImpl(MachineFunction &MF, MachineInstr *MI, const SmallVectorImpl &Ops, + MachineBasicBlock::iterator InsertPt, MachineInstr *LoadMI) const { // TODO: Implement this function return nullptr; Index: lib/Target/SystemZ/SystemZInstrInfo.h =================================================================== --- lib/Target/SystemZ/SystemZInstrInfo.h +++ lib/Target/SystemZ/SystemZInstrInfo.h @@ -184,9 +184,11 @@ LiveVariables *LV) const override; MachineInstr *foldMemoryOperandImpl(MachineFunction &MF, MachineInstr *MI, const SmallVectorImpl &Ops, + MachineBasicBlock::iterator InsertPt, int FrameIndex) const override; MachineInstr *foldMemoryOperandImpl(MachineFunction &MF, MachineInstr* MI, const SmallVectorImpl &Ops, + MachineBasicBlock::iterator InsertPt, MachineInstr* LoadMI) const override; bool expandPostRAPseudo(MachineBasicBlock::iterator MBBI) const override; bool ReverseBranchCondition(SmallVectorImpl &Cond) const Index: lib/Target/SystemZ/SystemZInstrInfo.cpp =================================================================== --- lib/Target/SystemZ/SystemZInstrInfo.cpp +++ lib/Target/SystemZ/SystemZInstrInfo.cpp @@ -747,6 +747,7 @@ SystemZInstrInfo::foldMemoryOperandImpl(MachineFunction &MF, MachineInstr *MI, const SmallVectorImpl &Ops, + MachineBasicBlock::iterator InsertPt, int FrameIndex) const { const MachineFrameInfo *MFI = MF.getFrameInfo(); unsigned Size = MFI->getObjectSize(FrameIndex); @@ -757,7 +758,7 @@ isInt<8>(MI->getOperand(2).getImm()) && !MI->getOperand(3).getReg()) { // LA(Y) %reg, CONST(%reg) -> AGSI %mem, CONST - return BuildMI(MF, MI->getDebugLoc(), get(SystemZ::AGSI)) + return BuildMI(MF, InsertPt, MI->getDebugLoc(), get(SystemZ::AGSI)) .addFrameIndex(FrameIndex).addImm(0) .addImm(MI->getOperand(2).getImm()); } @@ -778,7 +779,7 @@ isInt<8>(MI->getOperand(2).getImm())) { // A(G)HI %reg, CONST -> A(G)SI %mem, CONST Opcode = (Opcode == SystemZ::AHI ? SystemZ::ASI : SystemZ::AGSI); - return BuildMI(MF, MI->getDebugLoc(), get(Opcode)) + return BuildMI(MF, InsertPt, MI->getDebugLoc(), get(Opcode)) .addFrameIndex(FrameIndex).addImm(0) .addImm(MI->getOperand(2).getImm()); } @@ -790,7 +791,7 @@ // source register instead. if (OpNum == 0) { unsigned StoreOpcode = Op1IsGPR ? SystemZ::STG : SystemZ::STD; - return BuildMI(MF, MI->getDebugLoc(), get(StoreOpcode)) + return BuildMI(MF, InsertPt, MI->getDebugLoc(), get(StoreOpcode)) .addOperand(MI->getOperand(1)).addFrameIndex(FrameIndex) .addImm(0).addReg(0); } @@ -799,7 +800,7 @@ if (OpNum == 1) { unsigned LoadOpcode = Op0IsGPR ? SystemZ::LG : SystemZ::LD; unsigned Dest = MI->getOperand(0).getReg(); - return BuildMI(MF, MI->getDebugLoc(), get(LoadOpcode), Dest) + return BuildMI(MF, InsertPt, MI->getDebugLoc(), get(LoadOpcode), Dest) .addFrameIndex(FrameIndex).addImm(0).addReg(0); } } @@ -822,14 +823,14 @@ if (MMO->getSize() == Size && !MMO->isVolatile()) { // Handle conversion of loads. if (isSimpleBD12Move(MI, SystemZII::SimpleBDXLoad)) { - return BuildMI(MF, MI->getDebugLoc(), get(SystemZ::MVC)) + return BuildMI(MF, InsertPt, MI->getDebugLoc(), get(SystemZ::MVC)) .addFrameIndex(FrameIndex).addImm(0).addImm(Size) .addOperand(MI->getOperand(1)).addImm(MI->getOperand(2).getImm()) .addMemOperand(MMO); } // Handle conversion of stores. if (isSimpleBD12Move(MI, SystemZII::SimpleBDXStore)) { - return BuildMI(MF, MI->getDebugLoc(), get(SystemZ::MVC)) + return BuildMI(MF, InsertPt, MI->getDebugLoc(), get(SystemZ::MVC)) .addOperand(MI->getOperand(1)).addImm(MI->getOperand(2).getImm()) .addImm(Size).addFrameIndex(FrameIndex).addImm(0) .addMemOperand(MMO); @@ -848,7 +849,7 @@ assert(AccessBytes != 0 && "Size of access should be known"); assert(AccessBytes <= Size && "Access outside the frame index"); uint64_t Offset = Size - AccessBytes; - MachineInstrBuilder MIB = BuildMI(MF, MI->getDebugLoc(), get(MemOpcode)); + MachineInstrBuilder MIB = BuildMI(MF, InsertPt, MI->getDebugLoc(), get(MemOpcode)); for (unsigned I = 0; I < OpNum; ++I) MIB.addOperand(MI->getOperand(I)); MIB.addFrameIndex(FrameIndex).addImm(Offset); @@ -864,6 +865,7 @@ MachineInstr * SystemZInstrInfo::foldMemoryOperandImpl(MachineFunction &MF, MachineInstr* MI, const SmallVectorImpl &Ops, + MachineBasicBlock::iterator InsertPt, MachineInstr* LoadMI) const { return nullptr; } Index: lib/Target/X86/X86FastISel.cpp =================================================================== --- lib/Target/X86/X86FastISel.cpp +++ lib/Target/X86/X86FastISel.cpp @@ -3339,13 +3339,12 @@ AM.getFullAddress(AddrOps); MachineInstr *Result = - XII.foldMemoryOperandImpl(*FuncInfo.MF, MI, OpNo, AddrOps, + XII.foldMemoryOperandImpl(*FuncInfo.MF, MI, OpNo, AddrOps, FuncInfo.InsertPt, Size, Alignment, /*AllowCommute=*/true); if (!Result) return false; Result->addMemOperand(*FuncInfo.MF, createMachineMemOperandFor(LI)); - FuncInfo.MBB->insert(FuncInfo.InsertPt, Result); MI->eraseFromParent(); return true; } Index: lib/Target/X86/X86InstrInfo.h =================================================================== --- lib/Target/X86/X86InstrInfo.h +++ lib/Target/X86/X86InstrInfo.h @@ -302,6 +302,7 @@ MachineInstr* foldMemoryOperandImpl(MachineFunction &MF, MachineInstr* MI, const SmallVectorImpl &Ops, + MachineBasicBlock::iterator InsertPt, int FrameIndex) const override; /// foldMemoryOperand - Same as the previous version except it allows folding @@ -310,6 +311,7 @@ MachineInstr* foldMemoryOperandImpl(MachineFunction &MF, MachineInstr* MI, const SmallVectorImpl &Ops, + MachineBasicBlock::iterator InsertPt, MachineInstr* LoadMI) const override; /// canFoldMemoryOperand - Returns true if the specified load / store is @@ -404,6 +406,7 @@ MachineInstr* MI, unsigned OpNum, const SmallVectorImpl &MOs, + MachineBasicBlock::iterator InsertPt, unsigned Size, unsigned Alignment, bool AllowCommute) const; Index: lib/Target/X86/X86InstrInfo.cpp =================================================================== --- lib/Target/X86/X86InstrInfo.cpp +++ lib/Target/X86/X86InstrInfo.cpp @@ -4104,20 +4104,61 @@ return false; } +static unsigned constrainOperandRegClass(MachineFunction &MF, MachineBasicBlock::iterator InsertPt, + DebugLoc DL, + const MCInstrDesc &II, unsigned Op, + unsigned OpNum, const TargetInstrInfo &TII, + MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI) { + if (TargetRegisterInfo::isVirtualRegister(Op)) { + const TargetRegisterClass *RegClass = + TII.getRegClass(II, OpNum, &TRI, MF); + if (!MRI.constrainRegClass(Op, RegClass)) { + // If it's not legal to COPY between the register classes, something + // has gone very wrong before we got here. + unsigned NewOp = MRI.createVirtualRegister(RegClass); + BuildMI(MF, InsertPt, DL, + TII.get(TargetOpcode::COPY), NewOp).addReg(Op); + return NewOp; + } + } + return Op; +} + +static void addOperands(MachineFunction &MF, MachineInstrBuilder &MIB, unsigned Offset, + const MCInstrDesc &Desc, + const SmallVectorImpl &MOs, + MachineBasicBlock::iterator InsertPt, + MachineInstr *MI, + const TargetInstrInfo &TII){ + MachineRegisterInfo &MRI = MF.getRegInfo(); + const TargetRegisterInfo &TRI = *MF.getSubtarget().getRegisterInfo(); + + unsigned NumAddrOps = MOs.size(); + for (unsigned i = 0; i != NumAddrOps; ++i) { + MachineOperand MO = MOs[i]; + if (MO.isReg()) { + MO.setReg(constrainOperandRegClass(MF,InsertPt,MI->getDebugLoc(),Desc, + MO.getReg(),i+Offset,TII,MRI,TRI)); + } + MIB.addOperand(MO); + } + if (NumAddrOps < 4) // FrameIndex only + addOffset(MIB, 0); +} + static MachineInstr *FuseTwoAddrInst(MachineFunction &MF, unsigned Opcode, const SmallVectorImpl &MOs, + MachineBasicBlock::iterator InsertPt, MachineInstr *MI, const TargetInstrInfo &TII) { // Create the base instruction with the memory operand as the first part. // Omit the implicit operands, something BuildMI can't do. - MachineInstr *NewMI = MF.CreateMachineInstr(TII.get(Opcode), + const MCInstrDesc &MCID = TII.get(Opcode); + MachineInstr *NewMI = MF.CreateMachineInstr(MCID, MI->getDebugLoc(), true); MachineInstrBuilder MIB(MF, NewMI); - unsigned NumAddrOps = MOs.size(); - for (unsigned i = 0; i != NumAddrOps; ++i) - MIB.addOperand(MOs[i]); - if (NumAddrOps < 4) // FrameIndex only - addOffset(MIB, 0); + + addOperands(MF,MIB,0,MCID,MOs,InsertPt,MI,TII); // Loop over the rest of the ri operands, converting them over. unsigned NumOps = MI->getDesc().getNumOperands()-2; @@ -4129,15 +4170,21 @@ MachineOperand &MO = MI->getOperand(i); MIB.addOperand(MO); } + + MachineBasicBlock *MBB = InsertPt->getParent(); + MBB->insert(InsertPt, NewMI); + return MIB; } static MachineInstr *FuseInst(MachineFunction &MF, unsigned Opcode, unsigned OpNo, const SmallVectorImpl &MOs, + MachineBasicBlock::iterator InsertPt, MachineInstr *MI, const TargetInstrInfo &TII) { // Omit the implicit operands, something BuildMI can't do. - MachineInstr *NewMI = MF.CreateMachineInstr(TII.get(Opcode), + const MCInstrDesc &MCID = TII.get(Opcode); + MachineInstr *NewMI = MF.CreateMachineInstr(MCID, MI->getDebugLoc(), true); MachineInstrBuilder MIB(MF, NewMI); @@ -4145,29 +4192,32 @@ MachineOperand &MO = MI->getOperand(i); if (i == OpNo) { assert(MO.isReg() && "Expected to fold into reg operand!"); - unsigned NumAddrOps = MOs.size(); - for (unsigned i = 0; i != NumAddrOps; ++i) - MIB.addOperand(MOs[i]); - if (NumAddrOps < 4) // FrameIndex only - addOffset(MIB, 0); + addOperands(MF,MIB,OpNo,MCID,MOs,InsertPt,MI,TII); } else { MIB.addOperand(MO); } } + + MachineBasicBlock *MBB = InsertPt->getParent(); + MBB->insert(InsertPt, NewMI); + return MIB; } static MachineInstr *MakeM0Inst(const TargetInstrInfo &TII, unsigned Opcode, const SmallVectorImpl &MOs, + MachineBasicBlock::iterator InsertPt, MachineInstr *MI) { MachineFunction &MF = *MI->getParent()->getParent(); - MachineInstrBuilder MIB = BuildMI(MF, MI->getDebugLoc(), TII.get(Opcode)); + MachineRegisterInfo &MRI = MF.getRegInfo(); + const MCInstrDesc &MCID = TII.get(Opcode); + MachineInstrBuilder MIB = BuildMI(MF, MI->getDebugLoc(), MCID); + + addOperands(MF,MIB,0,MCID,MOs,InsertPt,MI,TII); + + MachineBasicBlock *MBB = InsertPt->getParent(); + MBB->insert(InsertPt, MIB); - unsigned NumAddrOps = MOs.size(); - for (unsigned i = 0; i != NumAddrOps; ++i) - MIB.addOperand(MOs[i]); - if (NumAddrOps < 4) // FrameIndex only - addOffset(MIB, 0); return MIB.addImm(0); } @@ -4175,12 +4225,14 @@ X86InstrInfo::foldMemoryOperandImpl(MachineFunction &MF, MachineInstr *MI, unsigned i, const SmallVectorImpl &MOs, + MachineBasicBlock::iterator InsertPt, unsigned Size, unsigned Align, bool AllowCommute) const { const DenseMap > *OpcodeTablePtr = nullptr; bool isCallRegIndirect = Subtarget.callRegIndirect(); bool isTwoAddrFold = false; + const MachineRegisterInfo &MRI = MF.getRegInfo(); // Atom favors register form of call. So, we do not fold loads into calls // when X86Subtarget is Atom. @@ -4211,7 +4263,7 @@ isTwoAddrFold = true; } else if (i == 0) { // If operand 0 if (MI->getOpcode() == X86::MOV32r0) { - NewMI = MakeM0Inst(*this, X86::MOV32mi, MOs, MI); + NewMI = MakeM0Inst(*this, X86::MOV32mi, MOs, InsertPt, MI); if (NewMI) return NewMI; } @@ -4254,9 +4306,9 @@ } if (isTwoAddrFold) - NewMI = FuseTwoAddrInst(MF, Opcode, MOs, MI, *this); + NewMI = FuseTwoAddrInst(MF, Opcode, MOs, InsertPt, MI, *this); else - NewMI = FuseInst(MF, Opcode, i, MOs, MI, *this); + NewMI = FuseInst(MF, Opcode, i, MOs, InsertPt, MI, *this); if (NarrowToMOV32rm) { // If this is the special case where we use a MOV32rm to load a 32-bit @@ -4308,7 +4360,7 @@ // Attempt to fold with the commuted version of the instruction. unsigned CommuteOp = (CommuteOpIdx1 == OriginalOpIdx ? CommuteOpIdx2 : CommuteOpIdx1); - NewMI = foldMemoryOperandImpl(MF, MI, CommuteOp, MOs, Size, Align, + NewMI = foldMemoryOperandImpl(MF, MI, CommuteOp, MOs, InsertPt, Size, Align, /*AllowCommute=*/false); if (NewMI) return NewMI; @@ -4497,6 +4549,7 @@ MachineInstr* X86InstrInfo::foldMemoryOperandImpl(MachineFunction &MF, MachineInstr *MI, const SmallVectorImpl &Ops, + MachineBasicBlock::iterator InsertPt, int FrameIndex) const { // Check switch flag if (NoFusing) return nullptr; @@ -4540,7 +4593,7 @@ SmallVector MOs; MOs.push_back(MachineOperand::CreateFI(FrameIndex)); - return foldMemoryOperandImpl(MF, MI, Ops[0], MOs, + return foldMemoryOperandImpl(MF, MI, Ops[0], MOs, InsertPt, Size, Alignment, /*AllowCommute=*/true); } @@ -4564,16 +4617,17 @@ } MachineInstr* X86InstrInfo::foldMemoryOperandImpl(MachineFunction &MF, - MachineInstr *MI, - const SmallVectorImpl &Ops, - MachineInstr *LoadMI) const { + MachineInstr *MI, + const SmallVectorImpl &Ops, + MachineBasicBlock::iterator InsertPt, + MachineInstr *LoadMI) const { // If loading from a FrameIndex, fold directly from the FrameIndex. unsigned NumOps = LoadMI->getDesc().getNumOperands(); int FrameIndex; if (isLoadFromStackSlot(LoadMI, FrameIndex)) { if (isPartialRegisterLoad(*LoadMI, MF)) return nullptr; - return foldMemoryOperandImpl(MF, MI, Ops, FrameIndex); + return foldMemoryOperandImpl(MF, MI, Ops, InsertPt, FrameIndex); } // Check switch flag @@ -4694,7 +4748,7 @@ break; } } - return foldMemoryOperandImpl(MF, MI, Ops[0], MOs, + return foldMemoryOperandImpl(MF, MI, Ops[0], MOs, InsertPt, /*Size=*/0, Alignment, /*AllowCommute=*/true); } Index: test/CodeGen/X86/fast-isel-regclass.ll =================================================================== --- /dev/null +++ test/CodeGen/X86/fast-isel-regclass.ll @@ -0,0 +1,30 @@ +; RUN: llc < %s -fast-isel -mcpu=core2 -O3 -verify-machineinstrs +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-apple-darwin14.0.0" + +define void @julia_ht_keyindex219890() { +top: + br i1 undef, label %idxend, label %oob + +if3: ; preds = %idxend + br i1 undef, label %L5, label %if4 + +oob: ; preds = %top + unreachable + +idxend: ; preds = %top + %0 = getelementptr i8* undef, i64 undef + %1 = load i8* %0 + %2 = icmp eq i8 %1, undef + %3 = xor i1 %2, true + br i1 %3, label %oob9, label %if3 + +if4: ; preds = %if3 + ret void + +L5: ; preds = %if3 + ret void + +oob9: ; preds = %idxend + unreachable +}