Index: include/llvm/Target/TargetInstrInfo.h =================================================================== --- include/llvm/Target/TargetInstrInfo.h +++ include/llvm/Target/TargetInstrInfo.h @@ -21,6 +21,7 @@ #include "llvm/MC/MCInstrInfo.h" #include "llvm/Support/BranchProbability.h" #include "llvm/Target/TargetRegisterInfo.h" +#include "llvm/CodeGen/LiveIntervalAnalysis.h" namespace llvm { @@ -799,7 +800,8 @@ /// The new instruction is inserted before MI, and the client is responsible /// for removing the old instruction. MachineInstr *foldMemoryOperand(MachineBasicBlock::iterator MI, - ArrayRef Ops, int FrameIndex) const; + ArrayRef Ops, int FrameIndex, + LiveIntervals &LIS) const; /// Same as the previous version except it allows folding of any load and /// store from / to any address, not just from a specific stack slot. @@ -884,7 +886,8 @@ /// at InsertPt. virtual MachineInstr *foldMemoryOperandImpl( MachineFunction &MF, MachineInstr *MI, ArrayRef Ops, - MachineBasicBlock::iterator InsertPt, int FrameIndex) const { + MachineBasicBlock::iterator InsertPt, int FrameIndex, + LiveIntervals &LIS) const { return nullptr; } Index: lib/CodeGen/InlineSpiller.cpp =================================================================== --- lib/CodeGen/InlineSpiller.cpp +++ lib/CodeGen/InlineSpiller.cpp @@ -762,7 +762,7 @@ MachineInstr *FoldMI = LoadMI ? TII.foldMemoryOperand(MI, FoldOps, LoadMI) - : TII.foldMemoryOperand(MI, FoldOps, StackSlot); + : TII.foldMemoryOperand(MI, FoldOps, StackSlot, LIS); if (!FoldMI) return false; Index: lib/CodeGen/TargetInstrInfo.cpp =================================================================== --- lib/CodeGen/TargetInstrInfo.cpp +++ lib/CodeGen/TargetInstrInfo.cpp @@ -497,7 +497,8 @@ /// stream. MachineInstr *TargetInstrInfo::foldMemoryOperand(MachineBasicBlock::iterator MI, ArrayRef Ops, - int FI) const { + int FI, + LiveIntervals &LIS) const { unsigned Flags = 0; for (unsigned i = 0, e = Ops.size(); i != e; ++i) if (MI->getOperand(Ops[i]).isDef()) @@ -519,7 +520,7 @@ MBB->insert(MI, NewMI); } else { // Ask the target to do the actual folding. - NewMI = foldMemoryOperandImpl(MF, MI, Ops, MI, FI); + NewMI = foldMemoryOperandImpl(MF, MI, Ops, MI, FI, LIS); } if (NewMI) { Index: lib/Target/SystemZ/SystemZInstrInfo.h =================================================================== --- lib/Target/SystemZ/SystemZInstrInfo.h +++ lib/Target/SystemZ/SystemZInstrInfo.h @@ -202,7 +202,8 @@ MachineInstr *foldMemoryOperandImpl(MachineFunction &MF, MachineInstr *MI, ArrayRef Ops, MachineBasicBlock::iterator InsertPt, - int FrameIndex) const override; + int FrameIndex, + LiveIntervals &LIS) const override; MachineInstr *foldMemoryOperandImpl(MachineFunction &MF, MachineInstr *MI, ArrayRef Ops, MachineBasicBlock::iterator InsertPt, Index: lib/Target/SystemZ/SystemZInstrInfo.cpp =================================================================== --- lib/Target/SystemZ/SystemZInstrInfo.cpp +++ lib/Target/SystemZ/SystemZInstrInfo.cpp @@ -15,6 +15,7 @@ #include "SystemZInstrBuilder.h" #include "SystemZTargetMachine.h" #include "llvm/CodeGen/LiveVariables.h" +#include "llvm/CodeGen/LiveIntervalAnalysis.h" #include "llvm/CodeGen/MachineRegisterInfo.h" using namespace llvm; @@ -846,31 +847,38 @@ MachineInstr *SystemZInstrInfo::foldMemoryOperandImpl( MachineFunction &MF, MachineInstr *MI, ArrayRef Ops, - MachineBasicBlock::iterator InsertPt, int FrameIndex) const { + MachineBasicBlock::iterator InsertPt, int FrameIndex, + LiveIntervals &LIS) const { + const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo(); const MachineFrameInfo *MFI = MF.getFrameInfo(); unsigned Size = MFI->getObjectSize(FrameIndex); unsigned Opcode = MI->getOpcode(); -// XXX This is an introduction of a CC def and is illegal! Reactivate -// with a check of liveness of CC reg. -#if 0 if (Ops.size() == 2 && Ops[0] == 0 && Ops[1] == 1) { if ((Opcode == SystemZ::LA || Opcode == SystemZ::LAY) && isInt<8>(MI->getOperand(2).getImm()) && !MI->getOperand(3).getReg()) { - // LA(Y) %reg, CONST(%reg) -> AGSI %mem, CONST - MachineInstr *BuiltMI = - BuildMI(*InsertPt->getParent(), InsertPt, MI->getDebugLoc(), - get(SystemZ::AGSI)) + + // Check CC liveness, since new instruction introduces a dead + // def of CC. + LiveRange &CCLiveRange = + LIS.getRegUnit(*MCRegUnitIterator(SystemZ::CC, TRI)); + SlotIndex MISlot = LIS.getSlotIndexes()->getInstructionIndex(*MI); + if (!CCLiveRange.liveAt(MISlot)) { + // LA(Y) %reg, CONST(%reg) -> AGSI %mem, CONST + MachineInstr *BuiltMI = + BuildMI(*InsertPt->getParent(), InsertPt, MI->getDebugLoc(), + get(SystemZ::AGSI)) .addFrameIndex(FrameIndex) .addImm(0) .addImm(MI->getOperand(2).getImm()); - BuiltMI->findRegisterDefOperand(SystemZ::CC)->setIsDead(true); - return BuiltMI; + BuiltMI->findRegisterDefOperand(SystemZ::CC)->setIsDead(true); + CCLiveRange.createDeadDef(MISlot, LIS.getVNInfoAllocator()); + return BuiltMI; + } } return nullptr; } -#endif // All other cases require a single operand. if (Ops.size() != 1) Index: test/CodeGen/SystemZ/int-add-12.ll =================================================================== --- test/CodeGen/SystemZ/int-add-12.ll +++ test/CodeGen/SystemZ/int-add-12.ll @@ -130,7 +130,7 @@ ; Check that adding 127 to a spilled value can use AGSI. define void @f11(i64 *%ptr, i32 %sel) { ; CHECK-LABEL: f11: -; _CHECK: agsi {{[0-9]+}}(%r15), 127 +; CHECK: agsi {{[0-9]+}}(%r15), 127 ; CHECK: br %r14 entry: %val0 = load volatile i64 , i64 *%ptr