Index: lib/CodeGen/SelectionDAG/DAGCombiner.cpp =================================================================== --- lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -14085,12 +14085,7 @@ if (LegalTypes) { SCC = DAG.getSetCC(DL, getSetCCResultType(N0.getValueType()), N0, N1, CC); - if (N2.getValueType().bitsLT(SCC.getValueType())) - Temp = DAG.getZeroExtendInReg(SCC, SDLoc(N2), - N2.getValueType()); - else - Temp = DAG.getNode(ISD::ZERO_EXTEND, SDLoc(N2), - N2.getValueType(), SCC); + Temp = DAG.getZExtOrTrunc(SCC, SDLoc(N2), N2.getValueType()); } else { SCC = DAG.getSetCC(SDLoc(N0), MVT::i1, N0, N1, CC); Temp = DAG.getNode(ISD::ZERO_EXTEND, SDLoc(N2), Index: lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp =================================================================== --- lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp +++ lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp @@ -510,7 +510,7 @@ /// Promote the overflow flag of an overflowing arithmetic node. SDValue DAGTypeLegalizer::PromoteIntRes_Overflow(SDNode *N) { // Simply change the return type of the boolean result. - EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(1)); + EVT NVT = getSetCCResultType(N->getValueType(1)); EVT ValueVTs[] = { N->getValueType(0), NVT }; SDValue Ops[] = { N->getOperand(0), N->getOperand(1) }; SDValue Res = DAG.getNode(N->getOpcode(), SDLoc(N), @@ -973,7 +973,7 @@ SDValue DAGTypeLegalizer::PromoteIntOp_ANY_EXTEND(SDNode *N) { SDValue Op = GetPromotedInteger(N->getOperand(0)); - return DAG.getNode(ISD::ANY_EXTEND, SDLoc(N), N->getValueType(0), Op); + return DAG.getAnyExtOrTrunc(Op, SDLoc(N), N->getValueType(0)); } SDValue DAGTypeLegalizer::PromoteIntOp_ATOMIC_STORE(AtomicSDNode *N) { Index: lib/CodeGen/SelectionDAG/LegalizeTypes.cpp =================================================================== --- lib/CodeGen/SelectionDAG/LegalizeTypes.cpp +++ lib/CodeGen/SelectionDAG/LegalizeTypes.cpp @@ -737,8 +737,9 @@ } void DAGTypeLegalizer::SetPromotedInteger(SDValue Op, SDValue Result) { - assert(Result.getValueType() == - TLI.getTypeToTransformTo(*DAG.getContext(), Op.getValueType()) && + assert(((Result.getValueType() == + TLI.getTypeToTransformTo(*DAG.getContext(), Op.getValueType())) || + (Result.getValueType() == getSetCCResultType(Op.getValueType()))) && "Invalid type for promoted integer"); AnalyzeNewValue(Result); Index: lib/Target/Mips/Disassembler/MipsDisassembler.cpp =================================================================== --- lib/Target/Mips/Disassembler/MipsDisassembler.cpp +++ lib/Target/Mips/Disassembler/MipsDisassembler.cpp @@ -124,9 +124,13 @@ uint64_t Address, const void *Decoder); -static DecodeStatus DecodeFGRCCRegisterClass(MCInst &Inst, unsigned RegNo, - uint64_t Address, - const void *Decoder); +static DecodeStatus DecodeFGRCC32RegisterClass(MCInst &Inst, unsigned RegNo, + uint64_t Address, + const void *Decoder); + +static DecodeStatus DecodeFGRCC64RegisterClass(MCInst &Inst, unsigned RegNo, + uint64_t Address, + const void *Decoder); static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst, unsigned Insn, @@ -1119,13 +1123,24 @@ return MCDisassembler::Success; } -static DecodeStatus DecodeFGRCCRegisterClass(MCInst &Inst, unsigned RegNo, - uint64_t Address, - const void *Decoder) { +static DecodeStatus DecodeFGRCC32RegisterClass(MCInst &Inst, unsigned RegNo, + uint64_t Address, + const void *Decoder) { + if (RegNo > 31) + return MCDisassembler::Fail; + + unsigned Reg = getReg(Decoder, Mips::FGRCC32RegClassID, RegNo); + Inst.addOperand(MCOperand::createReg(Reg)); + return MCDisassembler::Success; +} + +static DecodeStatus DecodeFGRCC64RegisterClass(MCInst &Inst, unsigned RegNo, + uint64_t Address, + const void *Decoder) { if (RegNo > 31) return MCDisassembler::Fail; - unsigned Reg = getReg(Decoder, Mips::FGRCCRegClassID, RegNo); + unsigned Reg = getReg(Decoder, Mips::FGRCC64RegClassID, RegNo); Inst.addOperand(MCOperand::createReg(Reg)); return MCDisassembler::Success; } Index: lib/Target/Mips/MicroMips32r6InstrInfo.td =================================================================== --- lib/Target/Mips/MicroMips32r6InstrInfo.td +++ lib/Target/Mips/MicroMips32r6InstrInfo.td @@ -601,71 +601,71 @@ II_CVT>, FGR_64; multiclass CMP_CC_MMR6 format, string Typestr, - RegisterOperand FGROpnd> { + RegisterOperand FGRCCOpnd, RegisterOperand FGROpnd> { def CMP_AF_#NAME : POOL32F_CMP_FM< !strconcat("cmp.af.", Typestr), format, FIELD_CMP_COND_AF>, - CMP_CONDN_DESC_BASE<"af", Typestr, FGROpnd>, HARDFLOAT, R6MMR6Rel, - ISA_MICROMIPS32R6; + CMP_CONDN_DESC_BASE<"af", Typestr, FGRCCOpnd, FGROpnd>, + HARDFLOAT, R6MMR6Rel, ISA_MICROMIPS32R6; def CMP_UN_#NAME : POOL32F_CMP_FM< !strconcat("cmp.un.", Typestr), format, FIELD_CMP_COND_UN>, - CMP_CONDN_DESC_BASE<"un", Typestr, FGROpnd>, HARDFLOAT, R6MMR6Rel, - ISA_MICROMIPS32R6; + CMP_CONDN_DESC_BASE<"un", Typestr, FGRCCOpnd, FGROpnd>, + HARDFLOAT, R6MMR6Rel, ISA_MICROMIPS32R6; def CMP_EQ_#NAME : POOL32F_CMP_FM< !strconcat("cmp.eq.", Typestr), format, FIELD_CMP_COND_EQ>, - CMP_CONDN_DESC_BASE<"eq", Typestr, FGROpnd>, HARDFLOAT, R6MMR6Rel, - ISA_MICROMIPS32R6; + CMP_CONDN_DESC_BASE<"eq", Typestr, FGRCCOpnd, FGROpnd>, + HARDFLOAT, R6MMR6Rel, ISA_MICROMIPS32R6; def CMP_UEQ_#NAME : POOL32F_CMP_FM< !strconcat("cmp.ueq.", Typestr), format, FIELD_CMP_COND_UEQ>, - CMP_CONDN_DESC_BASE<"ueq", Typestr, FGROpnd>, HARDFLOAT, R6MMR6Rel, - ISA_MICROMIPS32R6; + CMP_CONDN_DESC_BASE<"ueq", Typestr, FGRCCOpnd, FGROpnd>, + HARDFLOAT, R6MMR6Rel, ISA_MICROMIPS32R6; def CMP_LT_#NAME : POOL32F_CMP_FM< !strconcat("cmp.lt.", Typestr), format, FIELD_CMP_COND_LT>, - CMP_CONDN_DESC_BASE<"lt", Typestr, FGROpnd>, HARDFLOAT, R6MMR6Rel, - ISA_MICROMIPS32R6; + CMP_CONDN_DESC_BASE<"lt", Typestr, FGRCCOpnd, FGROpnd>, + HARDFLOAT, R6MMR6Rel, ISA_MICROMIPS32R6; def CMP_ULT_#NAME : POOL32F_CMP_FM< !strconcat("cmp.ult.", Typestr), format, FIELD_CMP_COND_ULT>, - CMP_CONDN_DESC_BASE<"ult", Typestr, FGROpnd>, HARDFLOAT, R6MMR6Rel, - ISA_MICROMIPS32R6; + CMP_CONDN_DESC_BASE<"ult", Typestr, FGRCCOpnd, FGROpnd>, + HARDFLOAT, R6MMR6Rel, ISA_MICROMIPS32R6; def CMP_LE_#NAME : POOL32F_CMP_FM< !strconcat("cmp.le.", Typestr), format, FIELD_CMP_COND_LE>, - CMP_CONDN_DESC_BASE<"le", Typestr, FGROpnd>, HARDFLOAT, R6MMR6Rel, - ISA_MICROMIPS32R6; + CMP_CONDN_DESC_BASE<"le", Typestr, FGRCCOpnd, FGROpnd>, + HARDFLOAT, R6MMR6Rel, ISA_MICROMIPS32R6; def CMP_ULE_#NAME : POOL32F_CMP_FM< !strconcat("cmp.ule.", Typestr), format, FIELD_CMP_COND_ULE>, - CMP_CONDN_DESC_BASE<"ule", Typestr, FGROpnd>, HARDFLOAT, R6MMR6Rel, - ISA_MICROMIPS32R6; + CMP_CONDN_DESC_BASE<"ule", Typestr, FGRCCOpnd, FGROpnd>, + HARDFLOAT, R6MMR6Rel, ISA_MICROMIPS32R6; def CMP_SAF_#NAME : POOL32F_CMP_FM< !strconcat("cmp.saf.", Typestr), format, FIELD_CMP_COND_SAF>, - CMP_CONDN_DESC_BASE<"saf", Typestr, FGROpnd>, HARDFLOAT, R6MMR6Rel, - ISA_MICROMIPS32R6; + CMP_CONDN_DESC_BASE<"saf", Typestr, FGRCCOpnd, FGROpnd>, + HARDFLOAT, R6MMR6Rel, ISA_MICROMIPS32R6; def CMP_SUN_#NAME : POOL32F_CMP_FM< !strconcat("cmp.sun.", Typestr), format, FIELD_CMP_COND_SUN>, - CMP_CONDN_DESC_BASE<"sun", Typestr, FGROpnd>, HARDFLOAT, R6MMR6Rel, - ISA_MICROMIPS32R6; + CMP_CONDN_DESC_BASE<"sun", Typestr, FGRCCOpnd, FGROpnd>, + HARDFLOAT, R6MMR6Rel, ISA_MICROMIPS32R6; def CMP_SEQ_#NAME : POOL32F_CMP_FM< !strconcat("cmp.seq.", Typestr), format, FIELD_CMP_COND_SEQ>, - CMP_CONDN_DESC_BASE<"seq", Typestr, FGROpnd>, HARDFLOAT, R6MMR6Rel, - ISA_MICROMIPS32R6; + CMP_CONDN_DESC_BASE<"seq", Typestr, FGRCCOpnd, FGROpnd>, + HARDFLOAT, R6MMR6Rel, ISA_MICROMIPS32R6; def CMP_SUEQ_#NAME : POOL32F_CMP_FM< !strconcat("cmp.sueq.", Typestr), format, FIELD_CMP_COND_SUEQ>, - CMP_CONDN_DESC_BASE<"sueq", Typestr, FGROpnd>, HARDFLOAT, R6MMR6Rel, - ISA_MICROMIPS32R6; + CMP_CONDN_DESC_BASE<"sueq", Typestr, FGRCCOpnd, FGROpnd>, + HARDFLOAT, R6MMR6Rel, ISA_MICROMIPS32R6; def CMP_SLT_#NAME : POOL32F_CMP_FM< !strconcat("cmp.slt.", Typestr), format, FIELD_CMP_COND_SLT>, - CMP_CONDN_DESC_BASE<"slt", Typestr, FGROpnd>, HARDFLOAT, R6MMR6Rel, - ISA_MICROMIPS32R6; + CMP_CONDN_DESC_BASE<"slt", Typestr, FGRCCOpnd, FGROpnd>, + HARDFLOAT, R6MMR6Rel, ISA_MICROMIPS32R6; def CMP_SULT_#NAME : POOL32F_CMP_FM< !strconcat("cmp.sult.", Typestr), format, FIELD_CMP_COND_SULT>, - CMP_CONDN_DESC_BASE<"sult", Typestr, FGROpnd>, HARDFLOAT, R6MMR6Rel, - ISA_MICROMIPS32R6; + CMP_CONDN_DESC_BASE<"sult", Typestr, FGRCCOpnd, FGROpnd>, + HARDFLOAT, R6MMR6Rel, ISA_MICROMIPS32R6; def CMP_SLE_#NAME : POOL32F_CMP_FM< !strconcat("cmp.sle.", Typestr), format, FIELD_CMP_COND_SLE>, - CMP_CONDN_DESC_BASE<"sle", Typestr, FGROpnd>, HARDFLOAT, R6MMR6Rel, - ISA_MICROMIPS32R6; + CMP_CONDN_DESC_BASE<"sle", Typestr, FGRCCOpnd, FGROpnd>, + HARDFLOAT, R6MMR6Rel, ISA_MICROMIPS32R6; def CMP_SULE_#NAME : POOL32F_CMP_FM< !strconcat("cmp.sule.", Typestr), format, FIELD_CMP_COND_SULE>, - CMP_CONDN_DESC_BASE<"sule", Typestr, FGROpnd>, HARDFLOAT, R6MMR6Rel, - ISA_MICROMIPS32R6; + CMP_CONDN_DESC_BASE<"sule", Typestr, FGRCCOpnd, FGROpnd>, + HARDFLOAT, R6MMR6Rel, ISA_MICROMIPS32R6; } class ABSS_FT_MMR6_DESC_BASE; -defm D_MMR6 : CMP_CC_MMR6<0b010101, "d", FGR64Opnd>; +defm S_MMR6 : CMP_CC_MMR6<0b000101, "s", FGRCC32Opnd, FGR32Opnd>; +defm D_MMR6 : CMP_CC_MMR6<0b010101, "d", FGRCC32Opnd, FGR64Opnd>; def ABS_S_MMR6 : StdMMR6Rel, ABS_S_MMR6_ENC, ABS_S_MMR6_DESC, ISA_MICROMIPS32R6; def ABS_D_MMR6 : StdMMR6Rel, ABS_D_MMR6_ENC, ABS_D_MMR6_DESC, ISA_MICROMIPS32R6; def FLOOR_L_S_MMR6 : StdMMR6Rel, FLOOR_L_S_MMR6_ENC, FLOOR_L_S_MMR6_DESC, Index: lib/Target/Mips/MicroMipsInstrInfo.td =================================================================== --- lib/Target/Mips/MicroMipsInstrInfo.td +++ lib/Target/Mips/MicroMipsInstrInfo.td @@ -684,10 +684,10 @@ ADDI_FM_MM<0xc>; def ADDi_MM : MMRel, ArithLogicI<"addi", simm16, GPR32Opnd>, ADDI_FM_MM<0x4>; - def SLTi_MM : MMRel, SetCC_I<"slti", setlt, simm16, immSExt16, GPR32Opnd>, - SLTI_FM_MM<0x24>; - def SLTiu_MM : MMRel, SetCC_I<"sltiu", setult, simm16, immSExt16, GPR32Opnd>, - SLTI_FM_MM<0x2c>; + def SLTi_MM : MMRel, SetCC_I<"slti", setlt, simm16, immSExt16, GPR32Opnd, + GPR32Opnd>, SLTI_FM_MM<0x24>; + def SLTiu_MM : MMRel, SetCC_I<"sltiu", setult, simm16, immSExt16, GPR32Opnd, + GPR32Opnd>, SLTI_FM_MM<0x2c>; def ANDi_MM : MMRel, ArithLogicI<"andi", uimm16, GPR32Opnd>, ADDI_FM_MM<0x34>; def ORi_MM : MMRel, ArithLogicI<"ori", uimm16, GPR32Opnd>, @@ -707,8 +707,9 @@ def MUL_MM : MMRel, ArithLogicR<"mul", GPR32Opnd>, ADD_FM_MM<0, 0x210>; def ADD_MM : MMRel, ArithLogicR<"add", GPR32Opnd>, ADD_FM_MM<0, 0x110>; def SUB_MM : MMRel, ArithLogicR<"sub", GPR32Opnd>, ADD_FM_MM<0, 0x190>; - def SLT_MM : MMRel, SetCC_R<"slt", setlt, GPR32Opnd>, ADD_FM_MM<0, 0x350>; - def SLTu_MM : MMRel, SetCC_R<"sltu", setult, GPR32Opnd>, + def SLT_MM : MMRel, SetCC_R<"slt", setlt, GPR32Opnd, GPR32Opnd>, + ADD_FM_MM<0, 0x350>; + def SLTu_MM : MMRel, SetCC_R<"sltu", setult, GPR32Opnd, GPR32Opnd>, ADD_FM_MM<0, 0x390>; def AND_MM : MMRel, ArithLogicR<"and", GPR32Opnd, 1, II_AND, and>, ADD_FM_MM<0, 0x250>; Index: lib/Target/Mips/Mips32r6InstrInfo.td =================================================================== --- lib/Target/Mips/Mips32r6InstrInfo.td +++ lib/Target/Mips/Mips32r6InstrInfo.td @@ -176,7 +176,7 @@ //===----------------------------------------------------------------------===// class CMP_CONDN_DESC_BASE { dag OutOperandList = (outs FGRCCOpnd:$fd); dag InOperandList = (ins FGROpnd:$fs, FGROpnd:$ft); @@ -184,58 +184,58 @@ list Pattern = [(set FGRCCOpnd:$fd, (Op FGROpnd:$fs, FGROpnd:$ft))]; } -multiclass CMP_CC_M { - let AdditionalPredicates = [NotInMicroMips] in { - def CMP_F_#NAME : COP1_CMP_CONDN_FM, - CMP_CONDN_DESC_BASE<"af", Typestr, FGROpnd>, - ISA_MIPS32R6, HARDFLOAT; - def CMP_UN_#NAME : COP1_CMP_CONDN_FM, - CMP_CONDN_DESC_BASE<"un", Typestr, FGROpnd, setuo>, - ISA_MIPS32R6, HARDFLOAT; - def CMP_EQ_#NAME : COP1_CMP_CONDN_FM, - CMP_CONDN_DESC_BASE<"eq", Typestr, FGROpnd, setoeq>, - ISA_MIPS32R6, HARDFLOAT; - def CMP_UEQ_#NAME : COP1_CMP_CONDN_FM, - CMP_CONDN_DESC_BASE<"ueq", Typestr, FGROpnd, setueq>, - ISA_MIPS32R6, HARDFLOAT; - def CMP_LT_#NAME : COP1_CMP_CONDN_FM, - CMP_CONDN_DESC_BASE<"lt", Typestr, FGROpnd, setolt>, - ISA_MIPS32R6, HARDFLOAT; - def CMP_ULT_#NAME : COP1_CMP_CONDN_FM, - CMP_CONDN_DESC_BASE<"ult", Typestr, FGROpnd, setult>, - ISA_MIPS32R6, HARDFLOAT; - def CMP_LE_#NAME : COP1_CMP_CONDN_FM, - CMP_CONDN_DESC_BASE<"le", Typestr, FGROpnd, setole>, - ISA_MIPS32R6, HARDFLOAT; - def CMP_ULE_#NAME : COP1_CMP_CONDN_FM, - CMP_CONDN_DESC_BASE<"ule", Typestr, FGROpnd, setule>, - ISA_MIPS32R6, HARDFLOAT; - def CMP_SAF_#NAME : COP1_CMP_CONDN_FM, - CMP_CONDN_DESC_BASE<"saf", Typestr, FGROpnd>, - ISA_MIPS32R6, HARDFLOAT; - def CMP_SUN_#NAME : COP1_CMP_CONDN_FM, - CMP_CONDN_DESC_BASE<"sun", Typestr, FGROpnd>, - ISA_MIPS32R6, HARDFLOAT; - def CMP_SEQ_#NAME : COP1_CMP_CONDN_FM, - CMP_CONDN_DESC_BASE<"seq", Typestr, FGROpnd>, - ISA_MIPS32R6, HARDFLOAT; - def CMP_SUEQ_#NAME : COP1_CMP_CONDN_FM, - CMP_CONDN_DESC_BASE<"sueq", Typestr, FGROpnd>, - ISA_MIPS32R6, HARDFLOAT; - def CMP_SLT_#NAME : COP1_CMP_CONDN_FM, - CMP_CONDN_DESC_BASE<"slt", Typestr, FGROpnd>, - ISA_MIPS32R6, HARDFLOAT; - def CMP_SULT_#NAME : COP1_CMP_CONDN_FM, - CMP_CONDN_DESC_BASE<"sult", Typestr, FGROpnd>, - ISA_MIPS32R6, HARDFLOAT; - def CMP_SLE_#NAME : COP1_CMP_CONDN_FM, - CMP_CONDN_DESC_BASE<"sle", Typestr, FGROpnd>, - ISA_MIPS32R6, HARDFLOAT; - def CMP_SULE_#NAME : COP1_CMP_CONDN_FM, - CMP_CONDN_DESC_BASE<"sule", Typestr, FGROpnd>, - ISA_MIPS32R6, HARDFLOAT; - } +multiclass CMP_CC_M{ +let AdditionalPredicates = [NotInMicroMips] in { +def CMP_F_#NAME : COP1_CMP_CONDN_FM, + CMP_CONDN_DESC_BASE<"af", Typestr, FGRCCOpnd, FGROpnd>, + ISA_MIPS32R6, HARDFLOAT; +def CMP_UN_#NAME : COP1_CMP_CONDN_FM, + CMP_CONDN_DESC_BASE<"un", Typestr, FGRCCOpnd, FGROpnd, + setuo>, ISA_MIPS32R6, HARDFLOAT; +def CMP_EQ_#NAME : COP1_CMP_CONDN_FM, + CMP_CONDN_DESC_BASE<"eq", Typestr, FGRCCOpnd, FGROpnd, + setoeq>, ISA_MIPS32R6, HARDFLOAT; +def CMP_UEQ_#NAME : COP1_CMP_CONDN_FM, + CMP_CONDN_DESC_BASE<"ueq", Typestr, FGRCCOpnd, FGROpnd, + setueq>, ISA_MIPS32R6, HARDFLOAT; +def CMP_LT_#NAME : COP1_CMP_CONDN_FM, + CMP_CONDN_DESC_BASE<"lt", Typestr, FGRCCOpnd, FGROpnd, + setolt>, ISA_MIPS32R6, HARDFLOAT; +def CMP_ULT_#NAME : COP1_CMP_CONDN_FM, + CMP_CONDN_DESC_BASE<"ult", Typestr, FGRCCOpnd, FGROpnd, + setult>, ISA_MIPS32R6, HARDFLOAT; +def CMP_LE_#NAME : COP1_CMP_CONDN_FM, + CMP_CONDN_DESC_BASE<"le", Typestr, FGRCCOpnd, FGROpnd, + setole>, ISA_MIPS32R6, HARDFLOAT; +def CMP_ULE_#NAME : COP1_CMP_CONDN_FM, + CMP_CONDN_DESC_BASE<"ule", Typestr, FGRCCOpnd, FGROpnd, + setule>, ISA_MIPS32R6, HARDFLOAT; +def CMP_SAF_#NAME : COP1_CMP_CONDN_FM, + CMP_CONDN_DESC_BASE<"saf", Typestr, FGRCCOpnd, FGROpnd>, + ISA_MIPS32R6, HARDFLOAT; +def CMP_SUN_#NAME : COP1_CMP_CONDN_FM, + CMP_CONDN_DESC_BASE<"sun", Typestr, FGRCCOpnd, FGROpnd>, + ISA_MIPS32R6, HARDFLOAT; +def CMP_SEQ_#NAME : COP1_CMP_CONDN_FM, + CMP_CONDN_DESC_BASE<"seq", Typestr, FGRCCOpnd, FGROpnd>, + ISA_MIPS32R6, HARDFLOAT; +def CMP_SUEQ_#NAME : COP1_CMP_CONDN_FM, + CMP_CONDN_DESC_BASE<"sueq", Typestr, FGRCCOpnd, FGROpnd>, + ISA_MIPS32R6, HARDFLOAT; +def CMP_SLT_#NAME : COP1_CMP_CONDN_FM, + CMP_CONDN_DESC_BASE<"slt", Typestr, FGRCCOpnd, FGROpnd>, + ISA_MIPS32R6, HARDFLOAT; +def CMP_SULT_#NAME : COP1_CMP_CONDN_FM, + CMP_CONDN_DESC_BASE<"sult", Typestr, FGRCCOpnd, FGROpnd>, + ISA_MIPS32R6, HARDFLOAT; +def CMP_SLE_#NAME : COP1_CMP_CONDN_FM, + CMP_CONDN_DESC_BASE<"sle", Typestr, FGRCCOpnd, FGROpnd>, + ISA_MIPS32R6, HARDFLOAT; +def CMP_SULE_#NAME : COP1_CMP_CONDN_FM, + CMP_CONDN_DESC_BASE<"sule", Typestr, FGRCCOpnd, FGROpnd>, + ISA_MIPS32R6, HARDFLOAT; +} } //===----------------------------------------------------------------------===// @@ -472,7 +472,8 @@ class MUL_R6_DESC : MUL_R6_DESC_BASE<"mul", GPR32Opnd, mul>; class MULU_DESC : MUL_R6_DESC_BASE<"mulu", GPR32Opnd>; -class COP1_SEL_DESC_BASE { +class COP1_SEL_DESC_BASE { dag OutOperandList = (outs FGROpnd:$fd); dag InOperandList = (ins FGRCCOpnd:$fd_in, FGROpnd:$fs, FGROpnd:$ft); string AsmString = !strconcat(instr_asm, "\t$fd, $fs, $ft"); @@ -482,11 +483,12 @@ string Constraints = "$fd_in = $fd"; } -class SEL_D_DESC : COP1_SEL_DESC_BASE<"sel.d", FGR64Opnd> { +class SEL_D_DESC : COP1_SEL_DESC_BASE<"sel.d", FGRCC32Opnd, FGR64Opnd> { // We must insert a SUBREG_TO_REG around $fd_in bit usesCustomInserter = 1; } -class SEL_S_DESC : COP1_SEL_DESC_BASE<"sel.s", FGR32Opnd>; + +class SEL_S_DESC : COP1_SEL_DESC_BASE<"sel.s", FGRCC32Opnd, FGR32Opnd>; class SELEQNE_Z_DESC_BASE : MipsR6Arch { @@ -691,8 +693,8 @@ def CLASS_S : CLASS_S_ENC, CLASS_S_DESC, ISA_MIPS32R6, HARDFLOAT; def CLO_R6 : R6MMR6Rel, CLO_R6_ENC, CLO_R6_DESC, ISA_MIPS32R6; def CLZ_R6 : R6MMR6Rel, CLZ_R6_ENC, CLZ_R6_DESC, ISA_MIPS32R6; -defm S : CMP_CC_M; -defm D : CMP_CC_M; +defm S : CMP_CC_M; +defm D : CMP_CC_M; def DIV : R6MMR6Rel, DIV_ENC, DIV_DESC, ISA_MIPS32R6; def DIVU : R6MMR6Rel, DIVU_ENC, DIVU_DESC, ISA_MIPS32R6; def JIALC : R6MMR6Rel, JIALC_ENC, JIALC_DESC, ISA_MIPS32R6; Index: lib/Target/Mips/Mips64InstrInfo.td =================================================================== --- lib/Target/Mips/Mips64InstrInfo.td +++ lib/Target/Mips/Mips64InstrInfo.td @@ -107,10 +107,14 @@ ADDI_FM<0x19>, IsAsCheapAsAMove, ISA_MIPS3; let isCodeGenOnly = 1 in { -def SLTi64 : SetCC_I<"slti", setlt, simm16_64, immSExt16, GPR64Opnd>, - SLTI_FM<0xa>; -def SLTiu64 : SetCC_I<"sltiu", setult, simm16_64, immSExt16, GPR64Opnd>, - SLTI_FM<0xb>; +def SLTi64 : SetCC_I<"slti", setlt, simm16_64, immSExt16, GPR64Opnd, + GPR64Opnd>, SLTI_FM<0xa>; +def SLTiu64 : SetCC_I<"sltiu", setult, simm16_64, immSExt16, GPR64Opnd, + GPR64Opnd>, SLTI_FM<0xb>; +def SLTi64_32 : SetCC_I<"slti", setlt, simm16, immSExt16, GPR64Opnd, + GPR32Opnd>, SLTI_FM<0xa>; +def SLTiu64_32 : SetCC_I<"sltiu", setult, simm16, immSExt16, GPR64Opnd, + GPR32Opnd>, SLTI_FM<0xb>; def ANDi64 : ArithLogicI<"andi", uimm16_64, GPR64Opnd, II_AND, immZExt16, and>, ADDI_FM<0xc>; def ORi64 : ArithLogicI<"ori", uimm16_64, GPR64Opnd, II_OR, immZExt16, or>, @@ -131,8 +135,10 @@ ISA_MIPS3; let isCodeGenOnly = 1 in { -def SLT64 : SetCC_R<"slt", setlt, GPR64Opnd>, ADD_FM<0, 0x2a>; -def SLTu64 : SetCC_R<"sltu", setult, GPR64Opnd>, ADD_FM<0, 0x2b>; +def SLT64 : SetCC_R<"slt", setlt, GPR64Opnd, GPR64Opnd>, ADD_FM<0, 0x2a>; +def SLTu64 : SetCC_R<"sltu", setult, GPR64Opnd, GPR64Opnd>, ADD_FM<0, 0x2b>; +def SLT64_32 : SetCC_R<"slt", setlt, GPR64Opnd, GPR32Opnd>, ADD_FM<0, 0x2a>; +def SLTu64_32 : SetCC_R<"sltu", setult, GPR64Opnd, GPR32Opnd>, ADD_FM<0, 0x2b>; def AND64 : ArithLogicR<"and", GPR64Opnd, 1, II_AND, and>, ADD_FM<0, 0x24>; def OR64 : ArithLogicR<"or", GPR64Opnd, 1, II_OR, or>, ADD_FM<0, 0x25>; def XOR64 : ArithLogicR<"xor", GPR64Opnd, 1, II_XOR, xor>, ADD_FM<0, 0x26>; @@ -327,8 +333,7 @@ class SetCC64_R : InstSE<(outs GPR64Opnd:$rd), (ins GPR64Opnd:$rs, GPR64Opnd:$rt), !strconcat(opstr, "\t$rd, $rs, $rt"), - [(set GPR64Opnd:$rd, (zext (cond_op GPR64Opnd:$rs, - GPR64Opnd:$rt)))], + [(set GPR64Opnd:$rd, (cond_op GPR64Opnd:$rs, GPR64Opnd:$rt))], II_SEQ_SNE, FrmR, opstr> { let TwoOperandAliasConstraint = "$rd = $rs"; } @@ -336,8 +341,7 @@ class SetCC64_I: InstSE<(outs GPR64Opnd:$rt), (ins GPR64Opnd:$rs, simm10_64:$imm10), !strconcat(opstr, "\t$rt, $rs, $imm10"), - [(set GPR64Opnd:$rt, (zext (cond_op GPR64Opnd:$rs, - immSExt10_64:$imm10)))], + [(set GPR64Opnd:$rt, (cond_op GPR64Opnd:$rs, immSExt10_64:$imm10))], II_SEQI_SNEI, FrmI, opstr> { let TwoOperandAliasConstraint = "$rt = $rs"; } @@ -346,7 +350,7 @@ RegisterOperand RO, bits<64> shift = 1> : InstSE<(outs), (ins RO:$rs, uimm5_64:$p, opnd:$offset), !strconcat(opstr, "\t$rs, $p, $offset"), - [(brcond (i32 (cond_op (and RO:$rs, (shl shift, immZExt5_64:$p)), 0)), + [(brcond (i64 (cond_op (and RO:$rs, (shl shift, immZExt5_64:$p)), 0)), bb:$offset)], II_BBIT, FrmI, opstr> { let isBranch = 1; let isTerminator = 1; @@ -479,20 +483,30 @@ def : WrapperPat; def : WrapperPat; -defm : BrcondPats; +defm : BrcondPats1; +defm : BrcondPats1; -def : MipsPat<(brcond (i32 (setlt i64:$lhs, 1)), bb:$dst), +def : MipsPat<(brcond (i64 (setlt i64:$lhs, 1)), bb:$dst), (BLEZ64 i64:$lhs, bb:$dst)>; -def : MipsPat<(brcond (i32 (setgt i64:$lhs, -1)), bb:$dst), +def : MipsPat<(brcond (i64 (setgt i64:$lhs, -1)), bb:$dst), (BGEZ64 i64:$lhs, bb:$dst)>; +def : MipsPat<(brcond (i64 (setlt i32:$lhs, 1)), bb:$dst), + (BLEZ64 (SUBREG_TO_REG (i32 0), i32:$lhs, sub_32), bb:$dst)>; +def : MipsPat<(brcond (i64 (setgt i32:$lhs, -1)), bb:$dst), + (BGEZ64 (SUBREG_TO_REG (i32 0), i32:$lhs, sub_32), bb:$dst)>; // setcc patterns defm : SeteqPats; -defm : SetlePats; +defm : SetlePats; defm : SetgtPats; -defm : SetgePats; -defm : SetgeImmPats; +defm : SetgePats; +defm : SetgeImmPats; + +defm : SeteqPats; +defm : SetlePats; +defm : SetgtPats; +defm : SetgePats; +defm : SetgeImmPats; // truncate def : MipsPat<(trunc (assertsext GPR64:$src)), @@ -536,13 +550,13 @@ // Octeon bbit0/bbit1 MipsPattern let Predicates = [HasMips64, HasCnMips] in { -def : MipsPat<(brcond (i32 (seteq (and i64:$lhs, PowerOf2LO:$mask), 0)), bb:$dst), +def : MipsPat<(brcond (i64 (seteq (and i64:$lhs, PowerOf2LO:$mask), 0)), bb:$dst), (BBIT0 i64:$lhs, (Log2LO PowerOf2LO:$mask), bb:$dst)>; -def : MipsPat<(brcond (i32 (seteq (and i64:$lhs, PowerOf2HI:$mask), 0)), bb:$dst), +def : MipsPat<(brcond (i64 (seteq (and i64:$lhs, PowerOf2HI:$mask), 0)), bb:$dst), (BBIT032 i64:$lhs, (Log2HI PowerOf2HI:$mask), bb:$dst)>; -def : MipsPat<(brcond (i32 (setne (and i64:$lhs, PowerOf2LO:$mask), 0)), bb:$dst), +def : MipsPat<(brcond (i64 (setne (and i64:$lhs, PowerOf2LO:$mask), 0)), bb:$dst), (BBIT1 i64:$lhs, (Log2LO PowerOf2LO:$mask), bb:$dst)>; -def : MipsPat<(brcond (i32 (setne (and i64:$lhs, PowerOf2HI:$mask), 0)), bb:$dst), +def : MipsPat<(brcond (i64 (setne (and i64:$lhs, PowerOf2HI:$mask), 0)), bb:$dst), (BBIT132 i64:$lhs, (Log2HI PowerOf2HI:$mask), bb:$dst)>; } Index: lib/Target/Mips/Mips64r6InstrInfo.td =================================================================== --- lib/Target/Mips/Mips64r6InstrInfo.td +++ lib/Target/Mips/Mips64r6InstrInfo.td @@ -74,6 +74,11 @@ class SCD_R6_DESC : SC_R6_DESC_BASE<"scd", GPR64Opnd>; class SELEQZ64_DESC : SELEQNE_Z_DESC_BASE<"seleqz", GPR64Opnd>; class SELNEZ64_DESC : SELEQNE_Z_DESC_BASE<"selnez", GPR64Opnd>; +class SEL64_S_DESC : COP1_SEL_DESC_BASE<"sel.s", FGRCC64Opnd, FGR32Opnd> { + // We must copy FGRCC64Opnd's subreg into FGR32. + bit usesCustomInserter = 1; +} +class SEL64_D_DESC : COP1_SEL_DESC_BASE<"sel.d", FGRCC64Opnd, FGR64Opnd>; //===----------------------------------------------------------------------===// // @@ -100,11 +105,15 @@ def DMUL_R6: DMUL_R6_ENC, DMUL_R6_DESC, ISA_MIPS64R6; def DMULU: DMULU_ENC, DMULU_DESC, ISA_MIPS64R6; def LDPC: LDPC_ENC, LDPC_DESC, ISA_MIPS64R6; -def LLD_R6 : LLD_R6_ENC, LLD_R6_DESC, ISA_MIPS32R6; -def SCD_R6 : SCD_R6_ENC, SCD_R6_DESC, ISA_MIPS32R6; +def LLD_R6 : LLD_R6_ENC, LLD_R6_DESC, ISA_MIPS64R6; +def SCD_R6 : SCD_R6_ENC, SCD_R6_DESC, ISA_MIPS64R6; let DecoderNamespace = "Mips32r6_64r6_GP64" in { - def SELEQZ64 : SELEQZ_ENC, SELEQZ64_DESC, ISA_MIPS32R6, GPR_64; - def SELNEZ64 : SELNEZ_ENC, SELNEZ64_DESC, ISA_MIPS32R6, GPR_64; + def SELEQZ64 : SELEQZ_ENC, SELEQZ64_DESC, ISA_MIPS64R6; + def SELNEZ64 : SELNEZ_ENC, SELNEZ64_DESC, ISA_MIPS64R6; + def SEL64_S : SEL_S_ENC, SEL64_S_DESC, ISA_MIPS64R6; + def SEL64_D : SEL_D_ENC, SEL64_D_DESC, ISA_MIPS64R6; + defm S64: CMP_CC_M, ISA_MIPS64R6; + defm D64: CMP_CC_M, ISA_MIPS64R6; } //===----------------------------------------------------------------------===// @@ -121,99 +130,71 @@ // //===----------------------------------------------------------------------===// +// comparisons supported via another comparison +defm S64: Cmp_Pats, ISA_MIPS64R6; +defm D64: Cmp_Pats, ISA_MIPS64R6; + +// i32 selects +defm : SelectInt_Pats, ISA_MIPS64R6; + +def : MipsPat<(select i64:$cond, i32:$t, i32:$f), + (OR (SELNEZ i32:$t, (EXTRACT_SUBREG i64:$cond, sub_32)), + (SELEQZ i32:$f, (EXTRACT_SUBREG i64:$cond, sub_32)))>, + ISA_MIPS64R6; +def : MipsPat<(select i64:$cond, i32:$t, immz), + (SELNEZ i32:$t, (EXTRACT_SUBREG i64:$cond, sub_32))>, + ISA_MIPS64R6; +def : MipsPat<(select i64:$cond, immz, i32:$f), + (SELEQZ i32:$f, (EXTRACT_SUBREG i64:$cond, sub_32))>, + ISA_MIPS64R6; + // i64 selects +defm : SelectInt_Pats, ISA_MIPS64R6; + def : MipsPat<(select i64:$cond, i64:$t, i64:$f), (OR64 (SELNEZ64 i64:$t, i64:$cond), (SELEQZ64 i64:$f, i64:$cond))>, - ISA_MIPS64R6; -def : MipsPat<(select (i32 (seteq i64:$cond, immz)), i64:$t, i64:$f), - (OR64 (SELEQZ64 i64:$t, i64:$cond), - (SELNEZ64 i64:$f, i64:$cond))>, - ISA_MIPS64R6; -def : MipsPat<(select (i32 (setne i64:$cond, immz)), i64:$t, i64:$f), - (OR64 (SELNEZ64 i64:$t, i64:$cond), - (SELEQZ64 i64:$f, i64:$cond))>, - ISA_MIPS64R6; -def : MipsPat<(select (i32 (seteq i64:$cond, immZExt16_64:$imm)), i64:$t, i64:$f), - (OR64 (SELEQZ64 i64:$t, (XORi64 i64:$cond, immZExt16_64:$imm)), - (SELNEZ64 i64:$f, (XORi64 i64:$cond, immZExt16_64:$imm)))>, - ISA_MIPS64R6; -def : MipsPat<(select (i32 (setne i64:$cond, immZExt16_64:$imm)), i64:$t, i64:$f), - (OR64 (SELNEZ64 i64:$t, (XORi64 i64:$cond, immZExt16_64:$imm)), - (SELEQZ64 i64:$f, (XORi64 i64:$cond, immZExt16_64:$imm)))>, - ISA_MIPS64R6; -def : MipsPat< - (select (i32 (setgt i64:$cond, immSExt16Plus1:$imm)), i64:$t, i64:$f), - (OR64 (SELEQZ64 i64:$t, - (SUBREG_TO_REG (i64 0), (SLTi64 i64:$cond, (Plus1 imm:$imm)), - sub_32)), - (SELNEZ64 i64:$f, - (SUBREG_TO_REG (i64 0), (SLTi64 i64:$cond, (Plus1 imm:$imm)), - sub_32)))>, - ISA_MIPS64R6; -def : MipsPat< - (select (i32 (setugt i64:$cond, immSExt16Plus1:$imm)), i64:$t, i64:$f), - (OR64 (SELEQZ64 i64:$t, - (SUBREG_TO_REG (i64 0), (SLTiu64 i64:$cond, (Plus1 imm:$imm)), - sub_32)), - (SELNEZ64 i64:$f, - (SUBREG_TO_REG (i64 0), (SLTiu64 i64:$cond, (Plus1 imm:$imm)), - sub_32)))>, - ISA_MIPS64R6; - -def : MipsPat<(select (i32 (setne i64:$cond, immz)), i64:$t, immz), - (SELNEZ64 i64:$t, i64:$cond)>, ISA_MIPS64R6; -def : MipsPat<(select (i32 (seteq i64:$cond, immz)), i64:$t, immz), - (SELEQZ64 i64:$t, i64:$cond)>, ISA_MIPS64R6; -def : MipsPat<(select (i32 (setne i64:$cond, immz)), immz, i64:$f), - (SELEQZ64 i64:$f, i64:$cond)>, ISA_MIPS64R6; -def : MipsPat<(select (i32 (seteq i64:$cond, immz)), immz, i64:$f), - (SELNEZ64 i64:$f, i64:$cond)>, ISA_MIPS64R6; + ISA_MIPS64R6; // i64 selects from an i32 comparison -// One complicating factor here is that bits 32-63 of an i32 are undefined. -// FIXME: Ideally, setcc would always produce an i64 on MIPS64 targets. -// This would allow us to remove the sign-extensions here. def : MipsPat<(select i32:$cond, i64:$t, i64:$f), - (OR64 (SELNEZ64 i64:$t, (SLL64_32 i32:$cond)), - (SELEQZ64 i64:$f, (SLL64_32 i32:$cond)))>, - ISA_MIPS64R6; -def : MipsPat<(select (i32 (seteq i32:$cond, immz)), i64:$t, i64:$f), - (OR64 (SELEQZ64 i64:$t, (SLL64_32 i32:$cond)), - (SELNEZ64 i64:$f, (SLL64_32 i32:$cond)))>, - ISA_MIPS64R6; -def : MipsPat<(select (i32 (setne i32:$cond, immz)), i64:$t, i64:$f), - (OR64 (SELNEZ64 i64:$t, (SLL64_32 i32:$cond)), - (SELEQZ64 i64:$f, (SLL64_32 i32:$cond)))>, - ISA_MIPS64R6; -def : MipsPat<(select (i32 (seteq i32:$cond, immZExt16:$imm)), i64:$t, i64:$f), - (OR64 (SELEQZ64 i64:$t, (SLL64_32 (XORi i32:$cond, - immZExt16:$imm))), - (SELNEZ64 i64:$f, (SLL64_32 (XORi i32:$cond, - immZExt16:$imm))))>, - ISA_MIPS64R6; -def : MipsPat<(select (i32 (setne i32:$cond, immZExt16:$imm)), i64:$t, i64:$f), - (OR64 (SELNEZ64 i64:$t, (SLL64_32 (XORi i32:$cond, - immZExt16:$imm))), - (SELEQZ64 i64:$f, (SLL64_32 (XORi i32:$cond, - immZExt16:$imm))))>, - ISA_MIPS64R6; + (OR64 (SELNEZ64 i64:$t, (SLL64_32 i32:$cond)), + (SELEQZ64 i64:$f, (SLL64_32 i32:$cond)))>, + ISA_MIPS64R6; +def : MipsPat<(select (i64 (seteq i32:$cond, immz)), i64:$t, i64:$f), + (OR64 (SELEQZ64 i64:$t, (SLL64_32 i32:$cond)), + (SELNEZ64 i64:$f, (SLL64_32 i32:$cond)))>, + ISA_MIPS64R6; +def : MipsPat<(select (i64 (setne i32:$cond, immz)), i64:$t, i64:$f), + (OR64 (SELNEZ64 i64:$t, (SLL64_32 i32:$cond)), + (SELEQZ64 i64:$f, (SLL64_32 i32:$cond)))>, + ISA_MIPS64R6; +def : MipsPat<(select (i64 (seteq i32:$cond, immZExt16:$imm)), i64:$t, i64:$f), + (OR64 (SELEQZ64 i64:$t, (SLL64_32 (XORi i32:$cond, immZExt16:$imm))), + (SELNEZ64 i64:$f, (SLL64_32 (XORi i32:$cond, immZExt16:$imm))))>, + ISA_MIPS64R6; +def : MipsPat<(select (i64 (setne i32:$cond, immZExt16:$imm)), i64:$t, i64:$f), + (OR64 (SELNEZ64 i64:$t, (SLL64_32 (XORi i32:$cond, immZExt16:$imm))), + (SELEQZ64 i64:$f, (SLL64_32 (XORi i32:$cond, immZExt16:$imm))))>, + ISA_MIPS64R6; def : MipsPat<(select i32:$cond, i64:$t, immz), (SELNEZ64 i64:$t, (SLL64_32 i32:$cond))>, - ISA_MIPS64R6; -def : MipsPat<(select (i32 (setne i32:$cond, immz)), i64:$t, immz), + ISA_MIPS64R6; +def : MipsPat<(select (i64 (setne i32:$cond, immz)), i64:$t, immz), (SELNEZ64 i64:$t, (SLL64_32 i32:$cond))>, - ISA_MIPS64R6; -def : MipsPat<(select (i32 (seteq i32:$cond, immz)), i64:$t, immz), + ISA_MIPS64R6; +def : MipsPat<(select (i64 (seteq i32:$cond, immz)), i64:$t, immz), (SELEQZ64 i64:$t, (SLL64_32 i32:$cond))>, - ISA_MIPS64R6; + ISA_MIPS64R6; def : MipsPat<(select i32:$cond, immz, i64:$f), (SELEQZ64 i64:$f, (SLL64_32 i32:$cond))>, - ISA_MIPS64R6; -def : MipsPat<(select (i32 (setne i32:$cond, immz)), immz, i64:$f), + ISA_MIPS64R6; +def : MipsPat<(select (i64 (setne i32:$cond, immz)), immz, i64:$f), (SELEQZ64 i64:$f, (SLL64_32 i32:$cond))>, - ISA_MIPS64R6; -def : MipsPat<(select (i32 (seteq i32:$cond, immz)), immz, i64:$f), + ISA_MIPS64R6; +def : MipsPat<(select (i64 (seteq i32:$cond, immz)), immz, i64:$f), (SELNEZ64 i64:$f, (SLL64_32 i32:$cond))>, - ISA_MIPS64R6; + ISA_MIPS64R6; Index: lib/Target/Mips/MipsCondMov.td =================================================================== --- lib/Target/Mips/MipsCondMov.td +++ lib/Target/Mips/MipsCondMov.td @@ -52,57 +52,6 @@ let Constraints = "$F = $fd"; } -// select patterns -multiclass MovzPats0 { - def : MipsPat<(select (i32 (setge CRC:$lhs, CRC:$rhs)), DRC:$T, DRC:$F), - (MOVZInst DRC:$T, (SLTOp CRC:$lhs, CRC:$rhs), DRC:$F)>; - def : MipsPat<(select (i32 (setuge CRC:$lhs, CRC:$rhs)), DRC:$T, DRC:$F), - (MOVZInst DRC:$T, (SLTuOp CRC:$lhs, CRC:$rhs), DRC:$F)>; - def : MipsPat<(select (i32 (setge CRC:$lhs, immSExt16:$rhs)), DRC:$T, DRC:$F), - (MOVZInst DRC:$T, (SLTiOp CRC:$lhs, immSExt16:$rhs), DRC:$F)>; - def : MipsPat<(select (i32 (setuge CRC:$lh, immSExt16:$rh)), DRC:$T, DRC:$F), - (MOVZInst DRC:$T, (SLTiuOp CRC:$lh, immSExt16:$rh), DRC:$F)>; - def : MipsPat<(select (i32 (setle CRC:$lhs, CRC:$rhs)), DRC:$T, DRC:$F), - (MOVZInst DRC:$T, (SLTOp CRC:$rhs, CRC:$lhs), DRC:$F)>; - def : MipsPat<(select (i32 (setule CRC:$lhs, CRC:$rhs)), DRC:$T, DRC:$F), - (MOVZInst DRC:$T, (SLTuOp CRC:$rhs, CRC:$lhs), DRC:$F)>; - def : MipsPat<(select (i32 (setgt CRC:$lhs, immSExt16Plus1:$rhs)), - DRC:$T, DRC:$F), - (MOVZInst DRC:$T, (SLTiOp CRC:$lhs, (Plus1 imm:$rhs)), DRC:$F)>; - def : MipsPat<(select (i32 (setugt CRC:$lhs, immSExt16Plus1:$rhs)), - DRC:$T, DRC:$F), - (MOVZInst DRC:$T, (SLTiuOp CRC:$lhs, (Plus1 imm:$rhs)), - DRC:$F)>; -} - -multiclass MovzPats1 { - def : MipsPat<(select (i32 (seteq CRC:$lhs, CRC:$rhs)), DRC:$T, DRC:$F), - (MOVZInst DRC:$T, (XOROp CRC:$lhs, CRC:$rhs), DRC:$F)>; - def : MipsPat<(select (i32 (seteq CRC:$lhs, 0)), DRC:$T, DRC:$F), - (MOVZInst DRC:$T, CRC:$lhs, DRC:$F)>; -} - -multiclass MovzPats2 { - def : MipsPat< - (select (i32 (seteq CRC:$lhs, immZExt16:$uimm16)), DRC:$T, DRC:$F), - (MOVZInst DRC:$T, (XORiOp CRC:$lhs, immZExt16:$uimm16), DRC:$F)>; -} - -multiclass MovnPats { - def : MipsPat<(select (i32 (setne CRC:$lhs, CRC:$rhs)), DRC:$T, DRC:$F), - (MOVNInst DRC:$T, (XOROp CRC:$lhs, CRC:$rhs), DRC:$F)>; - def : MipsPat<(select CRC:$cond, DRC:$T, DRC:$F), - (MOVNInst DRC:$T, CRC:$cond, DRC:$F)>; - def : MipsPat<(select (i32 (setne CRC:$lhs, 0)),DRC:$T, DRC:$F), - (MOVNInst DRC:$T, CRC:$lhs, DRC:$F)>; -} - // Instantiation of instructions. def MOVZ_I_I : MMRel, CMov_I_I_FT<"movz", GPR32Opnd, GPR32Opnd, II_MOVZ>, ADD_FM<0, 0xa>, INSN_MIPS4_32_NOT_32R6_64R6; @@ -199,96 +148,179 @@ CMov_F_F_FM<17, 0>, INSN_MIPS4_32_NOT_32R6_64R6, FGR_64; } -// Instantiation of conditional move patterns. -defm : MovzPats0, - INSN_MIPS4_32_NOT_32R6_64R6; -defm : MovzPats1, INSN_MIPS4_32_NOT_32R6_64R6; -defm : MovzPats2, INSN_MIPS4_32_NOT_32R6_64R6; +// select patterns +multiclass MovzPats0 { +// reg, reg +def : MipsPat<(select (VT (setge CRC:$lhs, CRC:$rhs)), DRC:$T, DRC:$F), + (MOVZInst DRC:$T, (SLTOp CRC:$lhs, CRC:$rhs), DRC:$F)>; +def : MipsPat<(select (VT (setuge CRC:$lhs, CRC:$rhs)), DRC:$T, DRC:$F), + (MOVZInst DRC:$T, (SLTuOp CRC:$lhs, CRC:$rhs), DRC:$F)>; +def : MipsPat<(select (VT (setle CRC:$lhs, CRC:$rhs)), DRC:$T, DRC:$F), + (MOVZInst DRC:$T, (SLTOp CRC:$rhs, CRC:$lhs), DRC:$F)>; +def : MipsPat<(select (VT (setule CRC:$lhs, CRC:$rhs)), DRC:$T, DRC:$F), + (MOVZInst DRC:$T, (SLTuOp CRC:$rhs, CRC:$lhs), DRC:$F)>; + +// reg, imm +def : MipsPat<(select (VT (setge CRC:$lhs, immSExt16:$rhs)), DRC:$T, DRC:$F), + (MOVZInst DRC:$T, (SLTiOp CRC:$lhs, immSExt16:$rhs), DRC:$F)>; +def : MipsPat<(select (VT (setuge CRC:$lh, immSExt16:$rh)), DRC:$T, DRC:$F), + (MOVZInst DRC:$T, (SLTiuOp CRC:$lh, immSExt16:$rh), DRC:$F)>; +def : MipsPat< + (select (VT (setgt CRC:$lhs, immSExt16Plus1:$rhs)), DRC:$T, DRC:$F), + (MOVZInst DRC:$T, (SLTiOp CRC:$lhs, (Plus1 imm:$rhs)), DRC:$F)>; +def : MipsPat< + (select (VT (setugt CRC:$lhs, immSExt16Plus1:$rhs)), DRC:$T, DRC:$F), + (MOVZInst DRC:$T, (SLTiuOp CRC:$lhs, (Plus1 imm:$rhs)), DRC:$F)>; +} -defm : MovzPats0, - INSN_MIPS4_32_NOT_32R6_64R6, GPR_64; -defm : MovzPats0, - INSN_MIPS4_32_NOT_32R6_64R6, GPR_64; -defm : MovzPats0, - INSN_MIPS4_32_NOT_32R6_64R6, GPR_64; -defm : MovzPats1, - INSN_MIPS4_32_NOT_32R6_64R6, GPR_64; -defm : MovzPats1, - INSN_MIPS4_32_NOT_32R6_64R6, GPR_64; -defm : MovzPats1, +// We have to wrap the instantiation of the MovzPats0 patterns in another +// multiclass that specifies the result type of the SETCC nodes. The patterns +// with VT=i64 (or i32) will be ignored when GPR-width=i32 (or i64). +multiclass MovzPats0_SuperClass { +defm : MovzPats0, + INSN_MIPS4_32_NOT_32R6_64R6; +defm : MovzPats0, INSN_MIPS4_32_NOT_32R6_64R6, GPR_64; -defm : MovzPats2, +defm : MovzPats0, + INSN_MIPS4_32_NOT_32R6_64R6; +defm : MovzPats0, + INSN_MIPS4_32_NOT_32R6_64R6, FGR_32; +defm : MovzPats0, + INSN_MIPS4_32_NOT_32R6_64R6, FGR_64; + +defm : MovzPats0, INSN_MIPS4_32_NOT_32R6_64R6, GPR_64; +defm : MovzPats0, INSN_MIPS4_32_NOT_32R6_64R6, GPR_64; +defm : MovzPats0, INSN_MIPS4_32_NOT_32R6_64R6, GPR_64; +defm : MovzPats0, INSN_MIPS4_32_NOT_32R6_64R6, GPR_64, FGR_64; + +defm : MovzPats0, INSN_MIPS4_32_NOT_32R6_64R6, GPR_64; -defm : MovzPats2, +defm : MovzPats0, INSN_MIPS4_32_NOT_32R6_64R6, GPR_64; -defm : MovzPats2, +defm : MovzPats0, INSN_MIPS4_32_NOT_32R6_64R6, GPR_64; +defm : MovzPats0, + INSN_MIPS4_32_NOT_32R6_64R6, GPR_64, FGR_64; +} -defm : MovnPats, INSN_MIPS4_32_NOT_32R6_64R6; +defm : MovzPats0_SuperClass; +defm : MovzPats0_SuperClass; -defm : MovnPats, INSN_MIPS4_32_NOT_32R6_64R6, - GPR_64; -defm : MovnPats, INSN_MIPS4_32_NOT_32R6_64R6, - GPR_64; -defm : MovnPats, INSN_MIPS4_32_NOT_32R6_64R6, - GPR_64; +multiclass MovzPats1 { +def : MipsPat<(select (iPTR (seteq CRC:$lhs, CRC:$rhs)), DRC:$T, DRC:$F), + (MOVZInst DRC:$T, (XOROp CRC:$lhs, CRC:$rhs), DRC:$F)>; +def : MipsPat<(select (iPTR (seteq CRC:$lhs, 0)), DRC:$T, DRC:$F), + (MOVZInst DRC:$T, CRC:$lhs, DRC:$F)>; +} -defm : MovzPats0, - INSN_MIPS4_32_NOT_32R6_64R6; +defm : MovzPats1, INSN_MIPS4_32_NOT_32R6_64R6; +defm : MovzPats1, INSN_MIPS4_32_NOT_32R6_64R6, + GPR_64; defm : MovzPats1, INSN_MIPS4_32_NOT_32R6_64R6; -defm : MovnPats, INSN_MIPS4_32_NOT_32R6_64R6; +defm : MovzPats1, INSN_MIPS4_32_NOT_32R6_64R6, + FGR_32; +defm : MovzPats1, INSN_MIPS4_32_NOT_32R6_64R6, + FGR_64; -defm : MovzPats0, +defm : MovzPats1, INSN_MIPS4_32_NOT_32R6_64R6, + GPR_64; +defm : MovzPats1, INSN_MIPS4_32_NOT_32R6_64R6, GPR_64; defm : MovzPats1, INSN_MIPS4_32_NOT_32R6_64R6, GPR_64; -defm : MovnPats, INSN_MIPS4_32_NOT_32R6_64R6, +defm : MovzPats1, + INSN_MIPS4_32_NOT_32R6_64R6, FGR_64; + +multiclass MovzPats2 { +def : MipsPat< + (select (iPTR (seteq CRC:$lhs, immZExt16:$uimm16)), DRC:$T, DRC:$F), + (MOVZInst DRC:$T, (XORiOp CRC:$lhs, immZExt16:$uimm16), DRC:$F)>; +} + +defm : MovzPats2, INSN_MIPS4_32_NOT_32R6_64R6; +defm : MovzPats2, INSN_MIPS4_32_NOT_32R6_64R6, + GPR_64; +defm : MovzPats2, INSN_MIPS4_32_NOT_32R6_64R6, GPR_64; +defm : MovzPats2, + INSN_MIPS4_32_NOT_32R6_64R6, GPR_64; -defm : MovzPats0, - INSN_MIPS4_32_NOT_32R6_64R6, FGR_32; -defm : MovzPats1, INSN_MIPS4_32_NOT_32R6_64R6, - FGR_32; +multiclass MovnPats { + def : MipsPat<(select (VT (setne CRC:$lhs, CRC:$rhs)), DRC:$T, DRC:$F), + (MOVNInst DRC:$T, (XOROp CRC:$lhs, CRC:$rhs), DRC:$F)>; + def : MipsPat<(select CRC:$cond, DRC:$T, DRC:$F), + (MOVNInst DRC:$T, CRC:$cond, DRC:$F)>; + def : MipsPat<(select (VT (setne CRC:$lhs, 0)),DRC:$T, DRC:$F), + (MOVNInst DRC:$T, CRC:$lhs, DRC:$F)>; +} + +defm : MovnPats, INSN_MIPS4_32_NOT_32R6_64R6; +defm : MovnPats, INSN_MIPS4_32_NOT_32R6_64R6; defm : MovnPats, INSN_MIPS4_32_NOT_32R6_64R6, FGR_32; - -defm : MovzPats0, - INSN_MIPS4_32_NOT_32R6_64R6, FGR_64; -defm : MovzPats0, - INSN_MIPS4_32_NOT_32R6_64R6, FGR_64; -defm : MovzPats1, INSN_MIPS4_32_NOT_32R6_64R6, - FGR_64; -defm : MovzPats1, - INSN_MIPS4_32_NOT_32R6_64R6, FGR_64; defm : MovnPats, INSN_MIPS4_32_NOT_32R6_64R6, FGR_64; -defm : MovnPats, INSN_MIPS4_32_NOT_32R6_64R6, - FGR_64; + +defm : MovnPats, INSN_MIPS4_32_NOT_32R6_64R6, + GPR_64; +defm : MovnPats, + INSN_MIPS4_32_NOT_32R6_64R6, GPR_64; +defm : MovnPats, INSN_MIPS4_32_NOT_32R6_64R6, + GPR_64; +defm : MovnPats, + INSN_MIPS4_32_NOT_32R6_64R6, FGR_32; +defm : MovnPats, + INSN_MIPS4_32_NOT_32R6_64R6, GPR_64, FGR_64; + +defm : MovnPats, + INSN_MIPS4_32_NOT_32R6_64R6, GPR_64; +defm : MovnPats, + INSN_MIPS4_32_NOT_32R6_64R6, GPR_64; +defm : MovnPats, + INSN_MIPS4_32_NOT_32R6_64R6, GPR_64; +defm : MovnPats, + INSN_MIPS4_32_NOT_32R6_64R6, GPR_64, FGR_64; // For targets that don't have conditional-move instructions // we have to match SELECT nodes with pseudo instructions. let usesCustomInserter = 1 in { - class Select_Pseudo : - PseudoSE<(outs RC:$dst), (ins GPR32Opnd:$cond, RC:$T, RC:$F), - [(set RC:$dst, (select GPR32Opnd:$cond, RC:$T, RC:$F))]>, + class Select_Pseudo : + PseudoSE<(outs RO:$dst), (ins RC:$cond, RO:$T, RO:$F), + [(set RO:$dst, (select RC:$cond, RO:$T, RO:$F))]>, ISA_MIPS1_NOT_4_32; - class SelectFP_Pseudo_T : - PseudoSE<(outs RC:$dst), (ins GPR32Opnd:$cond, RC:$T, RC:$F), - [(set RC:$dst, (MipsCMovFP_T RC:$T, GPR32Opnd:$cond, RC:$F))]>, + class SelectFP_Pseudo_T : + PseudoSE<(outs RO:$dst), (ins GPR32Opnd:$cond, RO:$T, RO:$F), + [(set RO:$dst, (MipsCMovFP_T RO:$T, GPR32Opnd:$cond, RO:$F))]>, ISA_MIPS1_NOT_4_32; - class SelectFP_Pseudo_F : - PseudoSE<(outs RC:$dst), (ins GPR32Opnd:$cond, RC:$T, RC:$F), - [(set RC:$dst, (MipsCMovFP_F RC:$T, GPR32Opnd:$cond, RC:$F))]>, + class SelectFP_Pseudo_F : + PseudoSE<(outs RO:$dst), (ins GPR32Opnd:$cond, RO:$T, RO:$F), + [(set RO:$dst, (MipsCMovFP_F RO:$T, GPR32Opnd:$cond, RO:$F))]>, ISA_MIPS1_NOT_4_32; } -def PseudoSELECT_I : Select_Pseudo; -def PseudoSELECT_I64 : Select_Pseudo; -def PseudoSELECT_S : Select_Pseudo; -def PseudoSELECT_D32 : Select_Pseudo, FGR_32; -def PseudoSELECT_D64 : Select_Pseudo, FGR_64; +def PseudoSELECT_I : Select_Pseudo; +def PseudoSELECT_I64 : Select_Pseudo; +def PseudoSELECT_S : Select_Pseudo; +def PseudoSELECT_D32 : Select_Pseudo, FGR_32; +def PseudoSELECT_D64 : Select_Pseudo, FGR_64; + +def PseudoSELECT64_I : Select_Pseudo, GPR_64; +def PseudoSELECT64_I64 : Select_Pseudo, GPR_64; +def PseudoSELECT64_S : Select_Pseudo, GPR_64; +def PseudoSELECT64_D32 : Select_Pseudo, GPR_64, FGR_32; +def PseudoSELECT64_D64 : Select_Pseudo, GPR_64, FGR_64; def PseudoSELECTFP_T_I : SelectFP_Pseudo_T; def PseudoSELECTFP_T_I64 : SelectFP_Pseudo_T; Index: lib/Target/Mips/MipsISelLowering.h =================================================================== --- lib/Target/Mips/MipsISelLowering.h +++ lib/Target/Mips/MipsISelLowering.h @@ -578,6 +578,9 @@ MachineBasicBlock *emitAtomicCmpSwapPartword(MachineInstr *MI, MachineBasicBlock *BB, unsigned Size) const; MachineBasicBlock *emitSEL_D(MachineInstr *MI, MachineBasicBlock *BB) const; + + MachineBasicBlock *emitSEL64_S(MachineInstr *MI, MachineBasicBlock *BB) const; + MachineBasicBlock *emitPseudoSELECT(MachineInstr *MI, MachineBasicBlock *BB, bool isFPCmp, unsigned Opc) const; Index: lib/Target/Mips/MipsISelLowering.cpp =================================================================== --- lib/Target/Mips/MipsISelLowering.cpp +++ lib/Target/Mips/MipsISelLowering.cpp @@ -265,7 +265,8 @@ // Without this, every float setcc comes with a AND/OR with the result, // we don't want this, since the fpcmp result goes to a flag register, // which is used implicitly by brcond and select operations. - AddPromotedToType(ISD::SETCC, MVT::i1, MVT::i32); + AddPromotedToType(ISD::SETCC, MVT::i1, + Subtarget.isGP32bit() ? MVT::i32 : MVT::i64); // Mips Custom Operations setOperationAction(ISD::BR_JT, MVT::Other, Custom); @@ -462,9 +463,10 @@ EVT MipsTargetLowering::getSetCCResultType(const DataLayout &, LLVMContext &, EVT VT) const { - if (!VT.isVector()) - return MVT::i32; - return VT.changeVectorElementTypeToInteger(); + if (VT.isVector()) + return VT.changeVectorElementTypeToInteger(); + + return Subtarget.isGP32bit() ? MVT::i32 : MVT::i64; } static SDValue performDivRemCombine(SDNode *N, SelectionDAG &DAG, @@ -627,19 +629,18 @@ if (!TrueC || !True.getValueType().isInteger()) return SDValue(); - // We'll also ignore MVT::i64 operands as this optimizations proves - // to be ineffective because of the required sign extensions as the result - // of a SETCC operator is always MVT::i32 for non-vector types. - if (True.getValueType() == MVT::i64) - return SDValue(); - int64_t Diff = TrueC->getSExtValue() - FalseC->getSExtValue(); // 1) (a < x) ? y : y-1 // slti $reg1, a, x // addiu $reg2, $reg1, y-1 - if (Diff == 1) - return DAG.getNode(ISD::ADD, DL, SetCC.getValueType(), SetCC, False); + if (Diff == 1) { + if (SetCC.getValueType().getSizeInBits() > False.getValueType().getSizeInBits()) + SetCC = DAG.getNode(ISD::TRUNCATE, DL, False.getValueType(), SetCC); + + SDValue Ret = DAG.getNode(ISD::ADD, DL, False.getValueType(), SetCC, False); + return Ret; + } // 2) (a < x) ? y-1 : y // slti $reg1, a, x @@ -649,6 +650,11 @@ ISD::CondCode CC = cast(SetCC.getOperand(2))->get(); SetCC = DAG.getSetCC(DL, SetCC.getValueType(), SetCC.getOperand(0), SetCC.getOperand(1), ISD::getSetCCInverse(CC, true)); + + if (SetCC.getValueType().getSizeInBits() > True.getValueType().getSizeInBits()) + SetCC = DAG.getNode(ISD::TRUNCATE, DL, True.getValueType(), SetCC); + + return DAG.getNode(ISD::ADD, DL, SetCC.getValueType(), SetCC, True); } @@ -1028,19 +1034,30 @@ return insertDivByZeroTrap(MI, *BB, *Subtarget.getInstrInfo(), true); case Mips::SEL_D: return emitSEL_D(MI, BB); + case Mips::SEL64_S: + return emitSEL64_S(MI, BB); case Mips::PseudoSELECT_I: case Mips::PseudoSELECT_I64: case Mips::PseudoSELECT_S: case Mips::PseudoSELECT_D32: case Mips::PseudoSELECT_D64: - return emitPseudoSELECT(MI, BB, false, Mips::BNE); + // 64-bit version + case Mips::PseudoSELECT64_I: + case Mips::PseudoSELECT64_I64: + case Mips::PseudoSELECT64_S: + case Mips::PseudoSELECT64_D32: + case Mips::PseudoSELECT64_D64: + return emitPseudoSELECT(MI, BB, false, + Subtarget.isGP32bit() ? Mips::BNE : Mips::BNE64); + case Mips::PseudoSELECTFP_F_I: case Mips::PseudoSELECTFP_F_I64: case Mips::PseudoSELECTFP_F_S: case Mips::PseudoSELECTFP_F_D32: case Mips::PseudoSELECTFP_F_D64: return emitPseudoSELECT(MI, BB, true, Mips::BC1F); + case Mips::PseudoSELECTFP_T_I: case Mips::PseudoSELECTFP_T_I64: case Mips::PseudoSELECTFP_T_S: @@ -1575,6 +1592,30 @@ return BB; } +MachineBasicBlock *MipsTargetLowering::emitSEL64_S(MachineInstr *MI, + MachineBasicBlock *BB) const { + MachineFunction *MF = BB->getParent(); + const TargetRegisterInfo *TRI = Subtarget.getRegisterInfo(); + const TargetInstrInfo *TII = Subtarget.getInstrInfo(); + MachineRegisterInfo &RegInfo = MF->getRegInfo(); + DebugLoc DL = MI->getDebugLoc(); + MachineBasicBlock::iterator II(MI); + + unsigned Fc64 = MI->getOperand(1).getReg(); + + const auto &FGR32RegClass = TRI->getRegClass(Mips::FGR32RegClassID); + unsigned Fc32 = RegInfo.createVirtualRegister(FGR32RegClass); + + BuildMI(*BB, II, DL, TII->get(Mips::COPY), Fc32) + .addReg(Fc64, 0, Mips::sub_lo); + + // We don't erase the original instruction, we just replace the condition + // register with the 32-bit sub-register. + MI->getOperand(1).setReg(Fc32); + + return BB; +} + //===----------------------------------------------------------------------===// // Misc Lower Operation implementation //===----------------------------------------------------------------------===// @@ -1670,8 +1711,10 @@ "Floating point operand expected."); SDLoc DL(Op); - SDValue True = DAG.getConstant(1, DL, MVT::i32); - SDValue False = DAG.getConstant(0, DL, MVT::i32); + EVT VT = getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), + Op.getValueType()); + SDValue True = DAG.getConstant(1, DL, VT); + SDValue False = DAG.getConstant(0, DL, VT); return createCMovFP(DAG, Cond, True, False, DL); } @@ -3927,7 +3970,7 @@ // bne rs, $0, sinkMBB BuildMI(BB, DL, TII->get(Opc)) .addReg(MI->getOperand(1).getReg()) - .addReg(Mips::ZERO) + .addReg(Subtarget.isGP32bit() ? Mips::ZERO : Mips::ZERO_64) .addMBB(sinkMBB); } Index: lib/Target/Mips/MipsInstrInfo.td =================================================================== --- lib/Target/Mips/MipsInstrInfo.td +++ lib/Target/Mips/MipsInstrInfo.td @@ -869,17 +869,18 @@ } // SetCC -class SetCC_R : - InstSE<(outs GPR32Opnd:$rd), (ins RO:$rs, RO:$rt), +class SetCC_R : + InstSE<(outs RD:$rd), (ins RO:$rs, RO:$rt), !strconcat(opstr, "\t$rd, $rs, $rt"), - [(set GPR32Opnd:$rd, (cond_op RO:$rs, RO:$rt))], + [(set RD:$rd, (cond_op RO:$rs, RO:$rt))], II_SLT_SLTU, FrmR, opstr>; class SetCC_I: - InstSE<(outs GPR32Opnd:$rt), (ins RO:$rs, Od:$imm16), + RegisterOperand RD, RegisterOperand RO>: + InstSE<(outs RD:$rt), (ins RO:$rs, Od:$imm16), !strconcat(opstr, "\t$rt, $rs, $imm16"), - [(set GPR32Opnd:$rt, (cond_op RO:$rs, imm_type:$imm16))], + [(set RD:$rt, (cond_op RO:$rs, imm_type:$imm16))], II_SLTI_SLTIU, FrmI, opstr>; // Jump @@ -1255,10 +1256,10 @@ } def ADDi : MMRel, ArithLogicI<"addi", simm16, GPR32Opnd>, ADDI_FM<0x8>, ISA_MIPS1_NOT_32R6_64R6; -def SLTi : MMRel, SetCC_I<"slti", setlt, simm16, immSExt16, GPR32Opnd>, - SLTI_FM<0xa>; -def SLTiu : MMRel, SetCC_I<"sltiu", setult, simm16, immSExt16, GPR32Opnd>, - SLTI_FM<0xb>; +def SLTi : MMRel, SetCC_I<"slti", setlt, simm16, immSExt16, GPR32Opnd, + GPR32Opnd>, SLTI_FM<0xa>; +def SLTiu : MMRel, SetCC_I<"sltiu", setult, simm16, immSExt16, GPR32Opnd, + GPR32Opnd>, SLTI_FM<0xb>; let AdditionalPredicates = [NotInMicroMips] in { def ANDi : MMRel, StdMMR6Rel, ArithLogicI<"andi", uimm16, GPR32Opnd, II_ANDI, immZExt16, and>, @@ -1283,8 +1284,8 @@ ADD_FM<0x1c, 2>, ISA_MIPS32_NOT_32R6_64R6; def ADD : MMRel, StdMMR6Rel, ArithLogicR<"add", GPR32Opnd>, ADD_FM<0, 0x20>; def SUB : MMRel, ArithLogicR<"sub", GPR32Opnd>, ADD_FM<0, 0x22>; -def SLT : MMRel, SetCC_R<"slt", setlt, GPR32Opnd>, ADD_FM<0, 0x2a>; -def SLTu : MMRel, SetCC_R<"sltu", setult, GPR32Opnd>, ADD_FM<0, 0x2b>; +def SLT : MMRel, SetCC_R<"slt", setlt, GPR32Opnd, GPR32Opnd>, ADD_FM<0, 0x2a>; +def SLTu : MMRel, SetCC_R<"sltu", setult, GPR32Opnd, GPR32Opnd>, ADD_FM<0, 0x2b>; let AdditionalPredicates = [NotInMicroMips] in { def AND : MMRel, StdMMR6Rel, ArithLogicR<"and", GPR32Opnd, 1, II_AND, and>, ADD_FM<0, 0x24>; @@ -2064,37 +2065,40 @@ def : MipsPat<(store (i32 0), addr:$dst), (SW ZERO, addr:$dst)>; // brcond patterns -multiclass BrcondPats { -def : MipsPat<(brcond (i32 (setne RC:$lhs, 0)), bb:$dst), +multiclass BrcondPats1 { +def : MipsPat<(brcond (VT (setne RC:$lhs, 0)), bb:$dst), (BNEOp RC:$lhs, ZEROReg, bb:$dst)>; -def : MipsPat<(brcond (i32 (seteq RC:$lhs, 0)), bb:$dst), +def : MipsPat<(brcond (VT (seteq RC:$lhs, 0)), bb:$dst), (BEQOp RC:$lhs, ZEROReg, bb:$dst)>; - -def : MipsPat<(brcond (i32 (setge RC:$lhs, RC:$rhs)), bb:$dst), - (BEQ (SLTOp RC:$lhs, RC:$rhs), ZERO, bb:$dst)>; -def : MipsPat<(brcond (i32 (setuge RC:$lhs, RC:$rhs)), bb:$dst), - (BEQ (SLTuOp RC:$lhs, RC:$rhs), ZERO, bb:$dst)>; -def : MipsPat<(brcond (i32 (setge RC:$lhs, immSExt16:$rhs)), bb:$dst), - (BEQ (SLTiOp RC:$lhs, immSExt16:$rhs), ZERO, bb:$dst)>; -def : MipsPat<(brcond (i32 (setuge RC:$lhs, immSExt16:$rhs)), bb:$dst), - (BEQ (SLTiuOp RC:$lhs, immSExt16:$rhs), ZERO, bb:$dst)>; -def : MipsPat<(brcond (i32 (setgt RC:$lhs, immSExt16Plus1:$rhs)), bb:$dst), - (BEQ (SLTiOp RC:$lhs, (Plus1 imm:$rhs)), ZERO, bb:$dst)>; -def : MipsPat<(brcond (i32 (setugt RC:$lhs, immSExt16Plus1:$rhs)), bb:$dst), - (BEQ (SLTiuOp RC:$lhs, (Plus1 imm:$rhs)), ZERO, bb:$dst)>; - -def : MipsPat<(brcond (i32 (setle RC:$lhs, RC:$rhs)), bb:$dst), - (BEQ (SLTOp RC:$rhs, RC:$lhs), ZERO, bb:$dst)>; -def : MipsPat<(brcond (i32 (setule RC:$lhs, RC:$rhs)), bb:$dst), - (BEQ (SLTuOp RC:$rhs, RC:$lhs), ZERO, bb:$dst)>; - def : MipsPat<(brcond RC:$cond, bb:$dst), (BNEOp RC:$cond, ZEROReg, bb:$dst)>; } -defm : BrcondPats; +multiclass BrcondPats2 { +def : MipsPat<(brcond (VT (setge RC:$lhs, RC:$rhs)), bb:$dst), + (BEQOp (SLTOp RC:$lhs, RC:$rhs), ZEROReg, bb:$dst)>; +def : MipsPat<(brcond (VT (setuge RC:$lhs, RC:$rhs)), bb:$dst), + (BEQOp (SLTuOp RC:$lhs, RC:$rhs), ZEROReg, bb:$dst)>; +def : MipsPat<(brcond (VT (setge RC:$lhs, immSExt16:$rhs)), bb:$dst), + (BEQOp (SLTiOp RC:$lhs, immSExt16:$rhs), ZEROReg, bb:$dst)>; +def : MipsPat<(brcond (VT (setuge RC:$lhs, immSExt16:$rhs)), bb:$dst), + (BEQOp (SLTiuOp RC:$lhs, immSExt16:$rhs), ZEROReg, bb:$dst)>; +def : MipsPat<(brcond (VT (setgt RC:$lhs, immSExt16Plus1:$rhs)), bb:$dst), + (BEQOp (SLTiOp RC:$lhs, (Plus1 imm:$rhs)), ZEROReg, bb:$dst)>; +def : MipsPat<(brcond (VT (setugt RC:$lhs, immSExt16Plus1:$rhs)), bb:$dst), + (BEQOp (SLTiuOp RC:$lhs, (Plus1 imm:$rhs)), ZEROReg, bb:$dst)>; +def : MipsPat<(brcond (VT (setle RC:$lhs, RC:$rhs)), bb:$dst), + (BEQOp (SLTOp RC:$rhs, RC:$lhs), ZEROReg, bb:$dst)>; +def : MipsPat<(brcond (VT (setule RC:$lhs, RC:$rhs)), bb:$dst), + (BEQOp (SLTuOp RC:$rhs, RC:$lhs), ZEROReg, bb:$dst)>; +} + +defm : BrcondPats1; +defm : BrcondPats2; def : MipsPat<(brcond (i32 (setlt i32:$lhs, 1)), bb:$dst), (BLEZ i32:$lhs, bb:$dst)>; @@ -2114,11 +2118,12 @@ (SLTuOp ZEROReg, (XOROp RC:$lhs, RC:$rhs))>; } -multiclass SetlePats { +multiclass SetlePats { def : MipsPat<(setle RC:$lhs, RC:$rhs), - (XORi (SLTOp RC:$rhs, RC:$lhs), 1)>; + (XORiOp (SLTOp RC:$rhs, RC:$lhs), 1)>; def : MipsPat<(setule RC:$lhs, RC:$rhs), - (XORi (SLTuOp RC:$rhs, RC:$lhs), 1)>; + (XORiOp (SLTuOp RC:$rhs, RC:$lhs), 1)>; } multiclass SetgtPats { @@ -2128,26 +2133,27 @@ (SLTuOp RC:$rhs, RC:$lhs)>; } -multiclass SetgePats { +multiclass SetgePats { def : MipsPat<(setge RC:$lhs, RC:$rhs), - (XORi (SLTOp RC:$lhs, RC:$rhs), 1)>; + (XORiOp (SLTOp RC:$lhs, RC:$rhs), 1)>; def : MipsPat<(setuge RC:$lhs, RC:$rhs), - (XORi (SLTuOp RC:$lhs, RC:$rhs), 1)>; + (XORiOp (SLTuOp RC:$lhs, RC:$rhs), 1)>; } multiclass SetgeImmPats { + Instruction SLTiuOp, Instruction XORiOp> { def : MipsPat<(setge RC:$lhs, immSExt16:$rhs), - (XORi (SLTiOp RC:$lhs, immSExt16:$rhs), 1)>; + (XORiOp (SLTiOp RC:$lhs, immSExt16:$rhs), 1)>; def : MipsPat<(setuge RC:$lhs, immSExt16:$rhs), - (XORi (SLTiuOp RC:$lhs, immSExt16:$rhs), 1)>; + (XORiOp (SLTiuOp RC:$lhs, immSExt16:$rhs), 1)>; } defm : SeteqPats; -defm : SetlePats; +defm : SetlePats; defm : SetgtPats; -defm : SetgePats; -defm : SetgeImmPats; +defm : SetgePats; +defm : SetgeImmPats; // bswap pattern def : MipsPat<(bswap GPR32:$rt), (ROTR (WSBH GPR32:$rt), 16)>; Index: lib/Target/Mips/MipsRegisterInfo.td =================================================================== --- lib/Target/Mips/MipsRegisterInfo.td +++ lib/Target/Mips/MipsRegisterInfo.td @@ -391,8 +391,9 @@ Unallocatable; // MIPS32r6/MIPS64r6 store FPU condition codes in normal FGR registers. -// This class allows us to represent this in codegen patterns. -def FGRCC : RegisterClass<"Mips", [i32], 32, (sequence "F%u", 0, 31)>; +// These classes allow us to represent this in codegen patterns. +def FGRCC32 : RegisterClass<"Mips", [i32], 32, (sequence "F%u", 0, 31)>; +def FGRCC64 : RegisterClass<"Mips", [i64], 64, (sequence "D%u_64", 0, 31)>; def MSA128B: RegisterClass<"Mips", [v16i8], 128, (sequence "W%u", 0, 31)>; @@ -595,7 +596,13 @@ let ParserMatchClass = FGR32AsmOperand; } -def FGRCCOpnd : RegisterOperand { +def FGRCC32Opnd : RegisterOperand { + // The assembler doesn't use register classes so we can re-use + // FGR32AsmOperand. + let ParserMatchClass = FGR32AsmOperand; +} + +def FGRCC64Opnd : RegisterOperand { // The assembler doesn't use register classes so we can re-use // FGR32AsmOperand. let ParserMatchClass = FGR32AsmOperand; Index: lib/Target/Mips/MipsSEISelDAGToDAG.cpp =================================================================== --- lib/Target/Mips/MipsSEISelDAGToDAG.cpp +++ lib/Target/Mips/MipsSEISelDAGToDAG.cpp @@ -251,28 +251,14 @@ SDValue LHS = Node->getOperand(0), RHS = Node->getOperand(1); EVT VT = LHS.getValueType(); - SDNode *Carry = CurDAG->getMachineNode(SLTuOp, DL, VT, Ops); - - if (Subtarget->isGP64bit()) { - // On 64-bit targets, sltu produces an i64 but our backend currently says - // that SLTu64 produces an i32. We need to fix this in the long run but for - // now, just make the DAG type-correct by asserting the upper bits are zero. - Carry = CurDAG->getMachineNode(Mips::SUBREG_TO_REG, DL, VT, - CurDAG->getTargetConstant(0, DL, VT), - SDValue(Carry, 0), - CurDAG->getTargetConstant(Mips::sub_32, DL, - VT)); - } - // Generate a second addition only if we know that RHS is not a // constant-zero node. - SDNode *AddCarry = Carry; + SDNode *Carry = CurDAG->getMachineNode(SLTuOp, DL, VT, Ops); ConstantSDNode *C = dyn_cast(RHS); if (!C || C->getZExtValue()) - AddCarry = CurDAG->getMachineNode(ADDuOp, DL, VT, SDValue(Carry, 0), RHS); + Carry = CurDAG->getMachineNode(ADDuOp, DL, VT, SDValue(Carry, 0), RHS); - return CurDAG->SelectNodeTo(Node, MOp, VT, MVT::Glue, LHS, - SDValue(AddCarry, 0)); + return CurDAG->SelectNodeTo(Node, MOp, VT, MVT::Glue, LHS, SDValue(Carry, 0)); } /// Match frameindex Index: lib/Target/Mips/MipsSEISelLowering.h =================================================================== --- lib/Target/Mips/MipsSEISelLowering.h +++ lib/Target/Mips/MipsSEISelLowering.h @@ -68,6 +68,8 @@ SDValue lowerMulDiv(SDValue Op, unsigned NewOpc, bool HasLo, bool HasHi, SelectionDAG &DAG) const; + SDValue lowerOverflowRes(SDValue Op, SelectionDAG &DAG) const; + SDValue lowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG) const; SDValue lowerINTRINSIC_W_CHAIN(SDValue Op, SelectionDAG &DAG) const; SDValue lowerINTRINSIC_VOID(SDValue Op, SelectionDAG &DAG) const; Index: lib/Target/Mips/MipsSEISelLowering.cpp =================================================================== --- lib/Target/Mips/MipsSEISelLowering.cpp +++ lib/Target/Mips/MipsSEISelLowering.cpp @@ -1292,7 +1292,6 @@ return DAG.getMergeValues(Vals, DL); } - static SDValue initAccumulator(SDValue In, SDLoc DL, SelectionDAG &DAG) { SDValue InLo = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i32, In, DAG.getConstant(0, DL, MVT::i32)); Index: test/CodeGen/Mips/atomic.ll =================================================================== --- test/CodeGen/Mips/atomic.ll +++ test/CodeGen/Mips/atomic.ll @@ -344,7 +344,11 @@ ; HAS-SEB-SEH: seb $[[R19:[0-9]+]], $[[R17]] ; ALL: xor $[[R20:[0-9]+]], $[[R19]], $5 -; ALL: sltiu $2, $[[R20]], 1 +; MIPS32-ANY: sltiu $2, $[[R20]], 1 + +; FIXME: remove redundant sign-extension. +; MIPS64-ANY: sltiu $[[R21:[0-9]+]], $[[R20]], 1 +; MIPS64-ANY: sll $2, $[[R21]], 0 } ; Check one i16 so that we cover the seh sign extend Index: test/CodeGen/Mips/blez_bgez.ll =================================================================== --- test/CodeGen/Mips/blez_bgez.ll +++ test/CodeGen/Mips/blez_bgez.ll @@ -1,10 +1,13 @@ -; RUN: llc -march=mipsel < %s | FileCheck %s -; RUN: llc -march=mips64el < %s | FileCheck %s +; RUN: llc -march=mipsel < %s | \ +; RUN: FileCheck %s -check-prefix=ALL +; RUN: llc -march=mips64el < %s | \ +; RUN: FileCheck %s -check-prefix=ALL -check-prefix=GP64 -; CHECK-LABEL: test_blez: -; CHECK: blez ${{[0-9]+}}, $BB +declare void @foo1() define void @test_blez(i32 %a) { +; ALL-LABEL: test_blez: +; ALL: blez ${{[0-9]+}}, $BB entry: %cmp = icmp sgt i32 %a, 0 br i1 %cmp, label %if.then, label %if.end @@ -17,13 +20,10 @@ ret void } -declare void @foo1() - -; CHECK-LABEL: test_bgez: -; CHECK: bgez ${{[0-9]+}}, $BB - define void @test_bgez(i32 %a) { entry: +; ALL-LABEL: test_bgez: +; ALL: bgez ${{[0-9]+}}, $BB %cmp = icmp slt i32 %a, 0 br i1 %cmp, label %if.then, label %if.end @@ -34,3 +34,33 @@ if.end: ret void } + +define void @test_blez_64(i64 %a) { +; GP64-LABEL: test_blez_64: +; GP64: blez ${{[0-9]+}}, $BB +entry: + %cmp = icmp sgt i64 %a, 0 + br i1 %cmp, label %if.then, label %if.end + +if.then: + tail call void @foo1() + br label %if.end + +if.end: + ret void +} + +define void @test_bgez_64(i64 %a) { +entry: +; ALL-LABEL: test_bgez_64: +; ALL: bgez ${{[0-9]+}}, $BB + %cmp = icmp slt i64 %a, 0 + br i1 %cmp, label %if.then, label %if.end + +if.then: + tail call void @foo1() + br label %if.end + +if.end: + ret void +} Index: test/CodeGen/Mips/cmov.ll =================================================================== --- test/CodeGen/Mips/cmov.ll +++ test/CodeGen/Mips/cmov.ll @@ -1,10 +1,17 @@ -; RUN: llc -march=mips -mcpu=mips32 < %s | FileCheck %s -check-prefix=ALL -check-prefix=32-CMOV -; RUN: llc -march=mips -mcpu=mips32 -regalloc=basic < %s | FileCheck %s -check-prefix=ALL -check-prefix=32-CMOV -; RUN: llc -march=mips -mcpu=mips32r2 < %s | FileCheck %s -check-prefix=ALL -check-prefix=32-CMOV -; RUN: llc -march=mips -mcpu=mips32r6 < %s | FileCheck %s -check-prefix=ALL -check-prefix=32-CMP -; RUN: llc -march=mips64el -mcpu=mips4 < %s | FileCheck %s -check-prefix=ALL -check-prefix=64-CMOV -; RUN: llc -march=mips64el -mcpu=mips64 < %s | FileCheck %s -check-prefix=ALL -check-prefix=64-CMOV -; RUN: llc -march=mips64el -mcpu=mips64r6 < %s | FileCheck %s -check-prefix=ALL -check-prefix=64-CMP +; RUN: llc -march=mips -mcpu=mips32 < %s | \ +; RUN: FileCheck %s -check-prefix=ALL -check-prefix=32-CMOV +; RUN: llc -march=mips -mcpu=mips32 -regalloc=basic < %s | \ +; RUN: FileCheck %s -check-prefix=ALL -check-prefix=32-CMOV +; RUN: llc -march=mips -mcpu=mips32r2 < %s | \ +; RUN: FileCheck %s -check-prefix=ALL -check-prefix=32-CMOV +; RUN: llc -march=mips -mcpu=mips32r6 < %s | \ +; RUN: FileCheck %s -check-prefix=ALL -check-prefix=32-CMP +; RUN: llc -march=mips64el -mcpu=mips4 < %s | \ +; RUN: FileCheck %s -check-prefix=ALL -check-prefix=64-CMOV -check-prefix=64 +; RUN: llc -march=mips64el -mcpu=mips64 < %s | \ +; RUN: FileCheck %s -check-prefix=ALL -check-prefix=64-CMOV -check-prefix=64 +; RUN: llc -march=mips64el -mcpu=mips64r6 < %s | \ +; RUN: FileCheck %s -check-prefix=ALL -check-prefix=64-CMP -check-prefix=64 @i1 = global [3 x i32] [i32 1, i32 2, i32 3], align 4 @i3 = common global i32* null, align 4 @@ -413,20 +420,9 @@ ; 32-CMP-DAG: or $3, $[[T1]], $[[T0]] ; 32-CMP-DAG: addiu $2, $zero, 0 -; 64-CMOV-DAG: addiu $[[I5:[0-9]+]], $zero, 5 -; 64-CMOV-DAG: addiu $[[I4:2]], $zero, 4 -; 64-CMOV-DAG: slti $[[R0:[0-9]+]], $4, 32767 -; 64-CMOV-DAG: movz $[[I4]], $[[I5]], $[[R0]] - -; 64-CMP-DAG: addiu $[[I5:[0-9]+]], $zero, 5 -; 64-CMP-DAG: addiu $[[I4:[0-9]+]], $zero, 4 -; 64-CMP-DAG: slti $[[R0:[0-9]+]], $4, 32767 -; FIXME: We can do better than this by adding/subtracting the result of slti -; to/from one of the constants. -; 64-CMP-DAG: seleqz $[[T0:[0-9]+]], $[[I5]], $[[R0]] -; 64-CMP-DAG: selnez $[[T1:[0-9]+]], $[[I4]], $[[R0]] -; 64-CMP-DAG: or $2, $[[T0]], $[[T1]] - +; 64-DAG: daddiu $[[T0:[0-9]+]], $zero, 32766 +; 64-DAG: slt $[[T1:[0-9]+]], $[[T0]], $4 +; 64-DAG: ori $2, $[[T1]], 4 define i64 @slti64_0(i64 %a) { entry: %cmp = icmp sgt i64 %a, 32766 @@ -458,21 +454,9 @@ ; 32-CMP-DAG: or $3, $[[T1]], $[[T0]] ; 32-CMP-DAG: addiu $2, $zero, 0 -; 64-CMOV-DAG: daddiu $[[I5:[0-9]+]], $zero, 5 -; 64-CMOV-DAG: daddiu $[[I4:2]], $zero, 4 -; 64-CMOV-DAG: daddiu $[[R1:[0-9]+]], $zero, 32767 -; 64-CMOV-DAG: slt $[[R0:[0-9]+]], $[[R1]], $4 -; 64-CMOV-DAG: movn $[[I4]], $[[I5]], $[[R0]] - -; 64-CMP-DAG: daddiu $[[I5:[0-9]+]], $zero, 5 -; 64-CMP-DAG: daddiu $[[I4:2]], $zero, 4 -; 64-CMP-DAG: daddiu $[[R1:[0-9]+]], $zero, 32767 -; 64-CMP-DAG: slt $[[R0:[0-9]+]], $[[R1]], $4 -; FIXME: We can do better than this by using selccz to choose between -0 and -2 -; 64-CMP-DAG: selnez $[[T0:[0-9]+]], $[[I5]], $[[R0]] -; 64-CMP-DAG: seleqz $[[T1:[0-9]+]], $[[I4]], $[[R0]] -; 64-CMP-DAG: or $2, $[[T0]], $[[T1]] - +; 64-DAG: daddiu $[[T0:[0-9]+]], $zero, 32767 +; 64-DAG: slt $[[T1:[0-9]+]], $[[T0]], $4 +; 64-DAG: ori $2, $[[T1]], 4 define i64 @slti64_1(i64 %a) { entry: %cmp = icmp sgt i64 %a, 32767 @@ -480,27 +464,23 @@ ret i64 %conv } -; ALL-LABEL: slti64_2: - -; FIXME: The 32-bit versions of this test are too complicated to reasonably -; match at the moment. They do show some missing optimizations though -; such as: -; (movz $a, $b, (neg $c)) -> (movn $a, $b, $c) +; ALL-LABEL: slti32_2: -; 64-CMOV-DAG: addiu $[[I3:[0-9]+]], $zero, 3 -; 64-CMOV-DAG: addiu $[[I4:2]], $zero, 4 -; 64-CMOV-DAG: slti $[[R0:[0-9]+]], $4, -32768 -; 64-CMOV-DAG: movz $[[I4]], $[[I3]], $[[R0]] +; FIXME: Remove unecessary sign-extension. +; 64-DAG: slti $[[T0:[0-9]+]], $4, -32768 +; 64-DAG: sll $[[T1:[0-9]+]], $[[T0]], 0 +; 64-DAG: addiu $2, $[[T1]], 3 +define i32 @slti32_2(i32 signext %a) { +entry: + %cmp = icmp sgt i32 %a, -32769 + %conv = select i1 %cmp, i32 3, i32 4 + ret i32 %conv +} -; 64-CMP-DAG: addiu $[[I3:[0-9]+]], $zero, 3 -; 64-CMP-DAG: addiu $[[I4:[0-9]+]], $zero, 4 -; 64-CMP-DAG: slti $[[R0:[0-9]+]], $4, -32768 -; FIXME: We can do better than this by adding/subtracting the result of slti -; to/from one of the constants. -; 64-CMP-DAG: seleqz $[[T0:[0-9]+]], $[[I3]], $[[R0]] -; 64-CMP-DAG: selnez $[[T1:[0-9]+]], $[[I4]], $[[R0]] -; 64-CMP-DAG: or $2, $[[T0]], $[[T1]] +; ALL-LABEL: slti64_2: +; 64-DAG: slti $[[T0:[0-9]+]], $4, -32768 +; 64-DAG: daddiu $2, $[[T0]], 3 define i64 @slti64_2(i64 %a) { entry: %cmp = icmp sgt i64 %a, -32769 @@ -508,28 +488,24 @@ ret i64 %conv } -; ALL-LABEL: slti64_3: - -; FIXME: The 32-bit versions of this test are too complicated to reasonably -; match at the moment. They do show some missing optimizations though -; such as: -; (movz $a, $b, (neg $c)) -> (movn $a, $b, $c) +; ALL-LABEL: slti32_3: -; 64-CMOV-DAG: daddiu $[[I5:[0-9]+]], $zero, 5 -; 64-CMOV-DAG: daddiu $[[I4:2]], $zero, 4 -; 64-CMOV-DAG: daddiu $[[R1:[0-9]+]], ${{[0-9]+}}, 32766 -; 64-CMOV-DAG: slt $[[R0:[0-9]+]], $[[R1]], $4 -; 64-CMOV-DAG: movn $[[I4]], $[[I5]], $[[R0]] +; FIXME: Remove unecessary sign-extension. +; 64-DAG: slt $[[R0:[0-9]+]], ${{[0-9]+}}, $4 +; 64-DAG: sll $[[R1:[0-9]+]], $[[R0]], 0 +; 64-DAG: ori $2, $[[R1]], 4 +define i32 @slti32_3(i32 signext %a) { +entry: + %cmp = icmp sgt i32 %a, -32770 + %conv = select i1 %cmp, i32 5, i32 4 + ret i32 %conv +} -; 64-CMP-DAG: daddiu $[[I5:[0-9]+]], $zero, 5 -; 64-CMP-DAG: daddiu $[[I4:2]], $zero, 4 -; 64-CMP-DAG: daddiu $[[R1:[0-9]+]], ${{[0-9]+}}, 32766 -; 64-CMP-DAG: slt $[[R0:[0-9]+]], $[[R1]], $4 -; FIXME: We can do better than this by using selccz to choose between -0 and -2 -; 64-CMP-DAG: selnez $[[T0:[0-9]+]], $[[I5]], $[[R0]] -; 64-CMP-DAG: seleqz $[[T1:[0-9]+]], $[[I4]], $[[R0]] -; 64-CMP-DAG: or $2, $[[T0]], $[[T1]] +; ALL-LABEL: slti64_3: +; 64-DAG: daddiu $[[R0:[0-9]+]], ${{[0-9]+}}, 32766 +; 64-DAG: slt $[[R1:[0-9]+]], $[[R0]], $4 +; 64-DAG: ori $2, $[[R1]], 4 define i64 @slti64_3(i64 %a) { entry: %cmp = icmp sgt i64 %a, -32770 Index: test/CodeGen/Mips/countleading.ll =================================================================== --- test/CodeGen/Mips/countleading.ll +++ test/CodeGen/Mips/countleading.ll @@ -4,7 +4,7 @@ ; RUN: llc -march=mips64el -mcpu=mips4 < %s | FileCheck -check-prefix=ALL -check-prefix=MIPS4 %s ; RUN: llc -march=mips64el -mcpu=mips64 < %s | FileCheck -check-prefix=ALL -check-prefix=MIPS64-GT-R1 %s ; RUN: llc -march=mips64el -mcpu=mips64r2 < %s | FileCheck -check-prefix=ALL -check-prefix=MIPS64-GT-R1 %s -; R!N: llc -march=mips64el -mcpu=mips64r6 < %s | FileCheck -check-prefix=ALL -check-prefix=MIPS64-GT-R1 %s +; RUN: llc -march=mips64el -mcpu=mips64r6 < %s | FileCheck -check-prefix=ALL -check-prefix=MIPS64-GT-R1 %s ; Prefixes: ; ALL - All Index: test/CodeGen/Mips/fcmp.ll =================================================================== --- test/CodeGen/Mips/fcmp.ll +++ test/CodeGen/Mips/fcmp.ll @@ -29,17 +29,21 @@ ; 32-C-DAG: c.eq.s $f12, $f14 ; 32-C: movf $2, $zero, $fcc0 -; 64-C-DAG: addiu $2, $zero, 1 +; FIXME: Remove redundant sign extension. +; 64-C-DAG: daddiu $[[T0:[0-9]+]], $zero, 1 ; 64-C-DAG: c.eq.s $f12, $f13 -; 64-C: movf $2, $zero, $fcc0 +; 64-C-DAG: movf $[[T0]], $zero, $fcc0 +; 64-C: sll $2, $[[T0]], 0 ; 32-CMP-DAG: cmp.eq.s $[[T0:f[0-9]+]], $f12, $f14 ; 32-CMP-DAG: mfc1 $[[T1:[0-9]+]], $[[T0]] ; 32-CMP-DAG: andi $2, $[[T1]], 1 +; FIXME: The sign extension below is redundant. ; 64-CMP-DAG: cmp.eq.s $[[T0:f[0-9]+]], $f12, $f13 -; 64-CMP-DAG: mfc1 $[[T1:[0-9]+]], $[[T0]] -; 64-CMP-DAG: andi $2, $[[T1]], 1 +; 64-CMP-DAG: dmfc1 $[[T1:[0-9]+]], $[[T0]] +; 64-CMP-DAG: sll $[[T2:[0-9]+]], $[[T1]], 0 +; 64-CMP-DAG: andi $2, $[[T2]], 1 %1 = fcmp oeq float %a, %b %2 = zext i1 %1 to i32 @@ -53,9 +57,11 @@ ; 32-C-DAG: c.ule.s $f12, $f14 ; 32-C: movt $2, $zero, $fcc0 -; 64-C-DAG: addiu $2, $zero, 1 +; FIXME: Remove redundant sign extension. +; 64-C-DAG: daddiu $[[T0:[0-9]+]], $zero, 1 ; 64-C-DAG: c.ule.s $f12, $f13 -; 64-C: movt $2, $zero, $fcc0 +; 64-C-DAG: movt $[[T0]], $zero, $fcc0 +; 64-C: sll $2, $[[T0]], 0 ; 32-CMP-DAG: cmp.lt.s $[[T0:f[0-9]+]], $f14, $f12 ; 32-CMP-DAG: mfc1 $[[T1:[0-9]+]], $[[T0]] @@ -77,9 +83,11 @@ ; 32-C-DAG: c.ult.s $f12, $f14 ; 32-C: movt $2, $zero, $fcc0 -; 64-C-DAG: addiu $2, $zero, 1 +; FIXME: Remove redundant sign extension. +; 64-C-DAG: daddiu $[[T0:[0-9]+]], $zero, 1 ; 64-C-DAG: c.ult.s $f12, $f13 -; 64-C: movt $2, $zero, $fcc0 +; 64-C-DAG: movt $[[T0]], $zero, $fcc0 +; 64-C: sll $2, $[[T0]], 0 ; 32-CMP-DAG: cmp.le.s $[[T0:f[0-9]+]], $f14, $f12 ; 32-CMP-DAG: mfc1 $[[T1:[0-9]+]], $[[T0]] @@ -101,9 +109,11 @@ ; 32-C-DAG: c.olt.s $f12, $f14 ; 32-C: movf $2, $zero, $fcc0 -; 64-C-DAG: addiu $2, $zero, 1 +; FIXME: Remove redundant sign extension. +; 64-C-DAG: daddiu $[[T0:[0-9]+]], $zero, 1 ; 64-C-DAG: c.olt.s $f12, $f13 -; 64-C: movf $2, $zero, $fcc0 +; 64-C-DAG: movf $[[T0]], $zero, $fcc0 +; 64-C: sll $2, $[[T0]], 0 ; 32-CMP-DAG: cmp.lt.s $[[T0:f[0-9]+]], $f12, $f14 ; 32-CMP-DAG: mfc1 $[[T1:[0-9]+]], $[[T0]] @@ -125,9 +135,11 @@ ; 32-C-DAG: c.ole.s $f12, $f14 ; 32-C: movf $2, $zero, $fcc0 -; 64-C-DAG: addiu $2, $zero, 1 +; FIXME: Remove redundant sign extension. +; 64-C-DAG: daddiu $[[T0:[0-9]+]], $zero, 1 ; 64-C-DAG: c.ole.s $f12, $f13 -; 64-C: movf $2, $zero, $fcc0 +; 64-C-DAG: movf $[[T0]], $zero, $fcc0 +; 64-C: sll $2, $[[T0]], 0 ; 32-CMP-DAG: cmp.le.s $[[T0:f[0-9]+]], $f12, $f14 ; 32-CMP-DAG: mfc1 $[[T1:[0-9]+]], $[[T0]] @@ -149,9 +161,11 @@ ; 32-C-DAG: c.ueq.s $f12, $f14 ; 32-C: movt $2, $zero, $fcc0 -; 64-C-DAG: addiu $2, $zero, 1 +; FIXME: Remove redundant sign extension. +; 64-C-DAG: daddiu $[[T0:[0-9]+]], $zero, 1 ; 64-C-DAG: c.ueq.s $f12, $f13 -; 64-C: movt $2, $zero, $fcc0 +; 64-C-DAG: movt $[[T0]], $zero, $fcc0 +; 64-C: sll $2, $[[T0]], 0 ; 32-CMP-DAG: cmp.ueq.s $[[T0:f[0-9]+]], $f12, $f14 ; 32-CMP-DAG: mfc1 $[[T1:[0-9]+]], $[[T0]] @@ -175,9 +189,11 @@ ; 32-C-DAG: c.un.s $f12, $f14 ; 32-C: movt $2, $zero, $fcc0 -; 64-C-DAG: addiu $2, $zero, 1 +; FIXME: Remove redundant sign extension. +; 64-C-DAG: daddiu $[[T0:[0-9]+]], $zero, 1 ; 64-C-DAG: c.un.s $f12, $f13 -; 64-C: movt $2, $zero, $fcc0 +; 64-C-DAG: movt $[[T0]], $zero, $fcc0 +; 64-C: sll $2, $[[T0]], 0 ; 32-CMP-DAG: cmp.un.s $[[T0:f[0-9]+]], $f12, $f14 ; 32-CMP-DAG: mfc1 $[[T1:[0-9]+]], $[[T0]] @@ -201,9 +217,11 @@ ; 32-C-DAG: c.ueq.s $f12, $f14 ; 32-C: movf $2, $zero, $fcc0 -; 64-C-DAG: addiu $2, $zero, 1 +; FIXME: Remove redundant sign extension. +; 64-C-DAG: daddiu $[[T0:[0-9]+]], $zero, 1 ; 64-C-DAG: c.ueq.s $f12, $f13 -; 64-C: movf $2, $zero, $fcc0 +; 64-C-DAG: movf $[[T0]], $zero, $fcc0 +; 64-C: sll $2, $[[T0]], 0 ; 32-CMP-DAG: cmp.ueq.s $[[T0:f[0-9]+]], $f12, $f14 ; 32-CMP-DAG: mfc1 $[[T1:[0-9]+]], $[[T0]] @@ -225,9 +243,11 @@ ; 32-C-DAG: c.ole.s $f12, $f14 ; 32-C: movt $2, $zero, $fcc0 -; 64-C-DAG: addiu $2, $zero, 1 +; FIXME: Remove redundant sign extension. +; 64-C-DAG: daddiu $[[T0:[0-9]+]], $zero, 1 ; 64-C-DAG: c.ole.s $f12, $f13 -; 64-C: movt $2, $zero, $fcc0 +; 64-C-DAG: movt $[[T0]], $zero, $fcc0 +; 64-C: sll $2, $[[T0]], 0 ; 32-CMP-DAG: cmp.ult.s $[[T0:f[0-9]+]], $f14, $f12 ; 32-CMP-DAG: mfc1 $[[T1:[0-9]+]], $[[T0]] @@ -249,9 +269,11 @@ ; 32-C-DAG: c.olt.s $f12, $f14 ; 32-C: movt $2, $zero, $fcc0 -; 64-C-DAG: addiu $2, $zero, 1 +; FIXME: Remove redundant sign extension. +; 64-C-DAG: daddiu $[[T0:[0-9]+]], $zero, 1 ; 64-C-DAG: c.olt.s $f12, $f13 -; 64-C: movt $2, $zero, $fcc0 +; 64-C-DAG: movt $[[T0]], $zero, $fcc0 +; 64-C: sll $2, $[[T0]], 0 ; 32-CMP-DAG: cmp.ule.s $[[T0:f[0-9]+]], $f14, $f12 ; 32-CMP-DAG: mfc1 $[[T1:[0-9]+]], $[[T0]] @@ -273,9 +295,11 @@ ; 32-C-DAG: c.ult.s $f12, $f14 ; 32-C: movf $2, $zero, $fcc0 -; 64-C-DAG: addiu $2, $zero, 1 +; FIXME: Remove redundant sign extension. +; 64-C-DAG: daddiu $[[T0:[0-9]+]], $zero, 1 ; 64-C-DAG: c.ult.s $f12, $f13 -; 64-C: movf $2, $zero, $fcc0 +; 64-C-DAG: movf $[[T0]], $zero, $fcc0 +; 64-C: sll $2, $[[T0]], 0 ; 32-CMP-DAG: cmp.ult.s $[[T0:f[0-9]+]], $f12, $f14 ; 32-CMP-DAG: mfc1 $[[T1:[0-9]+]], $[[T0]] @@ -298,9 +322,11 @@ ; 32-C-DAG: c.ule.s $f12, $f14 ; 32-C: movf $2, $zero, $fcc0 -; 64-C-DAG: addiu $2, $zero, 1 +; FIXME: Remove redundant sign extension. +; 64-C-DAG: daddiu $[[T0:[0-9]+]], $zero, 1 ; 64-C-DAG: c.ule.s $f12, $f13 -; 64-C: movf $2, $zero, $fcc0 +; 64-C-DAG: movf $[[T0]], $zero, $fcc0 +; 64-C: sll $2, $[[T0]], 0 ; 32-CMP-DAG: cmp.ule.s $[[T0:f[0-9]+]], $f12, $f14 ; 32-CMP-DAG: mfc1 $[[T1:[0-9]+]], $[[T0]] @@ -322,9 +348,11 @@ ; 32-C-DAG: c.eq.s $f12, $f14 ; 32-C: movt $2, $zero, $fcc0 -; 64-C-DAG: addiu $2, $zero, 1 +; FIXME: Remove redundant sign extension. +; 64-C-DAG: daddiu $[[T0:[0-9]+]], $zero, 1 ; 64-C-DAG: c.eq.s $f12, $f13 -; 64-C: movt $2, $zero, $fcc0 +; 64-C-DAG: movt $[[T0]], $zero, $fcc0 +; 64-C: sll $2, $[[T0]], 0 ; 32-CMP-DAG: cmp.eq.s $[[T0:f[0-9]+]], $f12, $f14 ; 32-CMP-DAG: mfc1 $[[T1:[0-9]+]], $[[T0]] @@ -348,9 +376,11 @@ ; 32-C-DAG: c.un.s $f12, $f14 ; 32-C: movf $2, $zero, $fcc0 -; 64-C-DAG: addiu $2, $zero, 1 +; FIXME: Remove redundant sign extension. +; 64-C-DAG: daddiu $[[T0:[0-9]+]], $zero, 1 ; 64-C-DAG: c.un.s $f12, $f13 -; 64-C: movf $2, $zero, $fcc0 +; 64-C-DAG: movf $[[T0]], $zero, $fcc0 +; 64-C: sll $2, $[[T0]], 0 ; 32-CMP-DAG: cmp.un.s $[[T0:f[0-9]+]], $f12, $f14 ; 32-CMP-DAG: mfc1 $[[T1:[0-9]+]], $[[T0]] @@ -390,9 +420,11 @@ ; 32-C-DAG: c.eq.d $f12, $f14 ; 32-C: movf $2, $zero, $fcc0 -; 64-C-DAG: addiu $2, $zero, 1 +; FIXME: Remove redundant sign extension. +; 64-C-DAG: daddiu $[[T0:[0-9]+]], $zero, 1 ; 64-C-DAG: c.eq.d $f12, $f13 -; 64-C: movf $2, $zero, $fcc0 +; 64-C-DAG: movf $[[T0]], $zero, $fcc0 +; 64-C: sll $2, $[[T0]], 0 ; 32-CMP-DAG: cmp.eq.d $[[T0:f[0-9]+]], $f12, $f14 ; 32-CMP-DAG: mfc1 $[[T1:[0-9]+]], $[[T0]] @@ -414,9 +446,11 @@ ; 32-C-DAG: c.ule.d $f12, $f14 ; 32-C: movt $2, $zero, $fcc0 -; 64-C-DAG: addiu $2, $zero, 1 +; FIXME: Remove redundant sign extension. +; 64-C-DAG: daddiu $[[T0:[0-9]+]], $zero, 1 ; 64-C-DAG: c.ule.d $f12, $f13 -; 64-C: movt $2, $zero, $fcc0 +; 64-C-DAG: movt $[[T0]], $zero, $fcc0 +; 64-C: sll $2, $[[T0]], 0 ; 32-CMP-DAG: cmp.lt.d $[[T0:f[0-9]+]], $f14, $f12 ; 32-CMP-DAG: mfc1 $[[T1:[0-9]+]], $[[T0]] @@ -438,9 +472,11 @@ ; 32-C-DAG: c.ult.d $f12, $f14 ; 32-C: movt $2, $zero, $fcc0 -; 64-C-DAG: addiu $2, $zero, 1 +; FIXME: Remove redundant sign extension. +; 64-C-DAG: daddiu $[[T0:[0-9]+]], $zero, 1 ; 64-C-DAG: c.ult.d $f12, $f13 -; 64-C: movt $2, $zero, $fcc0 +; 64-C-DAG: movt $[[T0]], $zero, $fcc0 +; 64-C: sll $2, $[[T0]], 0 ; 32-CMP-DAG: cmp.le.d $[[T0:f[0-9]+]], $f14, $f12 ; 32-CMP-DAG: mfc1 $[[T1:[0-9]+]], $[[T0]] @@ -462,9 +498,11 @@ ; 32-C-DAG: c.olt.d $f12, $f14 ; 32-C: movf $2, $zero, $fcc0 -; 64-C-DAG: addiu $2, $zero, 1 +; FIXME: Remove redundant sign extension. +; 64-C-DAG: daddiu $[[T0:[0-9]+]], $zero, 1 ; 64-C-DAG: c.olt.d $f12, $f13 -; 64-C: movf $2, $zero, $fcc0 +; 64-C-DAG: movf $[[T0]], $zero, $fcc0 +; 64-C: sll $2, $[[T0]], 0 ; 32-CMP-DAG: cmp.lt.d $[[T0:f[0-9]+]], $f12, $f14 ; 32-CMP-DAG: mfc1 $[[T1:[0-9]+]], $[[T0]] @@ -486,9 +524,11 @@ ; 32-C-DAG: c.ole.d $f12, $f14 ; 32-C: movf $2, $zero, $fcc0 -; 64-C-DAG: addiu $2, $zero, 1 +; FIXME: Remove redundant sign extension. +; 64-C-DAG: daddiu $[[T0:[0-9]+]], $zero, 1 ; 64-C-DAG: c.ole.d $f12, $f13 -; 64-C: movf $2, $zero, $fcc0 +; 64-C-DAG: movf $[[T0]], $zero, $fcc0 +; 64-C: sll $2, $[[T0]], 0 ; 32-CMP-DAG: cmp.le.d $[[T0:f[0-9]+]], $f12, $f14 ; 32-CMP-DAG: mfc1 $[[T1:[0-9]+]], $[[T0]] @@ -510,9 +550,11 @@ ; 32-C-DAG: c.ueq.d $f12, $f14 ; 32-C: movt $2, $zero, $fcc0 -; 64-C-DAG: addiu $2, $zero, 1 +; FIXME: Remove redundant sign extension. +; 64-C-DAG: daddiu $[[T0:[0-9]+]], $zero, 1 ; 64-C-DAG: c.ueq.d $f12, $f13 -; 64-C: movt $2, $zero, $fcc0 +; 64-C-DAG: movt $[[T0]], $zero, $fcc0 +; 64-C: sll $2, $[[T0]], 0 ; 32-CMP-DAG: cmp.ueq.d $[[T0:f[0-9]+]], $f12, $f14 ; 32-CMP-DAG: mfc1 $[[T1:[0-9]+]], $[[T0]] @@ -536,9 +578,11 @@ ; 32-C-DAG: c.un.d $f12, $f14 ; 32-C: movt $2, $zero, $fcc0 -; 64-C-DAG: addiu $2, $zero, 1 +; FIXME: Remove redundant sign extension. +; 64-C-DAG: daddiu $[[T0:[0-9]+]], $zero, 1 ; 64-C-DAG: c.un.d $f12, $f13 -; 64-C: movt $2, $zero, $fcc0 +; 64-C-DAG: movt $[[T0]], $zero, $fcc0 +; 64-C: sll $2, $[[T0]], 0 ; 32-CMP-DAG: cmp.un.d $[[T0:f[0-9]+]], $f12, $f14 ; 32-CMP-DAG: mfc1 $[[T1:[0-9]+]], $[[T0]] @@ -562,9 +606,11 @@ ; 32-C-DAG: c.ueq.d $f12, $f14 ; 32-C: movf $2, $zero, $fcc0 -; 64-C-DAG: addiu $2, $zero, 1 +; FIXME: Remove redundant sign extension. +; 64-C-DAG: daddiu $[[T0:[0-9]+]], $zero, 1 ; 64-C-DAG: c.ueq.d $f12, $f13 -; 64-C: movf $2, $zero, $fcc0 +; 64-C-DAG: movf $[[T0]], $zero, $fcc0 +; 64-C: sll $2, $[[T0]], 0 ; 32-CMP-DAG: cmp.ueq.d $[[T0:f[0-9]+]], $f12, $f14 ; 32-CMP-DAG: mfc1 $[[T1:[0-9]+]], $[[T0]] @@ -586,9 +632,11 @@ ; 32-C-DAG: c.ole.d $f12, $f14 ; 32-C: movt $2, $zero, $fcc0 -; 64-C-DAG: addiu $2, $zero, 1 +; FIXME: Remove redundant sign extension. +; 64-C-DAG: daddiu $[[T0:[0-9]+]], $zero, 1 ; 64-C-DAG: c.ole.d $f12, $f13 -; 64-C: movt $2, $zero, $fcc0 +; 64-C-DAG: movt $[[T0]], $zero, $fcc0 +; 64-C: sll $2, $[[T0]], 0 ; 32-CMP-DAG: cmp.ult.d $[[T0:f[0-9]+]], $f14, $f12 ; 32-CMP-DAG: mfc1 $[[T1:[0-9]+]], $[[T0]] @@ -610,9 +658,11 @@ ; 32-C-DAG: c.olt.d $f12, $f14 ; 32-C: movt $2, $zero, $fcc0 -; 64-C-DAG: addiu $2, $zero, 1 +; FIXME: Remove redundant sign extension. +; 64-C-DAG: daddiu $[[T0:[0-9]+]], $zero, 1 ; 64-C-DAG: c.olt.d $f12, $f13 -; 64-C: movt $2, $zero, $fcc0 +; 64-C-DAG: movt $[[T0]], $zero, $fcc0 +; 64-C: sll $2, $[[T0]], 0 ; 32-CMP-DAG: cmp.ule.d $[[T0:f[0-9]+]], $f14, $f12 ; 32-CMP-DAG: mfc1 $[[T1:[0-9]+]], $[[T0]] @@ -634,9 +684,11 @@ ; 32-C-DAG: c.ult.d $f12, $f14 ; 32-C: movf $2, $zero, $fcc0 -; 64-C-DAG: addiu $2, $zero, 1 +; FIXME: Remove redundant sign extension. +; 64-C-DAG: daddiu $[[T0:[0-9]+]], $zero, 1 ; 64-C-DAG: c.ult.d $f12, $f13 -; 64-C: movf $2, $zero, $fcc0 +; 64-C-DAG: movf $[[T0]], $zero, $fcc0 +; 64-C: sll $2, $[[T0]], 0 ; 32-CMP-DAG: cmp.ult.d $[[T0:f[0-9]+]], $f12, $f14 ; 32-CMP-DAG: mfc1 $[[T1:[0-9]+]], $[[T0]] @@ -658,9 +710,11 @@ ; 32-C-DAG: c.ule.d $f12, $f14 ; 32-C: movf $2, $zero, $fcc0 -; 64-C-DAG: addiu $2, $zero, 1 +; FIXME: Remove redundant sign extension. +; 64-C-DAG: daddiu $[[T0:[0-9]+]], $zero, 1 ; 64-C-DAG: c.ule.d $f12, $f13 -; 64-C: movf $2, $zero, $fcc0 +; 64-C-DAG: movf $[[T0]], $zero, $fcc0 +; 64-C: sll $2, $[[T0]], 0 ; 32-CMP-DAG: cmp.ule.d $[[T0:f[0-9]+]], $f12, $f14 ; 32-CMP-DAG: mfc1 $[[T1:[0-9]+]], $[[T0]] @@ -682,9 +736,11 @@ ; 32-C-DAG: c.eq.d $f12, $f14 ; 32-C: movt $2, $zero, $fcc0 -; 64-C-DAG: addiu $2, $zero, 1 +; FIXME: Remove redundant sign extension. +; 64-C-DAG: daddiu $[[T0:[0-9]+]], $zero, 1 ; 64-C-DAG: c.eq.d $f12, $f13 -; 64-C: movt $2, $zero, $fcc0 +; 64-C-DAG: movt $[[T0]], $zero, $fcc0 +; 64-C: sll $2, $[[T0]], 0 ; 32-CMP-DAG: cmp.eq.d $[[T0:f[0-9]+]], $f12, $f14 ; 32-CMP-DAG: mfc1 $[[T1:[0-9]+]], $[[T0]] @@ -708,9 +764,11 @@ ; 32-C-DAG: c.un.d $f12, $f14 ; 32-C: movf $2, $zero, $fcc0 -; 64-C-DAG: addiu $2, $zero, 1 +; FIXME: Remove redundant sign extension. +; 64-C-DAG: daddiu $[[T0:[0-9]+]], $zero, 1 ; 64-C-DAG: c.un.d $f12, $f13 -; 64-C: movf $2, $zero, $fcc0 +; 64-C-DAG: movf $[[T0]], $zero, $fcc0 +; 64-C: sll $2, $[[T0]], 0 ; 32-CMP-DAG: cmp.un.d $[[T0:f[0-9]+]], $f12, $f14 ; 32-CMP-DAG: mfc1 $[[T1:[0-9]+]], $[[T0]] Index: test/CodeGen/Mips/llvm-ir/select.ll =================================================================== --- test/CodeGen/Mips/llvm-ir/select.ll +++ test/CodeGen/Mips/llvm-ir/select.ll @@ -29,8 +29,7 @@ ; RUN: llc < %s -march=mips64 -mcpu=mips64r6 | FileCheck %s \ ; RUN: -check-prefix=ALL -check-prefix=SEL -check-prefix=SEL-64 -define signext i1 @tst_select_i1_i1(i1 signext %s, - i1 signext %x, i1 signext %y) { +define signext i1 @tst_select_i1_i1(i1 %s, i1 signext %x, i1 signext %y) { entry: ; ALL-LABEL: tst_select_i1_i1: @@ -54,8 +53,7 @@ ret i1 %r } -define signext i8 @tst_select_i1_i8(i1 signext %s, - i8 signext %x, i8 signext %y) { +define signext i8 @tst_select_i1_i8(i1 %s, i8 signext %x, i8 signext %y) { entry: ; ALL-LABEL: tst_select_i1_i8: @@ -79,8 +77,7 @@ ret i8 %r } -define signext i32 @tst_select_i1_i32(i1 signext %s, - i32 signext %x, i32 signext %y) { +define signext i32 @tst_select_i1_i32(i1 %s, i32 signext %x, i32 signext %y) { entry: ; ALL-LABEL: tst_select_i1_i32: @@ -104,8 +101,7 @@ ret i32 %r } -define signext i64 @tst_select_i1_i64(i1 signext %s, - i64 signext %x, i64 signext %y) { +define signext i64 @tst_select_i1_i64(i1 %s, i64 signext %x, i64 signext %y) { entry: ; ALL-LABEL: tst_select_i1_i64: @@ -152,8 +148,6 @@ ; CMOV-64: move $2, $6 ; SEL-64: andi $[[T0:[0-9]+]], $4, 1 - ; FIXME: This shift is redundant - ; SEL-64: sll $[[T0]], $[[T0]], 0 ; SEL-64: seleqz $[[T1:[0-9]+]], $6, $[[T0]] ; SEL-64: selnez $[[T0]], $5, $[[T0]] ; SEL-64: or $2, $[[T0]], $[[T1]] @@ -161,7 +155,7 @@ ret i64 %r } -define float @tst_select_i1_float(i1 signext %s, float %x, float %y) { +define float @tst_select_i1_float(i1 %s, float %x, float %y) { entry: ; ALL-LABEL: tst_select_i1_float: @@ -183,21 +177,24 @@ ; SEL-32: mtc1 $5, $[[F0:f[0-9]+]] ; SEL-32: mtc1 $6, $[[F1:f[0-9]+]] - ; SEL-32: mtc1 $4, $f0 + ; SEL-32: sll $[[T0:[0-9]+]], $4, 31 + ; SEL-32: sra $[[T1:[0-9]+]], $[[T0]], 31 + ; SEL-32: mtc1 $[[T1]], $f0 ; SEL-32: sel.s $f0, $[[F1]], $[[F0]] ; CMOV-64: andi $[[T0:[0-9]+]], $4, 1 ; CMOV-64: movn.s $f14, $f13, $[[T0]] ; CMOV-64: mov.s $f0, $f14 - ; SEL-64: mtc1 $4, $f0 + ; SEL-64: dsll $[[T0:[0-9]+]], $4, 63 + ; SEL-64: dsra $[[T1:[0-9]+]], $[[T0]], 63 + ; SEL-64: dmtc1 $[[T1]], $f0 ; SEL-64: sel.s $f0, $f14, $f13 %r = select i1 %s, float %x, float %y ret float %r } -define float @tst_select_i1_float_reordered(float %x, float %y, - i1 signext %s) { +define float @tst_select_i1_float_reordered(float %x, float %y, i1 %s) { entry: ; ALL-LABEL: tst_select_i1_float_reordered: @@ -214,20 +211,24 @@ ; CMOV-32: movn.s $f14, $f12, $[[T0]] ; CMOV-32: mov.s $f0, $f14 - ; SEL-32: mtc1 $6, $f0 + ; SEL-32: sll $[[T0:[0-9]+]], $6, 31 + ; SEL-32: sra $[[T1:[0-9]+]], $[[T0]], 31 + ; SEL-32: mtc1 $[[T1]], $f0 ; SEL-32: sel.s $f0, $f14, $f12 ; CMOV-64: andi $[[T0:[0-9]+]], $6, 1 ; CMOV-64: movn.s $f13, $f12, $[[T0]] ; CMOV-64: mov.s $f0, $f13 - ; SEL-64: mtc1 $6, $f0 + ; SEL-64: dsll $[[T0:[0-9]+]], $6, 63 + ; SEL-64: dsra $[[T1:[0-9]+]], $[[T0]], 63 + ; SEL-64: dmtc1 $[[T1]], $f0 ; SEL-64: sel.s $f0, $f13, $f12 %r = select i1 %s, float %x, float %y ret float %r } -define double @tst_select_i1_double(i1 signext %s, double %x, double %y) { +define double @tst_select_i1_double(i1 %s, double %x, double %y) { entry: ; ALL-LABEL: tst_select_i1_double: @@ -251,8 +252,10 @@ ; SEL-32: mtc1 $7, $[[F0:f[0-9]+]] ; SEL-32: mthc1 $6, $[[F0]] + ; SEL-32: sll $[[T0:[0-9]+]], $4, 31 + ; SEL-32: sra $[[T1:[0-9]+]], $[[T0]], 31 ; SEL-32: ldc1 $[[F1:f[0-9]+]], 16($sp) - ; SEL-32: mtc1 $4, $f0 + ; SEL-32: mtc1 $[[T1]], $f0 ; SEL-32: sel.d $f0, $[[F1]], $[[F0]] ; M3: andi $[[T0:[0-9]+]], $4, 1 @@ -267,14 +270,15 @@ ; CMOV-64: movn.d $f14, $f13, $[[T0]] ; CMOV-64: mov.d $f0, $f14 - ; SEL-64: mtc1 $4, $f0 + ; SEL-64: dsll $[[T0:[0-9]+]], $4, 63 + ; SEL-64: dsra $[[T1:[0-9]+]], $[[T0]], 63 + ; SEL-64: dmtc1 $[[T1]], $f0 ; SEL-64: sel.d $f0, $f14, $f13 %r = select i1 %s, double %x, double %y ret double %r } -define double @tst_select_i1_double_reordered(double %x, double %y, - i1 signext %s) { +define double @tst_select_i1_double_reordered(double %x, double %y, i1 %s) { entry: ; ALL-LABEL: tst_select_i1_double_reordered: @@ -308,7 +312,9 @@ ; CMOV-64: movn.d $f13, $f12, $[[T0]] ; CMOV-64: mov.d $f0, $f13 - ; SEL-64: mtc1 $6, $f0 + ; SEL-64: dsll $[[T0:[0-9]+]], $6, 63 + ; SEL-64: dsra $[[T1:[0-9]+]], $[[T0]], 63 + ; SEL-64: dmtc1 $[[T1]], $f0 ; SEL-64: sel.d $f0, $f13, $f12 %r = select i1 %s, double %x, double %y ret double %r Index: test/CodeGen/Mips/octeon.ll =================================================================== --- test/CodeGen/Mips/octeon.ll +++ test/CodeGen/Mips/octeon.ll @@ -32,10 +32,8 @@ ; OCTEON: jr $ra ; OCTEON: seq $2, $4, $5 ; MIPS64: xor $[[T0:[0-9]+]], $4, $5 -; MIPS64: sltiu $[[T1:[0-9]+]], $[[T0]], 1 -; MIPS64: dsll $[[T2:[0-9]+]], $[[T1]], 32 ; MIPS64: jr $ra -; MIPS64: dsrl $2, $[[T2]], 32 +; MIPS64: sltiu $2, $[[T0]], 1 %res = icmp eq i64 %a, %b %res2 = zext i1 %res to i64 ret i64 %res2 @@ -48,10 +46,8 @@ ; OCTEON: seqi $2, $4, 42 ; MIPS64: daddiu $[[T0:[0-9]+]], $zero, 42 ; MIPS64: xor $[[T1:[0-9]+]], $4, $[[T0]] -; MIPS64: sltiu $[[T2:[0-9]+]], $[[T1]], 1 -; MIPS64: dsll $[[T3:[0-9]+]], $[[T2]], 32 ; MIPS64: jr $ra -; MIPS64: dsrl $2, $[[T3]], 32 +; MIPS64: sltiu $2, $[[T1]], 1 %res = icmp eq i64 %a, 42 %res2 = zext i1 %res to i64 ret i64 %res2 @@ -63,10 +59,8 @@ ; OCTEON: jr $ra ; OCTEON: sne $2, $4, $5 ; MIPS64: xor $[[T0:[0-9]+]], $4, $5 -; MIPS64: sltu $[[T1:[0-9]+]], $zero, $[[T0]] -; MIPS64: dsll $[[T2:[0-9]+]], $[[T1]], 32 ; MIPS64: jr $ra -; MIPS64: dsrl $2, $[[T2]], 32 +; MIPS64: sltu $2, $zero, $[[T0]] %res = icmp ne i64 %a, %b %res2 = zext i1 %res to i64 ret i64 %res2 @@ -79,10 +73,8 @@ ; OCTEON: snei $2, $4, 42 ; MIPS64: daddiu $[[T0:[0-9]+]], $zero, 42 ; MIPS64: xor $[[T1:[0-9]+]], $4, $[[T0]] -; MIPS64: sltu $[[T2:[0-9]+]], $zero, $[[T1]] -; MIPS64: dsll $[[T3:[0-9]+]], $[[T2]], 32 ; MIPS64: jr $ra -; MIPS64: dsrl $2, $[[T3]], 32 +; MIPS64: sltu $2, $zero, $[[T1]] %res = icmp ne i64 %a, 42 %res2 = zext i1 %res to i64 ret i64 %res2