[llvm] r299768 - [mips][msa] Fix generation of bm(n)zi and bins[lr]i instructions

Petar Jovanovic via llvm-commits llvm-commits at lists.llvm.org
Fri Apr 7 06:31:36 PDT 2017


Author: petarj
Date: Fri Apr  7 08:31:36 2017
New Revision: 299768

URL: http://llvm.org/viewvc/llvm-project?rev=299768&view=rev
Log:
[mips][msa] Fix generation of bm(n)zi and bins[lr]i instructions

We have two cases here, the first one being the following instruction
selection from the builtin function:
bm(n)zi builtin -> vselect node -> bins[lr]i machine instruction

In case of bm(n)zi having an immediate which has either its high or low bits
set, a bins[lr] instruction can be selected through the selectVSplatMask[LR]
function. The function counts the number of bits set, and that value is
being passed to the bins[lr]i instruction as its immediate, which in turn
copies immediate modulo the size of the element in bits plus 1 as per specs,
where we get the off-by-one-error.

The other case is:
bins[lr]i -> vselect node -> bsel.v

In this case, a bsel.v instruction gets selected with a mask having one bit
less set than required.

Patch by Stefan Maksimovic.

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


Added:
    llvm/trunk/test/CodeGen/Mips/msa/bmzi_bmnzi.ll
Modified:
    llvm/trunk/lib/Target/Mips/MipsSEISelDAGToDAG.cpp
    llvm/trunk/lib/Target/Mips/MipsSEISelLowering.cpp
    llvm/trunk/test/CodeGen/Mips/msa/bitwise.ll
    llvm/trunk/test/CodeGen/Mips/msa/i5-b.ll
    llvm/trunk/test/CodeGen/Mips/msa/immediates.ll

Modified: llvm/trunk/lib/Target/Mips/MipsSEISelDAGToDAG.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsSEISelDAGToDAG.cpp?rev=299768&r1=299767&r2=299768&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Mips/MipsSEISelDAGToDAG.cpp (original)
+++ llvm/trunk/lib/Target/Mips/MipsSEISelDAGToDAG.cpp Fri Apr  7 08:31:36 2017
@@ -692,7 +692,7 @@ bool MipsSEDAGToDAGISel::selectVSplatMas
     // as the original value.
     if (ImmValue == ~(~ImmValue & ~(~ImmValue + 1))) {
 
-      Imm = CurDAG->getTargetConstant(ImmValue.countPopulation(), SDLoc(N),
+      Imm = CurDAG->getTargetConstant(ImmValue.countPopulation() - 1, SDLoc(N),
                                       EltTy);
       return true;
     }
@@ -724,7 +724,7 @@ bool MipsSEDAGToDAGISel::selectVSplatMas
     // Extract the run of set bits starting with bit zero, and test that the
     // result is the same as the original value
     if (ImmValue == (ImmValue & ~(ImmValue + 1))) {
-      Imm = CurDAG->getTargetConstant(ImmValue.countPopulation(), SDLoc(N),
+      Imm = CurDAG->getTargetConstant(ImmValue.countPopulation() - 1, SDLoc(N),
                                       EltTy);
       return true;
     }

Modified: llvm/trunk/lib/Target/Mips/MipsSEISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsSEISelLowering.cpp?rev=299768&r1=299767&r2=299768&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Mips/MipsSEISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/Mips/MipsSEISelLowering.cpp Fri Apr  7 08:31:36 2017
@@ -1644,7 +1644,7 @@ SDValue MipsSETargetLowering::lowerINTRI
     if (Op->getConstantOperandVal(3) >= EltTy.getSizeInBits())
       report_fatal_error("Immediate out of range");
     APInt Mask = APInt::getHighBitsSet(EltTy.getSizeInBits(),
-                                       Op->getConstantOperandVal(3));
+                                       Op->getConstantOperandVal(3) + 1);
     return DAG.getNode(ISD::VSELECT, DL, VecTy,
                        DAG.getConstant(Mask, DL, VecTy, true),
                        Op->getOperand(2), Op->getOperand(1));
@@ -1659,7 +1659,7 @@ SDValue MipsSETargetLowering::lowerINTRI
     if (Op->getConstantOperandVal(3) >= EltTy.getSizeInBits())
       report_fatal_error("Immediate out of range");
     APInt Mask = APInt::getLowBitsSet(EltTy.getSizeInBits(),
-                                      Op->getConstantOperandVal(3));
+                                      Op->getConstantOperandVal(3) + 1);
     return DAG.getNode(ISD::VSELECT, DL, VecTy,
                        DAG.getConstant(Mask, DL, VecTy, true),
                        Op->getOperand(2), Op->getOperand(1));

Modified: llvm/trunk/test/CodeGen/Mips/msa/bitwise.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Mips/msa/bitwise.ll?rev=299768&r1=299767&r2=299768&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/Mips/msa/bitwise.ll (original)
+++ llvm/trunk/test/CodeGen/Mips/msa/bitwise.ll Fri Apr  7 08:31:36 2017
@@ -1099,7 +1099,7 @@ define void @binsl_v16i8_i(<16 x i8>* %c
                           i8 63, i8 63, i8 63, i8 63,
                           i8 63, i8 63, i8 63, i8 63>
   %5 = or <16 x i8> %3, %4
-  ; CHECK-DAG: binsli.b [[R2]], [[R1]], 2
+  ; CHECK-DAG: binsli.b [[R2]], [[R1]], 1
   store <16 x i8> %5, <16 x i8>* %c
   ; CHECK-DAG: st.b [[R2]], 0($4)
 
@@ -1119,7 +1119,7 @@ define void @binsl_v8i16_i(<8 x i16>* %c
   %4 = and <8 x i16> %2, <i16 16383, i16 16383, i16 16383, i16 16383,
                           i16 16383, i16 16383, i16 16383, i16 16383>
   %5 = or <8 x i16> %3, %4
-  ; CHECK-DAG: binsli.h [[R2]], [[R1]], 2
+  ; CHECK-DAG: binsli.h [[R2]], [[R1]], 1
   store <8 x i16> %5, <8 x i16>* %c
   ; CHECK-DAG: st.h [[R2]], 0($4)
 
@@ -1137,7 +1137,7 @@ define void @binsl_v4i32_i(<4 x i32>* %c
   %3 = and <4 x i32> %1, <i32 3221225472, i32 3221225472, i32 3221225472, i32 3221225472>
   %4 = and <4 x i32> %2, <i32 1073741823, i32 1073741823, i32 1073741823, i32 1073741823>
   %5 = or <4 x i32> %3, %4
-  ; CHECK-DAG: binsli.w [[R2]], [[R1]], 2
+  ; CHECK-DAG: binsli.w [[R2]], [[R1]], 1
   store <4 x i32> %5, <4 x i32>* %c
   ; CHECK-DAG: st.w [[R2]], 0($4)
 
@@ -1159,7 +1159,7 @@ define void @binsl_v2i64_i(<2 x i64>* %c
   ;       issue. If the mask doesn't fit within a 10-bit immediate, it gets
   ;       legalized into a constant pool. We should add a test to cover the
   ;       other cases once they correctly select binsli.d.
-  ; CHECK-DAG: binsli.d [[R2]], [[R1]], 61
+  ; CHECK-DAG: binsli.d [[R2]], [[R1]], 60
   store <2 x i64> %5, <2 x i64>* %c
   ; CHECK-DAG: st.d [[R2]], 0($4)
 
@@ -1181,7 +1181,7 @@ define void @binsr_v16i8_i(<16 x i8>* %c
                           i8 252, i8 252, i8 252, i8 252,
                           i8 252, i8 252, i8 252, i8 252>
   %5 = or <16 x i8> %3, %4
-  ; CHECK-DAG: binsri.b [[R2]], [[R1]], 2
+  ; CHECK-DAG: binsri.b [[R2]], [[R1]], 1
   store <16 x i8> %5, <16 x i8>* %c
   ; CHECK-DAG: st.b [[R2]], 0($4)
 
@@ -1201,7 +1201,7 @@ define void @binsr_v8i16_i(<8 x i16>* %c
   %4 = and <8 x i16> %2, <i16 65532, i16 65532, i16 65532, i16 65532,
                           i16 65532, i16 65532, i16 65532, i16 65532>
   %5 = or <8 x i16> %3, %4
-  ; CHECK-DAG: binsri.h [[R2]], [[R1]], 2
+  ; CHECK-DAG: binsri.h [[R2]], [[R1]], 1
   store <8 x i16> %5, <8 x i16>* %c
   ; CHECK-DAG: st.h [[R2]], 0($4)
 
@@ -1219,7 +1219,7 @@ define void @binsr_v4i32_i(<4 x i32>* %c
   %3 = and <4 x i32> %1, <i32 3, i32 3, i32 3, i32 3>
   %4 = and <4 x i32> %2, <i32 4294967292, i32 4294967292, i32 4294967292, i32 4294967292>
   %5 = or <4 x i32> %3, %4
-  ; CHECK-DAG: binsri.w [[R2]], [[R1]], 2
+  ; CHECK-DAG: binsri.w [[R2]], [[R1]], 1
   store <4 x i32> %5, <4 x i32>* %c
   ; CHECK-DAG: st.w [[R2]], 0($4)
 
@@ -1237,7 +1237,7 @@ define void @binsr_v2i64_i(<2 x i64>* %c
   %3 = and <2 x i64> %1, <i64 3, i64 3>
   %4 = and <2 x i64> %2, <i64 18446744073709551612, i64 18446744073709551612>
   %5 = or <2 x i64> %3, %4
-  ; CHECK-DAG: binsri.d [[R2]], [[R1]], 2
+  ; CHECK-DAG: binsri.d [[R2]], [[R1]], 1
   store <2 x i64> %5, <2 x i64>* %c
   ; CHECK-DAG: st.d [[R2]], 0($4)
 

Added: llvm/trunk/test/CodeGen/Mips/msa/bmzi_bmnzi.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Mips/msa/bmzi_bmnzi.ll?rev=299768&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/Mips/msa/bmzi_bmnzi.ll (added)
+++ llvm/trunk/test/CodeGen/Mips/msa/bmzi_bmnzi.ll Fri Apr  7 08:31:36 2017
@@ -0,0 +1,55 @@
+; RUN: llc -march=mipsel -mattr=+msa,+fp64 -relocation-model=pic < %s | FileCheck %s
+
+ at llvm_mips_bmnzi_b_ARG1 = global <16 x i8> <i8 15, i8 15, i8 15, i8 15, i8 15, i8 15, i8 15, i8 15, i8 15, i8 15, i8 15, i8 15, i8 15, i8 15, i8 15, i8 15>, align 16
+ at llvm_mips_bmnzi_b_ARG2 = global <16 x i8> zeroinitializer, align 16
+ at llvm_mips_bmnzi_b_RES = global <16 x i8> zeroinitializer, align 16
+
+define void @llvm_mips_bmnzi_b_test() nounwind {
+entry:
+  %0 = load <16 x i8>, <16 x i8>* @llvm_mips_bmnzi_b_ARG1
+  %1 = load <16 x i8>, <16 x i8>* @llvm_mips_bmnzi_b_ARG2
+  %2 = tail call <16 x i8> @llvm.mips.bmnzi.b(<16 x i8> %0, <16 x i8> %1, i32 240)
+  store <16 x i8> %2, <16 x i8>* @llvm_mips_bmnzi_b_RES
+  %3 = tail call <16 x i8> @llvm.mips.bmnzi.b(<16 x i8> %0, <16 x i8> %1, i32 15)
+  store <16 x i8> %3, <16 x i8>* @llvm_mips_bmnzi_b_RES
+  %4 = tail call <16 x i8> @llvm.mips.bmnzi.b(<16 x i8> %0, <16 x i8> %1, i32 170)
+  store <16 x i8> %4, <16 x i8>* @llvm_mips_bmnzi_b_RES
+  ret void
+}
+; CHECK-LABEL: llvm_mips_bmnzi_b_test:
+; CHECK: lw [[R0:\$[0-9]+]], %got(llvm_mips_bmnzi_b_RES)(
+; CHECK: lw [[R1:\$[0-9]+]], %got(llvm_mips_bmnzi_b_ARG1)(
+; CHECK: lw [[R2:\$[0-9]+]], %got(llvm_mips_bmnzi_b_ARG2)(
+; CHECK: ld.b [[R3:\$w[0-9]+]], 0([[R2]])
+; CHECK: ld.b [[R4:\$w[0-9]+]], 0([[R1]])
+; CHECK: move.v [[R5:\$w[0-9]+]], [[R4]]
+; CHECK: binsli.b [[R5]], [[R3]], 3
+; CHECK: binsri.b [[R5]], [[R3]], 3
+; CHECK: bmnzi.b [[R4]], [[R3]], 170
+
+define void @llvm_mips_bmzi_b_test() nounwind {
+entry:
+  %0 = load <16 x i8>, <16 x i8>* @llvm_mips_bmnzi_b_ARG1
+  %1 = load <16 x i8>, <16 x i8>* @llvm_mips_bmnzi_b_ARG2
+  %2 = tail call <16 x i8> @llvm.mips.bmzi.b(<16 x i8> %0, <16 x i8> %1, i32 240)
+  store <16 x i8> %2, <16 x i8>* @llvm_mips_bmnzi_b_RES
+  %3 = tail call <16 x i8> @llvm.mips.bmzi.b(<16 x i8> %0, <16 x i8> %1, i32 15)
+  store <16 x i8> %3, <16 x i8>* @llvm_mips_bmnzi_b_RES
+  %4 = tail call <16 x i8> @llvm.mips.bmzi.b(<16 x i8> %0, <16 x i8> %1, i32 170)
+  store <16 x i8> %4, <16 x i8>* @llvm_mips_bmnzi_b_RES
+  ret void
+}
+; CHECK-LABEL: llvm_mips_bmzi_b_test:
+; CHECK: lw [[R0:\$[0-9]+]], %got(llvm_mips_bmnzi_b_RES)(
+; CHECK: lw [[R1:\$[0-9]+]], %got(llvm_mips_bmnzi_b_ARG2)(
+; CHECK: lw [[R2:\$[0-9]+]], %got(llvm_mips_bmnzi_b_ARG1)(
+; CHECK: ld.b [[R3:\$w[0-9]+]], 0([[R2]])
+; CHECK: ld.b [[R4:\$w[0-9]+]], 0([[R1]])
+; CHECK: move.v [[R5:\$w[0-9]+]], [[R4]]
+; CHECK: binsli.b [[R5]], [[R3]], 3
+; CHECK: binsri.b [[R5]], [[R3]], 3
+; bmnzi.b is the same as bmzi.b with ws and wd_in swapped
+; CHECK: bmnzi.b [[R4]], [[R3]], 170
+
+declare <16 x i8> @llvm.mips.bmnzi.b(<16 x i8>, <16 x i8>, i32) nounwind
+declare <16 x i8> @llvm.mips.bmzi.b(<16 x i8>, <16 x i8>, i32) nounwind

Modified: llvm/trunk/test/CodeGen/Mips/msa/i5-b.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Mips/msa/i5-b.ll?rev=299768&r1=299767&r2=299768&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/Mips/msa/i5-b.ll (original)
+++ llvm/trunk/test/CodeGen/Mips/msa/i5-b.ll Fri Apr  7 08:31:36 2017
@@ -89,7 +89,7 @@ define void @llvm_mips_binsli_b_test() n
 entry:
   %0 = load <16 x i8>, <16 x i8>* @llvm_mips_binsli_b_ARG1
   %1 = load <16 x i8>, <16 x i8>* @llvm_mips_binsli_b_ARG2
-  %2 = tail call <16 x i8> @llvm.mips.binsli.b(<16 x i8> %0, <16 x i8> %1, i32 7)
+  %2 = tail call <16 x i8> @llvm.mips.binsli.b(<16 x i8> %0, <16 x i8> %1, i32 6)
   store <16 x i8> %2, <16 x i8>* @llvm_mips_binsli_b_RES
   ret void
 }
@@ -101,7 +101,7 @@ declare <16 x i8> @llvm.mips.binsli.b(<1
 ; CHECK-DAG: lw [[R2:\$[0-9]+]], %got(llvm_mips_binsli_b_ARG2)(
 ; CHECK-DAG: ld.b [[R3:\$w[0-9]+]], 0([[R1]])
 ; CHECK-DAG: ld.b [[R4:\$w[0-9]+]], 0([[R2]])
-; CHECK-DAG: binsli.b [[R3]], [[R4]], 7
+; CHECK-DAG: binsli.b [[R3]], [[R4]], 6
 ; CHECK-DAG: lw [[R5:\$[0-9]+]], %got(llvm_mips_binsli_b_RES)(
 ; CHECK-DAG: st.b [[R3]], 0([[R5]])
 ; CHECK: .size llvm_mips_binsli_b_test
@@ -193,7 +193,7 @@ define void @llvm_mips_binsri_b_test() n
 entry:
   %0 = load <16 x i8>, <16 x i8>* @llvm_mips_binsri_b_ARG1
   %1 = load <16 x i8>, <16 x i8>* @llvm_mips_binsri_b_ARG2
-  %2 = tail call <16 x i8> @llvm.mips.binsri.b(<16 x i8> %0, <16 x i8> %1, i32 7)
+  %2 = tail call <16 x i8> @llvm.mips.binsri.b(<16 x i8> %0, <16 x i8> %1, i32 6)
   store <16 x i8> %2, <16 x i8>* @llvm_mips_binsri_b_RES
   ret void
 }
@@ -205,7 +205,7 @@ declare <16 x i8> @llvm.mips.binsri.b(<1
 ; CHECK-DAG: lw [[R2:\$[0-9]+]], %got(llvm_mips_binsri_b_ARG2)(
 ; CHECK-DAG: ld.b [[R3:\$w[0-9]+]], 0([[R1]])
 ; CHECK-DAG: ld.b [[R4:\$w[0-9]+]], 0([[R2]])
-; CHECK-DAG: binsri.b [[R3]], [[R4]], 7
+; CHECK-DAG: binsri.b [[R3]], [[R4]], 6
 ; CHECK-DAG: lw [[R5:\$[0-9]+]], %got(llvm_mips_binsri_b_RES)(
 ; CHECK-DAG: st.b [[R3]], 0([[R5]])
 ; CHECK: .size llvm_mips_binsri_b_test

Modified: llvm/trunk/test/CodeGen/Mips/msa/immediates.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Mips/msa/immediates.ll?rev=299768&r1=299767&r2=299768&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/Mips/msa/immediates.ll (original)
+++ llvm/trunk/test/CodeGen/Mips/msa/immediates.ll Fri Apr  7 08:31:36 2017
@@ -616,7 +616,7 @@ entry:
 ; CHECK: binsri.h
   %a = load <8 x i16>, <8 x i16> * %ptr, align 16
   %b = load <8 x i16>, <8 x i16> * %ptr2, align 16
-  %r = call <8 x i16> @llvm.mips.binsri.h(<8 x i16> %a, <8 x i16> %b, i32 15)
+  %r = call <8 x i16> @llvm.mips.binsri.h(<8 x i16> %a, <8 x i16> %b, i32 14)
   store <8 x i16> %r, <8 x i16> * %ptr, align 16
   ret void
 }




More information about the llvm-commits mailing list