Index: lib/Target/Mips/Mips64InstrInfo.td =================================================================== --- lib/Target/Mips/Mips64InstrInfo.td +++ lib/Target/Mips/Mips64InstrInfo.td @@ -442,6 +442,9 @@ // Arbitrary patterns that map to one or more instructions //===----------------------------------------------------------------------===// +// Materialize i64 constants. +defm : MaterializeImms; + // extended loads def : MipsPat<(i64 (extloadi1 addr:$src)), (LB64 addr:$src)>; def : MipsPat<(i64 (extloadi8 addr:$src)), (LB64 addr:$src)>; Index: lib/Target/Mips/MipsInstrInfo.td =================================================================== --- lib/Target/Mips/MipsInstrInfo.td +++ lib/Target/Mips/MipsInstrInfo.td @@ -2041,19 +2041,22 @@ class StoreRegImmPat : MipsPat<(store ValTy:$v, addrRegImm:$a), (StoreInst ValTy:$v, addrRegImm:$a)>; +// Materialize constants. +multiclass MaterializeImms { // Small immediates let AdditionalPredicates = [NotInMicroMips] in { -def : MipsPat<(i32 immSExt16:$in), - (ADDiu ZERO, imm:$in)>; -def : MipsPat<(i32 immZExt16:$in), - (ORi ZERO, imm:$in)>; +def : MipsPat<(VT immSExt16:$imm), (ADDiuOp ZEROReg, imm:$imm)>; +def : MipsPat<(VT immZExt16:$imm), (ORiOp ZEROReg, imm:$imm)>; } -def : MipsPat<(i32 immLow16Zero:$in), - (LUi (HI16 imm:$in))>; +def : MipsPat<(VT immLow16Zero:$imm), (LUiOp (HI16 imm:$imm))>; // Arbitrary immediates -def : MipsPat<(i32 imm:$imm), - (ORi (LUi (HI16 imm:$imm)), (LO16 imm:$imm))>; +def : MipsPat<(VT imm:$imm), (ORiOp (LUiOp (HI16 imm:$imm)), (LO16 imm:$imm))>; +} + +defm : MaterializeImms; // Carry MipsPatterns def : MipsPat<(subc GPR32:$lhs, GPR32:$rhs), Index: lib/Target/Mips/MipsSEISelDAGToDAG.cpp =================================================================== --- lib/Target/Mips/MipsSEISelDAGToDAG.cpp +++ lib/Target/Mips/MipsSEISelDAGToDAG.cpp @@ -743,13 +743,13 @@ case ISD::Constant: { const ConstantSDNode *CN = dyn_cast(Node); + int64_t Imm = CN->getSExtValue(); unsigned Size = CN->getValueSizeInBits(0); - if (Size == 32) + if (isInt<32>(Imm) || isUInt<32>(Imm)) break; MipsAnalyzeImmediate AnalyzeImm; - int64_t Imm = CN->getSExtValue(); const MipsAnalyzeImmediate::InstSeq &Seq = AnalyzeImm.Analyze(Imm, Size, false); Index: test/CodeGen/Mips/atomic.ll =================================================================== --- test/CodeGen/Mips/atomic.ll +++ test/CodeGen/Mips/atomic.ll @@ -349,10 +349,9 @@ ; 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: lui $[[R22:[0-9]+]], 65535 +; MIPS64-ANY: ori $[[R23:[0-9]+]], $[[R22]], 65535 +; MIPS64-ANY: and $[[R25:[0-9]+]], $5, $[[R22]] ; MIPS64-ANY: xor $[[R26:[0-9]+]], $[[R21]], $[[R25]] ; MIPS64-ANY: sltiu $2, $[[R26]], 1 } Index: test/CodeGen/Mips/cmov.ll =================================================================== --- test/CodeGen/Mips/cmov.ll +++ test/CodeGen/Mips/cmov.ll @@ -329,18 +329,14 @@ ; 64-CMOV-DAG: slti $[[R0:[0-9]+]], $4, -32768 ; 64-CMOV-DAG: movz $[[I5]], $[[I3]], $[[R0]] -; 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: lui $[[R0:[0-9]+]], 65535 +; 64-CMP-DAG: ori $[[R1:[0-9]+]], $[[R0]], 32767 ; 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 +; 64-CMP-DAG: slt $[[R2:[0-9]+]], $[[R1]], $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: seleqz $[[T0:[0-9]+]], $[[I5]], $[[R2]] +; 64-CMP-DAG: selnez $[[T1:[0-9]+]], $[[I3]], $[[R2]] ; 64-CMP-DAG: or $2, $[[T1]], $[[T0]] define i32 @slti2(i32 signext %a) { @@ -374,18 +370,14 @@ ; 64-CMOV-DAG: slt $[[R0:[0-9]+]], ${{[0-9]+}}, $4 ; 64-CMOV-DAG: movn $[[I5]], $[[I3]], $[[R0]] -; 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: lui $[[R0:[0-9]+]], 65535 +; 64-CMP-DAG: ori $[[R1:[0-9]+]], $[[R0]], 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 +; 64-CMP-DAG: slt $[[R2:[0-9]+]], $[[R1]], $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: seleqz $[[T0:[0-9]+]], $[[I5]], $[[R2]] +; 64-CMP-DAG: selnez $[[T1:[0-9]+]], $[[I3]], $[[R2]] ; 64-CMP-DAG: or $2, $[[T1]], $[[T0]] define i32 @slti3(i32 signext %a) { @@ -504,9 +496,10 @@ ; 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 +; 64-DAG: lui $[[R0:[0-9]+]], 65535 +; 64-DAG: ori $[[R1:[0-9]+]], $[[R0]], 32766 +; 64-DAG: slt $[[R2:[0-9]+]], $[[R1]], $4 +; 64-DAG: ori $2, $[[R2]], 4 define i64 @slti64_3(i64 %a) { entry: %cmp = icmp sgt i64 %a, -32770 @@ -611,18 +604,14 @@ ; 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: 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 +; 64-CMP-DAG: lui $[[R0:[0-9]+]], 65535 +; 64-CMP-DAG: ori $[[R1:[0-9]+]], $[[R0]], 32767 +; 64-CMP-DAG: sltu $[[R2:[0-9]+]], $[[R1]], $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: seleqz $[[T0:[0-9]+]], $[[I5]], $[[R1]] +; 64-CMP-DAG: selnez $[[T1:[0-9]+]], $[[I3]], $[[R1]] ; 64-CMP-DAG: or $2, $[[T1]], $[[T0]] define i32 @sltiu2(i32 signext %a) { @@ -656,18 +645,14 @@ ; 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: 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 +; 64-CMP-DAG: lui $[[R0:[0-9]+]], 65535 +; 64-CMP-DAG: ori $[[R1:[0-9]+]], $[[R0]], 32766 +; 64-CMP-DAG: sltu $[[R2:[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]+]], $[[I3]], $[[R5]] -; 64-CMP-DAG: seleqz $[[T1:[0-9]+]], $[[I5]], $[[R5]] +; 64-CMP-DAG: selnez $[[T0:[0-9]+]], $[[I3]], $[[R2]] +; 64-CMP-DAG: seleqz $[[T1:[0-9]+]], $[[I5]], $[[R2]] ; 64-CMP-DAG: or $2, $[[T0]], $[[T1]] define i32 @sltiu3(i32 signext %a) { Index: test/CodeGen/Mips/llvm-ir/ret.ll =================================================================== --- test/CodeGen/Mips/llvm-ir/ret.ll +++ test/CodeGen/Mips/llvm-ir/ret.ll @@ -133,7 +133,7 @@ ; GPR32-DAG: ori $3, $[[T0]], 1 ; GPR32-DAG: addiu $2, $zero, 0 -; GPR64-DAG: daddiu $2, $[[T0]], 1 +; GPR64-DAG: ori $2, $[[T0]], 1 ; NOT-R6-DAG: jr $ra #