4242#include " llvm/TargetParser/Triple.h"
4343#include < algorithm>
4444#include < cassert>
45+ #include < cstddef>
4546#include < cstdint>
4647#include < iterator>
4748#include < utility>
@@ -59,6 +60,45 @@ static cl::opt<bool> NoDPLoadStore("mno-ldc1-sdc1", cl::init(false),
5960 " stores to their single precision "
6061 " counterparts" ));
6162
63+ // Widen the v2 vectors to the register width, i.e. v2i16 -> v8i16,
64+ // v2i32 -> v4i32, etc, to ensure the correct rail size is used, i.e.
65+ // INST.h for v16, INST.w for v32, INST.d for v64.
66+ TargetLoweringBase::LegalizeTypeAction
67+ MipsSETargetLowering::getPreferredVectorAction (MVT VT) const {
68+ if (this ->Subtarget .hasMSA ()) {
69+ switch (VT.SimpleTy ) {
70+ // Leave v2i1 vectors to be promoted to larger ones.
71+ // Other i1 types will be promoted by default.
72+ case MVT::v2i1:
73+ return TypePromoteInteger;
74+ break ;
75+ // 16-bit vector types (v2 and longer)
76+ case MVT::v2i8:
77+ // 32-bit vector types (v2 and longer)
78+ case MVT::v2i16:
79+ case MVT::v4i8:
80+ // 64-bit vector types (v2 and longer)
81+ case MVT::v2i32:
82+ case MVT::v4i16:
83+ case MVT::v8i8:
84+ return TypeWidenVector;
85+ break ;
86+ // Only word (.w) and doubleword (.d) are available for floating point
87+ // vectors. That means floating point vectors should be either v2f64
88+ // or v4f32.
89+ // Here we only explicitly widen the f32 types - f16 will be promoted
90+ // by default.
91+ case MVT::v2f32:
92+ case MVT::v3f32:
93+ return TypeWidenVector;
94+ // v2i64 is already 128-bit wide.
95+ default :
96+ break ;
97+ }
98+ }
99+ return TargetLoweringBase::getPreferredVectorAction (VT);
100+ }
101+
62102MipsSETargetLowering::MipsSETargetLowering (const MipsTargetMachine &TM,
63103 const MipsSubtarget &STI)
64104 : MipsTargetLowering(TM, STI) {
@@ -2929,8 +2969,14 @@ static SDValue lowerVECTOR_SHUFFLE_PCKOD(SDValue Op, EVT ResTy,
29292969// if the type is v8i16 and all the indices are less than 8 then the second
29302970// operand is unused and can be replaced with anything. We choose to replace it
29312971// with the used operand since this reduces the number of instructions overall.
2972+ //
2973+ // NOTE: SPLATI shuffle masks may contain UNDEFs, since isSPLATI() treats
2974+ // UNDEFs as same as SPLATI index.
2975+ // For other instances we use the last valid index if UNDEF is
2976+ // encountered.
29322977static SDValue lowerVECTOR_SHUFFLE_VSHF (SDValue Op, EVT ResTy,
29332978 const SmallVector<int , 16 > &Indices,
2979+ const bool isSPLATI,
29342980 SelectionDAG &DAG) {
29352981 SmallVector<SDValue, 16 > Ops;
29362982 SDValue Op0;
@@ -2942,6 +2988,9 @@ static SDValue lowerVECTOR_SHUFFLE_VSHF(SDValue Op, EVT ResTy,
29422988 SDLoc DL (Op);
29432989 int ResTyNumElts = ResTy.getVectorNumElements ();
29442990
2991+ assert (Indices[0 ] >= 0 &&
2992+ " shuffle mask starts with an UNDEF, which is not expected" );
2993+
29452994 for (int i = 0 ; i < ResTyNumElts; ++i) {
29462995 // Idx == -1 means UNDEF
29472996 int Idx = Indices[i];
@@ -2951,9 +3000,17 @@ static SDValue lowerVECTOR_SHUFFLE_VSHF(SDValue Op, EVT ResTy,
29513000 if (ResTyNumElts <= Idx && Idx < ResTyNumElts * 2 )
29523001 Using2ndVec = true ;
29533002 }
2954-
2955- for (int Idx : Indices)
3003+ int LastValidIndex = 0 ;
3004+ for (size_t i = 0 ; i < Indices.size (); i++) {
3005+ int Idx = Indices[i];
3006+ if (Idx < 0 ) {
3007+ // Continue using splati index or use the last valid index.
3008+ Idx = isSPLATI ? Indices[0 ] : LastValidIndex;
3009+ } else {
3010+ LastValidIndex = Idx;
3011+ }
29563012 Ops.push_back (DAG.getTargetConstant (Idx, DL, MaskEltTy));
3013+ }
29573014
29583015 SDValue MaskVec = DAG.getBuildVector (MaskVecTy, DL, Ops);
29593016
@@ -2996,7 +3053,7 @@ SDValue MipsSETargetLowering::lowerVECTOR_SHUFFLE(SDValue Op,
29963053 // splati.[bhwd] is preferable to the others but is matched from
29973054 // MipsISD::VSHF.
29983055 if (isVECTOR_SHUFFLE_SPLATI (Op, ResTy, Indices, DAG))
2999- return lowerVECTOR_SHUFFLE_VSHF (Op, ResTy, Indices, DAG);
3056+ return lowerVECTOR_SHUFFLE_VSHF (Op, ResTy, Indices, true , DAG);
30003057 SDValue Result;
30013058 if ((Result = lowerVECTOR_SHUFFLE_ILVEV (Op, ResTy, Indices, DAG)))
30023059 return Result;
@@ -3012,7 +3069,7 @@ SDValue MipsSETargetLowering::lowerVECTOR_SHUFFLE(SDValue Op,
30123069 return Result;
30133070 if ((Result = lowerVECTOR_SHUFFLE_SHF (Op, ResTy, Indices, DAG)))
30143071 return Result;
3015- return lowerVECTOR_SHUFFLE_VSHF (Op, ResTy, Indices, DAG);
3072+ return lowerVECTOR_SHUFFLE_VSHF (Op, ResTy, Indices, false , DAG);
30163073}
30173074
30183075MachineBasicBlock *
0 commit comments