Index: lib/CodeGen/SelectionDAG/TargetLowering.cpp =================================================================== --- lib/CodeGen/SelectionDAG/TargetLowering.cpp +++ lib/CodeGen/SelectionDAG/TargetLowering.cpp @@ -1474,18 +1474,36 @@ case ISD::SETUGE: case ISD::SETULT: case ISD::SETULE: { - EVT newVT = N0.getOperand(0).getValueType(); + EVT NewVT = N0.getOperand(0).getValueType(); if (DCI.isBeforeLegalizeOps() || - (isOperationLegal(ISD::SETCC, newVT) && - getCondCodeAction(Cond, newVT.getSimpleVT()) == Legal)) { + (isOperationLegal(ISD::SETCC, NewVT) && + getCondCodeAction(Cond, NewVT.getSimpleVT()) == Legal)) { EVT NewSetCCVT = - getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), newVT); - SDValue NewConst = DAG.getConstant(C1.trunc(InSize), dl, newVT); + getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), NewVT); + SDValue NewConst = DAG.getConstant(C1.trunc(InSize), dl, NewVT); SDValue NewSetCC = DAG.getSetCC(dl, NewSetCCVT, N0.getOperand(0), NewConst, Cond); return DAG.getBoolExtOrTrunc(NewSetCC, dl, VT, N0.getValueType()); + } else { + SDValue N00 = N0.getOperand(0); + // We can avoid the truncation and the zero-extension, if we can + // sign-extend the low-part of the constant, so that its sign bits + // cover the sign-bits of the LHS. + if ((N00.getOpcode() == ISD::TRUNCATE) && + (N00.getOperand(0).getValueType() == VT)) { + unsigned CNSB = DAG.ComputeNumSignBits(N00.getOperand(0)); + unsigned VTBits = VT.getSizeInBits(); + unsigned NewVTBits = NewVT.getSizeInBits(); + + if (CNSB - (VTBits - NewVTBits) >= 1) { + SDValue NewConst = + DAG.getConstant(C1.trunc(NewVTBits).sext(VTBits), dl, VT); + return DAG.getSetCC(dl, VT, N00.getOperand(0), NewConst, Cond); + } + } } + break; } default: Index: lib/Target/Mips/Mips32r6InstrInfo.td =================================================================== --- lib/Target/Mips/Mips32r6InstrInfo.td +++ lib/Target/Mips/Mips32r6InstrInfo.td @@ -832,18 +832,13 @@ (SELNEZOp RC:$f, RC:$cond)>; def : MipsPat<(select (Opg (setne RC:$cond, immz)), immz, RC:$f), (SELEQZOp RC:$f, RC:$cond)>; + +def : MipsPat<(select RC:$cond, RC:$t, immz), (SELNEZOp RC:$t, RC:$cond)>; +def : MipsPat<(select RC:$cond, immz, RC:$f), (SELEQZOp RC:$f, RC:$cond)>; + +def : MipsPat<(select RC:$cond, RC:$t, RC:$f), + (OROp (SELNEZOp RC:$t, RC:$cond), (SELEQZOp RC:$f, RC:$cond))>; } defm : SelectInt_Pats, ISA_MIPS32R6; - -def : MipsPat<(select i32:$cond, i32:$t, i32:$f), - (OR (SELNEZ i32:$t, i32:$cond), - (SELEQZ i32:$f, i32:$cond))>, - ISA_MIPS32R6; -def : MipsPat<(select i32:$cond, i32:$t, immz), - (SELNEZ i32:$t, i32:$cond)>, - ISA_MIPS32R6; -def : MipsPat<(select i32:$cond, immz, i32:$f), - (SELEQZ i32:$f, i32:$cond)>, - ISA_MIPS32R6; Index: lib/Target/Mips/Mips64InstrInfo.td =================================================================== --- lib/Target/Mips/Mips64InstrInfo.td +++ lib/Target/Mips/Mips64InstrInfo.td @@ -107,10 +107,6 @@ 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>, @@ -133,8 +129,6 @@ let isCodeGenOnly = 1 in { 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>; @@ -507,12 +501,6 @@ defm : SetgePats; defm : SetgeImmPats; -defm : SeteqPats; -defm : SetlePats; -defm : SetgtPats; -defm : SetgePats; -defm : SetgeImmPats; - // truncate def : MipsPat<(trunc (assertsext GPR64:$src)), (EXTRACT_SUBREG GPR64:$src, sub_32)>; Index: lib/Target/Mips/Mips64r6InstrInfo.td =================================================================== --- lib/Target/Mips/Mips64r6InstrInfo.td +++ lib/Target/Mips/Mips64r6InstrInfo.td @@ -145,59 +145,61 @@ (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; +def : MipsPat<(select (i64 (seteq i64:$cond, immZExt16:$imm)), i32:$t, i32:$f), + (OR (SELEQZ i32:$t, + (EXTRACT_SUBREG (XORi64 i64:$cond, immZExt16:$imm), sub_32)), + (SELNEZ i32:$f, + (EXTRACT_SUBREG (XORi64 i64:$cond, immZExt16:$imm), sub_32)))>, + ISA_MIPS64R6; + +def : MipsPat<(select (i64 (setne i64:$cond, immZExt16:$imm)), i32:$t, i32:$f), + (OR (SELNEZ i32:$t, + (EXTRACT_SUBREG (XORi64 i64:$cond, immZExt16:$imm), sub_32)), + (SELEQZ i32:$f, + (EXTRACT_SUBREG (XORi64 i64:$cond, immZExt16:$imm), 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; - // i64 selects from an i32 comparison 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 (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))>, + +def : MipsPat<(select (i64 (setne i64:$cond, immz)), immz, i32:$f), + (EXTRACT_SUBREG (SELEQZ64 (SLL64_32 i32:$f), i64:$cond), sub_32)>, ISA_MIPS64R6; -def : MipsPat<(select (i64 (setne i32:$cond, immz)), i64:$t, immz), - (SELNEZ64 i64:$t, (SLL64_32 i32:$cond))>, + +def : MipsPat<(select (i64 (setne i64:$cond, immz)), i32:$t, immz), + (EXTRACT_SUBREG (SELNEZ64 (SLL64_32 i32:$t), i64:$cond), sub_32)>, ISA_MIPS64R6; -def : MipsPat<(select (i64 (seteq i32:$cond, immz)), i64:$t, immz), - (SELEQZ64 i64:$t, (SLL64_32 i32:$cond))>, + +def : MipsPat<(select (i64 (setne i64:$cond, immz)), i32:$t, i32:$f), + (EXTRACT_SUBREG (OR64 (SELNEZ64 (SLL64_32 i32:$t), i64:$cond), + (SELEQZ64 (SLL64_32 i32:$f), i64:$cond)), sub_32)>, ISA_MIPS64R6; -def : MipsPat<(select i32:$cond, immz, i64:$f), - (SELEQZ64 i64:$f, (SLL64_32 i32:$cond))>, + +def : MipsPat<(select (i64 (seteq i64:$cond, immz)), i32:$t, immz), + (EXTRACT_SUBREG (SELEQZ64 (SLL64_32 i32:$t), i64:$cond), sub_32)>, ISA_MIPS64R6; -def : MipsPat<(select (i64 (setne i32:$cond, immz)), immz, i64:$f), - (SELEQZ64 i64:$f, (SLL64_32 i32:$cond))>, +def : MipsPat<(select (i64 (seteq i64:$cond, immz)), immz, i32:$f), + (EXTRACT_SUBREG (SELNEZ64 (SLL64_32 i32:$f), i64:$cond), sub_32)>, ISA_MIPS64R6; -def : MipsPat<(select (i64 (seteq i32:$cond, immz)), immz, i64:$f), - (SELNEZ64 i64:$f, (SLL64_32 i32:$cond))>, + +def : MipsPat<(select (i64 (seteq i64:$cond, immz)), i32:$t, i32:$f), + (EXTRACT_SUBREG (OR64 (SELEQZ64 (SLL64_32 i32:$t), i64:$cond), + (SELNEZ64 (SLL64_32 i32:$f), i64:$cond)), sub_32)>, ISA_MIPS64R6; Index: lib/Target/Mips/MipsCondMov.td =================================================================== --- lib/Target/Mips/MipsCondMov.td +++ lib/Target/Mips/MipsCondMov.td @@ -191,15 +191,6 @@ 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 : MovzPats0, Index: lib/Target/Mips/MipsSEISelLowering.cpp =================================================================== --- lib/Target/Mips/MipsSEISelLowering.cpp +++ lib/Target/Mips/MipsSEISelLowering.cpp @@ -122,6 +122,8 @@ setOperationAction(ISD::MUL, MVT::i64, Custom); if (Subtarget.isGP64bit()) { + setOperationAction(ISD::SETCC, MVT::i32, Promote); + setOperationAction(ISD::SETCC, MVT::i64, Legal); setOperationAction(ISD::SMUL_LOHI, MVT::i64, Custom); setOperationAction(ISD::UMUL_LOHI, MVT::i64, Custom); setOperationAction(ISD::MULHS, MVT::i64, Custom); @@ -219,6 +221,7 @@ // MIPS64r6 replaces conditional moves with an equivalent that removes the // need for three GPR read ports. + setOperationAction(ISD::SETCC, MVT::i32, Promote); setOperationAction(ISD::SETCC, MVT::i64, Legal); setOperationAction(ISD::SELECT, MVT::i64, Legal); setOperationAction(ISD::SELECT_CC, MVT::i64, Expand); Index: test/CodeGen/Mips/atomic.ll =================================================================== --- test/CodeGen/Mips/atomic.ll +++ test/CodeGen/Mips/atomic.ll @@ -343,12 +343,18 @@ ; HAS-SEB-SEH: seb $[[R19:[0-9]+]], $[[R17]] -; ALL: xor $[[R20:[0-9]+]], $[[R19]], $5 - +; MIPS32-ANY: xor $[[R20:[0-9]+]], $[[R19]], $5 ; MIPS32-ANY: sltiu $2, $[[R20]], 1 -; MIPS64-ANY: sltiu $[[R21:[0-9]+]], $[[R20]], 1 -; MIPS64-ANY: sll $2, $[[R21]], 0 +; FIXME: avoid redundant sign/zero-extensions. +; MIPS64-ANY: dsll $[[R20:[0-9]+]], $[[R19]], 32 +; MIPS64-ANY: dsrl $[[R21:[0-9]+]], $[[R20]], 32 +; MIPS64-ANY: daddiu $[[R22:[0-9]+]], $zero, 1 +; MIPS64-ANY: dsll $[[R23:[0-9]+]], $[[R22]], 32 +; MIPS64-ANY: daddiu $[[R24:[0-9]+]], $[[R23]], -1 +; MIPS64-ANY: and $[[R25:[0-9]+]], $5, $[[R24]] +; MIPS64-ANY: xor $[[R26:[0-9]+]], $[[R21]], $[[R25]] +; MIPS64-ANY: sltiu $2, $[[R26]], 1 } ; Check one i16 so that we cover the seh sign extend Index: test/CodeGen/Mips/cmov.ll =================================================================== --- test/CodeGen/Mips/cmov.ll +++ test/CodeGen/Mips/cmov.ll @@ -36,12 +36,8 @@ ; 64-CMP-DAG: ld $[[R0:[0-9]+]], %got_disp(i3)( ; 64-CMP-DAG: daddiu $[[R1:[0-9]+]], ${{[0-9]+}}, %got_disp(i1) -; FIXME: This sll works around an implementation detail in the code generator -; (setcc's result is i32 so bits 32-63 are undefined). It's not really -; needed. -; 64-CMP-DAG: sll $[[CC:[0-9]+]], $4, 0 -; 64-CMP-DAG: selnez $[[T0:[0-9]+]], $[[R1]], $[[CC]] -; 64-CMP-DAG: seleqz $[[T1:[0-9]+]], $[[R0]], $[[CC]] +; 64-CMP-DAG: selnez $[[T0:[0-9]+]], $[[R1]], $4 +; 64-CMP-DAG: seleqz $[[T1:[0-9]+]], $[[R0]], $4 ; 64-CMP-DAG: or $[[T2:[0-9]+]], $[[T0]], $[[T1]] ; 64-CMP-DAG: ld $2, 0($[[T2]]) @@ -76,12 +72,8 @@ ; 64-CMP-DAG: daddiu $[[R1:[0-9]+]], ${{[0-9]+}}, %got_disp(d) ; 64-CMP-DAG: daddiu $[[R0:[0-9]+]], ${{[0-9]+}}, %got_disp(c) -; FIXME: This sll works around an implementation detail in the code generator -; (setcc's result is i32 so bits 32-63 are undefined). It's not really -; needed. -; 64-CMP-DAG: sll $[[CC:[0-9]+]], $4, 0 -; 64-CMP-DAG: selnez $[[T0:[0-9]+]], $[[R0]], $[[CC]] -; 64-CMP-DAG: seleqz $[[T1:[0-9]+]], $[[R1]], $[[CC]] +; 64-CMP-DAG: selnez $[[T0:[0-9]+]], $[[R0]], $4 +; 64-CMP-DAG: seleqz $[[T1:[0-9]+]], $[[R1]], $4 ; 64-CMP-DAG: or $[[T2:[0-9]+]], $[[T0]], $[[T1]] ; 64-CMP-DAG: lw $2, 0($[[T2]]) @@ -262,13 +254,14 @@ ; 64-CMOV-DAG: slti $[[R0:[0-9]+]], $4, 32767 ; 64-CMOV-DAG: movz $[[I5]], $[[I3]], $[[R0]] -; 64-CMP-DAG: addiu $[[I3:[0-9]+]], $zero, 3 +; 64-CMP-DAG: addiu $[[I3:[0-9]+]], $zero, 3{{$}} ; 64-CMP-DAG: addiu $[[I5:[0-9]+]], $zero, 5 -; 64-CMP-DAG: slti $[[R0:[0-9]+]], $4, 32767 +; 64-CMP-DAG: daddiu $[[R0:[0-9]+]], $zero, 32766 +; 64-CMP-DAG: slt $[[R1:[0-9]+]], $[[R0]], $4 ; FIXME: We can do better than this by using selccz to choose between +0 and +2 -; 64-CMP-DAG: seleqz $[[T0:[0-9]+]], $[[I3]], $[[R0]] -; 64-CMP-DAG: selnez $[[T1:[0-9]+]], $[[I5]], $[[R0]] -; 64-CMP-DAG: or $2, $[[T0]], $[[T1]] +; 64-CMP-DAG: seleqz $[[T0:[0-9]+]], $[[I5]], $[[R1]] +; 64-CMP-DAG: selnez $[[T1:[0-9]+]], $[[I3]], $[[R1]] +; 64-CMP-DAG: or $2, $[[T1]], $[[T0]] define i32 @slti0(i32 signext %a) { entry: @@ -336,13 +329,19 @@ ; 64-CMOV-DAG: slti $[[R0:[0-9]+]], $4, -32768 ; 64-CMOV-DAG: movz $[[I5]], $[[I3]], $[[R0]] -; 64-CMP-DAG: addiu $[[I3:[0-9]+]], $zero, 3 +; FIXME: Fix constant materialization for i64 imms. +; 64-CMP-DAG: daddiu $[[R0:[0-9]+]], $zero, 1 +; 64-CMP-DAG: dsll $[[R1:[0-9]+]], $[[R0]], 48 +; 64-CMP-DAG: daddiu $[[R2:[0-9]+]], $[[R1]], -1 +; 64-CMP-DAG: dsll $[[R3:[0-9]+]], $[[R2]], 16 +; 64-CMP-DAG: daddiu $[[R4:[0-9]+]], $[[R3]], 32767 +; 64-CMP-DAG: addiu $[[I3:[0-9]+]], $zero, 3{{$}} ; 64-CMP-DAG: addiu $[[I5:[0-9]+]], $zero, 5 -; 64-CMP-DAG: slti $[[R0:[0-9]+]], $4, -32768 +; 64-CMP-DAG: slt $[[R5:[0-9]+]], $[[R4]], $4 ; FIXME: We can do better than this by using selccz to choose between +0 and +2 -; 64-CMP-DAG: seleqz $[[T0:[0-9]+]], $[[I3]], $[[R0]] -; 64-CMP-DAG: selnez $[[T1:[0-9]+]], $[[I5]], $[[R0]] -; 64-CMP-DAG: or $2, $[[T0]], $[[T1]] +; 64-CMP-DAG: seleqz $[[T0:[0-9]+]], $[[I5]], $[[R5]] +; 64-CMP-DAG: selnez $[[T1:[0-9]+]], $[[I3]], $[[R5]] +; 64-CMP-DAG: or $2, $[[T1]], $[[T0]] define i32 @slti2(i32 signext %a) { entry: @@ -372,20 +371,22 @@ ; 64-CMOV-DAG: addiu $[[I3:[0-9]+]], $zero, 3 ; 64-CMOV-DAG: addiu $[[I5:2]], $zero, 5 -; 64-CMOV-DAG: lui $[[R1:[0-9]+]], 65535 -; 64-CMOV-DAG: ori $[[R1]], $[[R1]], 32766 -; 64-CMOV-DAG: slt $[[R0:[0-9]+]], $[[R1]], $4 +; 64-CMOV-DAG: slt $[[R0:[0-9]+]], ${{[0-9]+}}, $4 ; 64-CMOV-DAG: movn $[[I5]], $[[I3]], $[[R0]] -; 64-CMP-DAG: addiu $[[I3:[0-9]+]], $zero, 3 -; 64-CMP-DAG: addiu $[[I5:2]], $zero, 5 -; 64-CMP-DAG: lui $[[IMM:[0-9]+]], 65535 -; 64-CMP-DAG: ori $[[IMM]], $[[IMM]], 32766 -; 64-CMP-DAG: slt $[[R0:[0-9]+]], $[[IMM]], $4 -; FIXME: We can do better than this by using selccz to choose between -0 and -2 -; 64-CMP-DAG: selnez $[[T0:[0-9]+]], $[[I3]], $[[R0]] -; 64-CMP-DAG: seleqz $[[T1:[0-9]+]], $[[I5]], $[[R0]] -; 64-CMP-DAG: or $2, $[[T0]], $[[T1]] +; FIXME: Fix constant materialization for i64 imms. +; 64-CMP-DAG: daddiu $[[R0:[0-9]+]], $zero, 1 +; 64-CMP-DAG: dsll $[[R1:[0-9]+]], $[[R0]], 48 +; 64-CMP-DAG: daddiu $[[R2:[0-9]+]], $[[R1]], -1 +; 64-CMP-DAG: dsll $[[R3:[0-9]+]], $[[R2]], 16 +; 64-CMP-DAG: daddiu $[[R4:[0-9]+]], $[[R3]], 32766 +; 64-CMP-DAG: addiu $[[I3:[0-9]+]], $zero, 3{{$}} +; 64-CMP-DAG: addiu $[[I5:[0-9]+]], $zero, 5 +; 64-CMP-DAG: slt $[[R5:[0-9]+]], $[[R4]], $4 +; FIXME: We can do better than this by using selccz to choose between +0 and +2 +; 64-CMP-DAG: seleqz $[[T0:[0-9]+]], $[[I5]], $[[R5]] +; 64-CMP-DAG: selnez $[[T1:[0-9]+]], $[[I3]], $[[R5]] +; 64-CMP-DAG: or $2, $[[T1]], $[[T0]] define i32 @slti3(i32 signext %a) { entry: @@ -535,13 +536,14 @@ ; 64-CMOV-DAG: sltiu $[[R0:[0-9]+]], $4, 32767 ; 64-CMOV-DAG: movz $[[I5]], $[[I3]], $[[R0]] -; 64-CMP-DAG: addiu $[[I3:[0-9]+]], $zero, 3 +; 64-CMP-DAG: addiu $[[I3:[0-9]+]], $zero, 3{{$}} ; 64-CMP-DAG: addiu $[[I5:[0-9]+]], $zero, 5 -; 64-CMP-DAG: sltiu $[[R0:[0-9]+]], $4, 32767 +; 64-CMP-DAG: daddiu $[[R0:[0-9]+]], $zero, 32766 +; 64-CMP-DAG: sltu $[[R1:[0-9]+]], $[[R0]], $4 ; FIXME: We can do better than this by using selccz to choose between +0 and +2 -; 64-CMP-DAG: seleqz $[[T0:[0-9]+]], $[[I3]], $[[R0]] -; 64-CMP-DAG: selnez $[[T1:[0-9]+]], $[[I5]], $[[R0]] -; 64-CMP-DAG: or $2, $[[T0]], $[[T1]] +; 64-CMP-DAG: seleqz $[[T0:[0-9]+]], $[[I5]], $[[R1]] +; 64-CMP-DAG: selnez $[[T1:[0-9]+]], $[[I3]], $[[R1]] +; 64-CMP-DAG: or $2, $[[T1]], $[[T0]] define i32 @sltiu0(i32 signext %a) { entry: @@ -609,13 +611,19 @@ ; 64-CMOV-DAG: sltiu $[[R0:[0-9]+]], $4, -32768 ; 64-CMOV-DAG: movz $[[I5]], $[[I3]], $[[R0]] +; FIXME: Fix constant materialization for i64 imms. ; 64-CMP-DAG: addiu $[[I3:[0-9]+]], $zero, 3 ; 64-CMP-DAG: addiu $[[I5:[0-9]+]], $zero, 5 -; 64-CMP-DAG: sltiu $[[R0:[0-9]+]], $4, -32768 +; 64-CMP-DAG: daddiu $[[R0:[0-9]+]], $zero, 1 +; 64-CMP-DAG: dsll $[[R1:[0-9]+]], $[[R0]], 48 +; 64-CMP-DAG: daddiu $[[R2:[0-9]+]], $[[R1]], -1 +; 64-CMP-DAG: dsll $[[R3:[0-9]+]], $[[R2]], 16 +; 64-CMP-DAG: daddiu $[[R4:[0-9]+]], $[[R3]], 32767 +; 64-CMP-DAG: sltu $[[R5:[0-9]+]], $[[R4]], $4 ; FIXME: We can do better than this by using selccz to choose between +0 and +2 -; 64-CMP-DAG: seleqz $[[T0:[0-9]+]], $[[I3]], $[[R0]] -; 64-CMP-DAG: selnez $[[T1:[0-9]+]], $[[I5]], $[[R0]] -; 64-CMP-DAG: or $2, $[[T0]], $[[T1]] +; 64-CMP-DAG: seleqz $[[T0:[0-9]+]], $[[I5]], $[[R5]] +; 64-CMP-DAG: selnez $[[T1:[0-9]+]], $[[I3]], $[[R5]] +; 64-CMP-DAG: or $2, $[[T1]], $[[T0]] define i32 @sltiu2(i32 signext %a) { entry: @@ -645,19 +653,21 @@ ; 64-CMOV-DAG: addiu $[[I3:[0-9]+]], $zero, 3 ; 64-CMOV-DAG: addiu $[[I5:2]], $zero, 5 -; 64-CMOV-DAG: lui $[[R1:[0-9]+]], 65535 -; 64-CMOV-DAG: ori $[[R1]], $[[R1]], 32766 -; 64-CMOV-DAG: sltu $[[R0:[0-9]+]], $[[R1]], $4 +; 64-CMOV-DAG: sltu $[[R0:[0-9]+]], ${{[0-9]+}}, $4 ; 64-CMOV-DAG: movn $[[I5]], $[[I3]], $[[R0]] +; FIXME: Fix constant materialization for i64 imms. ; 64-CMP-DAG: addiu $[[I3:[0-9]+]], $zero, 3 ; 64-CMP-DAG: addiu $[[I5:2]], $zero, 5 -; 64-CMP-DAG: lui $[[IMM:[0-9]+]], 65535 -; 64-CMP-DAG: ori $[[IMM]], $[[IMM]], 32766 -; 64-CMP-DAG: sltu $[[R0:[0-9]+]], $[[IMM]], $4 +; 64-CMP-DAG: daddiu $[[R0:[0-9]+]], $zero, 1 +; 64-CMP-DAG: dsll $[[R1:[0-9]+]], $[[R0]], 48 +; 64-CMP-DAG: daddiu $[[R2:[0-9]+]], $[[R1]], -1 +; 64-CMP-DAG: dsll $[[R3:[0-9]+]], $[[R2]], 16 +; 64-CMP-DAG: daddiu $[[R4:[0-9]+]], $[[R3]], 32766 +; 64-CMP-DAG: sltu $[[R5:[0-9]+]], $[[R4]], $4 ; FIXME: We can do better than this by using selccz to choose between -0 and -2 -; 64-CMP-DAG: selnez $[[T0:[0-9]+]], $[[I3]], $[[R0]] -; 64-CMP-DAG: seleqz $[[T1:[0-9]+]], $[[I5]], $[[R0]] +; 64-CMP-DAG: selnez $[[T0:[0-9]+]], $[[I3]], $[[R5]] +; 64-CMP-DAG: seleqz $[[T1:[0-9]+]], $[[I5]], $[[R5]] ; 64-CMP-DAG: or $2, $[[T0]], $[[T1]] define i32 @sltiu3(i32 signext %a) { Index: test/CodeGen/Mips/llvm-ir/lshr.ll =================================================================== --- test/CodeGen/Mips/llvm-ir/lshr.ll +++ test/CodeGen/Mips/llvm-ir/lshr.ll @@ -170,20 +170,22 @@ ; GP64-NOT-R6: jr $ra ; GP64-NOT-R6: movn $2, $zero, $1 - ; 64R6: dsrlv $[[T0:[0-9]+]], $5, $7 - ; 64R6: dsll $[[T1:[0-9]+]], $4, 1 - ; 64R6: sll $[[T2:[0-9]+]], $7, 0 - ; 64R6: not $[[T3:[0-9]+]], $[[T2]] - ; 64R6: dsllv $[[T4:[0-9]+]], $[[T1]], $[[T3]] - ; 64R6: or $[[T5:[0-9]+]], $[[T4]], $[[T0]] - ; 64R6: andi $[[T6:[0-9]+]], $[[T2]], 64 - ; 64R6: sll $[[T7:[0-9]+]], $[[T6]], 0 - ; 64R6: seleqz $[[T8:[0-9]+]], $[[T5]], $[[T7]] - ; 64R6: dsrlv $[[T9:[0-9]+]], $4, $7 - ; 64R6: selnez $[[T10:[0-9]+]], $[[T9]], $[[T7]] - ; 64R6: or $3, $[[T10]], $[[T8]] - ; 64R6: jr $ra - ; 64R6: seleqz $2, $[[T9]], $[[T7]] + ; 64R6: dsrlv $[[R0:[0-9]+]], $4, $7 + ; 64R6: sll $[[R1:[0-9]+]], $7, 0 + ; 64R6: andi $[[R2:[0-9]+]], $[[R1]], 64 + ; 64R6: sll $[[R3:[0-9]+]], $[[R2]], 0 + ; 64R6: seleqz $[[R4:[0-9]+]], $1, $[[R3]] + ; 64R6: selnez $[[R5:[0-9]+]], $zero, $[[R3]] + ; 64R6: or $2, $[[R5]], $[[R4]] + ; 64R6: dsrlv $[[R6:[0-9]+]], $5, $7 + ; 64R6: dsll $[[R7:[0-9]+]], $4, 1 + ; 64R6: not $[[R8:[0-9]+]], $[[R1]] + ; 64R6: dsllv $[[R9:[0-9]+]], $[[R7]], $[[R8]] + ; 64R6: or $[[R10:[0-9]+]], $[[R9]], $[[R6]] + ; 64R6: seleqz $[[R11:[0-9]+]], $[[R10]], $[[R3]] + ; 64R6: selnez $[[R12:[0-9]+]], $[[R0]], $[[R3]] + ; 64R6: jr $ra + ; 64R6: or $3, $[[R12]], $[[R11]] %r = lshr i128 %a, %b ret i128 %r Index: test/CodeGen/Mips/mips64-f128.ll =================================================================== --- test/CodeGen/Mips/mips64-f128.ll +++ test/CodeGen/Mips/mips64-f128.ll @@ -624,15 +624,11 @@ ; C_CC_FMT: move $2, $8 ; C_CC_FMT: move $4, $9 -; FIXME: This sll works around an implementation detail in the code generator -; (setcc's result is i32 so bits 32-63 are undefined). It's not really -; needed. -; CMP_CC_FMT-DAG: sll $[[CC:[0-9]+]], $4, 0 -; CMP_CC_FMT-DAG: seleqz $[[EQ1:[0-9]+]], $8, $[[CC]] -; CMP_CC_FMT-DAG: selnez $[[NE1:[0-9]+]], $6, $[[CC]] +; CMP_CC_FMT-DAG: seleqz $[[EQ1:[0-9]+]], $8, $4 +; CMP_CC_FMT-DAG: selnez $[[NE1:[0-9]+]], $6, $4 ; CMP_CC_FMT-DAG: or $2, $[[NE1]], $[[EQ1]] -; CMP_CC_FMT-DAG: seleqz $[[EQ2:[0-9]+]], $9, $[[CC]] -; CMP_CC_FMT-DAG: selnez $[[NE2:[0-9]+]], $7, $[[CC]] +; CMP_CC_FMT-DAG: seleqz $[[EQ2:[0-9]+]], $9, $4 +; CMP_CC_FMT-DAG: selnez $[[NE2:[0-9]+]], $7, $4 ; CMP_CC_FMT-DAG: or $4, $[[NE2]], $[[EQ2]] define fp128 @select_LD(i32 signext %a, i64, fp128 %b, fp128 %c) { @@ -656,13 +652,13 @@ ; C_CC_FMT: move $2, $[[R1]] ; C_CC_FMT: move $4, $[[R0]] -; CMP_CC_FMT: slt $[[CC:[0-9]+]], $zero, $2 -; CMP_CC_FMT: seleqz $[[EQ1:[0-9]+]], $[[R1]], $[[CC]] -; CMP_CC_FMT: selnez $[[NE1:[0-9]+]], $[[R3]], $[[CC]] -; CMP_CC_FMT: or $2, $[[NE1]], $[[EQ1]] -; CMP_CC_FMT: seleqz $[[EQ2:[0-9]+]], $[[R0]], $[[CC]] -; CMP_CC_FMT: selnez $[[NE2:[0-9]+]], $[[R2]], $[[CC]] -; CMP_CC_FMT: or $4, $[[NE2]], $[[EQ2]] +; CMP_CC_FMT: slti $[[CC:[0-9]+]], $2, 1 +; CMP_CC_FMT: selnez $[[NE1:[0-9]+]], $[[R1]], $[[CC]] +; CMP_CC_FMT: seleqz $[[EQ1:[0-9]+]], $[[R3]], $[[CC]] +; CMP_CC_FMT: or $2, $[[EQ1]], $[[NE1]] +; CMP_CC_FMT: selnez $[[NE2:[0-9]+]], $[[R0]], $[[CC]] +; CMP_CC_FMT: seleqz $[[EQ2:[0-9]+]], $[[R2]], $[[CC]] +; CMP_CC_FMT: or $4, $[[EQ2]], $[[NE2]] define fp128 @selectCC_LD(fp128 %a, fp128 %b, fp128 %c, fp128 %d) { entry: Index: test/CodeGen/Mips/select.ll =================================================================== --- test/CodeGen/Mips/select.ll +++ test/CodeGen/Mips/select.ll @@ -28,9 +28,12 @@ ; 64R2: movn $5, $6, $4 ; 64R2: move $2, $5 -; 64R6-DAG: seleqz $[[T0:[0-9]+]], $5, $4 -; 64R6-DAG: selnez $[[T1:[0-9]+]], $6, $4 -; 64R6: or $2, $[[T1]], $[[T0]] +; FIXME: remove redundant sign-extensions. +; 64R6-DAG: sll $[[R0:[0-9]+]], $5, 0 +; 64R6-DAG: seleqz $[[R1:[0-9]+]], $[[R0]], $4 +; 64R6-DAG: sll $[[R2:[0-9]+]], $6, 0 +; 64R6-DAG: selnez $[[R3:[0-9]+]], $[[R2]], $4 +; 64R6: or $2, $[[R3]], $[[R1]] %tobool = icmp ne i32 %s, 0 %cond = select i1 %tobool, i32 %f1, i32 %f0 @@ -70,12 +73,8 @@ ; 64R2: movn $5, $6, $4 ; 64R2: move $2, $5 -; FIXME: This sll works around an implementation detail in the code generator -; (setcc's result is i32 so bits 32-63 are undefined). It's not really -; needed. -; 64R6-DAG: sll $[[CC:[0-9]+]], $4, 0 -; 64R6-DAG: seleqz $[[T0:[0-9]+]], $5, $[[CC]] -; 64R6-DAG: selnez $[[T1:[0-9]+]], $6, $[[CC]] +; 64R6-DAG: seleqz $[[T0:[0-9]+]], $5, $4 +; 64R6-DAG: selnez $[[T1:[0-9]+]], $6, $4 ; 64R6: or $2, $[[T1]], $[[T0]] %tobool = icmp ne i32 %s, 0 Index: test/CodeGen/Mips/zeroreg.ll =================================================================== --- test/CodeGen/Mips/zeroreg.ll +++ test/CodeGen/Mips/zeroreg.ll @@ -21,8 +21,10 @@ ; 64-CMOV: lw $2, 0(${{[0-9]+}}) ; 64-CMOV: movn $2, $zero, $4 +; FIXME: remove redundant sign-extension. ; 64R6: lw $[[R0:[0-9]+]], 0(${{[0-9]+}}) -; 64R6: seleqz $2, $[[R0]], $4 +; 64R6: sll $[[R1:[0-9]+]], $[[R0]], 0 +; 64R6: seleqz $2, $[[R1]], $4 %tobool = icmp ne i32 %s, 0 %0 = load i32, i32* @g1, align 4 @@ -43,8 +45,10 @@ ; 64-CMOV: lw $2, 0(${{[0-9]+}}) ; 64-CMOV: movz $2, $zero, $4 +; FIXME: remove redundant sign-extension. ; 64R6: lw $[[R0:[0-9]+]], 0(${{[0-9]+}}) -; 64R6: selnez $2, $[[R0]], $4 +; 64R6: sll $[[R1:[0-9]+]], $[[R0]], 0 +; 64R6: selnez $2, $[[R1]], $4 %tobool = icmp ne i32 %s, 0 %0 = load i32, i32* @g1, align 4