diff options
Diffstat (limited to 'llvm/lib/Target')
-rw-r--r-- | llvm/lib/Target/SystemZ/SystemZ.h | 16 | ||||
-rw-r--r-- | llvm/lib/Target/SystemZ/SystemZISelLowering.cpp | 65 | ||||
-rw-r--r-- | llvm/lib/Target/SystemZ/SystemZInstrFormats.td | 20 | ||||
-rw-r--r-- | llvm/lib/Target/SystemZ/SystemZInstrInfo.cpp | 52 | ||||
-rw-r--r-- | llvm/lib/Target/SystemZ/SystemZInstrInfo.h | 8 | ||||
-rw-r--r-- | llvm/lib/Target/SystemZ/SystemZInstrInfo.td | 31 | ||||
-rw-r--r-- | llvm/lib/Target/SystemZ/SystemZLongBranch.cpp | 10 | ||||
-rw-r--r-- | llvm/lib/Target/SystemZ/SystemZOperators.td | 10 | ||||
-rw-r--r-- | llvm/lib/Target/SystemZ/SystemZPatterns.td | 6 |
9 files changed, 137 insertions, 81 deletions
diff --git a/llvm/lib/Target/SystemZ/SystemZ.h b/llvm/lib/Target/SystemZ/SystemZ.h index 24612bbce83..4c1e81a082c 100644 --- a/llvm/lib/Target/SystemZ/SystemZ.h +++ b/llvm/lib/Target/SystemZ/SystemZ.h @@ -30,16 +30,28 @@ namespace llvm { const unsigned CCMASK_3 = 1 << 0; const unsigned CCMASK_ANY = CCMASK_0 | CCMASK_1 | CCMASK_2 | CCMASK_3; - // Condition-code mask assignments for floating-point comparisons. + // Condition-code mask assignments for integer and floating-point + // comparisons. const unsigned CCMASK_CMP_EQ = CCMASK_0; const unsigned CCMASK_CMP_LT = CCMASK_1; const unsigned CCMASK_CMP_GT = CCMASK_2; - const unsigned CCMASK_CMP_UO = CCMASK_3; const unsigned CCMASK_CMP_NE = CCMASK_CMP_LT | CCMASK_CMP_GT; const unsigned CCMASK_CMP_LE = CCMASK_CMP_EQ | CCMASK_CMP_LT; const unsigned CCMASK_CMP_GE = CCMASK_CMP_EQ | CCMASK_CMP_GT; + + // Condition-code mask assignments for floating-point comparisons only. + const unsigned CCMASK_CMP_UO = CCMASK_3; const unsigned CCMASK_CMP_O = CCMASK_ANY ^ CCMASK_CMP_UO; + // All condition-code values produced by comparisons. + const unsigned CCMASK_ICMP = CCMASK_0 | CCMASK_1 | CCMASK_2; + const unsigned CCMASK_FCMP = CCMASK_0 | CCMASK_1 | CCMASK_2 | CCMASK_3; + + // Condition-code mask assignments for CS. + const unsigned CCMASK_CS_EQ = CCMASK_0; + const unsigned CCMASK_CS_NE = CCMASK_1; + const unsigned CCMASK_CS = CCMASK_0 | CCMASK_1; + // Return true if Val fits an LLILL operand. static inline bool isImmLL(uint64_t Val) { return (Val & ~0x000000000000ffffULL) == 0; diff --git a/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp b/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp index d7cd5256e01..34697fed80b 100644 --- a/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp +++ b/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp @@ -1015,15 +1015,21 @@ static bool preferUnsignedComparison(SelectionDAG &DAG, SDValue CmpOp0, return false; } -// Return a target node that compares CmpOp0 and CmpOp1. Set CCMask to the -// 4-bit condition-code mask for CC. +// Return a target node that compares CmpOp0 with CmpOp1 and stores a +// 2-bit result in CC. Set CCValid to the CCMASK_* of all possible +// 2-bit results and CCMask to the subset of those results that are +// associated with Cond. static SDValue emitCmp(SelectionDAG &DAG, SDValue CmpOp0, SDValue CmpOp1, - ISD::CondCode CC, unsigned &CCMask) { + ISD::CondCode Cond, unsigned &CCValid, + unsigned &CCMask) { bool IsUnsigned = false; - CCMask = CCMaskForCondCode(CC); - if (!CmpOp0.getValueType().isFloatingPoint()) { + CCMask = CCMaskForCondCode(Cond); + if (CmpOp0.getValueType().isFloatingPoint()) + CCValid = SystemZ::CCMASK_FCMP; + else { IsUnsigned = CCMask & SystemZ::CCMASK_CMP_UO; - CCMask &= ~SystemZ::CCMASK_CMP_UO; + CCValid = SystemZ::CCMASK_ICMP; + CCMask &= CCValid; adjustSubwordCmp(DAG, IsUnsigned, CmpOp0, CmpOp1, CCMask); if (preferUnsignedComparison(DAG, CmpOp0, CmpOp1, CCMask)) IsUnsigned = true; @@ -1065,10 +1071,11 @@ SDValue SystemZTargetLowering::lowerBR_CC(SDValue Op, SelectionDAG &DAG) const { SDValue Dest = Op.getOperand(4); SDLoc DL(Op); - unsigned CCMask; - SDValue Flags = emitCmp(DAG, CmpOp0, CmpOp1, CC, CCMask); + unsigned CCValid, CCMask; + SDValue Flags = emitCmp(DAG, CmpOp0, CmpOp1, CC, CCValid, CCMask); return DAG.getNode(SystemZISD::BR_CCMASK, DL, Op.getValueType(), - Chain, DAG.getConstant(CCMask, MVT::i32), Dest, Flags); + Chain, DAG.getConstant(CCValid, MVT::i32), + DAG.getConstant(CCMask, MVT::i32), Dest, Flags); } SDValue SystemZTargetLowering::lowerSELECT_CC(SDValue Op, @@ -1080,12 +1087,13 @@ SDValue SystemZTargetLowering::lowerSELECT_CC(SDValue Op, ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(4))->get(); SDLoc DL(Op); - unsigned CCMask; - SDValue Flags = emitCmp(DAG, CmpOp0, CmpOp1, CC, CCMask); + unsigned CCValid, CCMask; + SDValue Flags = emitCmp(DAG, CmpOp0, CmpOp1, CC, CCValid, CCMask); - SmallVector<SDValue, 4> Ops; + SmallVector<SDValue, 5> Ops; Ops.push_back(TrueOp); Ops.push_back(FalseOp); + Ops.push_back(DAG.getConstant(CCValid, MVT::i32)); Ops.push_back(DAG.getConstant(CCMask, MVT::i32)); Ops.push_back(Flags); @@ -1704,7 +1712,8 @@ SystemZTargetLowering::emitSelect(MachineInstr *MI, unsigned DestReg = MI->getOperand(0).getReg(); unsigned TrueReg = MI->getOperand(1).getReg(); unsigned FalseReg = MI->getOperand(2).getReg(); - unsigned CCMask = MI->getOperand(3).getImm(); + unsigned CCValid = MI->getOperand(3).getImm(); + unsigned CCMask = MI->getOperand(4).getImm(); DebugLoc DL = MI->getDebugLoc(); MachineBasicBlock *StartMBB = MBB; @@ -1715,7 +1724,8 @@ SystemZTargetLowering::emitSelect(MachineInstr *MI, // BRC CCMask, JoinMBB // # fallthrough to FalseMBB MBB = StartMBB; - BuildMI(MBB, DL, TII->get(SystemZ::BRC)).addImm(CCMask).addMBB(JoinMBB); + BuildMI(MBB, DL, TII->get(SystemZ::BRC)) + .addImm(CCValid).addImm(CCMask).addMBB(JoinMBB); MBB->addSuccessor(JoinMBB); MBB->addSuccessor(FalseMBB); @@ -1751,7 +1761,8 @@ SystemZTargetLowering::emitCondStore(MachineInstr *MI, MachineOperand Base = MI->getOperand(1); int64_t Disp = MI->getOperand(2).getImm(); unsigned IndexReg = MI->getOperand(3).getReg(); - unsigned CCMask = MI->getOperand(4).getImm(); + unsigned CCValid = MI->getOperand(4).getImm(); + unsigned CCMask = MI->getOperand(5).getImm(); DebugLoc DL = MI->getDebugLoc(); StoreOpcode = TII->getOpcodeForOffset(StoreOpcode, Disp); @@ -1761,7 +1772,7 @@ SystemZTargetLowering::emitCondStore(MachineInstr *MI, // might be more complicated in that case. if (STOCOpcode && !IndexReg && TM.getSubtargetImpl()->hasLoadStoreOnCond()) { if (Invert) - CCMask = CCMask ^ SystemZ::CCMASK_ANY; + CCMask ^= CCValid; BuildMI(*MBB, MI, DL, TII->get(STOCOpcode)) .addReg(SrcReg).addOperand(Base).addImm(Disp).addImm(CCMask); MI->eraseFromParent(); @@ -1770,7 +1781,7 @@ SystemZTargetLowering::emitCondStore(MachineInstr *MI, // Get the condition needed to branch around the store. if (!Invert) - CCMask = CCMask ^ SystemZ::CCMASK_ANY; + CCMask ^= CCValid; MachineBasicBlock *StartMBB = MBB; MachineBasicBlock *JoinMBB = splitBlockAfter(MI, MBB); @@ -1780,7 +1791,8 @@ SystemZTargetLowering::emitCondStore(MachineInstr *MI, // BRC CCMask, JoinMBB // # fallthrough to FalseMBB MBB = StartMBB; - BuildMI(MBB, DL, TII->get(SystemZ::BRC)).addImm(CCMask).addMBB(JoinMBB); + BuildMI(MBB, DL, TII->get(SystemZ::BRC)) + .addImm(CCValid).addImm(CCMask).addMBB(JoinMBB); MBB->addSuccessor(JoinMBB); MBB->addSuccessor(FalseMBB); @@ -1812,7 +1824,6 @@ SystemZTargetLowering::emitAtomicLoadBinary(MachineInstr *MI, const SystemZInstrInfo *TII = TM.getInstrInfo(); MachineFunction &MF = *MBB->getParent(); MachineRegisterInfo &MRI = MF.getRegInfo(); - unsigned MaskNE = CCMaskForCondCode(ISD::SETNE); bool IsSubWord = (BitSize < 32); // Extract the operands. Base can be a register or a frame index. @@ -1912,7 +1923,8 @@ SystemZTargetLowering::emitAtomicLoadBinary(MachineInstr *MI, .addReg(RotatedNewVal).addReg(NegBitShift).addImm(0); BuildMI(MBB, DL, TII->get(CSOpcode), Dest) .addReg(OldVal).addReg(NewVal).addOperand(Base).addImm(Disp); - BuildMI(MBB, DL, TII->get(SystemZ::BRC)).addImm(MaskNE).addMBB(LoopMBB); + BuildMI(MBB, DL, TII->get(SystemZ::BRC)) + .addImm(SystemZ::CCMASK_CS).addImm(SystemZ::CCMASK_CS_NE).addMBB(LoopMBB); MBB->addSuccessor(LoopMBB); MBB->addSuccessor(DoneMBB); @@ -1935,7 +1947,6 @@ SystemZTargetLowering::emitAtomicLoadMinMax(MachineInstr *MI, const SystemZInstrInfo *TII = TM.getInstrInfo(); MachineFunction &MF = *MBB->getParent(); MachineRegisterInfo &MRI = MF.getRegInfo(); - unsigned MaskNE = CCMaskForCondCode(ISD::SETNE); bool IsSubWord = (BitSize < 32); // Extract the operands. Base can be a register or a frame index. @@ -2000,7 +2011,7 @@ SystemZTargetLowering::emitAtomicLoadMinMax(MachineInstr *MI, BuildMI(MBB, DL, TII->get(CompareOpcode)) .addReg(RotatedOldVal).addReg(Src2); BuildMI(MBB, DL, TII->get(SystemZ::BRC)) - .addImm(KeepOldMask).addMBB(UpdateMBB); + .addImm(SystemZ::CCMASK_ICMP).addImm(KeepOldMask).addMBB(UpdateMBB); MBB->addSuccessor(UpdateMBB); MBB->addSuccessor(UseAltMBB); @@ -2030,7 +2041,8 @@ SystemZTargetLowering::emitAtomicLoadMinMax(MachineInstr *MI, .addReg(RotatedNewVal).addReg(NegBitShift).addImm(0); BuildMI(MBB, DL, TII->get(CSOpcode), Dest) .addReg(OldVal).addReg(NewVal).addOperand(Base).addImm(Disp); - BuildMI(MBB, DL, TII->get(SystemZ::BRC)).addImm(MaskNE).addMBB(LoopMBB); + BuildMI(MBB, DL, TII->get(SystemZ::BRC)) + .addImm(SystemZ::CCMASK_CS).addImm(SystemZ::CCMASK_CS_NE).addMBB(LoopMBB); MBB->addSuccessor(LoopMBB); MBB->addSuccessor(DoneMBB); @@ -2046,7 +2058,6 @@ SystemZTargetLowering::emitAtomicCmpSwapW(MachineInstr *MI, const SystemZInstrInfo *TII = TM.getInstrInfo(); MachineFunction &MF = *MBB->getParent(); MachineRegisterInfo &MRI = MF.getRegInfo(); - unsigned MaskNE = CCMaskForCondCode(ISD::SETNE); // Extract the operands. Base can be a register or a frame index. unsigned Dest = MI->getOperand(0).getReg(); @@ -2122,7 +2133,8 @@ SystemZTargetLowering::emitAtomicCmpSwapW(MachineInstr *MI, BuildMI(MBB, DL, TII->get(SystemZ::CR)) .addReg(Dest).addReg(RetryCmpVal); BuildMI(MBB, DL, TII->get(SystemZ::BRC)) - .addImm(MaskNE).addMBB(DoneMBB); + .addImm(SystemZ::CCMASK_ICMP) + .addImm(SystemZ::CCMASK_CMP_NE).addMBB(DoneMBB); MBB->addSuccessor(DoneMBB); MBB->addSuccessor(SetMBB); @@ -2142,7 +2154,8 @@ SystemZTargetLowering::emitAtomicCmpSwapW(MachineInstr *MI, .addReg(RetrySwapVal).addReg(NegBitShift).addImm(-BitSize); BuildMI(MBB, DL, TII->get(CSOpcode), RetryOldVal) .addReg(OldVal).addReg(StoreVal).addOperand(Base).addImm(Disp); - BuildMI(MBB, DL, TII->get(SystemZ::BRC)).addImm(MaskNE).addMBB(LoopMBB); + BuildMI(MBB, DL, TII->get(SystemZ::BRC)) + .addImm(SystemZ::CCMASK_CS).addImm(SystemZ::CCMASK_CS_NE).addMBB(LoopMBB); MBB->addSuccessor(LoopMBB); MBB->addSuccessor(DoneMBB); diff --git a/llvm/lib/Target/SystemZ/SystemZInstrFormats.td b/llvm/lib/Target/SystemZ/SystemZInstrFormats.td index 1c55da4f581..c0bb7b73c76 100644 --- a/llvm/lib/Target/SystemZ/SystemZInstrFormats.td +++ b/llvm/lib/Target/SystemZ/SystemZInstrFormats.td @@ -684,7 +684,7 @@ class UnaryRRF<string mnemonic, bits<16> opcode, RegisterOperand cls1, // is added as an implicit use. class CondUnaryRRF<string mnemonic, bits<16> opcode, RegisterOperand cls1, RegisterOperand cls2> - : InstRRF<opcode, (outs cls1:$R1), (ins cls2:$R2, cond4:$R3), + : InstRRF<opcode, (outs cls1:$R1), (ins cls2:$R2, cond4:$valid, cond4:$R3), mnemonic#"r$R3\t$R1, $R2", []>, Requires<[FeatureLoadStoreOnCond]>; @@ -1256,8 +1256,10 @@ class Pseudo<dag outs, dag ins, list<dag> pattern> // Implements "$dst = $cc & (8 >> CC) ? $src1 : $src2", where CC is // the value of the PSW's 2-bit condition code field. class SelectWrapper<RegisterOperand cls> - : Pseudo<(outs cls:$dst), (ins cls:$src1, cls:$src2, i8imm:$cc), - [(set cls:$dst, (z_select_ccmask cls:$src1, cls:$src2, imm:$cc))]> { + : Pseudo<(outs cls:$dst), + (ins cls:$src1, cls:$src2, uimm8zx4:$valid, uimm8zx4:$cc), + [(set cls:$dst, (z_select_ccmask cls:$src1, cls:$src2, + uimm8zx4:$valid, uimm8zx4:$cc))]> { let usesCustomInserter = 1; // Although the instructions used by these nodes do not in themselves // change CC, the insertion requires new blocks, and CC cannot be live @@ -1270,12 +1272,16 @@ class SelectWrapper<RegisterOperand cls> multiclass CondStores<RegisterOperand cls, SDPatternOperator store, SDPatternOperator load, AddressingMode mode> { let Defs = [CC], Uses = [CC], usesCustomInserter = 1 in { - def "" : Pseudo<(outs), (ins cls:$new, mode:$addr, uimm8zx4:$cc), + def "" : Pseudo<(outs), + (ins cls:$new, mode:$addr, uimm8zx4:$valid, uimm8zx4:$cc), [(store (z_select_ccmask cls:$new, (load mode:$addr), - uimm8zx4:$cc), mode:$addr)]>; - def Inv : Pseudo<(outs), (ins cls:$new, mode:$addr, uimm8zx4:$cc), + uimm8zx4:$valid, uimm8zx4:$cc), + mode:$addr)]>; + def Inv : Pseudo<(outs), + (ins cls:$new, mode:$addr, uimm8zx4:$valid, uimm8zx4:$cc), [(store (z_select_ccmask (load mode:$addr), cls:$new, - uimm8zx4:$cc), mode:$addr)]>; + uimm8zx4:$valid, uimm8zx4:$cc), + mode:$addr)]>; } } diff --git a/llvm/lib/Target/SystemZ/SystemZInstrInfo.cpp b/llvm/lib/Target/SystemZ/SystemZInstrInfo.cpp index dfb5c0983cc..2b604a99fdb 100644 --- a/llvm/lib/Target/SystemZ/SystemZInstrInfo.cpp +++ b/llvm/lib/Target/SystemZ/SystemZInstrInfo.cpp @@ -201,13 +201,13 @@ bool SystemZInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB, // FIXME: add X86-style branch swap FBB = TBB; TBB = Branch.Target->getMBB(); + Cond.push_back(MachineOperand::CreateImm(Branch.CCValid)); Cond.push_back(MachineOperand::CreateImm(Branch.CCMask)); continue; } // Handle subsequent conditional branches. - assert(Cond.size() == 1); - assert(TBB); + assert(Cond.size() == 2 && TBB && "Should have seen a conditional branch"); // Only handle the case where all conditional branches branch to the same // destination. @@ -215,11 +215,13 @@ bool SystemZInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB, return true; // If the conditions are the same, we can leave them alone. - unsigned OldCond = Cond[0].getImm(); - if (OldCond == Branch.CCMask) + unsigned OldCCValid = Cond[0].getImm(); + unsigned OldCCMask = Cond[1].getImm(); + if (OldCCValid == Branch.CCValid && OldCCMask == Branch.CCMask) continue; // FIXME: Try combining conditions like X86 does. Should be easy on Z! + return false; } return false; @@ -247,6 +249,13 @@ unsigned SystemZInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const { return Count; } +bool SystemZInstrInfo:: +ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const { + assert(Cond.size() == 2 && "Invalid condition"); + Cond[1].setImm(Cond[1].getImm() ^ Cond[0].getImm()); + return false; +} + unsigned SystemZInstrInfo::InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB, @@ -258,7 +267,7 @@ SystemZInstrInfo::InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, // Shouldn't be a fall through. assert(TBB && "InsertBranch must not be told to insert a fallthrough"); - assert((Cond.size() == 1 || Cond.size() == 0) && + assert((Cond.size() == 2 || Cond.size() == 0) && "SystemZ branch conditions have one component!"); if (Cond.empty()) { @@ -270,8 +279,10 @@ SystemZInstrInfo::InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, // Conditional branch. unsigned Count = 0; - unsigned CC = Cond[0].getImm(); - BuildMI(&MBB, DL, get(SystemZ::BRC)).addImm(CC).addMBB(TBB); + unsigned CCValid = Cond[0].getImm(); + unsigned CCMask = Cond[1].getImm(); + BuildMI(&MBB, DL, get(SystemZ::BRC)) + .addImm(CCValid).addImm(CCMask).addMBB(TBB); ++Count; if (FBB) { @@ -321,13 +332,16 @@ isProfitableToIfCvt(MachineBasicBlock &TMBB, bool SystemZInstrInfo:: PredicateInstruction(MachineInstr *MI, const SmallVectorImpl<MachineOperand> &Pred) const { - unsigned CCMask = Pred[0].getImm(); + assert(Pred.size() == 2 && "Invalid condition"); + unsigned CCValid = Pred[0].getImm(); + unsigned CCMask = Pred[1].getImm(); assert(CCMask > 0 && CCMask < 15 && "Invalid predicate"); unsigned Opcode = MI->getOpcode(); if (TM.getSubtargetImpl()->hasLoadStoreOnCond()) { if (unsigned CondOpcode = getConditionalMove(Opcode)) { MI->setDesc(get(CondOpcode)); - MachineInstrBuilder(*MI->getParent()->getParent(), MI).addImm(CCMask); + MachineInstrBuilder(*MI->getParent()->getParent(), MI) + .addImm(CCValid).addImm(CCMask); return true; } } @@ -645,13 +659,6 @@ SystemZInstrInfo::expandPostRAPseudo(MachineBasicBlock::iterator MI) const { } } -bool SystemZInstrInfo:: -ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const { - assert(Cond.size() == 1 && "Invalid branch condition!"); - Cond[0].setImm(Cond[0].getImm() ^ SystemZ::CCMASK_ANY); - return false; -} - uint64_t SystemZInstrInfo::getInstSizeInBytes(const MachineInstr *MI) const { if (MI->getOpcode() == TargetOpcode::INLINEASM) { const MachineFunction *MF = MI->getParent()->getParent(); @@ -668,22 +675,23 @@ SystemZInstrInfo::getBranchInfo(const MachineInstr *MI) const { case SystemZ::J: case SystemZ::JG: return SystemZII::Branch(SystemZII::BranchNormal, SystemZ::CCMASK_ANY, - &MI->getOperand(0)); + SystemZ::CCMASK_ANY, &MI->getOperand(0)); case SystemZ::BRC: case SystemZ::BRCL: return SystemZII::Branch(SystemZII::BranchNormal, - MI->getOperand(0).getImm(), &MI->getOperand(1)); + MI->getOperand(0).getImm(), + MI->getOperand(1).getImm(), &MI->getOperand(2)); case SystemZ::CIJ: case SystemZ::CRJ: - return SystemZII::Branch(SystemZII::BranchC, MI->getOperand(2).getImm(), - &MI->getOperand(3)); + return SystemZII::Branch(SystemZII::BranchC, SystemZ::CCMASK_ICMP, + MI->getOperand(2).getImm(), &MI->getOperand(3)); case SystemZ::CGIJ: case SystemZ::CGRJ: - return SystemZII::Branch(SystemZII::BranchCG, MI->getOperand(2).getImm(), - &MI->getOperand(3)); + return SystemZII::Branch(SystemZII::BranchCG, SystemZ::CCMASK_ICMP, + MI->getOperand(2).getImm(), &MI->getOperand(3)); default: llvm_unreachable("Unrecognized branch opcode"); diff --git a/llvm/lib/Target/SystemZ/SystemZInstrInfo.h b/llvm/lib/Target/SystemZ/SystemZInstrInfo.h index 7617d03ddc7..917ac6e348e 100644 --- a/llvm/lib/Target/SystemZ/SystemZInstrInfo.h +++ b/llvm/lib/Target/SystemZ/SystemZInstrInfo.h @@ -66,14 +66,18 @@ namespace SystemZII { // The type of the branch. BranchType Type; + // CCMASK_<N> is set if CC might be equal to N. + unsigned CCValid; + // CCMASK_<N> is set if the branch should be taken when CC == N. unsigned CCMask; // The target of the branch. const MachineOperand *Target; - Branch(BranchType type, unsigned ccMask, const MachineOperand *target) - : Type(type), CCMask(ccMask), Target(target) {} + Branch(BranchType type, unsigned ccValid, unsigned ccMask, + const MachineOperand *target) + : Type(type), CCValid(ccValid), CCMask(ccMask), Target(target) {} }; } diff --git a/llvm/lib/Target/SystemZ/SystemZInstrInfo.td b/llvm/lib/Target/SystemZ/SystemZInstrInfo.td index b3ea36db7d6..a6efd41d043 100644 --- a/llvm/lib/Target/SystemZ/SystemZInstrInfo.td +++ b/llvm/lib/Target/SystemZ/SystemZInstrInfo.td @@ -58,17 +58,19 @@ let isBranch = 1, isTerminator = 1, isBarrier = 1, R1 = 15 in { // in their raw BRC/BRCL form, with the 4-bit condition-code mask being // the first operand. It seems friendlier to use mnemonic forms like // JE and JLH when writing out the assembly though. -multiclass CondBranches<Operand ccmask, string short, string long> { - let isBranch = 1, isTerminator = 1, Uses = [CC] in { - def "" : InstRI<0xA74, (outs), (ins ccmask:$R1, brtarget16:$I2), short, []>; - def L : InstRIL<0xC04, (outs), (ins ccmask:$R1, brtarget32:$I2), long, []>; +let isBranch = 1, isTerminator = 1, Uses = [CC] in { + let isCodeGenOnly = 1 in { + def BRC : InstRI<0xA74, (outs), (ins cond4:$valid, cond4:$R1, + brtarget16:$I2), "j$R1\t$I2", + [(z_br_ccmask cond4:$valid, cond4:$R1, bb:$I2)]>; + def BRCL : InstRIL<0xC04, (outs), (ins cond4:$valid, cond4:$R1, + brtarget32:$I2), "jg$R1\t$I2", []>; } + def AsmBRC : InstRI<0xA74, (outs), (ins uimm8zx4:$R1, brtarget16:$I2), + "brc\t$R1, $I2", []>; + def AsmBRCL : InstRIL<0xC04, (outs), (ins uimm8zx4:$R1, brtarget32:$I2), + "brcl\t$R1, $I2", []>; } -let isCodeGenOnly = 1 in - defm BRC : CondBranches<cond4, "j$R1\t$I2", "jg$R1\t$I2">; -defm AsmBRC : CondBranches<uimm8zx4, "brc\t$R1, $I2", "brcl\t$R1, $I2">; - -def : Pat<(z_br_ccmask cond4:$cond, bb:$dst), (BRC cond4:$cond, bb:$dst)>; // Fused compare-and-branch instructions. As for normal branches, // we handle these instructions internally in their raw CRJ-like form, @@ -1136,9 +1138,12 @@ def : Pat<(sub GR64:$src1, (zextloadi32 bdxaddr20only:$addr)), // Optimize sign-extended 1/0 selects to -1/0 selects. This is important // for vector legalization. -def : Pat<(sra (shl (i32 (z_select_ccmask 1, 0, imm:$cc)), (i32 31)), (i32 31)), - (Select32 (LHI -1), (LHI 0), imm:$cc)>; -def : Pat<(sra (shl (i64 (anyext (i32 (z_select_ccmask 1, 0, imm:$cc)))), +def : Pat<(sra (shl (i32 (z_select_ccmask 1, 0, uimm8zx4:$valid, uimm8zx4:$cc)), + (i32 31)), + (i32 31)), + (Select32 (LHI -1), (LHI 0), uimm8zx4:$valid, uimm8zx4:$cc)>; +def : Pat<(sra (shl (i64 (anyext (i32 (z_select_ccmask 1, 0, uimm8zx4:$valid, + uimm8zx4:$cc)))), (i32 63)), (i32 63)), - (Select64 (LGHI -1), (LGHI 0), imm:$cc)>; + (Select64 (LGHI -1), (LGHI 0), uimm8zx4:$valid, uimm8zx4:$cc)>; diff --git a/llvm/lib/Target/SystemZ/SystemZLongBranch.cpp b/llvm/lib/Target/SystemZ/SystemZLongBranch.cpp index 2d2605886b5..9b637c01c6e 100644 --- a/llvm/lib/Target/SystemZ/SystemZLongBranch.cpp +++ b/llvm/lib/Target/SystemZ/SystemZLongBranch.cpp @@ -297,13 +297,16 @@ bool SystemZLongBranch::fuseCompareAndBranch(MachineInstr *Compare) { for (++MBBI; MBBI != MBBE; ++MBBI) { if (MBBI->getOpcode() == SystemZ::BRC && !isCCLiveAfter(MBBI, TRI)) { // Read the branch mask and target. - MachineOperand CCMask(MBBI->getOperand(0)); - MachineOperand Target(MBBI->getOperand(1)); + MachineOperand CCMask(MBBI->getOperand(1)); + MachineOperand Target(MBBI->getOperand(2)); + assert((CCMask.getImm() & ~SystemZ::CCMASK_ICMP) == 0 && + "Invalid condition-code mask for integer comparison"); // Clear out all current operands. int CCUse = MBBI->findRegisterUseOperandIdx(SystemZ::CC, false, TRI); assert(CCUse >= 0 && "BRC must use CC"); MBBI->RemoveOperand(CCUse); + MBBI->RemoveOperand(2); MBBI->RemoveOperand(1); MBBI->RemoveOperand(0); @@ -441,10 +444,11 @@ void SystemZLongBranch::splitCompareBranch(MachineInstr *MI, .addOperand(MI->getOperand(0)) .addOperand(MI->getOperand(1)); MachineInstr *BRCL = BuildMI(*MBB, MI, DL, TII->get(SystemZ::BRCL)) + .addImm(SystemZ::CCMASK_ICMP) .addOperand(MI->getOperand(2)) .addOperand(MI->getOperand(3)); // The implicit use of CC is a killing use. - BRCL->getOperand(2).setIsKill(); + BRCL->addRegisterKilled(SystemZ::CC, &TII->getRegisterInfo()); MI->eraseFromParent(); } diff --git a/llvm/lib/Target/SystemZ/SystemZOperators.td b/llvm/lib/Target/SystemZ/SystemZOperators.td index 693f3a1e166..6a3af2b8905 100644 --- a/llvm/lib/Target/SystemZ/SystemZOperators.td +++ b/llvm/lib/Target/SystemZ/SystemZOperators.td @@ -15,13 +15,15 @@ def SDT_CallSeqEnd : SDCallSeqEnd<[SDTCisVT<0, i64>, SDTCisVT<1, i64>]>; def SDT_ZCall : SDTypeProfile<0, -1, [SDTCisPtrTy<0>]>; def SDT_ZCmp : SDTypeProfile<0, 2, [SDTCisSameAs<0, 1>]>; -def SDT_ZBRCCMask : SDTypeProfile<0, 2, +def SDT_ZBRCCMask : SDTypeProfile<0, 3, [SDTCisVT<0, i8>, - SDTCisVT<1, OtherVT>]>; -def SDT_ZSelectCCMask : SDTypeProfile<1, 3, + SDTCisVT<1, i8>, + SDTCisVT<2, OtherVT>]>; +def SDT_ZSelectCCMask : SDTypeProfile<1, 4, [SDTCisSameAs<0, 1>, SDTCisSameAs<1, 2>, - SDTCisVT<3, i8>]>; + SDTCisVT<3, i8>, + SDTCisVT<4, i8>]>; def SDT_ZWrapPtr : SDTypeProfile<1, 1, [SDTCisSameAs<0, 1>, SDTCisPtrTy<0>]>; diff --git a/llvm/lib/Target/SystemZ/SystemZPatterns.td b/llvm/lib/Target/SystemZ/SystemZPatterns.td index 4e4386a3984..5419c2badf9 100644 --- a/llvm/lib/Target/SystemZ/SystemZPatterns.td +++ b/llvm/lib/Target/SystemZ/SystemZPatterns.td @@ -58,10 +58,12 @@ multiclass RMWIByte<SDPatternOperator operator, AddressingMode mode, // register of class CLS. The load may trap even if the condition is false. multiclass CondLoad<Instruction insn, RegisterOperand cls, SDPatternOperator load> { - def : Pat<(z_select_ccmask (load bdaddr20only:$addr), cls:$new, uimm8zx4:$cc), + def : Pat<(z_select_ccmask (load bdaddr20only:$addr), cls:$new, uimm8zx4, + uimm8zx4:$cc), (insn cls:$new, bdaddr20only:$addr, uimm8zx4:$cc)>, Requires<[FeatureLoadStoreOnCond]>; - def : Pat<(z_select_ccmask cls:$new, (load bdaddr20only:$addr), uimm8zx4:$cc), + def : Pat<(z_select_ccmask cls:$new, (load bdaddr20only:$addr), uimm8zx4, + uimm8zx4:$cc), (insn cls:$new, bdaddr20only:$addr, (INVCC uimm8zx4:$cc))>, Requires<[FeatureLoadStoreOnCond]>; } |