[llvm] r331771 - [mips][msa] Pattern match the splat.d instruction

Stefan Maksimovic via llvm-commits llvm-commits at lists.llvm.org
Tue May 8 08:12:29 PDT 2018


Author: smaksimovic
Date: Tue May  8 08:12:29 2018
New Revision: 331771

URL: http://llvm.org/viewvc/llvm-project?rev=331771&view=rev
Log:
[mips][msa] Pattern match the splat.d instruction

Introduced a new pattern for matching splat.d explicitly.

Both splat.d and splati.d can now be generated from the @llvm.mips.splat.d
intrinsic depending on whether an immediate value has been passed.

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

Modified:
    llvm/trunk/lib/Target/Mips/MipsMSAInstrInfo.td
    llvm/trunk/lib/Target/Mips/MipsSEISelLowering.cpp
    llvm/trunk/test/CodeGen/Mips/msa/3r_splat.ll

Modified: llvm/trunk/lib/Target/Mips/MipsMSAInstrInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsMSAInstrInfo.td?rev=331771&r1=331770&r2=331771&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Mips/MipsMSAInstrInfo.td (original)
+++ llvm/trunk/lib/Target/Mips/MipsMSAInstrInfo.td Tue May  8 08:12:29 2018
@@ -181,8 +181,28 @@ def vsplati16 : PatFrag<(ops node:$e0),
 def vsplati32 : PatFrag<(ops node:$e0),
                         (v4i32 (build_vector node:$e0, node:$e0,
                                              node:$e0, node:$e0))>;
+
+def vsplati64_imm_eq_1 : PatLeaf<(bitconvert (v4i32 (build_vector))), [{
+  APInt Imm;
+  SDNode *BV = N->getOperand(0).getNode();
+  EVT EltTy = N->getValueType(0).getVectorElementType();
+
+  return selectVSplat(BV, Imm, EltTy.getSizeInBits()) &&
+         Imm.getBitWidth() == EltTy.getSizeInBits() && Imm == 1;
+}]>;
+
 def vsplati64 : PatFrag<(ops node:$e0),
                         (v2i64 (build_vector node:$e0, node:$e0))>;
+
+def vsplati64_splat_d : PatFrag<(ops node:$e0),
+                                (v2i64 (bitconvert
+                                         (v4i32 (and
+                                           (v4i32 (build_vector node:$e0,
+                                                                node:$e0,
+                                                                node:$e0,
+                                                                node:$e0)),
+                                           vsplati64_imm_eq_1))))>;
+
 def vsplatf32 : PatFrag<(ops node:$e0),
                         (v4f32 (build_vector node:$e0, node:$e0,
                                              node:$e0, node:$e0))>;
@@ -196,7 +216,8 @@ def vsplati16_elt : PatFrag<(ops node:$v
 def vsplati32_elt : PatFrag<(ops node:$v, node:$i),
                             (MipsVSHF (vsplati32 node:$i), node:$v, node:$v)>;
 def vsplati64_elt : PatFrag<(ops node:$v, node:$i),
-                            (MipsVSHF (vsplati64 node:$i), node:$v, node:$v)>;
+                            (MipsVSHF (vsplati64_splat_d node:$i),
+                                      node:$v, node:$v)>;
 
 class SplatPatLeaf<Operand opclass, dag frag, code pred = [{}],
                    SDNodeXForm xform = NOOP_SDNodeXForm>
@@ -327,15 +348,6 @@ def vsplat_imm_eq_1 : PatLeaf<(build_vec
          Imm.getBitWidth() == EltTy.getSizeInBits() && Imm == 1;
 }]>;
 
-def vsplati64_imm_eq_1 : PatLeaf<(bitconvert (v4i32 (build_vector))), [{
-  APInt Imm;
-  SDNode *BV = N->getOperand(0).getNode();
-  EVT EltTy = N->getValueType(0).getVectorElementType();
-
-  return selectVSplat(BV, Imm, EltTy.getSizeInBits()) &&
-         Imm.getBitWidth() == EltTy.getSizeInBits() && Imm == 1;
-}]>;
-
 def vbclr_b : PatFrag<(ops node:$ws, node:$wt),
                       (and node:$ws, (xor (shl vsplat_imm_eq_1, node:$wt),
                                           immAllOnesV))>;

Modified: llvm/trunk/lib/Target/Mips/MipsSEISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsSEISelLowering.cpp?rev=331771&r1=331770&r2=331771&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Mips/MipsSEISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/Mips/MipsSEISelLowering.cpp Tue May  8 08:12:29 2018
@@ -1343,7 +1343,16 @@ static SDValue lowerMSASplatZExt(SDValue
   SDValue LaneB;
 
   if (ResVecTy == MVT::v2i64) {
-    LaneB = DAG.getConstant(0, DL, MVT::i32);
+    // In case of the index being passed as an immediate value, set the upper
+    // lane to 0 so that the splati.d instruction can be matched.
+    if (isa<ConstantSDNode>(LaneA))
+      LaneB = DAG.getConstant(0, DL, MVT::i32);
+    // Having the index passed in a register, set the upper lane to the same
+    // value as the lower - this results in the BUILD_VECTOR node not being
+    // expanded through stack. This way we are able to pattern match the set of
+    // nodes created here to splat.d.
+    else
+      LaneB = LaneA;
     ViaVecTy = MVT::v4i32;
     if(BigEndian)
       std::swap(LaneA, LaneB);

Modified: llvm/trunk/test/CodeGen/Mips/msa/3r_splat.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Mips/msa/3r_splat.ll?rev=331771&r1=331770&r2=331771&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/Mips/msa/3r_splat.ll (original)
+++ llvm/trunk/test/CodeGen/Mips/msa/3r_splat.ll Tue May  8 08:12:29 2018
@@ -1,9 +1,9 @@
 ; Test the MSA splat intrinsics that are encoded with the 3R instruction
 ; format.
 
-; RUN: llc -march=mips -mattr=+msa,+fp64 -relocation-model=pic < %s | \
+; RUN: llc -march=mips -mcpu=mips32r5 -mattr=+msa,+fp64 -relocation-model=pic < %s | \
 ; RUN:     FileCheck -check-prefix=MIPS32 %s
-; RUN: llc -march=mipsel -mattr=+msa,+fp64 -relocation-model=pic < %s | \
+; RUN: llc -march=mipsel -mcpu=mips32r5 -mattr=+msa,+fp64 -relocation-model=pic < %s | \
 ; RUN:     FileCheck -check-prefix=MIPS32 %s
 
 @llvm_mips_splat_b_ARG1 = global <16 x i8> <i8 0, i8 1, i8 2, i8 3, i8 4, i8 5, i8 6, i8 7, i8 8, i8 9, i8 10, i8 11, i8 12, i8 13, i8 14, i8 15>, align 16
@@ -83,14 +83,11 @@ entry:
 declare <2 x i64> @llvm.mips.splat.d(<2 x i64>, i32) nounwind
 
 ; MIPS32: llvm_mips_splat_d_test:
-; FIXME: This test is currently disabled for MIPS32 because the indices are
-;        difficult to match. This is because 64-bit values cannot be stored in
-;        GPR32.
-; MIPS64-DAG: lw   [[R1:\$[0-9]+]], %got(llvm_mips_splat_d_ARG1)(
-; MIPS64-DAG: lw   [[R2:\$[0-9]+]], %got(llvm_mips_splat_d_RES)(
-; MIPS64-DAG: ld.d [[R3:\$w[0-9]+]], 0([[R1]])
-; MIPS64-DAG: splat.d [[R4:\$w[0-9]+]], [[R3]][$4]
-; MIPS64-DAG: st.d [[R4]], 0([[R2]])
+; MIPS32-DAG: lw   [[R1:\$[0-9]+]], %got(llvm_mips_splat_d_ARG1)(
+; MIPS32-DAG: lw   [[R2:\$[0-9]+]], %got(llvm_mips_splat_d_RES)(
+; MIPS32-DAG: ld.d [[R3:\$w[0-9]+]], 0([[R1]])
+; MIPS32-DAG: splat.d [[R4:\$w[0-9]+]], [[R3]][$4]
+; MIPS32-DAG: st.d [[R4]], 0([[R2]])
 ; MIPS32: .size llvm_mips_splat_d_test
 
 define void @llvm_mips_splat_d_arg_test(i32 %arg) {
@@ -99,10 +96,14 @@ entry:
   store volatile <2 x i64> %0, <2 x i64>* @llvm_mips_splat_d_RES
   ret void
 }
-; CHECK-LABEL: llvm_mips_splat_d_arg_test
-; CHECK: ldi.w [[R1:\$w[0-9]+]], 1 
-; CHECK: and.v [[R2:\$w[0-9]+]], {{\$w[0-9]+}}, [[R1]]
-; CHECK: vshf.d [[R2]], {{.*}}
+; MIPS32-LABEL: llvm_mips_splat_d_arg_test
+; MIPS32-DAG: lw      [[R0:\$[0-9]+]], %got(
+; MIPS32-DAG: addiu   [[R1:\$[0-9]+]], [[R0]], %lo(
+; MIPS32-DAG: lw      [[R2:\$[0-9]+]], %got(llvm_mips_splat_d_RES)(
+; MIPS32-DAG: ld.d    [[R3:\$w[0-9]+]], 0([[R1]])
+; MIPS32-DAG: splat.d [[R4:\$w[0-9]+]], [[R3]][$4]
+; MIPS32-DAG: st.d    [[R4]], 0([[R2]])
+; MIPS32-NOT: vshf.d
 
 define void @llvm_mips_splat_d_imm_test() {
 entry:
@@ -110,6 +111,11 @@ entry:
   store volatile<2 x i64> %0, <2 x i64>* @llvm_mips_splat_d_RES
   ret void
 }
-; CHECK-LABEL: llvm_mips_splat_d_imm_test
-; CHECK: splati. d {{.*}}, {{.*}}[0]
-; CHECK-NOT: vshf.d
+; MIPS32-LABEL: llvm_mips_splat_d_imm_test
+; MIPS32-DAG: lw       [[R0:\$[0-9]+]], %got(
+; MIPS32-DAG: addiu    [[R1:\$[0-9]+]], [[R0]], %lo(
+; MIPS32-DAG: lw       [[R2:\$[0-9]+]], %got(llvm_mips_splat_d_RES)(
+; MIPS32-DAG: ld.d     [[R3:\$w[0-9]+]], 0([[R1]])
+; MIPS32-DAG: splati.d [[R4:\$w[0-9]+]], [[R3]][0]
+; MIPS32-DAG: st.d     [[R4]], 0([[R2]])
+; MIPS32-NOT: vshf.d




More information about the llvm-commits mailing list