[mips] BSEL's and BINS[RL] operands are reversed compared to the vselect node used in the pattern.

Summary:
Correct the match patterns and the lowerings that made the CodeGen tests pass despite the mistakes.

The original testcase that discovered the problem was SingleSource/UnitTests/SignlessType/factor.c in test-suite.
During review, we also found that some of the existing CodeGen tests were incorrect and fixed them:
* bitwise.ll: In bsel_v16i8 the IfSet/IfClear were reversed because bsel and bmnz have different operand orders and the test didn't correctly account for this. bmnz goes 'IfClear, IfSet, CondMask', while bsel goes 'CondMask, IfClear, IfSet'.
* vec.ll: In the cases where a bsel is emitted as a bmnz (they are the same operation with a different input tied to the result) the operands were in the wrong order.
* compare.ll and compare_float.ll: The bsel operand order was correct for a greater-than comparison, but a greater-than comparison instruction doesn't exist. Lowering this operation inverts the condition so the IfSet/IfClear need to be swapped to match.

The differences between BSEL, BMNZ, and BMZ and how they map to/from vselect are rather confusing. I've therefore added a note to MSA.txt to explain this in a single place in addition to the comments that explain each case.

Reviewers: matheusalmeida, jacksprat

Reviewed By: matheusalmeida

Differential Revision: http://llvm-reviews.chandlerc.com/D3028

llvm-svn: 203657
This commit is contained in:
Daniel Sanders 2014-03-12 11:54:00 +00:00
parent 3912f10885
commit 0ea082ce7e
7 changed files with 85 additions and 49 deletions

View File

@ -62,11 +62,16 @@ binsri.[bhwd], binsli.[bhwd]:
bmnz.v, bmz.v, bsel.v: bmnz.v, bmz.v, bsel.v:
These three operations differ only in the operand that is tied to the These three operations differ only in the operand that is tied to the
result. result and the order of the operands.
It is (currently) not possible to emit bmz.v, or bsel.v since bmnz.v is It is (currently) not possible to emit bmz.v, or bsel.v since bmnz.v is
the same operation and will be emitted instead. the same operation and will be emitted instead.
In future, the compiler may choose between these three instructions In future, the compiler may choose between these three instructions
according to register allocation. according to register allocation.
These three operations can be very confusing so here is a mapping
between the instructions and the vselect node in one place:
bmz.v wd, ws, wt/i8 -> (vselect wt/i8, wd, ws)
bmnz.v wd, ws, wt/i8 -> (vselect wt/i8, ws, wd)
bsel.v wd, ws, wt/i8 -> (vselect wd, wt/i8, ws)
bmnzi.b, bmzi.b: bmnzi.b, bmzi.b:
Like their non-immediate counterparts, bmnzi.v and bmzi.v are the same Like their non-immediate counterparts, bmnzi.v and bmzi.v are the same

View File

@ -1230,8 +1230,12 @@ class MSA_BIT_BINSXI_DESC_BASE<string instr_asm, ValueType Ty,
dag OutOperandList = (outs ROWD:$wd); dag OutOperandList = (outs ROWD:$wd);
dag InOperandList = (ins ROWD:$wd_in, ROWS:$ws, vsplat_uimm8:$m); dag InOperandList = (ins ROWD:$wd_in, ROWS:$ws, vsplat_uimm8:$m);
string AsmString = !strconcat(instr_asm, "\t$wd, $ws, $m"); string AsmString = !strconcat(instr_asm, "\t$wd, $ws, $m");
list<dag> Pattern = [(set ROWD:$wd, (vselect (Ty Mask:$m), (Ty ROWD:$wd_in), // Note that binsxi and vselect treat the condition operand the opposite
ROWS:$ws))]; // way to each other.
// (vselect cond, if_set, if_clear)
// (BSEL_V cond, if_clear, if_set)
list<dag> Pattern = [(set ROWD:$wd, (vselect (Ty Mask:$m), (Ty ROWD:$ws),
ROWS:$wd_in))];
InstrItinClass Itinerary = itin; InstrItinClass Itinerary = itin;
string Constraints = "$wd = $wd_in"; string Constraints = "$wd = $wd_in";
} }
@ -1758,9 +1762,13 @@ class BSEL_V_DESC {
dag InOperandList = (ins MSA128BOpnd:$wd_in, MSA128BOpnd:$ws, dag InOperandList = (ins MSA128BOpnd:$wd_in, MSA128BOpnd:$ws,
MSA128BOpnd:$wt); MSA128BOpnd:$wt);
string AsmString = "bsel.v\t$wd, $ws, $wt"; string AsmString = "bsel.v\t$wd, $ws, $wt";
// Note that vselect and BSEL_V treat the condition operand the opposite way
// from each other.
// (vselect cond, if_set, if_clear)
// (BSEL_V cond, if_clear, if_set)
list<dag> Pattern = [(set MSA128BOpnd:$wd, list<dag> Pattern = [(set MSA128BOpnd:$wd,
(vselect MSA128BOpnd:$wd_in, MSA128BOpnd:$ws, (vselect MSA128BOpnd:$wd_in, MSA128BOpnd:$wt,
MSA128BOpnd:$wt))]; MSA128BOpnd:$ws))];
InstrItinClass Itinerary = NoItinerary; InstrItinClass Itinerary = NoItinerary;
string Constraints = "$wd = $wd_in"; string Constraints = "$wd = $wd_in";
} }
@ -1770,9 +1778,13 @@ class BSELI_B_DESC {
dag InOperandList = (ins MSA128BOpnd:$wd_in, MSA128BOpnd:$ws, dag InOperandList = (ins MSA128BOpnd:$wd_in, MSA128BOpnd:$ws,
vsplat_uimm8:$u8); vsplat_uimm8:$u8);
string AsmString = "bseli.b\t$wd, $ws, $u8"; string AsmString = "bseli.b\t$wd, $ws, $u8";
// Note that vselect and BSEL_V treat the condition operand the opposite way
// from each other.
// (vselect cond, if_set, if_clear)
// (BSEL_V cond, if_clear, if_set)
list<dag> Pattern = [(set MSA128BOpnd:$wd, (vselect MSA128BOpnd:$wd_in, list<dag> Pattern = [(set MSA128BOpnd:$wd, (vselect MSA128BOpnd:$wd_in,
MSA128BOpnd:$ws, vsplati8_uimm8:$u8,
vsplati8_uimm8:$u8))]; MSA128BOpnd:$ws))];
InstrItinClass Itinerary = NoItinerary; InstrItinClass Itinerary = NoItinerary;
string Constraints = "$wd = $wd_in"; string Constraints = "$wd = $wd_in";
} }
@ -2834,7 +2846,11 @@ def BSEL_V : BSEL_V_ENC, BSEL_V_DESC;
class MSA_BSEL_PSEUDO_BASE<RegisterOperand RO, ValueType Ty> : class MSA_BSEL_PSEUDO_BASE<RegisterOperand RO, ValueType Ty> :
MSAPseudo<(outs RO:$wd), (ins RO:$wd_in, RO:$ws, RO:$wt), MSAPseudo<(outs RO:$wd), (ins RO:$wd_in, RO:$ws, RO:$wt),
[(set RO:$wd, (Ty (vselect RO:$wd_in, RO:$ws, RO:$wt)))]>, [(set RO:$wd, (Ty (vselect RO:$wd_in, RO:$wt, RO:$ws)))]>,
// Note that vselect and BSEL_V treat the condition operand the opposite way
// from each other.
// (vselect cond, if_set, if_clear)
// (BSEL_V cond, if_clear, if_set)
PseudoInstExpansion<(BSEL_V MSA128BOpnd:$wd, MSA128BOpnd:$wd_in, PseudoInstExpansion<(BSEL_V MSA128BOpnd:$wd, MSA128BOpnd:$wd_in,
MSA128BOpnd:$ws, MSA128BOpnd:$wt)> { MSA128BOpnd:$ws, MSA128BOpnd:$wt)> {
let Constraints = "$wd_in = $wd"; let Constraints = "$wd_in = $wd";

View File

@ -677,7 +677,7 @@ static SDValue performORCombine(SDNode *N, SelectionDAG &DAG,
} }
// Transform the DAG into an equivalent VSELECT. // Transform the DAG into an equivalent VSELECT.
return DAG.getNode(ISD::VSELECT, SDLoc(N), Ty, Cond, IfClr, IfSet); return DAG.getNode(ISD::VSELECT, SDLoc(N), Ty, Cond, IfSet, IfClr);
} }
return SDValue(); return SDValue();
@ -1459,25 +1459,27 @@ SDValue MipsSETargetLowering::lowerINTRINSIC_WO_CHAIN(SDValue Op,
case Intrinsic::mips_binsli_h: case Intrinsic::mips_binsli_h:
case Intrinsic::mips_binsli_w: case Intrinsic::mips_binsli_w:
case Intrinsic::mips_binsli_d: { case Intrinsic::mips_binsli_d: {
// binsli_x(IfClear, IfSet, nbits) -> (vselect LBitsMask, IfSet, IfClear)
EVT VecTy = Op->getValueType(0); EVT VecTy = Op->getValueType(0);
EVT EltTy = VecTy.getVectorElementType(); EVT EltTy = VecTy.getVectorElementType();
APInt Mask = APInt::getHighBitsSet(EltTy.getSizeInBits(), APInt Mask = APInt::getHighBitsSet(EltTy.getSizeInBits(),
Op->getConstantOperandVal(3)); Op->getConstantOperandVal(3));
return DAG.getNode(ISD::VSELECT, DL, VecTy, return DAG.getNode(ISD::VSELECT, DL, VecTy,
DAG.getConstant(Mask, VecTy, true), Op->getOperand(1), DAG.getConstant(Mask, VecTy, true), Op->getOperand(2),
Op->getOperand(2)); Op->getOperand(1));
} }
case Intrinsic::mips_binsri_b: case Intrinsic::mips_binsri_b:
case Intrinsic::mips_binsri_h: case Intrinsic::mips_binsri_h:
case Intrinsic::mips_binsri_w: case Intrinsic::mips_binsri_w:
case Intrinsic::mips_binsri_d: { case Intrinsic::mips_binsri_d: {
// binsri_x(IfClear, IfSet, nbits) -> (vselect RBitsMask, IfSet, IfClear)
EVT VecTy = Op->getValueType(0); EVT VecTy = Op->getValueType(0);
EVT EltTy = VecTy.getVectorElementType(); EVT EltTy = VecTy.getVectorElementType();
APInt Mask = APInt::getLowBitsSet(EltTy.getSizeInBits(), APInt Mask = APInt::getLowBitsSet(EltTy.getSizeInBits(),
Op->getConstantOperandVal(3)); Op->getConstantOperandVal(3));
return DAG.getNode(ISD::VSELECT, DL, VecTy, return DAG.getNode(ISD::VSELECT, DL, VecTy,
DAG.getConstant(Mask, VecTy, true), Op->getOperand(1), DAG.getConstant(Mask, VecTy, true), Op->getOperand(2),
Op->getOperand(2)); Op->getOperand(1));
} }
case Intrinsic::mips_bmnz_v: case Intrinsic::mips_bmnz_v:
return DAG.getNode(ISD::VSELECT, DL, Op->getValueType(0), Op->getOperand(3), return DAG.getNode(ISD::VSELECT, DL, Op->getValueType(0), Op->getOperand(3),
@ -1520,13 +1522,15 @@ SDValue MipsSETargetLowering::lowerINTRINSIC_WO_CHAIN(SDValue Op,
return DAG.getNode(MipsISD::VANY_NONZERO, DL, Op->getValueType(0), return DAG.getNode(MipsISD::VANY_NONZERO, DL, Op->getValueType(0),
Op->getOperand(1)); Op->getOperand(1));
case Intrinsic::mips_bsel_v: case Intrinsic::mips_bsel_v:
// bsel_v(Mask, IfClear, IfSet) -> (vselect Mask, IfSet, IfClear)
return DAG.getNode(ISD::VSELECT, DL, Op->getValueType(0), return DAG.getNode(ISD::VSELECT, DL, Op->getValueType(0),
Op->getOperand(1), Op->getOperand(2), Op->getOperand(1), Op->getOperand(3),
Op->getOperand(3)); Op->getOperand(2));
case Intrinsic::mips_bseli_b: case Intrinsic::mips_bseli_b:
// bseli_v(Mask, IfClear, IfSet) -> (vselect Mask, IfSet, IfClear)
return DAG.getNode(ISD::VSELECT, DL, Op->getValueType(0), return DAG.getNode(ISD::VSELECT, DL, Op->getValueType(0),
Op->getOperand(1), Op->getOperand(2), Op->getOperand(1), lowerMSASplatImm(Op, 3, DAG),
lowerMSASplatImm(Op, 3, DAG)); Op->getOperand(2));
case Intrinsic::mips_bset_b: case Intrinsic::mips_bset_b:
case Intrinsic::mips_bset_h: case Intrinsic::mips_bset_h:
case Intrinsic::mips_bset_w: case Intrinsic::mips_bset_w:

View File

@ -990,9 +990,10 @@ define void @bsel_v16i8(<16 x i8>* %c, <16 x i8>* %a, <16 x i8>* %b, <16 x i8>*
%6 = and <16 x i8> %2, %4 %6 = and <16 x i8> %2, %4
%7 = or <16 x i8> %5, %6 %7 = or <16 x i8> %5, %6
; bmnz is the same operation ; bmnz is the same operation
; CHECK-DAG: bmnz.v [[R1]], [[R2]], [[R3]] ; (vselect Mask, IfSet, IfClr) -> (BMNZ IfClr, IfSet, Mask)
; CHECK-DAG: bmnz.v [[R2]], [[R1]], [[R3]]
store <16 x i8> %7, <16 x i8>* %c store <16 x i8> %7, <16 x i8>* %c
; CHECK-DAG: st.b [[R1]], 0($4) ; CHECK-DAG: st.b [[R2]], 0($4)
ret void ret void
; CHECK: .size bsel_v16i8 ; CHECK: .size bsel_v16i8

View File

@ -761,7 +761,8 @@ define void @bsel_s_v8i16(<8 x i16>* %d, <8 x i16>* %a, <8 x i16>* %b,
%4 = icmp sgt <8 x i16> %1, %2 %4 = icmp sgt <8 x i16> %1, %2
; CHECK-DAG: clt_s.h [[R4:\$w[0-9]+]], [[R2]], [[R1]] ; CHECK-DAG: clt_s.h [[R4:\$w[0-9]+]], [[R2]], [[R1]]
%5 = select <8 x i1> %4, <8 x i16> %1, <8 x i16> %3 %5 = select <8 x i1> %4, <8 x i16> %1, <8 x i16> %3
; CHECK-DAG: bsel.v [[R4]], [[R1]], [[R3]] ; Note that IfSet and IfClr are swapped since the condition is inverted
; CHECK-DAG: bsel.v [[R4]], [[R3]], [[R1]]
store <8 x i16> %5, <8 x i16>* %d store <8 x i16> %5, <8 x i16>* %d
; CHECK-DAG: st.h [[R4]], 0($4) ; CHECK-DAG: st.h [[R4]], 0($4)
@ -782,7 +783,8 @@ define void @bsel_s_v4i32(<4 x i32>* %d, <4 x i32>* %a, <4 x i32>* %b,
%4 = icmp sgt <4 x i32> %1, %2 %4 = icmp sgt <4 x i32> %1, %2
; CHECK-DAG: clt_s.w [[R4:\$w[0-9]+]], [[R2]], [[R1]] ; CHECK-DAG: clt_s.w [[R4:\$w[0-9]+]], [[R2]], [[R1]]
%5 = select <4 x i1> %4, <4 x i32> %1, <4 x i32> %3 %5 = select <4 x i1> %4, <4 x i32> %1, <4 x i32> %3
; CHECK-DAG: bsel.v [[R4]], [[R1]], [[R3]] ; Note that IfSet and IfClr are swapped since the condition is inverted
; CHECK-DAG: bsel.v [[R4]], [[R3]], [[R1]]
store <4 x i32> %5, <4 x i32>* %d store <4 x i32> %5, <4 x i32>* %d
; CHECK-DAG: st.w [[R4]], 0($4) ; CHECK-DAG: st.w [[R4]], 0($4)
@ -803,7 +805,8 @@ define void @bsel_s_v2i64(<2 x i64>* %d, <2 x i64>* %a, <2 x i64>* %b,
%4 = icmp sgt <2 x i64> %1, %2 %4 = icmp sgt <2 x i64> %1, %2
; CHECK-DAG: clt_s.d [[R4:\$w[0-9]+]], [[R2]], [[R1]] ; CHECK-DAG: clt_s.d [[R4:\$w[0-9]+]], [[R2]], [[R1]]
%5 = select <2 x i1> %4, <2 x i64> %1, <2 x i64> %3 %5 = select <2 x i1> %4, <2 x i64> %1, <2 x i64> %3
; CHECK-DAG: bsel.v [[R4]], [[R1]], [[R3]] ; Note that IfSet and IfClr are swapped since the condition is inverted
; CHECK-DAG: bsel.v [[R4]], [[R3]], [[R1]]
store <2 x i64> %5, <2 x i64>* %d store <2 x i64> %5, <2 x i64>* %d
; CHECK-DAG: st.d [[R4]], 0($4) ; CHECK-DAG: st.d [[R4]], 0($4)
@ -846,7 +849,8 @@ define void @bsel_u_v8i16(<8 x i16>* %d, <8 x i16>* %a, <8 x i16>* %b,
%4 = icmp ugt <8 x i16> %1, %2 %4 = icmp ugt <8 x i16> %1, %2
; CHECK-DAG: clt_u.h [[R4:\$w[0-9]+]], [[R2]], [[R1]] ; CHECK-DAG: clt_u.h [[R4:\$w[0-9]+]], [[R2]], [[R1]]
%5 = select <8 x i1> %4, <8 x i16> %1, <8 x i16> %3 %5 = select <8 x i1> %4, <8 x i16> %1, <8 x i16> %3
; CHECK-DAG: bsel.v [[R4]], [[R1]], [[R3]] ; Note that IfSet and IfClr are swapped since the condition is inverted
; CHECK-DAG: bsel.v [[R4]], [[R3]], [[R1]]
store <8 x i16> %5, <8 x i16>* %d store <8 x i16> %5, <8 x i16>* %d
; CHECK-DAG: st.h [[R4]], 0($4) ; CHECK-DAG: st.h [[R4]], 0($4)
@ -867,7 +871,8 @@ define void @bsel_u_v4i32(<4 x i32>* %d, <4 x i32>* %a, <4 x i32>* %b,
%4 = icmp ugt <4 x i32> %1, %2 %4 = icmp ugt <4 x i32> %1, %2
; CHECK-DAG: clt_u.w [[R4:\$w[0-9]+]], [[R2]], [[R1]] ; CHECK-DAG: clt_u.w [[R4:\$w[0-9]+]], [[R2]], [[R1]]
%5 = select <4 x i1> %4, <4 x i32> %1, <4 x i32> %3 %5 = select <4 x i1> %4, <4 x i32> %1, <4 x i32> %3
; CHECK-DAG: bsel.v [[R4]], [[R1]], [[R3]] ; Note that IfSet and IfClr are swapped since the condition is inverted
; CHECK-DAG: bsel.v [[R4]], [[R3]], [[R1]]
store <4 x i32> %5, <4 x i32>* %d store <4 x i32> %5, <4 x i32>* %d
; CHECK-DAG: st.w [[R4]], 0($4) ; CHECK-DAG: st.w [[R4]], 0($4)
@ -888,7 +893,8 @@ define void @bsel_u_v2i64(<2 x i64>* %d, <2 x i64>* %a, <2 x i64>* %b,
%4 = icmp ugt <2 x i64> %1, %2 %4 = icmp ugt <2 x i64> %1, %2
; CHECK-DAG: clt_u.d [[R4:\$w[0-9]+]], [[R2]], [[R1]] ; CHECK-DAG: clt_u.d [[R4:\$w[0-9]+]], [[R2]], [[R1]]
%5 = select <2 x i1> %4, <2 x i64> %1, <2 x i64> %3 %5 = select <2 x i1> %4, <2 x i64> %1, <2 x i64> %3
; CHECK-DAG: bsel.v [[R4]], [[R1]], [[R3]] ; Note that IfSet and IfClr are swapped since the condition is inverted
; CHECK-DAG: bsel.v [[R4]], [[R3]], [[R1]]
store <2 x i64> %5, <2 x i64>* %d store <2 x i64> %5, <2 x i64>* %d
; CHECK-DAG: st.d [[R4]], 0($4) ; CHECK-DAG: st.d [[R4]], 0($4)
@ -906,7 +912,7 @@ define void @bseli_s_v16i8(<16 x i8>* %d, <16 x i8>* %a, <16 x i8>* %b,
; CHECK-DAG: ld.b [[R2:\$w[0-9]+]], 0($6) ; CHECK-DAG: ld.b [[R2:\$w[0-9]+]], 0($6)
%3 = icmp sgt <16 x i8> %1, %2 %3 = icmp sgt <16 x i8> %1, %2
; CHECK-DAG: clt_s.b [[R4:\$w[0-9]+]], [[R2]], [[R1]] ; CHECK-DAG: clt_s.b [[R4:\$w[0-9]+]], [[R2]], [[R1]]
%4 = select <16 x i1> %3, <16 x i8> %1, <16 x i8> <i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1> %4 = select <16 x i1> %3, <16 x i8> <i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1>, <16 x i8> %1
; CHECK-DAG: bseli.b [[R4]], [[R1]], 1 ; CHECK-DAG: bseli.b [[R4]], [[R1]], 1
store <16 x i8> %4, <16 x i8>* %d store <16 x i8> %4, <16 x i8>* %d
; CHECK-DAG: st.b [[R4]], 0($4) ; CHECK-DAG: st.b [[R4]], 0($4)
@ -925,7 +931,7 @@ define void @bseli_s_v8i16(<8 x i16>* %d, <8 x i16>* %a, <8 x i16>* %b,
; CHECK-DAG: ld.h [[R2:\$w[0-9]+]], 0($6) ; CHECK-DAG: ld.h [[R2:\$w[0-9]+]], 0($6)
%3 = icmp sgt <8 x i16> %1, %2 %3 = icmp sgt <8 x i16> %1, %2
; CHECK-DAG: clt_s.h [[R4:\$w[0-9]+]], [[R2]], [[R1]] ; CHECK-DAG: clt_s.h [[R4:\$w[0-9]+]], [[R2]], [[R1]]
%4 = select <8 x i1> %3, <8 x i16> %1, <8 x i16> <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1> %4 = select <8 x i1> %3, <8 x i16> <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>, <8 x i16> %1
; CHECK-DAG: ldi.h [[R3:\$w[0-9]+]], 1 ; CHECK-DAG: ldi.h [[R3:\$w[0-9]+]], 1
; CHECK-DAG: bsel.v [[R4]], [[R1]], [[R3]] ; CHECK-DAG: bsel.v [[R4]], [[R1]], [[R3]]
store <8 x i16> %4, <8 x i16>* %d store <8 x i16> %4, <8 x i16>* %d
@ -945,7 +951,7 @@ define void @bseli_s_v4i32(<4 x i32>* %d, <4 x i32>* %a, <4 x i32>* %b,
; CHECK-DAG: ld.w [[R2:\$w[0-9]+]], 0($6) ; CHECK-DAG: ld.w [[R2:\$w[0-9]+]], 0($6)
%3 = icmp sgt <4 x i32> %1, %2 %3 = icmp sgt <4 x i32> %1, %2
; CHECK-DAG: clt_s.w [[R4:\$w[0-9]+]], [[R2]], [[R1]] ; CHECK-DAG: clt_s.w [[R4:\$w[0-9]+]], [[R2]], [[R1]]
%4 = select <4 x i1> %3, <4 x i32> %1, <4 x i32> <i32 1, i32 1, i32 1, i32 1> %4 = select <4 x i1> %3, <4 x i32> <i32 1, i32 1, i32 1, i32 1>, <4 x i32> %1
; CHECK-DAG: ldi.w [[R3:\$w[0-9]+]], 1 ; CHECK-DAG: ldi.w [[R3:\$w[0-9]+]], 1
; CHECK-DAG: bsel.v [[R4]], [[R1]], [[R3]] ; CHECK-DAG: bsel.v [[R4]], [[R1]], [[R3]]
store <4 x i32> %4, <4 x i32>* %d store <4 x i32> %4, <4 x i32>* %d
@ -965,7 +971,7 @@ define void @bseli_s_v2i64(<2 x i64>* %d, <2 x i64>* %a, <2 x i64>* %b,
; CHECK-DAG: ld.d [[R2:\$w[0-9]+]], 0($6) ; CHECK-DAG: ld.d [[R2:\$w[0-9]+]], 0($6)
%3 = icmp sgt <2 x i64> %1, %2 %3 = icmp sgt <2 x i64> %1, %2
; CHECK-DAG: clt_s.d [[R4:\$w[0-9]+]], [[R2]], [[R1]] ; CHECK-DAG: clt_s.d [[R4:\$w[0-9]+]], [[R2]], [[R1]]
%4 = select <2 x i1> %3, <2 x i64> %1, <2 x i64> <i64 1, i64 1> %4 = select <2 x i1> %3, <2 x i64> <i64 1, i64 1>, <2 x i64> %1
; CHECK-DAG: ldi.d [[R3:\$w[0-9]+]], 1 ; CHECK-DAG: ldi.d [[R3:\$w[0-9]+]], 1
; CHECK-DAG: bsel.v [[R4]], [[R1]], [[R3]] ; CHECK-DAG: bsel.v [[R4]], [[R1]], [[R3]]
store <2 x i64> %4, <2 x i64>* %d store <2 x i64> %4, <2 x i64>* %d
@ -985,7 +991,7 @@ define void @bseli_u_v16i8(<16 x i8>* %d, <16 x i8>* %a, <16 x i8>* %b,
; CHECK-DAG: ld.b [[R2:\$w[0-9]+]], 0($6) ; CHECK-DAG: ld.b [[R2:\$w[0-9]+]], 0($6)
%3 = icmp ugt <16 x i8> %1, %2 %3 = icmp ugt <16 x i8> %1, %2
; CHECK-DAG: clt_u.b [[R4:\$w[0-9]+]], [[R2]], [[R1]] ; CHECK-DAG: clt_u.b [[R4:\$w[0-9]+]], [[R2]], [[R1]]
%4 = select <16 x i1> %3, <16 x i8> %1, <16 x i8> <i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1> %4 = select <16 x i1> %3, <16 x i8> <i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1>, <16 x i8> %1
; CHECK-DAG: bseli.b [[R4]], [[R1]], 1 ; CHECK-DAG: bseli.b [[R4]], [[R1]], 1
store <16 x i8> %4, <16 x i8>* %d store <16 x i8> %4, <16 x i8>* %d
; CHECK-DAG: st.b [[R4]], 0($4) ; CHECK-DAG: st.b [[R4]], 0($4)
@ -1004,7 +1010,7 @@ define void @bseli_u_v8i16(<8 x i16>* %d, <8 x i16>* %a, <8 x i16>* %b,
; CHECK-DAG: ld.h [[R2:\$w[0-9]+]], 0($6) ; CHECK-DAG: ld.h [[R2:\$w[0-9]+]], 0($6)
%3 = icmp ugt <8 x i16> %1, %2 %3 = icmp ugt <8 x i16> %1, %2
; CHECK-DAG: clt_u.h [[R4:\$w[0-9]+]], [[R2]], [[R1]] ; CHECK-DAG: clt_u.h [[R4:\$w[0-9]+]], [[R2]], [[R1]]
%4 = select <8 x i1> %3, <8 x i16> %1, <8 x i16> <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1> %4 = select <8 x i1> %3, <8 x i16> <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>, <8 x i16> %1
; CHECK-DAG: ldi.h [[R3:\$w[0-9]+]], 1 ; CHECK-DAG: ldi.h [[R3:\$w[0-9]+]], 1
; CHECK-DAG: bsel.v [[R4]], [[R1]], [[R3]] ; CHECK-DAG: bsel.v [[R4]], [[R1]], [[R3]]
store <8 x i16> %4, <8 x i16>* %d store <8 x i16> %4, <8 x i16>* %d
@ -1024,7 +1030,7 @@ define void @bseli_u_v4i32(<4 x i32>* %d, <4 x i32>* %a, <4 x i32>* %b,
; CHECK-DAG: ld.w [[R2:\$w[0-9]+]], 0($6) ; CHECK-DAG: ld.w [[R2:\$w[0-9]+]], 0($6)
%3 = icmp ugt <4 x i32> %1, %2 %3 = icmp ugt <4 x i32> %1, %2
; CHECK-DAG: clt_u.w [[R4:\$w[0-9]+]], [[R2]], [[R1]] ; CHECK-DAG: clt_u.w [[R4:\$w[0-9]+]], [[R2]], [[R1]]
%4 = select <4 x i1> %3, <4 x i32> %1, <4 x i32> <i32 1, i32 1, i32 1, i32 1> %4 = select <4 x i1> %3, <4 x i32> <i32 1, i32 1, i32 1, i32 1>, <4 x i32> %1
; CHECK-DAG: ldi.w [[R3:\$w[0-9]+]], 1 ; CHECK-DAG: ldi.w [[R3:\$w[0-9]+]], 1
; CHECK-DAG: bsel.v [[R4]], [[R1]], [[R3]] ; CHECK-DAG: bsel.v [[R4]], [[R1]], [[R3]]
store <4 x i32> %4, <4 x i32>* %d store <4 x i32> %4, <4 x i32>* %d
@ -1044,7 +1050,7 @@ define void @bseli_u_v2i64(<2 x i64>* %d, <2 x i64>* %a, <2 x i64>* %b,
; CHECK-DAG: ld.d [[R2:\$w[0-9]+]], 0($6) ; CHECK-DAG: ld.d [[R2:\$w[0-9]+]], 0($6)
%3 = icmp ugt <2 x i64> %1, %2 %3 = icmp ugt <2 x i64> %1, %2
; CHECK-DAG: clt_u.d [[R4:\$w[0-9]+]], [[R2]], [[R1]] ; CHECK-DAG: clt_u.d [[R4:\$w[0-9]+]], [[R2]], [[R1]]
%4 = select <2 x i1> %3, <2 x i64> %1, <2 x i64> <i64 1, i64 1> %4 = select <2 x i1> %3, <2 x i64> <i64 1, i64 1>, <2 x i64> %1
; CHECK-DAG: ldi.d [[R3:\$w[0-9]+]], 1 ; CHECK-DAG: ldi.d [[R3:\$w[0-9]+]], 1
; CHECK-DAG: bsel.v [[R4]], [[R1]], [[R3]] ; CHECK-DAG: bsel.v [[R4]], [[R1]], [[R3]]
store <2 x i64> %4, <2 x i64>* %d store <2 x i64> %4, <2 x i64>* %d

View File

@ -525,7 +525,8 @@ define void @bsel_v4f32(<4 x float>* %d, <4 x float>* %a, <4 x float>* %b,
%4 = fcmp ogt <4 x float> %1, %2 %4 = fcmp ogt <4 x float> %1, %2
; CHECK-DAG: fclt.w [[R4:\$w[0-9]+]], [[R2]], [[R1]] ; CHECK-DAG: fclt.w [[R4:\$w[0-9]+]], [[R2]], [[R1]]
%5 = select <4 x i1> %4, <4 x float> %1, <4 x float> %3 %5 = select <4 x i1> %4, <4 x float> %1, <4 x float> %3
; CHECK-DAG: bsel.v [[R4]], [[R1]], [[R3]] ; Note that IfSet and IfClr are swapped since the condition is inverted
; CHECK-DAG: bsel.v [[R4]], [[R3]], [[R1]]
store <4 x float> %5, <4 x float>* %d store <4 x float> %5, <4 x float>* %d
; CHECK-DAG: st.w [[R4]], 0($4) ; CHECK-DAG: st.w [[R4]], 0($4)
@ -546,7 +547,8 @@ define void @bsel_v2f64(<2 x double>* %d, <2 x double>* %a, <2 x double>* %b,
%4 = fcmp ogt <2 x double> %1, %2 %4 = fcmp ogt <2 x double> %1, %2
; CHECK-DAG: fclt.d [[R4:\$w[0-9]+]], [[R2]], [[R1]] ; CHECK-DAG: fclt.d [[R4:\$w[0-9]+]], [[R2]], [[R1]]
%5 = select <2 x i1> %4, <2 x double> %1, <2 x double> %3 %5 = select <2 x i1> %4, <2 x double> %1, <2 x double> %3
; CHECK-DAG: bsel.v [[R4]], [[R1]], [[R3]] ; Note that IfSet and IfClr are swapped since the condition is inverted
; CHECK-DAG: bsel.v [[R4]], [[R3]], [[R1]]
store <2 x double> %5, <2 x double>* %d store <2 x double> %5, <2 x double>* %d
; CHECK-DAG: st.d [[R4]], 0($4) ; CHECK-DAG: st.d [[R4]], 0($4)
@ -565,7 +567,8 @@ define void @bseli_v4f32(<4 x float>* %d, <4 x float>* %a, <4 x float>* %b,
%3 = fcmp ogt <4 x float> %1, %2 %3 = fcmp ogt <4 x float> %1, %2
; CHECK-DAG: fclt.w [[R4:\$w[0-9]+]], [[R2]], [[R1]] ; CHECK-DAG: fclt.w [[R4:\$w[0-9]+]], [[R2]], [[R1]]
%4 = select <4 x i1> %3, <4 x float> %1, <4 x float> zeroinitializer %4 = select <4 x i1> %3, <4 x float> %1, <4 x float> zeroinitializer
; CHECK-DAG: bsel.v [[R4]], [[R1]], [[R3:\$w[0-9]+]] ; Note that IfSet and IfClr are swapped since the condition is inverted
; CHECK-DAG: bsel.v [[R4]], [[R3:\$w[0-9]+]], [[R1]]
store <4 x float> %4, <4 x float>* %d store <4 x float> %4, <4 x float>* %d
; CHECK-DAG: st.w [[R4]], 0($4) ; CHECK-DAG: st.w [[R4]], 0($4)
@ -584,7 +587,8 @@ define void @bseli_v2f64(<2 x double>* %d, <2 x double>* %a, <2 x double>* %b,
%3 = fcmp ogt <2 x double> %1, %2 %3 = fcmp ogt <2 x double> %1, %2
; CHECK-DAG: fclt.d [[R4:\$w[0-9]+]], [[R2]], [[R1]] ; CHECK-DAG: fclt.d [[R4:\$w[0-9]+]], [[R2]], [[R1]]
%4 = select <2 x i1> %3, <2 x double> %1, <2 x double> zeroinitializer %4 = select <2 x i1> %3, <2 x double> %1, <2 x double> zeroinitializer
; CHECK-DAG: bsel.v [[R4]], [[R1]], [[R3:\$w[0-9]+]] ; Note that IfSet and IfClr are swapped since the condition is inverted
; CHECK-DAG: bsel.v [[R4]], [[R3:\$w[0-9]+]], [[R1]]
store <2 x double> %4, <2 x double>* %d store <2 x double> %4, <2 x double>* %d
; CHECK-DAG: st.d [[R4]], 0($4) ; CHECK-DAG: st.d [[R4]], 0($4)

View File

@ -431,9 +431,9 @@ entry:
; ANYENDIAN-DAG: ld.b [[R4:\$w[0-9]+]], 0([[R1]]) ; ANYENDIAN-DAG: ld.b [[R4:\$w[0-9]+]], 0([[R1]])
; ANYENDIAN-DAG: ld.b [[R5:\$w[0-9]+]], 0([[R2]]) ; ANYENDIAN-DAG: ld.b [[R5:\$w[0-9]+]], 0([[R2]])
; ANYENDIAN-DAG: ld.b [[R6:\$w[0-9]+]], 0([[R3]]) ; ANYENDIAN-DAG: ld.b [[R6:\$w[0-9]+]], 0([[R3]])
; bmnz.v is the same as bsel.v with wt and wd_in swapped ; bmnz.v is the same as bsel.v with (wd_in, wt, ws) -> (wt, ws, wd_in)
; ANYENDIAN-DAG: bmnz.v [[R6]], [[R5]], [[R4]] ; ANYENDIAN-DAG: bmnz.v [[R5]], [[R6]], [[R4]]
; ANYENDIAN-DAG: st.b [[R6]], 0( ; ANYENDIAN-DAG: st.b [[R5]], 0(
; ANYENDIAN: .size llvm_mips_bsel_v_b_test ; ANYENDIAN: .size llvm_mips_bsel_v_b_test
@llvm_mips_bsel_v_h_ARG1 = global <8 x i16> <i16 0, i16 1, i16 2, i16 3, i16 4, i16 5, i16 6, i16 7>, align 16 @llvm_mips_bsel_v_h_ARG1 = global <8 x i16> <i16 0, i16 1, i16 2, i16 3, i16 4, i16 5, i16 6, i16 7>, align 16
@ -462,9 +462,9 @@ entry:
; ANYENDIAN-DAG: ld.b [[R4:\$w[0-9]+]], 0([[R1]]) ; ANYENDIAN-DAG: ld.b [[R4:\$w[0-9]+]], 0([[R1]])
; ANYENDIAN-DAG: ld.b [[R5:\$w[0-9]+]], 0([[R2]]) ; ANYENDIAN-DAG: ld.b [[R5:\$w[0-9]+]], 0([[R2]])
; ANYENDIAN-DAG: ld.b [[R6:\$w[0-9]+]], 0([[R3]]) ; ANYENDIAN-DAG: ld.b [[R6:\$w[0-9]+]], 0([[R3]])
; bmnz.v is the same as bsel.v with wt and wd_in swapped ; bmnz.v is the same as bsel.v with (wd_in, wt, ws) -> (wt, ws, wd_in)
; ANYENDIAN-DAG: bmnz.v [[R6]], [[R5]], [[R4]] ; ANYENDIAN-DAG: bmnz.v [[R5]], [[R6]], [[R4]]
; ANYENDIAN-DAG: st.b [[R6]], 0( ; ANYENDIAN-DAG: st.b [[R5]], 0(
; ANYENDIAN: .size llvm_mips_bsel_v_h_test ; ANYENDIAN: .size llvm_mips_bsel_v_h_test
@llvm_mips_bsel_v_w_ARG1 = global <4 x i32> <i32 0, i32 1, i32 2, i32 3>, align 16 @llvm_mips_bsel_v_w_ARG1 = global <4 x i32> <i32 0, i32 1, i32 2, i32 3>, align 16
@ -493,9 +493,9 @@ entry:
; ANYENDIAN-DAG: ld.b [[R4:\$w[0-9]+]], 0([[R1]]) ; ANYENDIAN-DAG: ld.b [[R4:\$w[0-9]+]], 0([[R1]])
; ANYENDIAN-DAG: ld.b [[R5:\$w[0-9]+]], 0([[R2]]) ; ANYENDIAN-DAG: ld.b [[R5:\$w[0-9]+]], 0([[R2]])
; ANYENDIAN-DAG: ld.b [[R6:\$w[0-9]+]], 0([[R3]]) ; ANYENDIAN-DAG: ld.b [[R6:\$w[0-9]+]], 0([[R3]])
; bmnz.v is the same as bsel.v with wt and wd_in swapped ; bmnz.v is the same as bsel.v with (wd_in, wt, ws) -> (wt, ws, wd_in)
; ANYENDIAN-DAG: bmnz.v [[R6]], [[R5]], [[R4]] ; ANYENDIAN-DAG: bmnz.v [[R5]], [[R6]], [[R4]]
; ANYENDIAN-DAG: st.b [[R6]], 0( ; ANYENDIAN-DAG: st.b [[R5]], 0(
; ANYENDIAN: .size llvm_mips_bsel_v_w_test ; ANYENDIAN: .size llvm_mips_bsel_v_w_test
@llvm_mips_bsel_v_d_ARG1 = global <2 x i64> <i64 0, i64 1>, align 16 @llvm_mips_bsel_v_d_ARG1 = global <2 x i64> <i64 0, i64 1>, align 16
@ -524,9 +524,9 @@ entry:
; ANYENDIAN-DAG: ld.b [[R4:\$w[0-9]+]], 0([[R1]]) ; ANYENDIAN-DAG: ld.b [[R4:\$w[0-9]+]], 0([[R1]])
; ANYENDIAN-DAG: ld.b [[R5:\$w[0-9]+]], 0([[R2]]) ; ANYENDIAN-DAG: ld.b [[R5:\$w[0-9]+]], 0([[R2]])
; ANYENDIAN-DAG: ld.b [[R6:\$w[0-9]+]], 0([[R3]]) ; ANYENDIAN-DAG: ld.b [[R6:\$w[0-9]+]], 0([[R3]])
; bmnz.v is the same as bsel.v with wt and wd_in swapped ; bmnz.v is the same as bsel.v with (wd_in, wt, ws) -> (wt, ws, wd_in)
; ANYENDIAN-DAG: bmnz.v [[R6]], [[R5]], [[R4]] ; ANYENDIAN-DAG: bmnz.v [[R5]], [[R6]], [[R4]]
; ANYENDIAN-DAG: st.b [[R6]], 0( ; ANYENDIAN-DAG: st.b [[R5]], 0(
; ANYENDIAN: .size llvm_mips_bsel_v_d_test ; ANYENDIAN: .size llvm_mips_bsel_v_d_test
@llvm_mips_nor_v_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 @llvm_mips_nor_v_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