From 3c380d5e28f86984b147fcd424736c498773f37e Mon Sep 17 00:00:00 2001 From: Daniel Sanders Date: Wed, 28 Aug 2013 12:14:50 +0000 Subject: [PATCH] [mips][msa] Added bnz.df, bnz.v, bz.df, and bz.v These intrinsics are legalized to V(ALL|ANY)_(NON)?ZERO nodes, are matched as SN?Z_[BHWDV]_PSEUDO pseudo's, and emitted as a branch/mov sequence to evaluate to 0 or 1. Note: The resulting code is sub-optimal since it doesnt seem to be possible to feed the result of an intrinsic directly into a brcond. At the moment it uses (SETCC (VALL_ZERO $ws), 0, SETEQ) and similar which unnecessarily evaluates the boolean twice. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@189478 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/IR/IntrinsicsMips.td | 24 +++++++ lib/Target/Mips/MipsISelLowering.cpp | 4 ++ lib/Target/Mips/MipsISelLowering.h | 6 ++ lib/Target/Mips/MipsMSAInstrFormats.td | 5 ++ lib/Target/Mips/MipsMSAInstrInfo.td | 95 ++++++++++++++++++++++++++- lib/Target/Mips/MipsSEISelLowering.cpp | 114 ++++++++++++++++++++++++++++++++- lib/Target/Mips/MipsSEISelLowering.h | 3 + test/CodeGen/Mips/msa/i10.ll | 88 +++++++++++++++++++++++++ test/CodeGen/Mips/msa/vecs10.ll | 46 +++++++++++++ 9 files changed, 383 insertions(+), 2 deletions(-) create mode 100644 test/CodeGen/Mips/msa/i10.ll create mode 100644 test/CodeGen/Mips/msa/vecs10.ll diff --git a/include/llvm/IR/IntrinsicsMips.td b/include/llvm/IR/IntrinsicsMips.td index c8178a91ac7..202bc37db01 100644 --- a/include/llvm/IR/IntrinsicsMips.td +++ b/include/llvm/IR/IntrinsicsMips.td @@ -631,6 +631,18 @@ def int_mips_bnegi_w : GCCBuiltin<"__builtin_msa_bnegi_w">, def int_mips_bnegi_d : GCCBuiltin<"__builtin_msa_bnegi_d">, Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem]>; +def int_mips_bnz_b : GCCBuiltin<"__builtin_msa_bnz_b">, + Intrinsic<[llvm_i32_ty], [llvm_v16i8_ty], [IntrNoMem]>; +def int_mips_bnz_h : GCCBuiltin<"__builtin_msa_bnz_h">, + Intrinsic<[llvm_i32_ty], [llvm_v8i16_ty], [IntrNoMem]>; +def int_mips_bnz_w : GCCBuiltin<"__builtin_msa_bnz_w">, + Intrinsic<[llvm_i32_ty], [llvm_v4i32_ty], [IntrNoMem]>; +def int_mips_bnz_d : GCCBuiltin<"__builtin_msa_bnz_d">, + Intrinsic<[llvm_i32_ty], [llvm_v2i64_ty], [IntrNoMem]>; + +def int_mips_bnz_v : GCCBuiltin<"__builtin_msa_bnz_v">, + Intrinsic<[llvm_i32_ty], [llvm_v16i8_ty], [IntrNoMem]>; + def int_mips_bsel_v : GCCBuiltin<"__builtin_msa_bsel_v">, Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>; @@ -661,6 +673,18 @@ def int_mips_bseti_w : GCCBuiltin<"__builtin_msa_bseti_w">, def int_mips_bseti_d : GCCBuiltin<"__builtin_msa_bseti_d">, Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem]>; +def int_mips_bz_b : GCCBuiltin<"__builtin_msa_bz_b">, + Intrinsic<[llvm_i32_ty], [llvm_v16i8_ty], [IntrNoMem]>; +def int_mips_bz_h : GCCBuiltin<"__builtin_msa_bz_h">, + Intrinsic<[llvm_i32_ty], [llvm_v8i16_ty], [IntrNoMem]>; +def int_mips_bz_w : GCCBuiltin<"__builtin_msa_bz_w">, + Intrinsic<[llvm_i32_ty], [llvm_v4i32_ty], [IntrNoMem]>; +def int_mips_bz_d : GCCBuiltin<"__builtin_msa_bz_d">, + Intrinsic<[llvm_i32_ty], [llvm_v2i64_ty], [IntrNoMem]>; + +def int_mips_bz_v : GCCBuiltin<"__builtin_msa_bz_v">, + Intrinsic<[llvm_i32_ty], [llvm_v16i8_ty], [IntrNoMem]>; + def int_mips_ceq_b : GCCBuiltin<"__builtin_msa_ceq_b">, Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>; def int_mips_ceq_h : GCCBuiltin<"__builtin_msa_ceq_h">, diff --git a/lib/Target/Mips/MipsISelLowering.cpp b/lib/Target/Mips/MipsISelLowering.cpp index c13f53a3ebe..4d1f3297060 100644 --- a/lib/Target/Mips/MipsISelLowering.cpp +++ b/lib/Target/Mips/MipsISelLowering.cpp @@ -208,6 +208,10 @@ const char *MipsTargetLowering::getTargetNodeName(unsigned Opcode) const { case MipsISD::SHRL_DSP: return "MipsISD::SHRL_DSP"; case MipsISD::SETCC_DSP: return "MipsISD::SETCC_DSP"; case MipsISD::SELECT_CC_DSP: return "MipsISD::SELECT_CC_DSP"; + case MipsISD::VALL_ZERO: return "MipsISD::VALL_ZERO"; + case MipsISD::VANY_ZERO: return "MipsISD::VANY_ZERO"; + case MipsISD::VALL_NONZERO: return "MipsISD::VALL_NONZERO"; + case MipsISD::VANY_NONZERO: return "MipsISD::VANY_NONZERO"; default: return NULL; } } diff --git a/lib/Target/Mips/MipsISelLowering.h b/lib/Target/Mips/MipsISelLowering.h index 29671b0cf3a..4cc5a6a6ec3 100644 --- a/lib/Target/Mips/MipsISelLowering.h +++ b/lib/Target/Mips/MipsISelLowering.h @@ -152,6 +152,12 @@ namespace llvm { SETCC_DSP, SELECT_CC_DSP, + // Vector comparisons + VALL_ZERO, + VANY_ZERO, + VALL_NONZERO, + VANY_NONZERO, + // Load/Store Left/Right nodes. LWL = ISD::FIRST_TARGET_MEMORY_OPCODE, LWR, diff --git a/lib/Target/Mips/MipsMSAInstrFormats.td b/lib/Target/Mips/MipsMSAInstrFormats.td index f337f9d8fff..b0116747192 100644 --- a/lib/Target/Mips/MipsMSAInstrFormats.td +++ b/lib/Target/Mips/MipsMSAInstrFormats.td @@ -119,3 +119,8 @@ class MSA_VEC_FMT major, bits<6> minor>: MSAInst { let Inst{25-21} = major; let Inst{5-0} = minor; } + +class MSA_VECS10_FMT major, bits<6> minor>: MSAInst { + let Inst{25-21} = major; + let Inst{5-0} = minor; +} diff --git a/lib/Target/Mips/MipsMSAInstrInfo.td b/lib/Target/Mips/MipsMSAInstrInfo.td index 53fceb79ef8..1814b1c8691 100644 --- a/lib/Target/Mips/MipsMSAInstrInfo.td +++ b/lib/Target/Mips/MipsMSAInstrInfo.td @@ -11,6 +11,13 @@ // //===----------------------------------------------------------------------===// +def SDT_MipsVecCond : SDTypeProfile<1, 1, [SDTCisInt<0>, SDTCisVec<1>]>; + +def MipsVAllNonZero : SDNode<"MipsISD::VALL_NONZERO", SDT_MipsVecCond>; +def MipsVAnyNonZero : SDNode<"MipsISD::VANY_NONZERO", SDT_MipsVecCond>; +def MipsVAllZero : SDNode<"MipsISD::VALL_ZERO", SDT_MipsVecCond>; +def MipsVAnyZero : SDNode<"MipsISD::VANY_ZERO", SDT_MipsVecCond>; + def immSExt5 : ImmLeaf(Imm);}]>; def immSExt10: ImmLeaf(Imm);}]>; @@ -147,7 +154,14 @@ class BNEGI_H_ENC : MSA_BIT_H_FMT<0b101, 0b001001>; class BNEGI_W_ENC : MSA_BIT_W_FMT<0b101, 0b001001>; class BNEGI_D_ENC : MSA_BIT_D_FMT<0b101, 0b001001>; -class BSEL_V_ENC : MSA_VEC_FMT<0b00110, 0b011110>; +class BNZ_B_ENC : MSA_I10_FMT<0b000, 0b00, 0b001100>; +class BNZ_H_ENC : MSA_I10_FMT<0b000, 0b01, 0b001100>; +class BNZ_W_ENC : MSA_I10_FMT<0b000, 0b10, 0b001100>; +class BNZ_D_ENC : MSA_I10_FMT<0b000, 0b11, 0b001100>; + +class BNZ_V_ENC : MSA_VEC_FMT<0b01000, 0b011110>; + +class BSEL_V_ENC : MSA_VECS10_FMT<0b00110, 0b011110>; class BSELI_B_ENC : MSA_I8_FMT<0b10, 0b000001>; @@ -161,6 +175,13 @@ class BSETI_H_ENC : MSA_BIT_H_FMT<0b100, 0b001001>; class BSETI_W_ENC : MSA_BIT_W_FMT<0b100, 0b001001>; class BSETI_D_ENC : MSA_BIT_D_FMT<0b100, 0b001001>; +class BZ_B_ENC : MSA_I10_FMT<0b001, 0b00, 0b001100>; +class BZ_H_ENC : MSA_I10_FMT<0b001, 0b01, 0b001100>; +class BZ_W_ENC : MSA_I10_FMT<0b001, 0b10, 0b001100>; +class BZ_D_ENC : MSA_I10_FMT<0b001, 0b11, 0b001100>; + +class BZ_V_ENC : MSA_VECS10_FMT<0b01001, 0b011110>; + class CEQ_B_ENC : MSA_3R_FMT<0b000, 0b00, 0b001111>; class CEQ_H_ENC : MSA_3R_FMT<0b000, 0b01, 0b001111>; class CEQ_W_ENC : MSA_3R_FMT<0b000, 0b10, 0b001111>; @@ -875,6 +896,18 @@ class MSA_3RF_4RF_DESC_BASE : MSA_3R_4R_DESC_BASE; +class MSA_CBRANCH_DESC_BASE { + dag OutOperandList = (outs); + dag InOperandList = (ins RCWD:$wd, brtarget:$offset); + string AsmString = !strconcat(instr_asm, "\t$wd, $offset"); + list Pattern = []; + InstrItinClass Itinerary = IIBranch; + bit isBranch = 1; + bit isTerminator = 1; + bit hasDelaySlot = 1; + list Defs = [AT]; +} + class MSA_INSERT_DESC_BASE { @@ -1129,6 +1162,13 @@ class BNEGI_W_DESC : MSA_BIT_W_DESC_BASE<"bnegi.w", int_mips_bnegi_w, class BNEGI_D_DESC : MSA_BIT_D_DESC_BASE<"bnegi.d", int_mips_bnegi_d, NoItinerary, MSA128D, MSA128D>; +class BNZ_B_DESC : MSA_CBRANCH_DESC_BASE<"bnz.b", MSA128B>; +class BNZ_H_DESC : MSA_CBRANCH_DESC_BASE<"bnz.h", MSA128H>; +class BNZ_W_DESC : MSA_CBRANCH_DESC_BASE<"bnz.w", MSA128W>; +class BNZ_D_DESC : MSA_CBRANCH_DESC_BASE<"bnz.d", MSA128D>; + +class BNZ_V_DESC : MSA_CBRANCH_DESC_BASE<"bnz.v", MSA128B>; + class BSEL_V_DESC : MSA_VEC_DESC_BASE<"bsel.v", int_mips_bsel_v, NoItinerary, MSA128B, MSA128B>; @@ -1153,6 +1193,13 @@ class BSETI_W_DESC : MSA_BIT_W_DESC_BASE<"bseti.w", int_mips_bseti_w, class BSETI_D_DESC : MSA_BIT_D_DESC_BASE<"bseti.d", int_mips_bseti_d, NoItinerary, MSA128D, MSA128D>; +class BZ_B_DESC : MSA_CBRANCH_DESC_BASE<"bz.b", MSA128B>; +class BZ_H_DESC : MSA_CBRANCH_DESC_BASE<"bz.h", MSA128H>; +class BZ_W_DESC : MSA_CBRANCH_DESC_BASE<"bz.w", MSA128W>; +class BZ_D_DESC : MSA_CBRANCH_DESC_BASE<"bz.d", MSA128D>; + +class BZ_V_DESC : MSA_CBRANCH_DESC_BASE<"bz.v", MSA128B>; + class CEQ_B_DESC : MSA_3R_DESC_BASE<"ceq.b", int_mips_ceq_b, NoItinerary, MSA128B, MSA128B>, IsCommutable; class CEQ_H_DESC : MSA_3R_DESC_BASE<"ceq.h", int_mips_ceq_h, NoItinerary, @@ -2344,6 +2391,13 @@ def BNEGI_H : BNEGI_H_ENC, BNEGI_H_DESC, Requires<[HasMSA]>; def BNEGI_W : BNEGI_W_ENC, BNEGI_W_DESC, Requires<[HasMSA]>; def BNEGI_D : BNEGI_D_ENC, BNEGI_D_DESC, Requires<[HasMSA]>; +def BNZ_B : BNZ_B_ENC, BNZ_B_DESC, Requires<[HasMSA]>; +def BNZ_H : BNZ_H_ENC, BNZ_H_DESC, Requires<[HasMSA]>; +def BNZ_W : BNZ_W_ENC, BNZ_W_DESC, Requires<[HasMSA]>; +def BNZ_D : BNZ_D_ENC, BNZ_D_DESC, Requires<[HasMSA]>; + +def BNZ_V : BNZ_V_ENC, BNZ_V_DESC, Requires<[HasMSA]>; + def BSEL_V : BSEL_V_ENC, BSEL_V_DESC, Requires<[HasMSA]>; def BSELI_B : BSELI_B_ENC, BSELI_B_DESC, Requires<[HasMSA]>; @@ -2358,6 +2412,13 @@ def BSETI_H : BSETI_H_ENC, BSETI_H_DESC, Requires<[HasMSA]>; def BSETI_W : BSETI_W_ENC, BSETI_W_DESC, Requires<[HasMSA]>; def BSETI_D : BSETI_D_ENC, BSETI_D_DESC, Requires<[HasMSA]>; +def BZ_B : BZ_B_ENC, BZ_B_DESC, Requires<[HasMSA]>; +def BZ_H : BZ_H_ENC, BZ_H_DESC, Requires<[HasMSA]>; +def BZ_W : BZ_W_ENC, BZ_W_DESC, Requires<[HasMSA]>; +def BZ_D : BZ_D_ENC, BZ_D_DESC, Requires<[HasMSA]>; + +def BZ_V : BZ_V_ENC, BZ_V_DESC, Requires<[HasMSA]>; + def CEQ_B : CEQ_B_ENC, CEQ_B_DESC, Requires<[HasMSA]>; def CEQ_H : CEQ_H_ENC, CEQ_H_DESC, Requires<[HasMSA]>; def CEQ_W : CEQ_W_ENC, CEQ_W_DESC, Requires<[HasMSA]>; @@ -3117,3 +3178,35 @@ def : MSABitconvertReverseHInDPat; def : MSABitconvertReverseHInDPat; def : MSABitconvertReverseWInDPat; def : MSABitconvertReverseWInDPat; + +// Pseudos used to implement BNZ.df, and BZ.df + +class MSA_CBRANCH_PSEUDO_DESC_BASE : + MipsPseudo<(outs GPR32:$dst), + (ins RCWS:$ws), + [(set GPR32:$dst, (OpNode (TyNode RCWS:$ws)))]> { + bit usesCustomInserter = 1; +} + +def SNZ_B_PSEUDO : MSA_CBRANCH_PSEUDO_DESC_BASE; +def SNZ_H_PSEUDO : MSA_CBRANCH_PSEUDO_DESC_BASE; +def SNZ_W_PSEUDO : MSA_CBRANCH_PSEUDO_DESC_BASE; +def SNZ_D_PSEUDO : MSA_CBRANCH_PSEUDO_DESC_BASE; +def SNZ_V_PSEUDO : MSA_CBRANCH_PSEUDO_DESC_BASE; + +def SZ_B_PSEUDO : MSA_CBRANCH_PSEUDO_DESC_BASE; +def SZ_H_PSEUDO : MSA_CBRANCH_PSEUDO_DESC_BASE; +def SZ_W_PSEUDO : MSA_CBRANCH_PSEUDO_DESC_BASE; +def SZ_D_PSEUDO : MSA_CBRANCH_PSEUDO_DESC_BASE; +def SZ_V_PSEUDO : MSA_CBRANCH_PSEUDO_DESC_BASE; diff --git a/lib/Target/Mips/MipsSEISelLowering.cpp b/lib/Target/Mips/MipsSEISelLowering.cpp index 5341277d2da..91082114336 100644 --- a/lib/Target/Mips/MipsSEISelLowering.cpp +++ b/lib/Target/Mips/MipsSEISelLowering.cpp @@ -125,6 +125,7 @@ MipsSETargetLowering::MipsSETargetLowering(MipsTargetMachine &TM) setTargetDAGCombine(ISD::SUBE); setTargetDAGCombine(ISD::MUL); + setOperationAction(ISD::INTRINSIC_WO_CHAIN, MVT::Other, Custom); setOperationAction(ISD::INTRINSIC_W_CHAIN, MVT::Other, Custom); setOperationAction(ISD::INTRINSIC_VOID, MVT::Other, Custom); @@ -554,6 +555,26 @@ MipsSETargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI, return MipsTargetLowering::EmitInstrWithCustomInserter(MI, BB); case Mips::BPOSGE32_PSEUDO: return emitBPOSGE32(MI, BB); + case Mips::SNZ_B_PSEUDO: + return emitMSACBranchPseudo(MI, BB, Mips::BNZ_B); + case Mips::SNZ_H_PSEUDO: + return emitMSACBranchPseudo(MI, BB, Mips::BNZ_H); + case Mips::SNZ_W_PSEUDO: + return emitMSACBranchPseudo(MI, BB, Mips::BNZ_W); + case Mips::SNZ_D_PSEUDO: + return emitMSACBranchPseudo(MI, BB, Mips::BNZ_D); + case Mips::SNZ_V_PSEUDO: + return emitMSACBranchPseudo(MI, BB, Mips::BNZ_V); + case Mips::SZ_B_PSEUDO: + return emitMSACBranchPseudo(MI, BB, Mips::BZ_B); + case Mips::SZ_H_PSEUDO: + return emitMSACBranchPseudo(MI, BB, Mips::BZ_H); + case Mips::SZ_W_PSEUDO: + return emitMSACBranchPseudo(MI, BB, Mips::BZ_W); + case Mips::SZ_D_PSEUDO: + return emitMSACBranchPseudo(MI, BB, Mips::BZ_D); + case Mips::SZ_V_PSEUDO: + return emitMSACBranchPseudo(MI, BB, Mips::BZ_V); } } @@ -690,6 +711,16 @@ static SDValue lowerDSPIntr(SDValue Op, SelectionDAG &DAG, unsigned Opc) { return DAG.getMergeValues(Vals, 2, DL); } +static SDValue lowerMSABranchIntr(SDValue Op, SelectionDAG &DAG, unsigned Opc) { + SDLoc DL(Op); + SDValue Value = Op->getOperand(1); + EVT ResTy = Op->getValueType(0); + + SDValue Result = DAG.getNode(Opc, DL, ResTy, Value); + + return Result; +} + SDValue MipsSETargetLowering::lowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG) const { switch (cast(Op->getOperand(0))->getZExtValue()) { @@ -727,6 +758,20 @@ SDValue MipsSETargetLowering::lowerINTRINSIC_WO_CHAIN(SDValue Op, return lowerDSPIntr(Op, DAG, MipsISD::MSub); case Intrinsic::mips_msubu: return lowerDSPIntr(Op, DAG, MipsISD::MSubu); + case Intrinsic::mips_bnz_b: + case Intrinsic::mips_bnz_h: + case Intrinsic::mips_bnz_w: + case Intrinsic::mips_bnz_d: + return lowerMSABranchIntr(Op, DAG, MipsISD::VALL_NONZERO); + case Intrinsic::mips_bnz_v: + return lowerMSABranchIntr(Op, DAG, MipsISD::VANY_NONZERO); + case Intrinsic::mips_bz_b: + case Intrinsic::mips_bz_h: + case Intrinsic::mips_bz_w: + case Intrinsic::mips_bz_d: + return lowerMSABranchIntr(Op, DAG, MipsISD::VALL_ZERO); + case Intrinsic::mips_bz_v: + return lowerMSABranchIntr(Op, DAG, MipsISD::VANY_ZERO); } } @@ -830,7 +875,7 @@ SDValue MipsSETargetLowering::lowerINTRINSIC_VOID(SDValue Op, case Intrinsic::mips_stx_h: case Intrinsic::mips_stx_w: case Intrinsic::mips_stx_d: - return lowerMSAStoreIntr(Op, DAG, Intr); + return lowerMSAStoreIntr(Op, DAG, Intr); } } @@ -896,3 +941,70 @@ emitBPOSGE32(MachineInstr *MI, MachineBasicBlock *BB) const{ MI->eraseFromParent(); // The pseudo instruction is gone now. return Sink; } + +MachineBasicBlock * MipsSETargetLowering:: +emitMSACBranchPseudo(MachineInstr *MI, MachineBasicBlock *BB, + unsigned BranchOp) const{ + // $bb: + // vany_nonzero $rd, $ws + // => + // $bb: + // bnz.b $ws, $tbb + // b $fbb + // $fbb: + // li $rd1, 0 + // b $sink + // $tbb: + // li $rd2, 1 + // $sink: + // $rd = phi($rd1, $fbb, $rd2, $tbb) + + MachineRegisterInfo &RegInfo = BB->getParent()->getRegInfo(); + const TargetInstrInfo *TII = getTargetMachine().getInstrInfo(); + const TargetRegisterClass *RC = &Mips::GPR32RegClass; + DebugLoc DL = MI->getDebugLoc(); + const BasicBlock *LLVM_BB = BB->getBasicBlock(); + MachineFunction::iterator It = llvm::next(MachineFunction::iterator(BB)); + MachineFunction *F = BB->getParent(); + MachineBasicBlock *FBB = F->CreateMachineBasicBlock(LLVM_BB); + MachineBasicBlock *TBB = F->CreateMachineBasicBlock(LLVM_BB); + MachineBasicBlock *Sink = F->CreateMachineBasicBlock(LLVM_BB); + F->insert(It, FBB); + F->insert(It, TBB); + F->insert(It, Sink); + + // Transfer the remainder of BB and its successor edges to Sink. + Sink->splice(Sink->begin(), BB, llvm::next(MachineBasicBlock::iterator(MI)), + BB->end()); + Sink->transferSuccessorsAndUpdatePHIs(BB); + + // Add successors. + BB->addSuccessor(FBB); + BB->addSuccessor(TBB); + FBB->addSuccessor(Sink); + TBB->addSuccessor(Sink); + + // Insert the real bnz.b instruction to $BB. + BuildMI(BB, DL, TII->get(BranchOp)) + .addReg(MI->getOperand(1).getReg()) + .addMBB(TBB); + + // Fill $FBB. + unsigned RD1 = RegInfo.createVirtualRegister(RC); + BuildMI(*FBB, FBB->end(), DL, TII->get(Mips::ADDiu), RD1) + .addReg(Mips::ZERO).addImm(0); + BuildMI(*FBB, FBB->end(), DL, TII->get(Mips::B)).addMBB(Sink); + + // Fill $TBB. + unsigned RD2 = RegInfo.createVirtualRegister(RC); + BuildMI(*TBB, TBB->end(), DL, TII->get(Mips::ADDiu), RD2) + .addReg(Mips::ZERO).addImm(1); + + // Insert phi function to $Sink. + BuildMI(*Sink, Sink->begin(), DL, TII->get(Mips::PHI), + MI->getOperand(0).getReg()) + .addReg(RD1).addMBB(FBB).addReg(RD2).addMBB(TBB); + + MI->eraseFromParent(); // The pseudo instruction is gone now. + return Sink; +} diff --git a/lib/Target/Mips/MipsSEISelLowering.h b/lib/Target/Mips/MipsSEISelLowering.h index de4309236c9..d1a18e1fa60 100644 --- a/lib/Target/Mips/MipsSEISelLowering.h +++ b/lib/Target/Mips/MipsSEISelLowering.h @@ -67,6 +67,9 @@ namespace llvm { MachineBasicBlock *emitBPOSGE32(MachineInstr *MI, MachineBasicBlock *BB) const; + MachineBasicBlock *emitMSACBranchPseudo(MachineInstr *MI, + MachineBasicBlock *BB, + unsigned BranchOp) const; }; } diff --git a/test/CodeGen/Mips/msa/i10.ll b/test/CodeGen/Mips/msa/i10.ll new file mode 100644 index 00000000000..cfc48bd7d34 --- /dev/null +++ b/test/CodeGen/Mips/msa/i10.ll @@ -0,0 +1,88 @@ +; Test the MSA intrinsics that are encoded with the I10 instruction format. + +; RUN: llc -march=mips -mattr=+msa < %s | FileCheck %s + +@llvm_mips_bnz_b_ARG1 = global <16 x i8> , align 16 + +define i32 @llvm_mips_bnz_b_test() nounwind { +entry: + %0 = load <16 x i8>* @llvm_mips_bnz_b_ARG1 + %1 = tail call i32 @llvm.mips.bnz.b(<16 x i8> %0) + %2 = icmp eq i32 %1, 0 + br i1 %2, label %true, label %false +true: + ret i32 2 +false: + ret i32 3 +} + +declare i32 @llvm.mips.bnz.b(<16 x i8>) nounwind + +; CHECK: llvm_mips_bnz_b_test: +; CHECK-DAG: ld.b [[R0:\$w[0-9]+]] +; CHECK-DAG: bnz.b [[R0]] +; CHECK: .size llvm_mips_bnz_b_test + +@llvm_mips_bnz_h_ARG1 = global <8 x i16> , align 16 + +define i32 @llvm_mips_bnz_h_test() nounwind { +entry: + %0 = load <8 x i16>* @llvm_mips_bnz_h_ARG1 + %1 = tail call i32 @llvm.mips.bnz.h(<8 x i16> %0) + %2 = icmp eq i32 %1, 0 + br i1 %2, label %true, label %false +true: + ret i32 2 +false: + ret i32 3 +} + +declare i32 @llvm.mips.bnz.h(<8 x i16>) nounwind + +; CHECK: llvm_mips_bnz_h_test: +; CHECK-DAG: ld.h [[R0:\$w[0-9]+]] +; CHECK-DAG: bnz.h [[R0]] +; CHECK: .size llvm_mips_bnz_h_test + +@llvm_mips_bnz_w_ARG1 = global <4 x i32> , align 16 + +define i32 @llvm_mips_bnz_w_test() nounwind { +entry: + %0 = load <4 x i32>* @llvm_mips_bnz_w_ARG1 + %1 = tail call i32 @llvm.mips.bnz.w(<4 x i32> %0) + %2 = icmp eq i32 %1, 0 + br i1 %2, label %true, label %false +true: + ret i32 2 +false: + ret i32 3 +} + +declare i32 @llvm.mips.bnz.w(<4 x i32>) nounwind + +; CHECK: llvm_mips_bnz_w_test: +; CHECK-DAG: ld.w [[R0:\$w[0-9]+]] +; CHECK-DAG: bnz.w [[R0]] +; CHECK: .size llvm_mips_bnz_w_test + +@llvm_mips_bnz_d_ARG1 = global <2 x i64> , align 16 + +define i32 @llvm_mips_bnz_d_test() nounwind { +entry: + %0 = load <2 x i64>* @llvm_mips_bnz_d_ARG1 + %1 = tail call i32 @llvm.mips.bnz.d(<2 x i64> %0) + %2 = icmp eq i32 %1, 0 + br i1 %2, label %true, label %false +true: + ret i32 2 +false: + ret i32 3 +} + +declare i32 @llvm.mips.bnz.d(<2 x i64>) nounwind + +; CHECK: llvm_mips_bnz_d_test: +; CHECK-DAG: ld.d [[R0:\$w[0-9]+]] +; CHECK-DAG: bnz.d [[R0]] +; CHECK: .size llvm_mips_bnz_d_test + diff --git a/test/CodeGen/Mips/msa/vecs10.ll b/test/CodeGen/Mips/msa/vecs10.ll new file mode 100644 index 00000000000..8d68a0e6ca9 --- /dev/null +++ b/test/CodeGen/Mips/msa/vecs10.ll @@ -0,0 +1,46 @@ +; Test the MSA intrinsics that are encoded with the VECS10 instruction format. + +; RUN: llc -march=mips -mattr=+msa < %s | FileCheck %s + +@llvm_mips_bnz_v_ARG1 = global <16 x i8> , align 16 + +define i32 @llvm_mips_bnz_v_test() nounwind { +entry: + %0 = load <16 x i8>* @llvm_mips_bnz_v_ARG1 + %1 = tail call i32 @llvm.mips.bnz.v(<16 x i8> %0) + %2 = icmp eq i32 %1, 0 + br i1 %2, label %true, label %false +true: + ret i32 2 +false: + ret i32 3 +} + +declare i32 @llvm.mips.bnz.v(<16 x i8>) nounwind + +; CHECK: llvm_mips_bnz_v_test: +; CHECK-DAG: ld.b [[R0:\$w[0-9]+]] +; CHECK-DAG: bnz.v [[R0]] +; CHECK: .size llvm_mips_bnz_v_test + +@llvm_mips_bz_v_ARG1 = global <16 x i8> , align 16 + +define i32 @llvm_mips_bz_v_test() nounwind { +entry: + %0 = load <16 x i8>* @llvm_mips_bz_v_ARG1 + %1 = tail call i32 @llvm.mips.bz.v(<16 x i8> %0) + %2 = icmp eq i32 %1, 0 + br i1 %2, label %true, label %false +true: + ret i32 2 +false: + ret i32 3 +} + +declare i32 @llvm.mips.bz.v(<16 x i8>) nounwind + +; CHECK: llvm_mips_bz_v_test: +; CHECK-DAG: ld.b [[R0:\$w[0-9]+]] +; CHECK-DAG: bz.v [[R0]] +; CHECK: .size llvm_mips_bz_v_test +; -- 2.11.0