def : MipsPat<(atomic_store_64 addr:$a, GPR64:$v), (SD GPR64:$v, addr:$a)>,
ISA_MIPS3, GPR_64;
+// Patterns used for matching away redundant sign extensions.
+// MIPS32 arithmetic instructions sign extend their result implicitly.
+def : MipsPat<(i64 (sext (i32 (add GPR32:$src, immSExt16:$imm16)))),
+ (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
+ (ADDiu GPR32:$src, immSExt16:$imm16), sub_32)>;
+def : MipsPat<(i64 (sext (i32 (add GPR32:$src, GPR32:$src2)))),
+ (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
+ (ADDu GPR32:$src, GPR32:$src2), sub_32)>;
+def : MipsPat<(i64 (sext (i32 (sub GPR32:$src, GPR32:$src2)))),
+ (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
+ (SUBu GPR32:$src, GPR32:$src2), sub_32)>;
+def : MipsPat<(i64 (sext (i32 (mul GPR32:$src, GPR32:$src2)))),
+ (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
+ (MUL GPR32:$src, GPR32:$src2), sub_32)>;
+def : MipsPat<(i64 (sext (i32 (MipsMFHI ACC64:$src)))),
+ (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
+ (PseudoMFHI ACC64:$src), sub_32)>;
+def : MipsPat<(i64 (sext (i32 (MipsMFLO ACC64:$src)))),
+ (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
+ (PseudoMFLO ACC64:$src), sub_32)>;
+def : MipsPat<(i64 (sext (i32 (shl GPR32:$src, immZExt5:$imm5)))),
+ (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
+ (SLL GPR32:$src, immZExt5:$imm5), sub_32)>;
+def : MipsPat<(i64 (sext (i32 (shl GPR32:$src, GPR32:$src2)))),
+ (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
+ (SLLV GPR32:$src, GPR32:$src2), sub_32)>;
+def : MipsPat<(i64 (sext (i32 (srl GPR32:$src, immZExt5:$imm5)))),
+ (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
+ (SRL GPR32:$src, immZExt5:$imm5), sub_32)>;
+def : MipsPat<(i64 (sext (i32 (srl GPR32:$src, GPR32:$src2)))),
+ (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
+ (SRLV GPR32:$src, GPR32:$src2), sub_32)>;
+def : MipsPat<(i64 (sext (i32 (sra GPR32:$src, immZExt5:$imm5)))),
+ (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
+ (SRA GPR32:$src, immZExt5:$imm5), sub_32)>;
+def : MipsPat<(i64 (sext (i32 (sra GPR32:$src, GPR32:$src2)))),
+ (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
+ (SRAV GPR32:$src, GPR32:$src2), sub_32)>;
+
//===----------------------------------------------------------------------===//
// Instruction aliases
//===----------------------------------------------------------------------===//
(SELNEZ64 i64:$f, (SLL64_32 i32:$cond))>,
ISA_MIPS64R6;
+// Patterns used for matching away redundant sign extensions.
+// MIPS32 arithmetic instructions sign extend their result implicitly.
+def : MipsPat<(i64 (sext (i32 (sdiv GPR32:$src, GPR32:$src2)))),
+ (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
+ (DIV GPR32:$src, GPR32:$src2), sub_32)>, ISA_MIPS64R6;
+def : MipsPat<(i64 (sext (i32 (udiv GPR32:$src, GPR32:$src2)))),
+ (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
+ (DIVU GPR32:$src, GPR32:$src2), sub_32)>, ISA_MIPS64R6;
+def : MipsPat<(i64 (sext (i32 (srem GPR32:$src, GPR32:$src2)))),
+ (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
+ (MOD GPR32:$src, GPR32:$src2), sub_32)>, ISA_MIPS64R6;
+def : MipsPat<(i64 (sext (i32 (urem GPR32:$src, GPR32:$src2)))),
+ (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
+ (MODU GPR32:$src, GPR32:$src2), sub_32)>, ISA_MIPS64R6;
+
// Pseudo instructions
let AdditionalPredicates = [NotInMips16Mode, NotInMicroMips,
true);
}
+EVT MipsTargetLowering::getTypeForExtReturn(LLVMContext &Context, EVT VT,
+ ISD::NodeType) const {
+ bool Cond = !Subtarget.isABI_O32() && VT.getSizeInBits() == 32;
+ EVT MinVT = getRegisterType(Context, Cond ? MVT::i64 : MVT::i32);
+ return VT.bitsLT(MinVT) ? MinVT : VT;
+}
+
std::pair<unsigned, const TargetRegisterClass *> MipsTargetLowering::
parseRegForInlineAsmConstraint(StringRef C, MVT VT) const {
const TargetRegisterInfo *TRI =
return MVT::i32;
}
+ EVT getTypeForExtReturn(LLVMContext &Context, EVT VT,
+ ISD::NodeType) const override;
+
bool isCheapToSpeculateCttz() const override;
bool isCheapToSpeculateCtlz() const override;
; RUN: llc < %s -march=mips64 -mcpu=mips3 | FileCheck %s
-; We have to XFAIL this temporarily because of the reversion of r229675.
-; XFAIL: *
; Currently, the following IR assembly generates a KILL instruction between
; the bitwise-and instruction and the return instruction. We verify that the
;
; MIPS64-LABEL: and_i32:
; MIPS64: # %bb.0: # %entry
-; MIPS64-NEXT: and $1, $4, $5
; MIPS64-NEXT: jr $ra
-; MIPS64-NEXT: sll $2, $1, 0
+; MIPS64-NEXT: and $2, $4, $5
;
; MIPS64R2-LABEL: and_i32:
; MIPS64R2: # %bb.0: # %entry
-; MIPS64R2-NEXT: and $1, $4, $5
; MIPS64R2-NEXT: jr $ra
-; MIPS64R2-NEXT: sll $2, $1, 0
+; MIPS64R2-NEXT: and $2, $4, $5
;
; MIPS64R6-LABEL: and_i32:
; MIPS64R6: # %bb.0: # %entry
-; MIPS64R6-NEXT: and $1, $4, $5
; MIPS64R6-NEXT: jr $ra
-; MIPS64R6-NEXT: sll $2, $1, 0
+; MIPS64R6-NEXT: and $2, $4, $5
;
; MM32R3-LABEL: and_i32:
; MM32R3: # %bb.0: # %entry
; GP32: not $2, $4
- ; GP64: not $2, $4
+ ; GP64: not $1, $4
+ ; GP64: sll $2, $1, 0
; MM: not16 $2, $4
; GP64: or $[[T0:[0-9]+]], $5, $4
; GP64: sll $[[T1:[0-9]+]], $[[T0]], 0
- ; GP64: not $2, $[[T1]]
+ ; GP64: not $[[T2:[0-9]+]], $[[T1]]
+ ; GP64: sll $2, $[[T2]], 0
; MM32: nor $2, $5, $4
;
; GP64-LABEL: or_i32:
; GP64: # %bb.0: # %entry
-; GP64-NEXT: or $1, $4, $5
; GP64-NEXT: jr $ra
-; GP64-NEXT: sll $2, $1, 0
+; GP64-NEXT: or $2, $4, $5
;
; MM32-LABEL: or_i32:
; MM32: # %bb.0: # %entry
;
; GP64-LABEL: or_i32_4:
; GP64: # %bb.0: # %entry
+; GP64-NEXT: ori $1, $4, 4
; GP64-NEXT: jr $ra
-; GP64-NEXT: ori $2, $4, 4
+; GP64-NEXT: sll $2, $1, 0
;
; MM32-LABEL: or_i32_4:
; MM32: # %bb.0: # %entry
;
; GP64-LABEL: or_i32_31:
; GP64: # %bb.0: # %entry
+; GP64-NEXT: ori $1, $4, 31
; GP64-NEXT: jr $ra
-; GP64-NEXT: ori $2, $4, 31
+; GP64-NEXT: sll $2, $1, 0
;
; MM32-LABEL: or_i32_31:
; MM32: # %bb.0: # %entry
;
; GP64-LABEL: or_i32_255:
; GP64: # %bb.0: # %entry
+; GP64-NEXT: ori $1, $4, 255
; GP64-NEXT: jr $ra
-; GP64-NEXT: ori $2, $4, 255
+; GP64-NEXT: sll $2, $1, 0
;
; MM32-LABEL: or_i32_255:
; MM32: # %bb.0: # %entry
;
; GP64-LABEL: or_i32_32768:
; GP64: # %bb.0: # %entry
+; GP64-NEXT: ori $1, $4, 32768
; GP64-NEXT: jr $ra
-; GP64-NEXT: ori $2, $4, 32768
+; GP64-NEXT: sll $2, $1, 0
;
; MM32-LABEL: or_i32_32768:
; MM32: # %bb.0: # %entry
;
; GP64-LABEL: or_i32_65:
; GP64: # %bb.0: # %entry
+; GP64-NEXT: ori $1, $4, 65
; GP64-NEXT: jr $ra
-; GP64-NEXT: ori $2, $4, 65
+; GP64-NEXT: sll $2, $1, 0
;
; MM32-LABEL: or_i32_65:
; MM32: # %bb.0: # %entry
;
; GP64-LABEL: or_i32_256:
; GP64: # %bb.0: # %entry
+; GP64-NEXT: ori $1, $4, 256
; GP64-NEXT: jr $ra
-; GP64-NEXT: ori $2, $4, 256
+; GP64-NEXT: sll $2, $1, 0
;
; MM32-LABEL: or_i32_256:
; MM32: # %bb.0: # %entry
; M2-M3: move $5, $6
; M2-M3: [[BB0]]:
; M2-M3: jr $ra
- ; M2-M3: move $2, $5
+ ; M3: sll $2, $5, 0
; CMOV: andi $[[T0:[0-9]+]], $4, 1
; CMOV: movn $6, $5, $[[T0]]
- ; CMOV: move $2, $6
+ ; CMOV-64:sll $2, $6, 0
; SEL: andi $[[T0:[0-9]+]], $4, 1
; SEL: seleqz $[[T1:[0-9]+]], $6, $[[T0]]
; SEL: selnez $[[T2:[0-9]+]], $5, $[[T0]]
- ; SEL: or $2, $[[T2]], $[[T1]]
+ ; SEL: or $[[T3:[0-9]+]], $[[T2]], $[[T1]]
+ ; SEL-64: sll $2, $[[T3]], 0
; MM32R3: andi16 $[[T0:[0-9]+]], $4, 1
; MM32R3: movn $[[T1:[0-9]+]], $5, $[[T0]] # <MCInst #{{[0-9]+}} MOVN_I_MM
;
; MIPS64-LABEL: xor_i32:
; MIPS64: # %bb.0: # %entry
-; MIPS64-NEXT: xor $1, $4, $5
; MIPS64-NEXT: jr $ra
-; MIPS64-NEXT: sll $2, $1, 0
+; MIPS64-NEXT: xor $2, $4, $5
;
; MIPS64R2-LABEL: xor_i32:
; MIPS64R2: # %bb.0: # %entry
-; MIPS64R2-NEXT: xor $1, $4, $5
; MIPS64R2-NEXT: jr $ra
-; MIPS64R2-NEXT: sll $2, $1, 0
+; MIPS64R2-NEXT: xor $2, $4, $5
;
; MIPS64R6-LABEL: xor_i32:
; MIPS64R6: # %bb.0: # %entry
-; MIPS64R6-NEXT: xor $1, $4, $5
; MIPS64R6-NEXT: jr $ra
-; MIPS64R6-NEXT: sll $2, $1, 0
+; MIPS64R6-NEXT: xor $2, $4, $5
;
; MM32R3-LABEL: xor_i32:
; MM32R3: # %bb.0: # %entry
;
; MIPS64-LABEL: xor_i32_4:
; MIPS64: # %bb.0: # %entry
+; MIPS64-NEXT: xori $1, $4, 4
; MIPS64-NEXT: jr $ra
-; MIPS64-NEXT: xori $2, $4, 4
+; MIPS64-NEXT: sll $2, $1, 0
;
; MIPS64R2-LABEL: xor_i32_4:
; MIPS64R2: # %bb.0: # %entry
+; MIPS64R2-NEXT: xori $1, $4, 4
; MIPS64R2-NEXT: jr $ra
-; MIPS64R2-NEXT: xori $2, $4, 4
+; MIPS64R2-NEXT: sll $2, $1, 0
;
; MIPS64R6-LABEL: xor_i32_4:
; MIPS64R6: # %bb.0: # %entry
+; MIPS64R6-NEXT: xori $1, $4, 4
; MIPS64R6-NEXT: jr $ra
-; MIPS64R6-NEXT: xori $2, $4, 4
+; MIPS64R6-NEXT: sll $2, $1, 0
;
; MM32R3-LABEL: xor_i32_4:
; MM32R3: # %bb.0: # %entry
; SHRINK-WRAP-64-STATIC-NEXT: .cfi_def_cfa_offset 16
; SHRINK-WRAP-64-STATIC-NEXT: sd $ra, 8($sp) # 8-byte Folded Spill
; SHRINK-WRAP-64-STATIC-NEXT: .cfi_offset 31, -8
-; SHRINK-WRAP-64-STATIC-NEXT: addiu $1, $4, 1
; SHRINK-WRAP-64-STATIC-NEXT: jal f
-; SHRINK-WRAP-64-STATIC-NEXT: sll $4, $1, 0
+; SHRINK-WRAP-64-STATIC-NEXT: addiu $4, $4, 1
; SHRINK-WRAP-64-STATIC-NEXT: ld $ra, 8($sp) # 8-byte Folded Reload
; SHRINK-WRAP-64-STATIC-NEXT: daddiu $sp, $sp, 16
; SHRINK-WRAP-64-STATIC-NEXT: .LBB0_2: # %return
; NO-SHRINK-WRAP-64-STATIC-NEXT: beqz $4, .LBB0_2
; NO-SHRINK-WRAP-64-STATIC-NEXT: nop
; NO-SHRINK-WRAP-64-STATIC-NEXT: # %bb.1: # %if.end
-; NO-SHRINK-WRAP-64-STATIC-NEXT: addiu $1, $4, 1
; NO-SHRINK-WRAP-64-STATIC-NEXT: jal f
-; NO-SHRINK-WRAP-64-STATIC-NEXT: sll $4, $1, 0
+; NO-SHRINK-WRAP-64-STATIC-NEXT: addiu $4, $4, 1
; NO-SHRINK-WRAP-64-STATIC-NEXT: .LBB0_2: # %return
; NO-SHRINK-WRAP-64-STATIC-NEXT: addiu $2, $zero, 0
; NO-SHRINK-WRAP-64-STATIC-NEXT: ld $ra, 8($sp) # 8-byte Folded Reload
; SHRINK-WRAP-64-PIC-NEXT: .cfi_offset 31, -8
; SHRINK-WRAP-64-PIC-NEXT: .cfi_offset 28, -16
; SHRINK-WRAP-64-PIC-NEXT: daddiu $gp, $2, %lo(%neg(%gp_rel(foo)))
-; SHRINK-WRAP-64-PIC-NEXT: addiu $1, $4, 1
; SHRINK-WRAP-64-PIC-NEXT: ld $25, %call16(f)($gp)
; SHRINK-WRAP-64-PIC-NEXT: jalr $25
-; SHRINK-WRAP-64-PIC-NEXT: sll $4, $1, 0
+; SHRINK-WRAP-64-PIC-NEXT: addiu $4, $4, 1
; SHRINK-WRAP-64-PIC-NEXT: ld $gp, 0($sp) # 8-byte Folded Reload
; SHRINK-WRAP-64-PIC-NEXT: ld $ra, 8($sp) # 8-byte Folded Reload
; SHRINK-WRAP-64-PIC-NEXT: daddiu $sp, $sp, 16
; NO-SHRINK-WRAP-64-PIC-NEXT: daddu $2, $1, $25
; NO-SHRINK-WRAP-64-PIC-NEXT: # %bb.1: # %if.end
; NO-SHRINK-WRAP-64-PIC-NEXT: daddiu $gp, $2, %lo(%neg(%gp_rel(foo)))
-; NO-SHRINK-WRAP-64-PIC-NEXT: addiu $1, $4, 1
; NO-SHRINK-WRAP-64-PIC-NEXT: ld $25, %call16(f)($gp)
; NO-SHRINK-WRAP-64-PIC-NEXT: jalr $25
-; NO-SHRINK-WRAP-64-PIC-NEXT: sll $4, $1, 0
+; NO-SHRINK-WRAP-64-PIC-NEXT: addiu $4, $4, 1
; NO-SHRINK-WRAP-64-PIC-NEXT: .LBB0_2: # %return
; NO-SHRINK-WRAP-64-PIC-NEXT: addiu $2, $zero, 0
; NO-SHRINK-WRAP-64-PIC-NEXT: ld $gp, 0($sp) # 8-byte Folded Reload