// 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;
}
// 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;
}
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));
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));
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)
%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)
%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)
; 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)
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)
%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)
%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)
%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)
--- /dev/null
+; RUN: llc -march=mipsel -mattr=+msa,+fp64 -relocation-model=pic < %s | FileCheck %s
+
+@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
+@llvm_mips_bmnzi_b_ARG2 = global <16 x i8> zeroinitializer, align 16
+@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
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
}
; 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
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
}
; 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
; 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
}