[llvm] r303537 - [MIPS] Add support to match more patterns for DINS instruction

Strahinja Petrovic via llvm-commits llvm-commits at lists.llvm.org
Mon May 22 02:06:45 PDT 2017


Author: spetrovic
Date: Mon May 22 04:06:44 2017
New Revision: 303537

URL: http://llvm.org/viewvc/llvm-project?rev=303537&view=rev
Log:
[MIPS] Add support to match more patterns for DINS instruction

This patch adds support for recognizing patterns to match
DINS instruction.

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

Added:
    llvm/trunk/test/CodeGen/Mips/dins.ll
Modified:
    llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp
    llvm/trunk/test/CodeGen/Mips/mips64-f128.ll

Modified: llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp?rev=303537&r1=303536&r2=303537&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp Mon May 22 04:06:44 2017
@@ -795,7 +795,7 @@ static SDValue performORCombine(SDNode *
 
   SDValue And0 = N->getOperand(0), And1 = N->getOperand(1);
   uint64_t SMPos0, SMSize0, SMPos1, SMSize1;
-  ConstantSDNode *CN;
+  ConstantSDNode *CN, *CN1;
 
   // See if Op's first operand matches (and $src1 , mask0).
   if (And0.getOpcode() != ISD::AND)
@@ -806,37 +806,74 @@ static SDValue performORCombine(SDNode *
     return SDValue();
 
   // See if Op's second operand matches (and (shl $src, pos), mask1).
-  if (And1.getOpcode() != ISD::AND)
-    return SDValue();
-
-  if (!(CN = dyn_cast<ConstantSDNode>(And1.getOperand(1))) ||
-      !isShiftedMask(CN->getZExtValue(), SMPos1, SMSize1))
-    return SDValue();
-
-  // The shift masks must have the same position and size.
-  if (SMPos0 != SMPos1 || SMSize0 != SMSize1)
-    return SDValue();
+  if (And1.getOpcode() == ISD::AND &&
+      And1.getOperand(0).getOpcode() == ISD::SHL) {
 
-  SDValue Shl = And1.getOperand(0);
-  if (Shl.getOpcode() != ISD::SHL)
-    return SDValue();
+    if (!(CN = dyn_cast<ConstantSDNode>(And1.getOperand(1))) ||
+        !isShiftedMask(CN->getZExtValue(), SMPos1, SMSize1))
+      return SDValue();
+
+      // The shift masks must have the same position and size.
+      if (SMPos0 != SMPos1 || SMSize0 != SMSize1)
+        return SDValue();
+
+      SDValue Shl = And1.getOperand(0);
+
+      if (!(CN = dyn_cast<ConstantSDNode>(Shl.getOperand(1))))
+        return SDValue();
+
+      unsigned Shamt = CN->getZExtValue();
+
+      // Return if the shift amount and the first bit position of mask are not the
+      // same.
+      EVT ValTy = N->getValueType(0);
+      if ((Shamt != SMPos0) || (SMPos0 + SMSize0 > ValTy.getSizeInBits()))
+        return SDValue();
+
+      SDLoc DL(N);
+      return DAG.getNode(MipsISD::Ins, DL, ValTy, Shl.getOperand(0),
+                         DAG.getConstant(SMPos0, DL, MVT::i32),
+                         DAG.getConstant(SMSize0, DL, MVT::i32),
+                         And0.getOperand(0));
+  } else {
+    // Pattern match DINS.
+    //  $dst = or (and $src, mask0), mask1
+    //  where mask0 = ((1 << SMSize0) -1) << SMPos0
+    //  => dins $dst, $src, pos, size
+    if (~CN->getSExtValue() == ((((int64_t)1 << SMSize0) - 1) << SMPos0) &&
+        ((SMSize0 + SMPos0 <= 64 && Subtarget.hasMips64r2()) ||
+         (SMSize0 + SMPos0 <= 32))) {
+      // Check if AND instruction has constant as argument
+      bool isConstCase = And1.getOpcode() != ISD::AND;
+      if (And1.getOpcode() == ISD::AND) {
+        if (!(CN1 = dyn_cast<ConstantSDNode>(And1->getOperand(1))))
+          return SDValue();
+      } else {
+        if (!(CN1 = dyn_cast<ConstantSDNode>(N->getOperand(1))))
+          return SDValue();
+      }
+      SDLoc DL(N);
+      EVT ValTy = N->getOperand(0)->getValueType(0);
+      SDValue Const1;
+      SDValue SrlX;
+      if (!isConstCase) {
+        Const1 = DAG.getConstant(SMPos0, DL, MVT::i32);
+        SrlX = DAG.getNode(ISD::SRL, DL, And1->getValueType(0), And1, Const1);
+      }
+      return DAG.getNode(
+          MipsISD::Ins, DL, N->getValueType(0),
+          isConstCase
+              ? DAG.getConstant(CN1->getSExtValue() >> SMPos0, DL, ValTy)
+              : SrlX,
+          DAG.getConstant(SMPos0, DL, MVT::i32),
+          DAG.getConstant(ValTy.getSizeInBits() / 8 < 8 ? SMSize0 & 31
+                                                        : SMSize0,
+                          DL, MVT::i32),
+          And0->getOperand(0));
 
-  if (!(CN = dyn_cast<ConstantSDNode>(Shl.getOperand(1))))
+    }
     return SDValue();
-
-  unsigned Shamt = CN->getZExtValue();
-
-  // Return if the shift amount and the first bit position of mask are not the
-  // same.
-  EVT ValTy = N->getValueType(0);
-  if ((Shamt != SMPos0) || (SMPos0 + SMSize0 > ValTy.getSizeInBits()))
-    return SDValue();
-
-  SDLoc DL(N);
-  return DAG.getNode(MipsISD::Ins, DL, ValTy, Shl.getOperand(0),
-                     DAG.getConstant(SMPos0, DL, MVT::i32),
-                     DAG.getConstant(SMSize0, DL, MVT::i32),
-                     And0.getOperand(0));
+  }
 }
 
 static SDValue performADDCombine(SDNode *N, SelectionDAG &DAG,

Added: llvm/trunk/test/CodeGen/Mips/dins.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Mips/dins.ll?rev=303537&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/Mips/dins.ll (added)
+++ llvm/trunk/test/CodeGen/Mips/dins.ll Mon May 22 04:06:44 2017
@@ -0,0 +1,70 @@
+; RUN: llc -O2 -march=mips64 -mcpu=mips64r2 -target-abi=n64 < %s -o - | FileCheck %s -check-prefix=MIPS64R2
+; RUN: llc -O2 -march=mips -mcpu=mips32r2 < %s -o - | FileCheck %s -check-prefix=MIPS32R2
+; RUN: llc -O2 -march=mips -mattr=mips16 < %s -o - | FileCheck %s -check-prefix=MIPS16
+
+; #include <stdint.h>
+; #include <stdio.h>
+; struct cvmx_buf_ptr {
+
+;   struct {
+;     unsigned long long addr :37;
+;     unsigned long long addr1 :15;
+;     unsigned int lenght:14;
+;     uint64_t total_bytes:16;
+;     uint64_t segs : 6;
+;   } s;
+; }
+;
+; unsigned long long foo(volatile struct cvmx_buf_ptr bufptr) {
+;   bufptr.s.addr = 123;
+;   bufptr.s.segs = 4;
+;   bufptr.s.lenght = 5;
+;   bufptr.s.total_bytes = bufptr.s.lenght;
+;   return bufptr.s.addr;
+; }
+
+; Testing of selection INS/DINS instruction
+
+define i64 @f123(i64 inreg %bufptr.coerce0, i64 inreg %bufptr.coerce1) local_unnamed_addr #0 {
+entry:
+  %bufptr.sroa.0 = alloca i64, align 8
+  %bufptr.sroa.4 = alloca i64, align 8
+  store i64 %bufptr.coerce0, i64* %bufptr.sroa.0, align 8
+  store i64 %bufptr.coerce1, i64* %bufptr.sroa.4, align 8
+  %bufptr.sroa.0.0.bufptr.sroa.0.0.bufptr.sroa.0.0.bf.load = load volatile i64, i64* %bufptr.sroa.0, align 8
+  %bf.clear = and i64 %bufptr.sroa.0.0.bufptr.sroa.0.0.bufptr.sroa.0.0.bf.load, 134217727
+  %bf.set = or i64 %bf.clear, 16508780544
+  store volatile i64 %bf.set, i64* %bufptr.sroa.0, align 8
+  %bufptr.sroa.4.0.bufptr.sroa.4.0.bufptr.sroa.4.8.bf.load2 = load volatile i64, i64* %bufptr.sroa.4, align 8
+  %bf.clear3 = and i64 %bufptr.sroa.4.0.bufptr.sroa.4.0.bufptr.sroa.4.8.bf.load2, -16911433729
+  %bf.set4 = or i64 %bf.clear3, 1073741824
+  store volatile i64 %bf.set4, i64* %bufptr.sroa.4, align 8
+  %bufptr.sroa.4.0.bufptr.sroa.4.0.bufptr.sroa.4.8.bf.load6 = load volatile i64, i64* %bufptr.sroa.4, align 8
+  %bf.clear7 = and i64 %bufptr.sroa.4.0.bufptr.sroa.4.0.bufptr.sroa.4.8.bf.load6, 1125899906842623
+  %bf.set8 = or i64 %bf.clear7, 5629499534213120
+  store volatile i64 %bf.set8, i64* %bufptr.sroa.4, align 8
+  %bufptr.sroa.4.0.bufptr.sroa.4.0.bufptr.sroa.4.8.bf.load11 = load volatile i64, i64* %bufptr.sroa.4, align 8
+  %bf.lshr = lshr i64 %bufptr.sroa.4.0.bufptr.sroa.4.0.bufptr.sroa.4.8.bf.load11, 50
+  %bufptr.sroa.4.0.bufptr.sroa.4.0.bufptr.sroa.4.8.bf.load13 = load volatile i64, i64* %bufptr.sroa.4, align 8
+  %bf.shl = shl nuw nsw i64 %bf.lshr, 34
+  %bf.clear14 = and i64 %bufptr.sroa.4.0.bufptr.sroa.4.0.bufptr.sroa.4.8.bf.load13, -1125882726973441
+  %bf.set15 = or i64 %bf.clear14, %bf.shl
+  store volatile i64 %bf.set15, i64* %bufptr.sroa.4, align 8
+  %bufptr.sroa.0.0.bufptr.sroa.0.0.bufptr.sroa.0.0.bf.load17 = load volatile i64, i64* %bufptr.sroa.0, align 8
+  %bf.lshr18 = lshr i64 %bufptr.sroa.0.0.bufptr.sroa.0.0.bufptr.sroa.0.0.bf.load17, 27
+  ret i64 %bf.lshr18
+}
+
+
+; CHECK-LABEL: f123:
+; MIPS64R2: daddiu	$[[R0:[0-9]+]], $zero, 123
+; MIPS64R2: dins    $[[R0:[0-9]+]], $[[R1:[0-9]+]], 27, 37
+; MIPS64R2: daddiu	$[[R0:[0-9]+]], $zero, 5
+; MIPS64R2: daddiu	$[[R0:[0-9]+]], $zero, 4
+; MIPS64R2: dins    $[[R0:[0-9]+]], $[[R1:[0-9]+]], 28, 6
+; MIPS64R2: dins    $[[R0:[0-9]+]], $[[R1:[0-9]+]], 50, 14
+; MIPS64R2: dsrl	  $[[R0:[0-9]+]], $[[R1:[0-9]+]], 50
+; MIPS64R2: dins    $[[R0:[0-9]+]], $[[R1:[0-9]+]], 34, 16
+; MIPS32R2: ins     $[[R0:[0-9]+]], $[[R1:[0-9]+]], 2, 16
+; MIPS32R2-NOT: ins $[[R0:[0-9]+]], $[[R1:[0-9]+]], 18, 46
+; MIPS16-NOT: ins{{[[:space:]].*}}
\ No newline at end of file

Modified: llvm/trunk/test/CodeGen/Mips/mips64-f128.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Mips/mips64-f128.ll?rev=303537&r1=303536&r2=303537&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/Mips/mips64-f128.ll (original)
+++ llvm/trunk/test/CodeGen/Mips/mips64-f128.ll Mon May 22 04:06:44 2017
@@ -418,18 +418,17 @@ entry:
 declare fp128 @llvm.powi.f128(fp128, i32) #3
 
 ; ALL-LABEL:     libcall2_copysignl:
-; ALL-DAG:      daddiu $[[R2:[0-9]+]], $zero, 1
-; ALL-DAG:      dsll   $[[R3:[0-9]+]], $[[R2]], 63
+; NOT-R2R6-DAG: daddiu $[[R2:[0-9]+]], $zero, 1
+; NOT-R2R6-DAG: dsll   $[[R3:[0-9]+]], $[[R2]], 63
 ; ALL-DAG:      ld     $[[R0:[0-9]+]], %got_disp(gld1)
 ; ALL-DAG:      ld     $[[R1:[0-9]+]], 8($[[R0]])
-; ALL-DAG:      and    $[[R4:[0-9]+]], $[[R1]], $[[R3]]
+; NOT-R2R6-DAG: and    $[[R4:[0-9]+]], $[[R1]], $[[R3]]
 ; ALL-DAG:      ld     $[[R5:[0-9]+]], %got_disp(gld0)
 ; ALL-DAG:      ld     $[[R6:[0-9]+]], 8($[[R5]])
+; R2R6:         dins   $[[R0:[0-9]+]], $[[R1:[0-9]+]], 63, 1
 ; NOT-R2R6-DAG: daddiu $[[R7:[0-9]+]], $[[R3]], -1
 ; NOT-R2R6-DAG: and    $[[R8:[0-9]+]], $[[R6]], $[[R7]]
 ; NOT-R2R6-DAG: or     $4, $[[R8]], $[[R4]]
-; R2R6-DAG:     dextm  $[[R7:[0-9]+]], $[[R6]], 0, 63
-; R2R6-DAG:     or     $4, $[[R7]], $[[R4]]
 ; ALL-DAG:      ld     $2, 0($[[R5]])
 
 define fp128 @libcall2_copysignl() {




More information about the llvm-commits mailing list