]> granicus.if.org Git - llvm/commitdiff
[Mips] Add support to match more patterns for DEXT and CINS
authorPetar Jovanovic <petar.jovanovic@imgtec.com>
Wed, 15 Mar 2017 13:10:08 +0000 (13:10 +0000)
committerPetar Jovanovic <petar.jovanovic@imgtec.com>
Wed, 15 Mar 2017 13:10:08 +0000 (13:10 +0000)
This patch adds support for recognizing more patterns to match to DEXT and
CINS instructions.
It finds cases where multiple instructions could be replaced with a single
DEXT or CINS instruction.

For example, for the following:

define i64 @dext_and32(i64 zeroext %a) {
entry:

 %and = and i64 %a, 4294967295
 ret i64 %and
}

instead of generating:

 0000000000000088 <dext_and32>:

 88:   64010001        daddiu  at,zero,1
 8c:   0001083c        dsll32  at,at,0x0
 90:   6421ffff        daddiu  at,at,-1
 94:   03e00008        jr      ra
 98:   00811024        and     v0,a0,at
 9c:   00000000        nop

the following gets generated:

 0000000000000068 <dext_and32>:

 68:   03e00008        jr      ra
 6c:   7c82f803        dext    v0,a0,0x0,0x20

Cases that are covered:

DEXT:

 1. and $src, mask where mask > 0xffff
 2. zext $src zero extend from i32 to i64

CINS:

 1. and (shl $src, pos), mask
 2. shl (and $src, mask), pos
 3. zext (shl $src, pos) zero extend from i32 to i64

Patch by Violeta Vukobrat.

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

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

lib/Target/Mips/Mips64InstrInfo.td
lib/Target/Mips/MipsISelLowering.cpp
lib/Target/Mips/MipsISelLowering.h
lib/Target/Mips/MipsInstrInfo.td
lib/Target/Mips/MipsSEISelLowering.cpp
test/CodeGen/Mips/cins.ll [new file with mode: 0644]
test/CodeGen/Mips/dext.ll [new file with mode: 0644]
test/CodeGen/Mips/load-store-left-right.ll
test/CodeGen/Mips/mips64-f128.ll
test/MC/Mips/sext_64_32.ll

index f3081d32baefd0276e6e9ad37ea9392d0b610e92..99025fe1341dab1d069451462327c7d500e5e7c6 100644 (file)
@@ -326,6 +326,14 @@ let AdditionalPredicates = [NotInMicroMips] in {
               EXT_FM<5>, ISA_MIPS64R2;
 }
 
+let isCodeGenOnly = 1, AdditionalPredicates = [NotInMicroMips] in {
+  def DEXT64_32 : InstSE<(outs GPR64Opnd:$rt),
+                         (ins GPR32Opnd:$rs, uimm5_report_uimm6:$pos,
+                              uimm5_plus1:$size),
+                         "dext $rt, $rs, $pos, $size", [], II_EXT, FrmR, "dext">,
+                  EXT_FM<3>, ISA_MIPS64R2;
+}
+
 let isCodeGenOnly = 1, rs = 0, shamt = 0 in {
   def DSLL64_32 : FR<0x00, 0x3c, (outs GPR64:$rd), (ins GPR32:$rt),
                      "dsll\t$rd, $rt, 32", [], II_DSLL>;
@@ -356,11 +364,11 @@ class Count1s<string opstr, RegisterOperand RO>:
   let TwoOperandAliasConstraint = "$rd = $rs";
 }
 
-class ExtsCins<string opstr, InstrItinClass itin,
-               SDPatternOperator Op = null_frag>:
-  InstSE<(outs GPR64Opnd:$rt), (ins GPR64Opnd:$rs, uimm5:$pos, uimm5:$lenm1),
-         !strconcat(opstr, " $rt, $rs, $pos, $lenm1"),
-         [(set GPR64Opnd:$rt, (Op GPR64Opnd:$rs, imm:$pos, imm:$lenm1))],
+class ExtsCins<string opstr, InstrItinClass itin, RegisterOperand RO,
+               PatFrag PosImm, SDPatternOperator Op = null_frag>:
+  InstSE<(outs RO:$rt), (ins RO:$rs, uimm5:$pos, uimm5:$lenm1),
+         !strconcat(opstr, "\t$rt, $rs, $pos, $lenm1"),
+         [(set RO:$rt, (Op RO:$rs, PosImm:$pos, imm:$lenm1))],
          itin, FrmR, opstr> {
   let TwoOperandAliasConstraint = "$rt = $rs";
 }
@@ -424,13 +432,28 @@ def DMUL  : ArithLogicR<"dmul", GPR64Opnd, 1, II_DMUL, mul>,
   let Defs = [HI0, LO0, P0, P1, P2];
 }
 
-// Extract a signed bit field /+32
-def EXTS  : ExtsCins<"exts", II_EXT>, EXTS_FM<0x3a>, ASE_CNMIPS;
-def EXTS32: ExtsCins<"exts32", II_EXT>, EXTS_FM<0x3b>, ASE_CNMIPS;
-
-// Clear and insert a bit field /+32
-def CINS  : ExtsCins<"cins", II_INS>, EXTS_FM<0x32>, ASE_CNMIPS;
-def CINS32: ExtsCins<"cins32", II_INS>, EXTS_FM<0x33>, ASE_CNMIPS;
+let AdditionalPredicates = [NotInMicroMips] in {
+  // Extract a signed bit field /+32
+  def EXTS  : ExtsCins<"exts", II_EXT, GPR64Opnd, immZExt5>, EXTS_FM<0x3a>,
+              ASE_MIPS64_CNMIPS;
+  def EXTS32: ExtsCins<"exts32", II_EXT, GPR64Opnd, immZExt5Plus32>,
+              EXTS_FM<0x3b>, ASE_MIPS64_CNMIPS;
+
+  // Clear and insert a bit field /+32
+  def CINS  : ExtsCins<"cins", II_INS, GPR64Opnd, immZExt5, MipsCIns>,
+              EXTS_FM<0x32>, ASE_MIPS64_CNMIPS;
+  def CINS32: ExtsCins<"cins32", II_INS, GPR64Opnd, immZExt5Plus32, MipsCIns>,
+              EXTS_FM<0x33>, ASE_MIPS64_CNMIPS;
+  let isCodeGenOnly = 1 in {
+    def CINS_i32 : ExtsCins<"cins", II_INS, GPR32Opnd, immZExt5, MipsCIns>,
+                   EXTS_FM<0x32>, ASE_MIPS64_CNMIPS;
+    def CINS64_32 :InstSE<(outs GPR64Opnd:$rt),
+                          (ins GPR32Opnd:$rs, uimm5:$pos, uimm5:$lenm1),
+                          "cins\t$rt, $rs, $pos, $lenm1", [], II_INS, FrmR,
+                          "cins">,
+                   EXTS_FM<0x32>, ASE_MIPS64_CNMIPS;
+  }
+}
 
 // Move to multiplier/product register
 def MTM0   : MoveToLOHI<"mtm0", GPR64Opnd, [MPL0, P0, P1, P2]>, MTMR_FM<0x08>,
@@ -646,6 +669,14 @@ def : MipsPat<(i64 (anyext GPR32:$src)),
 def : MipsPat<(i64 (zext GPR32:$src)), (DSRL (DSLL64_32 GPR32:$src), 32)>;
 def : MipsPat<(i64 (sext GPR32:$src)), (SLL64_32 GPR32:$src)>;
 
+let AdditionalPredicates = [NotInMicroMips] in {
+  def : MipsPat<(i64 (zext GPR32:$src)), (DEXT64_32 GPR32:$src, 0, 32)>,
+        ISA_MIPS64R2;
+  def : MipsPat<(i64 (zext (i32 (shl GPR32:$rt, immZExt5:$imm)))),
+                (CINS64_32 GPR32:$rt, imm:$imm, (immZExt5To31 imm:$imm))>,
+        ASE_MIPS64_CNMIPS;
+}
+
 // Sign extend in register
 def : MipsPat<(i64 (sext_inreg GPR64:$src, i32)),
               (SLL64_64 GPR64:$src)>;
@@ -796,21 +827,21 @@ def : MipsInstAlias<"bbit1 $rs, $p, $offset",
 def : MipsInstAlias<"exts $rt, $rs, $pos, $lenm1",
                     (EXTS32 GPR64Opnd:$rt, GPR64Opnd:$rs,
                             uimm5_plus32_normalize:$pos, uimm5:$lenm1), 0>,
-      ASE_CNMIPS;
+      ASE_MIPS64_CNMIPS;
 def : MipsInstAlias<"exts $rt, $pos, $lenm1",
                     (EXTS32 GPR64Opnd:$rt, GPR64Opnd:$rt,
                             uimm5_plus32_normalize:$pos, uimm5:$lenm1), 0>,
-      ASE_CNMIPS;
+      ASE_MIPS64_CNMIPS;
 
 // cins with $pos 32-63 in converted to cins32 with $pos 0-31
 def : MipsInstAlias<"cins $rt, $rs, $pos, $lenm1",
                     (CINS32 GPR64Opnd:$rt, GPR64Opnd:$rs,
                             uimm5_plus32_normalize:$pos, uimm5:$lenm1), 0>,
-      ASE_CNMIPS;
+      ASE_MIPS64_CNMIPS;
 def : MipsInstAlias<"cins $rt, $pos, $lenm1",
                     (CINS32 GPR64Opnd:$rt, GPR64Opnd:$rt,
                             uimm5_plus32_normalize:$pos, uimm5:$lenm1), 0>,
-      ASE_CNMIPS;
+      ASE_MIPS64_CNMIPS;
 
 //===----------------------------------------------------------------------===//
 // Assembler Pseudo Instructions
index f0f2424f7224cd4e329fe49c7915816e88ec9b12..4df6979d8a7d6ff8ea89fbccbf92211f2ca323e5 100644 (file)
@@ -147,6 +147,7 @@ const char *MipsTargetLowering::getTargetNodeName(unsigned Opcode) const {
   case MipsISD::Sync:              return "MipsISD::Sync";
   case MipsISD::Ext:               return "MipsISD::Ext";
   case MipsISD::Ins:               return "MipsISD::Ins";
+  case MipsISD::CIns:              return "MipsISD::CIns";
   case MipsISD::LWL:               return "MipsISD::LWL";
   case MipsISD::LWR:               return "MipsISD::LWR";
   case MipsISD::SWL:               return "MipsISD::SWL";
@@ -428,6 +429,7 @@ MipsTargetLowering::MipsTargetLowering(const MipsTargetMachine &TM,
   setTargetDAGCombine(ISD::OR);
   setTargetDAGCombine(ISD::ADD);
   setTargetDAGCombine(ISD::AssertZext);
+  setTargetDAGCombine(ISD::SHL);
 
   if (ABI.IsO32()) {
     // These libcalls are not available in 32-bit.
@@ -702,41 +704,81 @@ static SDValue performCMovFPCombine(SDNode *N, SelectionDAG &DAG,
 static SDValue performANDCombine(SDNode *N, SelectionDAG &DAG,
                                  TargetLowering::DAGCombinerInfo &DCI,
                                  const MipsSubtarget &Subtarget) {
-  // Pattern match EXT.
-  //  $dst = and ((sra or srl) $src , pos), (2**size - 1)
-  //  => ext $dst, $src, size, pos
   if (DCI.isBeforeLegalizeOps() || !Subtarget.hasExtractInsert())
     return SDValue();
 
-  SDValue ShiftRight = N->getOperand(0), Mask = N->getOperand(1);
-  unsigned ShiftRightOpc = ShiftRight.getOpcode();
-
-  // Op's first operand must be a shift right.
-  if (ShiftRightOpc != ISD::SRA && ShiftRightOpc != ISD::SRL)
-    return SDValue();
+  SDValue FirstOperand = N->getOperand(0);
+  unsigned FirstOperandOpc = FirstOperand.getOpcode();
+  SDValue Mask = N->getOperand(1);
+  EVT ValTy = N->getValueType(0);
+  SDLoc DL(N);
 
-  // The second operand of the shift must be an immediate.
+  uint64_t Pos = 0, SMPos, SMSize;
   ConstantSDNode *CN;
-  if (!(CN = dyn_cast<ConstantSDNode>(ShiftRight.getOperand(1))))
-    return SDValue();
-
-  uint64_t Pos = CN->getZExtValue();
-  uint64_t SMPos, SMSize;
+  SDValue NewOperand;
+  unsigned Opc;
 
   // Op's second operand must be a shifted mask.
   if (!(CN = dyn_cast<ConstantSDNode>(Mask)) ||
       !isShiftedMask(CN->getZExtValue(), SMPos, SMSize))
     return SDValue();
 
-  // Return if the shifted mask does not start at bit 0 or the sum of its size
-  // and Pos exceeds the word's size.
-  EVT ValTy = N->getValueType(0);
-  if (SMPos != 0 || Pos + SMSize > ValTy.getSizeInBits())
-    return SDValue();
+  if (FirstOperandOpc == ISD::SRA || FirstOperandOpc == ISD::SRL) {
+    // Pattern match EXT.
+    //  $dst = and ((sra or srl) $src , pos), (2**size - 1)
+    //  => ext $dst, $src, pos, size
+
+    // The second operand of the shift must be an immediate.
+    if (!(CN = dyn_cast<ConstantSDNode>(FirstOperand.getOperand(1))))
+      return SDValue();
+
+    Pos = CN->getZExtValue();
+
+    // Return if the shifted mask does not start at bit 0 or the sum of its size
+    // and Pos exceeds the word's size.
+    if (SMPos != 0 || Pos + SMSize > ValTy.getSizeInBits())
+      return SDValue();
+
+    Opc = MipsISD::Ext;
+    NewOperand = FirstOperand.getOperand(0);
+  } else if (FirstOperandOpc == ISD::SHL && Subtarget.hasCnMips()) {
+    // Pattern match CINS.
+    //  $dst = and (shl $src , pos), mask
+    //  => cins $dst, $src, pos, size
+    // mask is a shifted mask with consecutive 1's, pos = shift amount,
+    // size = population count.
+
+    // The second operand of the shift must be an immediate.
+    if (!(CN = dyn_cast<ConstantSDNode>(FirstOperand.getOperand(1))))
+      return SDValue();
+
+    Pos = CN->getZExtValue();
+
+    if (SMPos != Pos || Pos >= ValTy.getSizeInBits() || SMSize >= 32 ||
+        Pos + SMSize > ValTy.getSizeInBits())
+      return SDValue();
+
+    NewOperand = FirstOperand.getOperand(0);
+    // SMSize is 'location' (position) in this case, not size.
+    SMSize--;
+    Opc = MipsISD::CIns;
+  } else {
+    // Pattern match EXT.
+    //  $dst = and $src, (2**size - 1) , if size > 16
+    //  => ext $dst, $src, pos, size , pos = 0
 
-  SDLoc DL(N);
-  return DAG.getNode(MipsISD::Ext, DL, ValTy,
-                     ShiftRight.getOperand(0),
+    // If the mask is <= 0xffff, andi can be used instead.
+    if (CN->getZExtValue() <= 0xffff)
+      return SDValue();
+
+    // Return if the mask doesn't start at position 0.
+    if (SMPos)
+      return SDValue();
+
+    Opc = MipsISD::Ext;
+    NewOperand = FirstOperand;
+  }
+  return DAG.getNode(Opc, DL, ValTy, NewOperand,
                      DAG.getConstant(Pos, DL, MVT::i32),
                      DAG.getConstant(SMSize, DL, MVT::i32));
 }
@@ -855,6 +897,58 @@ static SDValue performAssertZextCombine(SDNode *N, SelectionDAG &DAG,
   return SDValue();
 }
 
+
+static SDValue performSHLCombine(SDNode *N, SelectionDAG &DAG,
+                                 TargetLowering::DAGCombinerInfo &DCI,
+                                 const MipsSubtarget &Subtarget) {
+  // Pattern match CINS.
+  //  $dst = shl (and $src , imm), pos
+  //  => cins $dst, $src, pos, size
+
+  if (DCI.isBeforeLegalizeOps() || !Subtarget.hasCnMips())
+    return SDValue();
+
+  SDValue FirstOperand = N->getOperand(0);
+  unsigned FirstOperandOpc = FirstOperand.getOpcode();
+  SDValue SecondOperand = N->getOperand(1);
+  EVT ValTy = N->getValueType(0);
+  SDLoc DL(N);
+
+  uint64_t Pos = 0, SMPos, SMSize;
+  ConstantSDNode *CN;
+  SDValue NewOperand;
+
+  // The second operand of the shift must be an immediate.
+  if (!(CN = dyn_cast<ConstantSDNode>(SecondOperand)))
+    return SDValue();
+
+  Pos = CN->getZExtValue();
+
+  if (Pos >= ValTy.getSizeInBits())
+    return SDValue();
+
+  if (FirstOperandOpc != ISD::AND)
+    return SDValue();
+
+  // AND's second operand must be a shifted mask.
+  if (!(CN = dyn_cast<ConstantSDNode>(FirstOperand.getOperand(1))) ||
+      !isShiftedMask(CN->getZExtValue(), SMPos, SMSize))
+    return SDValue();
+
+  // Return if the shifted mask does not start at bit 0 or the sum of its size
+  // and Pos exceeds the word's size.
+  if (SMPos != 0 || SMSize > 32 || Pos + SMSize > ValTy.getSizeInBits())
+    return SDValue();
+
+  NewOperand = FirstOperand.getOperand(0);
+  // SMSize is 'location' (position) in this case, not size.
+  SMSize--;
+
+  return DAG.getNode(MipsISD::CIns, DL, ValTy, NewOperand,
+                     DAG.getConstant(Pos, DL, MVT::i32),
+                     DAG.getConstant(SMSize, DL, MVT::i32));
+}
+
 SDValue  MipsTargetLowering::PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI)
   const {
   SelectionDAG &DAG = DCI.DAG;
@@ -878,6 +972,8 @@ SDValue  MipsTargetLowering::PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI)
     return performADDCombine(N, DAG, DCI, Subtarget);
   case ISD::AssertZext:
     return performAssertZextCombine(N, DAG, DCI, Subtarget);
+  case ISD::SHL:
+    return performSHLCombine(N, DAG, DCI, Subtarget);
   }
 
   return SDValue();
index abc34be63779389d342eb2a8dc6b2fd9d7d7ffde..2dcafd51061a281f33032703d7c23ae0af57d571 100644 (file)
@@ -116,6 +116,7 @@ namespace llvm {
 
       Ext,
       Ins,
+      CIns,
 
       // EXTR.W instrinsic nodes.
       EXTP,
index a25a9165a17421321f5610b6984fb251d07550ea..b90077d7807d8a1c618ee5af3e8a9a8f194b95f1 100644 (file)
@@ -138,6 +138,7 @@ def MipsSync : SDNode<"MipsISD::Sync", SDT_Sync, [SDNPHasChain,SDNPSideEffect]>;
 
 def MipsExt :  SDNode<"MipsISD::Ext", SDT_Ext>;
 def MipsIns :  SDNode<"MipsISD::Ins", SDT_Ins>;
+def MipsCIns : SDNode<"MipsISD::CIns", SDT_Ext>;
 
 def MipsLWL : SDNode<"MipsISD::LWL", SDTMipsLoadLR,
                      [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>;
@@ -1172,6 +1173,10 @@ def immZExt5Plus33 : PatLeaf<(imm), [{
   return isUInt<5>(N->getZExtValue() - 33);
 }]>;
 
+def immZExt5To31 : SDNodeXForm<imm, [{
+  return getImm(N, 31 - N->getZExtValue());
+}]>;
+
 // True if (N + 1) fits in 16-bit field.
 def immSExt16Plus1 : PatLeaf<(imm), [{
   return isInt<17>(N->getSExtValue()) && isInt<16>(N->getSExtValue() + 1);
index c78c24bf47b71019e09b871e957c93ac6cb39fa3..71bccc52482775661e69dc8f5fed623fc44b3827 100644 (file)
@@ -1123,7 +1123,8 @@ MipsSETargetLowering::PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const {
   case ISD::MUL:
     return performMULCombine(N, DAG, DCI, this);
   case ISD::SHL:
-    return performSHLCombine(N, DAG, DCI, Subtarget);
+    Val = performSHLCombine(N, DAG, DCI, Subtarget);
+    break;
   case ISD::SRA:
     return performSRACombine(N, DAG, DCI, Subtarget);
   case ISD::SRL:
diff --git a/test/CodeGen/Mips/cins.ll b/test/CodeGen/Mips/cins.ll
new file mode 100644 (file)
index 0000000..4fe2556
--- /dev/null
@@ -0,0 +1,92 @@
+; RUN: llc -march=mips64 -mcpu=octeon -target-abi=n64 < %s -o - | FileCheck %s
+
+define i64 @cins_zext(i32 signext %n) {
+entry:
+  %shl = shl i32 %n, 5
+  %conv = zext i32 %shl to i64
+  ret i64 %conv
+
+; CHECK-LABEL: cins_zext:
+; CHECK:       cins $[[R0:[0-9]+]], $[[R1:[0-9]+]], 5, 26
+
+}
+
+define i64 @cins_and_shl(i64 zeroext %n) {
+entry:
+  %and = shl i64 %n, 8
+  %shl = and i64 %and, 16776960
+  ret i64 %shl
+
+; CHECK-LABEL: cins_and_shl:
+; CHECK:       cins $[[R0:[0-9]+]], $[[R1:[0-9]+]], 8, 15
+
+}
+
+define i64 @cins_and_shl32(i64 zeroext %n) {
+entry:
+  %and = shl i64 %n, 38
+  %shl = and i64 %and, 18014123631575040
+  ret i64 %shl
+
+; CHECK-LABEL: cins_and_shl32:
+; CHECK:       cins32 $[[R0:[0-9]+]], $[[R1:[0-9]+]], 6, 15
+
+}
+
+define zeroext i16 @cins_and_shl_16(i16 zeroext %n) {
+entry:
+  %0 = shl i16 %n, 2
+  %1 = and i16 %0, 60
+  ret i16 %1
+
+; CHECK-LABEL: cins_and_shl_16:
+; CHECK:       cins $[[R0:[0-9]+]], $[[R1:[0-9]+]], 2, 3
+
+}
+
+define zeroext i8 @cins_and_shl_8(i8 zeroext %n) {
+entry:
+  %0 = shl i8 %n, 2
+  %1 = and i8 %0, 12
+  ret i8 %1
+
+; CHECK-LABEL: cins_and_shl_8:
+; CHECK:       cins $[[R0:[0-9]+]], $[[R1:[0-9]+]], 2, 1
+
+}
+
+define i32 @cins_i32(i32 signext %a) {
+entry:
+  %and = shl i32 %a, 17
+  %shl = and i32 %and, 536739840
+  ret i32 %shl
+
+; CHECK-LABEL: cins_i32:
+; CHECK:       cins $[[R0:[0-9]+]], $[[R1:[0-9]+]], 17, 11
+
+}
+
+define i64 @cins_shl_and(i32 signext %n) {
+entry:
+  %and = and i32 %n, 65535
+  %conv = zext i32 %and to i64
+  %shl = shl nuw nsw i64 %conv, 31
+  ret i64 %shl
+
+; CHECK-LABEL: cins_shl_and:
+; CHECK:       cins $[[R0:[0-9]+]], $[[R1:[0-9]+]], 31, 15
+
+}
+
+
+define i64 @cins_shl_and32(i32 signext %n) {
+entry:
+  %and = and i32 %n, 65535
+  %conv = zext i32 %and to i64
+  %shl = shl nuw nsw i64 %conv, 47
+  ret i64 %shl
+
+; CHECK-LABEL: cins_shl_and32:
+; CHECK:       cins32 $[[R0:[0-9]+]], $[[R1:[0-9]+]], 15, 15
+
+}
diff --git a/test/CodeGen/Mips/dext.ll b/test/CodeGen/Mips/dext.ll
new file mode 100644 (file)
index 0000000..1794f16
--- /dev/null
@@ -0,0 +1,105 @@
+; RUN: llc -march=mips64 -mcpu=mips64r2 -target-abi=n64 < %s -o - | FileCheck %s
+
+define i64 @dext_add_zext(i32 signext %n) {
+entry:
+  %add = add i32 %n, 1
+  %res = zext i32 %add to i64
+  ret i64 %res
+
+; CHECK-LABEL: dext_add_zext:
+; CHECK:       dext $[[R0:[0-9]+]], $[[R0:[0-9]+]], 0, 32
+
+}
+
+define i32 @ext_and24(i32 signext %a) {
+entry:
+  %and = and i32 %a, 16777215
+  ret i32 %and
+
+; CHECK-LABEL: ext_and24:
+; CHECK:       ext $[[R0:[0-9]+]], $[[R1:[0-9]+]], 0, 24
+
+}
+
+define i64 @dext_and32(i64 zeroext %a) {
+entry:
+  %and = and i64 %a, 4294967295
+  ret i64 %and
+
+; CHECK-LABEL: dext_and32:
+; CHECK:       dext $[[R0:[0-9]+]], $[[R1:[0-9]+]], 0, 32
+
+}
+
+define i64 @dext_and35(i64 zeroext %a) {
+entry:
+  %and = and i64 %a, 34359738367
+  ret i64 %and
+
+; CHECK-LABEL: dext_and35:
+; CHECK:       dextm $[[R0:[0-9]+]], $[[R1:[0-9]+]], 0, 35
+
+}
+
+define i64 @dext_and20(i64 zeroext %a) {
+entry:
+  %and = and i64 %a, 1048575
+  ret i64 %and
+
+; CHECK-LABEL: dext_and20:
+; CHECK:       dext $[[R0:[0-9]+]], $[[R1:[0-9]+]], 0, 20
+
+}
+
+define i64 @dext_and16(i64 zeroext %a) {
+entry:
+  %and = and i64 %a, 65535
+  ret i64 %and
+
+; CHECK-LABEL: dext_and16:
+; CHECK:       andi $[[R0:[0-9]+]], $[[R1:[0-9]+]], 65535
+
+}
+
+define i64 @dext_lsr_and20(i64 zeroext %a) {
+entry:
+  %shr = lshr i64 %a, 5
+  %and = and i64 %shr, 1048575
+  ret i64 %and
+
+; CHECK-LABEL: dext_lsr_and20:
+; CHECK:       dext $[[R0:[0-9]+]], $[[R1:[0-9]+]], 5, 20
+
+}
+
+define i64 @dext_lsr_and8(i64 zeroext %a) {
+entry:
+  %shr = lshr i64 %a, 40
+  %and = and i64 %shr, 255
+  ret i64 %and
+
+; CHECK-LABEL: dext_lsr_and8:
+; CHECK:       dextu $[[R0:[0-9]+]], $[[R1:[0-9]+]], 40, 8
+
+}
+
+define i64 @dext_zext(i32 signext %a) {
+entry:
+  %conv = zext i32 %a to i64
+  ret i64 %conv
+
+; CHECK-LABEL: dext_zext:
+; CHECK:       dext $[[R0:[0-9]+]], $[[R1:[0-9]+]], 0, 32
+
+}
+
+define i64 @dext_and_lsr(i64 zeroext %n) {
+entry:
+  %and = lshr i64 %n, 8
+  %shr = and i64 %and, 4095
+  ret i64 %shr
+
+; CHECK-LABEL: dext_and_lsr:
+; CHECK:       dext $[[R0:[0-9]+]], $[[R1:[0-9]+]], 8, 12
+
+}
index 6def55cf88383be2256c4aaa9245819a40313934..b998772d367c472bba2b19b99bf19cd948116b14 100644 (file)
@@ -8,8 +8,8 @@
 ; RUN: llc -march=mips64   -mcpu=mips4    -target-abi=n64 -relocation-model=pic < %s | FileCheck -check-prefixes=ALL,MIPS64,MIPS64-EB %s
 ; RUN: llc -march=mips64el -mcpu=mips64   -target-abi=n64 -relocation-model=pic < %s | FileCheck -check-prefixes=ALL,MIPS64,MIPS64-EL %s
 ; RUN: llc -march=mips64   -mcpu=mips64   -target-abi=n64 -relocation-model=pic < %s | FileCheck -check-prefixes=ALL,MIPS64,MIPS64-EB %s
-; RUN: llc -march=mips64el -mcpu=mips64r2 -target-abi=n64 -relocation-model=pic < %s | FileCheck -check-prefixes=ALL,MIPS64,MIPS64-EL %s
-; RUN: llc -march=mips64   -mcpu=mips64r2 -target-abi=n64 -relocation-model=pic < %s | FileCheck -check-prefixes=ALL,MIPS64,MIPS64-EB %s
+; RUN: llc -march=mips64el -mcpu=mips64r2 -target-abi=n64 -relocation-model=pic < %s | FileCheck -check-prefixes=ALL,MIPS64,MIPS64R2-EL %s
+; RUN: llc -march=mips64   -mcpu=mips64r2 -target-abi=n64 -relocation-model=pic < %s | FileCheck -check-prefixes=ALL,MIPS64,MIPS64R2-EB %s
 ; RUN: llc -march=mips64el -mcpu=mips64r6 -target-abi=n64 -relocation-model=pic < %s | FileCheck -check-prefixes=ALL,MIPS64R6,MIPS64R6-EL %s
 ; RUN: llc -march=mips64   -mcpu=mips64r6 -target-abi=n64 -relocation-model=pic < %s | FileCheck -check-prefixes=ALL,MIPS64R6,MIPS64R6-EB %s
 
@@ -37,9 +37,15 @@ entry:
 ; MIPS64-EL:     lwl $[[R0:[0-9]+]], 3($[[R1:[0-9]+]])
 ; MIPS64-EL:     lwr $[[R0]], 0($[[R1]])
 
+; MIPS64R2-EL:   lwl $[[R0:[0-9]+]], 3($[[R1:[0-9]+]])
+; MIPS64R2-EL:   lwr $[[R0]], 0($[[R1]])
+
 ; MIPS64-EB:     lwl $[[R0:[0-9]+]], 0($[[R1:[0-9]+]])
 ; MIPS64-EB:     lwr $[[R0]], 3($[[R1]])
 
+; MIPS64R2-EB:   lwl $[[R0:[0-9]+]], 0($[[R1:[0-9]+]])
+; MIPS64R2-EB:   lwr $[[R0]], 3($[[R1]])
+
 ; MIPS64R6:      ld $[[PTR:[0-9]+]], %got_disp(si)(
 ; MIPS64R6:      lw $2, 0($[[PTR]])
 
@@ -63,9 +69,15 @@ entry:
 ; MIPS64-EL:     swl $[[R0:[0-9]+]], 3($[[R1:[0-9]+]])
 ; MIPS64-EL:     swr $[[R0]], 0($[[R1]])
 
+; MIPS64R2-EL:   swl $[[R0:[0-9]+]], 3($[[R1:[0-9]+]])
+; MIPS64R2-EL:   swr $[[R0]], 0($[[R1]])
+
 ; MIPS64-EB:     swl $[[R0:[0-9]+]], 0($[[R1:[0-9]+]])
 ; MIPS64-EB:     swr $[[R0]], 3($[[R1]])
 
+; MIPS64R2-EB:   swl $[[R0:[0-9]+]], 0($[[R1:[0-9]+]])
+; MIPS64R2-EB:   swr $[[R0]], 3($[[R1]])
+
 ; MIPS64R6:      ld $[[PTR:[0-9]+]], %got_disp(si)(
 ; MIPS64R6:      sw $4, 0($[[PTR]])
 
@@ -94,9 +106,15 @@ entry:
 ; MIPS64-EL:     ldl $[[R0:[0-9]+]], 7($[[R1:[0-9]+]])
 ; MIPS64-EL:     ldr $[[R0]], 0($[[R1]])
 
+; MIPS64R2-EL:   ldl $[[R0:[0-9]+]], 7($[[R1:[0-9]+]])
+; MIPS64R2-EL:   ldr $[[R0]], 0($[[R1]])
+
 ; MIPS64-EB:     ldl $[[R0:[0-9]+]], 0($[[R1:[0-9]+]])
 ; MIPS64-EB:     ldr $[[R0]], 7($[[R1]])
 
+; MIPS64R2-EB:   ldl $[[R0:[0-9]+]], 0($[[R1:[0-9]+]])
+; MIPS64R2-EB:   ldr $[[R0]], 7($[[R1]])
+
 ; MIPS64R6:      ld $[[PTR:[0-9]+]], %got_disp(sll)(
 ; MIPS64R6:      ld $2, 0($[[PTR]])
 
@@ -123,9 +141,15 @@ entry:
 ; MIPS64-EL:     lwl $[[R0:[0-9]+]], 3($[[R1:[0-9]+]])
 ; MIPS64-EL:     lwr $[[R0]], 0($[[R1]])
 
+; MIPS64R2-EL:   lwl $[[R0:[0-9]+]], 3($[[R1:[0-9]+]])
+; MIPS64R2-EL:   lwr $[[R0]], 0($[[R1]])
+
 ; MIPS64-EB:     lwl $[[R0:[0-9]+]], 0($[[R1:[0-9]+]])
 ; MIPS64-EB:     lwr $[[R0]], 3($[[R1]])
 
+; MIPS64R2-EB:   lwl $[[R0:[0-9]+]], 0($[[R1:[0-9]+]])
+; MIPS64R2-EB:   lwr $[[R0]], 3($[[R1]])
+
 ; MIPS64R6:      ld $[[PTR:[0-9]+]], %got_disp(si)(
 ; MIPS64R6:      lw $2, 0($[[PTR]])
 
@@ -159,9 +183,17 @@ entry:
 ; MIPS64-EL-DAG: daddiu $[[R4:[0-9]+]], $[[R3]], -1
 ; MIPS64-EL-DAG: and    ${{[0-9]+}}, $[[R0]], $[[R4]]
 
+; MIPS64R2-EL-DAG: lwl $[[R0:[0-9]+]], 3($[[R1:[0-9]+]])
+; MIPS64R2-EL-DAG: lwr $[[R0]], 0($[[R1]])
+; MIPS64R2-EL-DAG: dext $[[R0]], $[[R0]], 0, 32
+
 ; MIPS64-EB:     lwl $[[R0:[0-9]+]], 0($[[R1:[0-9]+]])
 ; MIPS64-EB:     lwr $[[R0]], 3($[[R1]])
 
+; MIPS64R2-EB:   lwl $[[R0:[0-9]+]], 0($[[R1:[0-9]+]])
+; MIPS64R2-EB:   lwr $[[R0]], 3($[[R1]])
+; MIPS64R2-EB:   dext $[[R0]], $[[R0]], 0, 32
+
 ; MIPS64R6:      ld $[[PTR:[0-9]+]], %got_disp(sui)(
 ; MIPS64R6:      lwu $2, 0($[[PTR]])
 
@@ -191,9 +223,15 @@ entry:
 ; MIPS64-EL:     sdl $[[R0:[0-9]+]], 7($[[R1:[0-9]+]])
 ; MIPS64-EL:     sdr $[[R0]], 0($[[R1]])
 
+; MIPS64R2-EL:   sdl $[[R0:[0-9]+]], 7($[[R1:[0-9]+]])
+; MIPS64R2-EL:   sdr $[[R0]], 0($[[R1]])
+
 ; MIPS64-EB:     sdl $[[R0:[0-9]+]], 0($[[R1:[0-9]+]])
 ; MIPS64-EB:     sdr $[[R0]], 7($[[R1]])
 
+; MIPS64R2-EB:   sdl $[[R0:[0-9]+]], 0($[[R1:[0-9]+]])
+; MIPS64R2-EB:   sdr $[[R0]], 7($[[R1]])
+
 ; MIPS64R6:      ld $[[PTR:[0-9]+]], %got_disp(sll)(
 ; MIPS64R6:      sd $4, 0($[[PTR]])
 
@@ -217,9 +255,15 @@ entry:
 ; MIPS64-EL:     swl $[[R0:[0-9]+]], 3($[[R1:[0-9]+]])
 ; MIPS64-EL:     swr $[[R0]], 0($[[R1]])
 
+; MIPS64R2-EL:   swl $[[R0:[0-9]+]], 3($[[R1:[0-9]+]])
+; MIPS64R2-EL:   swr $[[R0]], 0($[[R1]])
+
 ; MIPS64-EB:     swl $[[R0:[0-9]+]], 0($[[R1:[0-9]+]])
 ; MIPS64-EB:     swr $[[R0]], 3($[[R1]])
 
+; MIPS64R2-EB:   swl $[[R0:[0-9]+]], 0($[[R1:[0-9]+]])
+; MIPS64R2-EB:   swr $[[R0]], 3($[[R1]])
+
 ; MIPS64R6:      ld $[[PTR:[0-9]+]], %got_disp(si)(
 ; MIPS64R6:      sw $4, 0($[[PTR]])
 
@@ -247,7 +291,9 @@ entry:
 ; MIPS32-EB:     lw $[[PTR:[0-9]+]], %got(struct_s0)(
 ; MIPS32R6:      lw $[[PTR:[0-9]+]], %got(struct_s0)(
 ; MIPS64-EL:     ld $[[PTR:[0-9]+]], %got_disp(struct_s0)(
+; MIPS64R2-EL:   ld $[[PTR:[0-9]+]], %got_disp(struct_s0)(
 ; MIPS64-EB:     ld $[[PTR:[0-9]+]], %got_disp(struct_s0)(
+; MIPS64R2-EB:   ld $[[PTR:[0-9]+]], %got_disp(struct_s0)(
 ; MIPS64R6:      ld $[[PTR:[0-9]+]], %got_disp(struct_s0)(
 
 ; MIPS32-DAG:       lbu $[[R1:[0-9]+]], 0($[[PTR]])
@@ -297,18 +343,29 @@ entry:
 ; MIPS32R6-DAG:  sw $[[R1]], 4($[[PTR]])
 
 ; MIPS64-EL:     ld $[[PTR:[0-9]+]], %got_disp(struct_s1)(
+; MIPS64R2-EL:   ld $[[PTR:[0-9]+]], %got_disp(struct_s1)(
 ; MIPS64-EB:     ld $[[PTR:[0-9]+]], %got_disp(struct_s1)(
+; MIPS64R2-EB:   ld $[[PTR:[0-9]+]], %got_disp(struct_s1)(
 
 ; MIPS64-EL-DAG:    lwl $[[R1:[0-9]+]], 3($[[PTR]])
 ; MIPS64-EL-DAG:    lwr $[[R1]], 0($[[PTR]])
 ; MIPS64-EL-DAG:    swl $[[R1]], 7($[[PTR]])
 ; MIPS64-EL-DAG:    swr $[[R1]], 4($[[PTR]])
 
+; MIPS64R2-EL-DAG:    lwl $[[R1:[0-9]+]], 3($[[PTR]])
+; MIPS64R2-EL-DAG:    lwr $[[R1]], 0($[[PTR]])
+; MIPS64R2-EL-DAG:    swl $[[R1]], 7($[[PTR]])
+; MIPS64R2-EL-DAG:    swr $[[R1]], 4($[[PTR]])
+
 ; MIPS64-EB-DAG:    lwl $[[R1:[0-9]+]], 0($[[PTR]])
 ; MIPS64-EB-DAG:    lwr $[[R1]], 3($[[PTR]])
 ; MIPS64-EB-DAG:    swl $[[R1]], 4($[[PTR]])
 ; MIPS64-EB-DAG:    swr $[[R1]], 7($[[PTR]])
 
+; MIPS64R2-EB-DAG:    lwl $[[R1:[0-9]+]], 0($[[PTR]])
+; MIPS64R2-EB-DAG:    lwr $[[R1]], 3($[[PTR]])
+; MIPS64R2-EB-DAG:    swl $[[R1]], 4($[[PTR]])
+; MIPS64R2-EB-DAG:    swr $[[R1]], 7($[[PTR]])
 
 ; MIPS64-NOLEFTRIGHT-DAG:    lbu $[[R1:[0-9]+]], 0($[[PTR]])
 ; MIPS64-NOLEFTRIGHT-DAG:    sb $[[R1]], 4($[[PTR]])
@@ -365,12 +422,25 @@ entry:
 ; MIPS64-EL-DAG: sdl $[[R1]],       15($[[PTR]])
 ; MIPS64-EL-DAG: sdr $[[R1]],        8($[[PTR]])
 
+; MIPS64R2-EL:     ld $[[PTR:[0-9]+]], %got_disp(struct_s2)(
+
+; MIPS64R2-EL-DAG: ldl $[[R1:[0-9]+]], 7($[[PTR]])
+; MIPS64R2-EL-DAG: ldr $[[R1]],        0($[[PTR]])
+; MIPS64R2-EL-DAG: sdl $[[R1]],       15($[[PTR]])
+; MIPS64R2-EL-DAG: sdr $[[R1]],        8($[[PTR]])
+
 ; MIPS64-EB:     ld $[[PTR:[0-9]+]], %got_disp(struct_s2)(
 ; MIPS64-EB-DAG: ldl $[[R1:[0-9]+]], 0($[[PTR]])
 ; MIPS64-EB-DAG: ldr $[[R1]],        7($[[PTR]])
 ; MIPS64-EB-DAG: sdl $[[R1]],        8($[[PTR]])
 ; MIPS64-EB-DAG: sdr $[[R1]],       15($[[PTR]])
 
+; MIPS64R2-EB:     ld $[[PTR:[0-9]+]], %got_disp(struct_s2)(
+; MIPS64R2-EB-DAG: ldl $[[R1:[0-9]+]], 0($[[PTR]])
+; MIPS64R2-EB-DAG: ldr $[[R1]],        7($[[PTR]])
+; MIPS64R2-EB-DAG: sdl $[[R1]],        8($[[PTR]])
+; MIPS64R2-EB-DAG: sdr $[[R1]],       15($[[PTR]])
+
 ; MIPS64R6:      ld $[[PTR:[0-9]+]], %got_disp(struct_s2)(
 ; MIPS64R6-DAG:  ld $[[R1:[0-9]+]], 0($[[PTR]])
 ; MIPS64R6-DAG:  sd $[[R1]],        8($[[PTR]])
@@ -430,6 +500,10 @@ entry:
 ; MIPS64-EL-DAG: lwl $[[R1:[0-9]+]], 3($[[PTR]])
 ; MIPS64-EL-DAG: lwr $[[R1]],   0($[[PTR]])
 
+; MIPS64R2-EL:     ld $[[SPTR:[0-9]+]], %got_disp(arr)(
+; MIPS64R2-EL-DAG: lwl $[[R1:[0-9]+]], 3($[[PTR]])
+; MIPS64R2-EL-DAG: lwr $[[R1]],   0($[[PTR]])
+
 ; MIPS64-EB: ld $[[SPTR:[0-9]+]], %got_disp(arr)(
 ; MIPS64-EB-DAG: lbu  $[[R2:[0-9]+]], 5($[[PTR]])
 ; MIPS64-EB-DAG: lbu  $[[R3:[0-9]+]], 4($[[PTR]])
@@ -444,6 +518,21 @@ entry:
 ; MIPS64-EB-DAG: dsll $[[T4:[0-9]+]], $[[R4]], 8
 ; MIPS64-EB-DAG: or   $4, $[[T3]], $[[T4]]
 
+; MIPS64R2-EB: ld $[[SPTR:[0-9]+]], %got_disp(arr)(
+; MIPS64R2-EB-DAG: lbu  $[[R1:[0-9]+]], 5($[[PTR]])
+; MIPS64R2-EB-DAG: lbu  $[[R2:[0-9]+]], 4($[[PTR]])
+; MIPS64R2-EB-DAG: dsll $[[T0:[0-9]+]], $[[R2]], 8
+; MIPS64R2-EB-DAG: or   $[[T1:[0-9]+]], $[[T0]], $[[R1]]
+; MIPS64R2-EB-DAG: dsll $[[T1]], $[[T1]], 16
+; MIPS64R2-EB-DAG: lwl  $[[R3:[0-9]+]], 0($[[PTR]])
+; MIPS64R2-EB-DAG: lwr  $[[R3]], 3($[[PTR]])
+; MIPS64R2-EB-DAG: dext $[[R3]], $[[R3]], 0, 32
+; MIPS64R2-EB-DAG: dsll $[[R3]], $[[R3]], 32
+; MIPS64R2-EB-DAG: or   $[[T2:[0-9]+]], $[[R3]], $[[T1]]
+; MIPS64R2-EB-DAG: lbu  $[[R4:[0-9]+]], 6($[[PTR]])
+; MIPS64R2-EB-DAG: dsll $[[T3:[0-9]+]], $[[R4]], 8
+; MIPS64R2-EB-DAG: or   $4, $[[T2]], $[[T3]]
+
 ; MIPS64R6:      ld $[[SPTR:[0-9]+]], %got_disp(arr)(
 
   tail call void @extern_func([7 x i8]* byval @arr) nounwind
index 237b4c5f1ee200f8806a6d4145c612a56c21e10c..a6dafb1abfd664037ca157e29ab2b0dafa488739 100644 (file)
@@ -1,15 +1,15 @@
 ; RUN: llc -mtriple=mips64el-unknown-unknown -mcpu=mips4 -mattr=+soft-float -O1 \
 ; RUN:     -disable-mips-delay-filler -relocation-model=pic < %s | FileCheck \
-; RUN:     %s -check-prefixes=ALL,C_CC_FMT,PRER6
+; RUN:     %s -check-prefixes=ALL,C_CC_FMT,PRER6,NOT-R2R6
 ; RUN: llc -mtriple=mips64el-unknown-unknown -mcpu=mips64 -mattr=+soft-float -O1 \
 ; RUN:     -disable-mips-delay-filler -relocation-model=pic < %s | FileCheck \
-; RUN:     %s -check-prefixes=ALL,C_CC_FMT,PRER6
+; RUN:     %s -check-prefixes=ALL,C_CC_FMT,PRER6,NOT-R2R6
 ; RUN: llc -mtriple=mips64el-unknown-unknown -mcpu=mips64r2 -mattr=+soft-float \
 ; RUN:     -O1 -disable-mips-delay-filler -relocation-model=pic < %s | FileCheck \
-; RUN:     %s -check-prefixes=ALL,C_CC_FMT,PRER6
+; RUN:     %s -check-prefixes=ALL,C_CC_FMT,PRER6,R2R6
 ; RUN: llc -mtriple=mips64el-unknown-unknown -mcpu=mips64r6 -mattr=+soft-float \
 ; RUN:     -O1 -disable-mips-delay-filler -relocation-model=pic < %s | FileCheck \
-; RUN:     %s -check-prefixes=ALL,CMP_CC_FMT,R6
+; RUN:     %s -check-prefixes=ALL,CMP_CC_FMT,R6,R2R6
 
 @gld0 = external global fp128
 @gld1 = external global fp128
@@ -242,12 +242,16 @@ entry:
 }
 
 ; ALL-LABEL:             libcall1_fabsl:
-; ALL-DAG: ld      $[[R0:[0-9]+]], 8($[[R4:[0-9]+]])
-; ALL-DAG: daddiu  $[[R1:[0-9]+]], $zero, 1
-; ALL-DAG: dsll    $[[R2:[0-9]+]], $[[R1]], 63
-; ALL-DAG: daddiu  $[[R3:[0-9]+]], $[[R2]], -1
-; ALL-DAG: and     $4, $[[R0]], $[[R3]]
-; ALL-DAG: ld      $2, 0($[[R4]])
+; NOT-R2R6-DAG: ld      $[[R0:[0-9]+]], 8($[[R4:[0-9]+]])
+; NOT-R2R6-DAG: daddiu  $[[R1:[0-9]+]], $zero, 1
+; NOT-R2R6-DAG: dsll    $[[R2:[0-9]+]], $[[R1]], 63
+; NOT-R2R6-DAG: daddiu  $[[R3:[0-9]+]], $[[R2]], -1
+; NOT-R2R6-DAG: and     $4, $[[R0]], $[[R3]]
+; NOT-R2R6-DAG: ld      $2, 0($[[R4]])
+
+; R2R6-DAG: ld     $[[R0:[0-9]+]], 0($[[R3:[0-9]+]])
+; R2R6-DAG: ld     $[[R1:[0-9]+]], 8($[[R3]])
+; R2R6-DAG: dextm  $[[R2:[0-9]+]], $[[R1]], 0, 63
 
 define fp128 @libcall1_fabsl() {
 entry:
@@ -414,17 +418,19 @@ 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
-; 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]]
-; ALL-DAG: ld     $[[R5:[0-9]+]], %got_disp(gld0)
-; ALL-DAG: ld     $[[R6:[0-9]+]], 8($[[R5]])
-; ALL-DAG: daddiu $[[R7:[0-9]+]], $[[R3]], -1
-; ALL-DAG: and    $[[R8:[0-9]+]], $[[R6]], $[[R7]]
-; ALL-DAG: or     $4, $[[R8]], $[[R4]]
-; ALL-DAG: ld     $2, 0($[[R5]])
+; ALL-DAG:      daddiu $[[R2:[0-9]+]], $zero, 1
+; ALL-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]]
+; ALL-DAG:      ld     $[[R5:[0-9]+]], %got_disp(gld0)
+; ALL-DAG:      ld     $[[R6:[0-9]+]], 8($[[R5]])
+; 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() {
 entry:
index 5679829e8eab900517aa3fd7601a20584c7e13ed..f6c468187d7bd77e8052b3a1bacc41c6106b6031 100644 (file)
@@ -11,7 +11,8 @@ entry:
   ret i64 %conv
 }
 
-; CHECK: dsll32 ${{[a-z0-9]+}}, ${{[a-z0-9]+}}, 0
+; CHECK-LABEL: foo_2:
+; CHECK: dext ${{[a-z0-9]+}}, ${{[a-z0-9]+}}, 0, 32
 
 define i64 @foo_2(i32 %ival_2) nounwind readnone {
 entry: