llvm.org GIT mirror llvm / e342c68
Merging r214923: ------------------------------------------------------------------------ r214923 | wschmidt | 2014-08-05 15:47:25 -0500 (Tue, 05 Aug 2014) | 12 lines [PowerPC] Swap arguments and adjust shift count for vsldoi on little endian Commits r213915 and r214718 fix recognition of shuffle masks for vmrg* and vpku*um instructions for a little-endian target, by swapping the input arguments. The vsldoi instruction requires similar treatment, and also needs its shift count adjusted for little endian. Reviewed by Ulrich Weigand. This is a bug fix candidate for release 3.5 (and hopefully the last of those for PowerPC). ------------------------------------------------------------------------ git-svn-id: https://llvm.org/svn/llvm-project/llvm/branches/release_35@214926 91177308-0d34-0410-b5e6-96231b3b80d8 Bill Schmidt 5 years ago
4 changed file(s) with 45 addition(s) and 18 deletion(s). Raw diff Collapse all Expand all
986986
987987 /// isVSLDOIShuffleMask - If this is a vsldoi shuffle mask, return the shift
988988 /// amount, otherwise return -1.
989 int PPC::isVSLDOIShuffleMask(SDNode *N, bool isUnary, SelectionDAG &DAG) {
989 /// The ShuffleKind distinguishes between big-endian operations with two
990 /// different inputs (0), either-endian operations with two identical inputs
991 /// (1), and little-endian operations with two different inputs (2). For the
992 /// latter, the input operands are swapped (see PPCInstrAltivec.td).
993 int PPC::isVSLDOIShuffleMask(SDNode *N, unsigned ShuffleKind,
994 SelectionDAG &DAG) {
990995 if (N->getValueType(0) != MVT::v16i8)
991996 return -1;
992997
10051010 if (ShiftAmt < i) return -1;
10061011
10071012 ShiftAmt -= i;
1008
1009 if (!isUnary) {
1013 bool isLE = DAG.getTarget().getSubtargetImpl()->getDataLayout()->
1014 isLittleEndian();
1015
1016 if ((ShuffleKind == 0 && !isLE) || (ShuffleKind == 2 && isLE)) {
10101017 // Check the rest of the elements to see if they are consecutive.
10111018 for (++i; i != 16; ++i)
10121019 if (!isConstantOrUndef(SVOp->getMaskElt(i), ShiftAmt+i))
10131020 return -1;
1014 } else {
1021 } else if (ShuffleKind == 1) {
10151022 // Check the rest of the elements to see if they are consecutive.
10161023 for (++i; i != 16; ++i)
10171024 if (!isConstantOrUndef(SVOp->getMaskElt(i), (ShiftAmt+i) & 15))
10181025 return -1;
1019 }
1026 } else
1027 return -1;
1028
1029 if (ShuffleKind == 2 && isLE)
1030 ShiftAmt = 16 - ShiftAmt;
10201031
10211032 return ShiftAmt;
10221033 }
60316042 PPC::isSplatShuffleMask(SVOp, 4) ||
60326043 PPC::isVPKUWUMShuffleMask(SVOp, 1, DAG) ||
60336044 PPC::isVPKUHUMShuffleMask(SVOp, 1, DAG) ||
6034 PPC::isVSLDOIShuffleMask(SVOp, true, DAG) != -1 ||
6045 PPC::isVSLDOIShuffleMask(SVOp, 1, DAG) != -1 ||
60356046 PPC::isVMRGLShuffleMask(SVOp, 1, 1, DAG) ||
60366047 PPC::isVMRGLShuffleMask(SVOp, 2, 1, DAG) ||
60376048 PPC::isVMRGLShuffleMask(SVOp, 4, 1, DAG) ||
60486059 unsigned int ShuffleKind = isLittleEndian ? 2 : 0;
60496060 if (PPC::isVPKUWUMShuffleMask(SVOp, ShuffleKind, DAG) ||
60506061 PPC::isVPKUHUMShuffleMask(SVOp, ShuffleKind, DAG) ||
6051 PPC::isVSLDOIShuffleMask(SVOp, false, DAG) != -1 ||
6062 PPC::isVSLDOIShuffleMask(SVOp, ShuffleKind, DAG) != -1 ||
60526063 PPC::isVMRGLShuffleMask(SVOp, 1, ShuffleKind, DAG) ||
60536064 PPC::isVMRGLShuffleMask(SVOp, 2, ShuffleKind, DAG) ||
60546065 PPC::isVMRGLShuffleMask(SVOp, 4, ShuffleKind, DAG) ||
314314 bool isVMRGHShuffleMask(ShuffleVectorSDNode *N, unsigned UnitSize,
315315 unsigned ShuffleKind, SelectionDAG &DAG);
316316
317 /// isVSLDOIShuffleMask - If this is a vsldoi shuffle mask, return the shift
318 /// amount, otherwise return -1.
319 int isVSLDOIShuffleMask(SDNode *N, bool isUnary, SelectionDAG &DAG);
317 /// isVSLDOIShuffleMask - If this is a vsldoi shuffle mask, return the
318 /// shift amount, otherwise return -1.
319 int isVSLDOIShuffleMask(SDNode *N, unsigned ShuffleKind,
320 SelectionDAG &DAG);
320321
321322 /// isSplatShuffleMask - Return true if the specified VECTOR_SHUFFLE operand
322323 /// specifies a splat of a single element that is suitable for input to
128128
129129
130130 def VSLDOI_get_imm : SDNodeXForm
131 return getI32Imm(PPC::isVSLDOIShuffleMask(N, false, *CurDAG));
131 return getI32Imm(PPC::isVSLDOIShuffleMask(N, 0, *CurDAG));
132132 }]>;
133133 def vsldoi_shuffle : PatFrag<(ops node:$lhs, node:$rhs),
134134 (vector_shuffle node:$lhs, node:$rhs), [{
135 return PPC::isVSLDOIShuffleMask(N, false, *CurDAG) != -1;
135 return PPC::isVSLDOIShuffleMask(N, 0, *CurDAG) != -1;
136136 }], VSLDOI_get_imm>;
137137
138138
139139 /// VSLDOI_unary* - These are used to match vsldoi(X,X), which is turned into
140140 /// vector_shuffle(X,undef,mask) by the dag combiner.
141141 def VSLDOI_unary_get_imm : SDNodeXForm
142 return getI32Imm(PPC::isVSLDOIShuffleMask(N, true, *CurDAG));
142 return getI32Imm(PPC::isVSLDOIShuffleMask(N, 1, *CurDAG));
143143 }]>;
144144 def vsldoi_unary_shuffle : PatFrag<(ops node:$lhs, node:$rhs),
145145 (vector_shuffle node:$lhs, node:$rhs), [{
146 return PPC::isVSLDOIShuffleMask(N, true, *CurDAG) != -1;
146 return PPC::isVSLDOIShuffleMask(N, 1, *CurDAG) != -1;
147147 }], VSLDOI_unary_get_imm>;
148
149
150 /// VSLDOI_swapped* - These fragments are provided for little-endian, where
151 /// the inputs must be swapped for correct semantics.
152 def VSLDOI_swapped_get_imm : SDNodeXForm
153 return getI32Imm(PPC::isVSLDOIShuffleMask(N, 2, *CurDAG));
154 }]>;
155 def vsldoi_swapped_shuffle : PatFrag<(ops node:$lhs, node:$rhs),
156 (vector_shuffle node:$lhs, node:$rhs), [{
157 return PPC::isVSLDOIShuffleMask(N, 2, *CurDAG) != -1;
158 }], VSLDOI_get_imm>;
148159
149160
150161 // VSPLT*_get_imm xform function: convert vector_shuffle mask to VSPLT* imm.
810821 def:Pat<(vpkuhum_unary_shuffle v16i8:$vA, undef),
811822 (VPKUHUM $vA, $vA)>;
812823
813 // Match vpkuwum(y,x), vpkuhum(y,x), i.e., swapped operands.
814 // These fragments are matched for little-endian, where the
815 // inputs must be swapped for correct semantics.
824 // Match vsldoi(y,x), vpkuwum(y,x), vpkuhum(y,x), i.e., swapped operands.
825 // These fragments are matched for little-endian, where the inputs must
826 // be swapped for correct semantics.
827 def:Pat<(vsldoi_swapped_shuffle:$in v16i8:$vA, v16i8:$vB),
828 (VSLDOI $vB, $vA, (VSLDOI_swapped_get_imm $in))>;
816829 def:Pat<(vpkuwum_swapped_shuffle v16i8:$vA, v16i8:$vB),
817830 (VPKUWUM $vB, $vA)>;
818831 def:Pat<(vpkuhum_swapped_shuffle v16i8:$vA, v16i8:$vB),
189189 %tmp = load <16 x i8>* %A
190190 %tmp2 = load <16 x i8>* %B
191191 %tmp3 = shufflevector <16 x i8> %tmp, <16 x i8> %tmp2, <16 x i32>
192 ; CHECK: vsldoi
192 ; CHECK: lvx [[REG1:[0-9]+]]
193 ; CHECK: lvx [[REG2:[0-9]+]]
194 ; CHECK: vsldoi [[REG3:[0-9]+]], [[REG2]], [[REG1]], 4
193195 store <16 x i8> %tmp3, <16 x i8>* %A
194196 ret void
195197 }