llvm.org GIT mirror llvm / 52c50f5
[X86] Fix the inversion of low and high bits for the lowering of MUL_LOHI. Also add a few comments. <rdar://problem/17581756> git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@212808 91177308-0d34-0410-b5e6-96231b3b80d8 Quentin Colombet 5 years ago
2 changed file(s) with 41 addition(s) and 12 deletion(s). Raw diff Collapse all Expand all
1515515155 assert((VT == MVT::v4i32 && Subtarget->hasSSE2()) ||
1515615156 (VT == MVT::v8i32 && Subtarget->hasInt256()));
1515715157
15158 // Get the high parts.
15158 // PMULxD operations multiply each even value (starting at 0) of LHS with
15159 // the related value of RHS and produce a widen result.
15160 // E.g., PMULUDQ <4 x i32> , <4 x i32>
15161 // => <2 x i64>
15162 //
15163 // In other word, to have all the results, we need to perform two PMULxD:
15164 // 1. one with the even values.
15165 // 2. one with the odd values.
15166 // To achieve #2, with need to place the odd values at an even position.
15167 //
15168 // Place the odd value at an even position (basically, shift all values 1
15169 // step to the left):
1515915170 const int Mask[] = {1, -1, 3, -1, 5, -1, 7, -1};
15160 SDValue Hi0 = DAG.getVectorShuffle(VT, dl, Op0, Op0, Mask);
15161 SDValue Hi1 = DAG.getVectorShuffle(VT, dl, Op1, Op1, Mask);
15171 // =>
15172 SDValue Odd0 = DAG.getVectorShuffle(VT, dl, Op0, Op0, Mask);
15173 // =>
15174 SDValue Odd1 = DAG.getVectorShuffle(VT, dl, Op1, Op1, Mask);
1516215175
1516315176 // Emit two multiplies, one for the lower 2 ints and one for the higher 2
1516415177 // ints.
1516615179 bool IsSigned = Op->getOpcode() == ISD::SMUL_LOHI;
1516715180 unsigned Opcode =
1516815181 (!IsSigned || !Subtarget->hasSSE41()) ? X86ISD::PMULUDQ : X86ISD::PMULDQ;
15182 // PMULUDQ <4 x i32> , <4 x i32>
15183 // => <2 x i64>
1516915184 SDValue Mul1 = DAG.getNode(ISD::BITCAST, dl, VT,
1517015185 DAG.getNode(Opcode, dl, MulVT, Op0, Op1));
15186 // PMULUDQ <4 x i32> , <4 x i32>
15187 // => <2 x i64>
1517115188 SDValue Mul2 = DAG.getNode(ISD::BITCAST, dl, VT,
15172 DAG.getNode(Opcode, dl, MulVT, Hi0, Hi1));
15189 DAG.getNode(Opcode, dl, MulVT, Odd0, Odd1));
1517315190
1517415191 // Shuffle it back into the right order.
15192 // The internal representation is big endian.
15193 // In other words, a i64 bitcasted to 2 x i32 has its high part at index 0
15194 // and its low part at index 1.
15195 // Moreover, we have: Mul1 = ; Mul2 =
15196 // Vector index 0 1 ; 2 3
15197 // We want
15198 // Vector index 0 2 1 3
15199 // Since each element is seen as 2 x i32, we get:
15200 // high_mask[i] = 2 x vector_index[i]
15201 // low_mask[i] = 2 x vector_index[i] + 1
15202 // where vector_index = {0, Size/2, 1, Size/2 + 1, ...,
15203 // Size/2 - 1, Size/2 + Size/2 - 1}
15204 // where Size is the number of element of the final vector.
1517515205 SDValue Highs, Lows;
1517615206 if (VT == MVT::v8i32) {
15177 const int HighMask[] = {1, 9, 3, 11, 5, 13, 7, 15};
15207 const int HighMask[] = {0, 8, 2, 10, 4, 12, 6, 14};
1517815208 Highs = DAG.getVectorShuffle(VT, dl, Mul1, Mul2, HighMask);
15179 const int LowMask[] = {0, 8, 2, 10, 4, 12, 6, 14};
15209 const int LowMask[] = {1, 9, 3, 11, 5, 13, 7, 15};
1518015210 Lows = DAG.getVectorShuffle(VT, dl, Mul1, Mul2, LowMask);
1518115211 } else {
15182 const int HighMask[] = {1, 5, 3, 7};
15212 const int HighMask[] = {0, 4, 2, 6};
1518315213 Highs = DAG.getVectorShuffle(VT, dl, Mul1, Mul2, HighMask);
15184 const int LowMask[] = {0, 4, 2, 6};
15214 const int LowMask[] = {1, 5, 3, 7};
1518515215 Lows = DAG.getVectorShuffle(VT, dl, Mul1, Mul2, LowMask);
1518615216 }
1518715217
1519915229 Highs = DAG.getNode(ISD::SUB, dl, VT, Highs, Fixup);
1520015230 }
1520115231
15202 return DAG.getNode(ISD::MERGE_VALUES, dl, Op.getValueType(), Highs, Lows);
15232 // The low part of a MUL_LOHI is supposed to be the first value and the
15233 // high part the second value.
15234 return DAG.getNode(ISD::MERGE_VALUES, dl, Op.getValueType(), Lows, Highs);
1520315235 }
1520415236
1520515237 static SDValue LowerScalarImmediateShift(SDValue Op, SelectionDAG &DAG,
131131 ; SSE41: padd
132132
133133 ; SSE-LABEL: test8:
134 ; SSE: psrad $31
135 ; SSE: pand
136 ; SSE: paddd
137134 ; SSE: pmuludq
138135 ; SSE: pshufd $49
139136 ; SSE-NOT: pshufd $49