]> granicus.if.org Git - llvm/commitdiff
[mips] Sign extend i32 return values on MIPS64
authorStefan Maksimovic <stefan.maksimovic@mips.com>
Thu, 26 Jul 2018 10:59:35 +0000 (10:59 +0000)
committerStefan Maksimovic <stefan.maksimovic@mips.com>
Thu, 26 Jul 2018 10:59:35 +0000 (10:59 +0000)
Override getTypeForExtReturn so that functions returning
an i32 typed value have it sign extended on MIPS64.

Also provide patterns to get rid of unneeded sign extensions
for arithmetic instructions which implicitly sign extend
their results.

Differential Revision: https://reviews.llvm.org/D48374

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@338019 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/Mips/Mips64InstrInfo.td
lib/Target/Mips/Mips64r6InstrInfo.td
lib/Target/Mips/MipsISelLowering.cpp
lib/Target/Mips/MipsISelLowering.h
test/CodeGen/Mips/delay-slot-kill.ll
test/CodeGen/Mips/llvm-ir/and.ll
test/CodeGen/Mips/llvm-ir/not.ll
test/CodeGen/Mips/llvm-ir/or.ll
test/CodeGen/Mips/llvm-ir/select-int.ll
test/CodeGen/Mips/llvm-ir/xor.ll
test/CodeGen/Mips/shrink-wrapping.ll

index bc80098ade8019c88697de188b9194f32405f9b9..878ec29b188d6e46145ea0310cc9c5357427b899 100644 (file)
@@ -825,6 +825,45 @@ def : MipsPat<(atomic_store_32 addr:$a, GPR64:$v), (SW64 GPR64:$v, addr:$a)>,
 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
 //===----------------------------------------------------------------------===//
index 853702c30ddffea5dcba6fae7d58a81375497070..9df802cc30b93743d75504f2599d3cd673ebf362 100644 (file)
@@ -299,6 +299,21 @@ def : MipsPat<(select (i32 (seteq i32:$cond, immz)), immz, i64:$f),
               (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,
index ba4dbefa21a2bc9a39c32cbc757212edd6b932d9..9ffc38356b76437e39a0488f55b3d58a97db7694 100644 (file)
@@ -3714,6 +3714,13 @@ static std::pair<bool, bool> parsePhysicalReg(StringRef C, StringRef &Prefix,
                         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 =
index 7e5d6a2a017f37af6d67f37b04c0205456c5aca1..b58d92c370d8b8525286c29e6d025aed3276e7e3 100644 (file)
@@ -280,6 +280,9 @@ class TargetRegisterClass;
       return MVT::i32;
     }
 
+    EVT getTypeForExtReturn(LLVMContext &Context, EVT VT,
+                            ISD::NodeType) const override;
+
     bool isCheapToSpeculateCttz() const override;
     bool isCheapToSpeculateCtlz() const override;
 
index 5e301441fd2603ec6c61e4b6a60ca62a266eff76..57b630303c264f4472579d3f20ea0cef74877b9d 100644 (file)
@@ -1,6 +1,4 @@
 ; 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
index cc3613670016d1821d18214991de33f36ef88577..87f7edb2b7132344e6d7bdd15c7f3bccffcdba63 100644 (file)
@@ -195,21 +195,18 @@ define signext i32 @and_i32(i32 signext %a, i32 signext %b) {
 ;
 ; 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
index 6a27612c0e2b6f1e2922d26d30d4c6f2fe41f383..03ba8e562ef052636404b91734ec351dc3f15952 100644 (file)
@@ -75,7 +75,8 @@ entry:
 
   ; GP32:         not     $2, $4
 
-  ; GP64:         not     $2, $4
+  ; GP64:         not     $1, $4
+  ; GP64:         sll     $2, $1, 0
 
   ; MM:           not16   $2, $4
 
@@ -169,7 +170,8 @@ entry:
 
   ; 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
 
index ce22f08385b0eab9f1772c44a77ef85ce8cd5ee5..c595ff42086b2516f696441cc82da5ec00000f75 100644 (file)
@@ -106,9 +106,8 @@ define signext i32 @or_i32(i32 signext %a, i32 signext %b) {
 ;
 ; 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
@@ -284,8 +283,9 @@ define signext i32 @or_i32_4(i32 signext %b) {
 ;
 ; 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
@@ -450,8 +450,9 @@ define signext i32 @or_i32_31(i32 signext %b) {
 ;
 ; 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
@@ -616,8 +617,9 @@ define signext i32 @or_i32_255(i32 signext %b) {
 ;
 ; 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
@@ -786,8 +788,9 @@ define signext i32 @or_i32_32768(i32 signext %b) {
 ;
 ; 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
@@ -952,8 +955,9 @@ define signext i32 @or_i32_65(i32 signext %b) {
 ;
 ; 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
@@ -1118,8 +1122,9 @@ define signext i32 @or_i32_256(i32 signext %b) {
 ;
 ; 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
index 5d20a3cb9b7da17e5817787321683166ecdba9d1..d07051f05e1f587343dc93b0fd2b059867123d4b 100644 (file)
@@ -113,16 +113,17 @@ 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
index 54bb179b1177bf22820925054d7ae8ce47e1800c..972e3b6685a6587fb9d7f11bae8ed84d28b88f06 100644 (file)
@@ -193,21 +193,18 @@ define signext i32 @xor_i32(i32 signext %a, i32 signext %b) {
 ;
 ; 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
@@ -511,18 +508,21 @@ define signext i32 @xor_i32_4(i32 signext %b) {
 ;
 ; 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
index 76bd3834d2053eae27eed75fb0d5d6313488f799..54ae8699d1c19c32084c958718772b816da17b47 100644 (file)
@@ -118,9 +118,8 @@ define i32 @foo(i32 signext %a) {
 ; 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
@@ -136,9 +135,8 @@ define i32 @foo(i32 signext %a) {
 ; 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
@@ -158,10 +156,9 @@ define i32 @foo(i32 signext %a) {
 ; 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
@@ -182,10 +179,9 @@ define i32 @foo(i32 signext %a) {
 ; 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