llvm.org GIT mirror llvm / 8306968
implement SplitVecOp_CONCAT_VECTORS, fixing the included testcase with SSE1. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@112171 91177308-0d34-0410-b5e6-96231b3b80d8 Chris Lattner 10 years ago
4 changed file(s) with 101 addition(s) and 69 deletion(s). Raw diff Collapse all Expand all
580580 SDValue SplitVecOp_EXTRACT_SUBVECTOR(SDNode *N);
581581 SDValue SplitVecOp_EXTRACT_VECTOR_ELT(SDNode *N);
582582 SDValue SplitVecOp_STORE(StoreSDNode *N, unsigned OpNo);
583 SDValue SplitVecOp_CONCAT_VECTORS(SDNode *N);
583584
584585 //===--------------------------------------------------------------------===//
585586 // Vector Widening Support: LegalizeVectorTypes.cpp
982982 case ISD::BIT_CONVERT: Res = SplitVecOp_BIT_CONVERT(N); break;
983983 case ISD::EXTRACT_SUBVECTOR: Res = SplitVecOp_EXTRACT_SUBVECTOR(N); break;
984984 case ISD::EXTRACT_VECTOR_ELT:Res = SplitVecOp_EXTRACT_VECTOR_ELT(N); break;
985 case ISD::CONCAT_VECTORS: Res = SplitVecOp_CONCAT_VECTORS(N); break;
985986 case ISD::STORE:
986987 Res = SplitVecOp_STORE(cast(N), OpNo);
987988 break;
10901091 return SDValue(DAG.UpdateNodeOperands(N, Lo, Idx), 0);
10911092 return SDValue(DAG.UpdateNodeOperands(N, Hi,
10921093 DAG.getConstant(IdxVal - LoElts,
1093 Idx.getValueType())),
1094 0);
1094 Idx.getValueType())), 0);
10951095 }
10961096
10971097 // Store the vector to the stack.
11121112 SDValue DAGTypeLegalizer::SplitVecOp_STORE(StoreSDNode *N, unsigned OpNo) {
11131113 assert(N->isUnindexed() && "Indexed store of vector?");
11141114 assert(OpNo == 1 && "Can only split the stored value");
1115 DebugLoc dl = N->getDebugLoc();
1115 DebugLoc DL = N->getDebugLoc();
11161116
11171117 bool isTruncating = N->isTruncatingStore();
11181118 SDValue Ch = N->getChain();
11311131 unsigned IncrementSize = LoMemVT.getSizeInBits()/8;
11321132
11331133 if (isTruncating)
1134 Lo = DAG.getTruncStore(Ch, dl, Lo, Ptr, N->getSrcValue(), SVOffset,
1134 Lo = DAG.getTruncStore(Ch, DL, Lo, Ptr, N->getSrcValue(), SVOffset,
11351135 LoMemVT, isVol, isNT, Alignment);
11361136 else
1137 Lo = DAG.getStore(Ch, dl, Lo, Ptr, N->getSrcValue(), SVOffset,
1137 Lo = DAG.getStore(Ch, DL, Lo, Ptr, N->getSrcValue(), SVOffset,
11381138 isVol, isNT, Alignment);
11391139
11401140 // Increment the pointer to the other half.
1141 Ptr = DAG.getNode(ISD::ADD, dl, Ptr.getValueType(), Ptr,
1141 Ptr = DAG.getNode(ISD::ADD, DL, Ptr.getValueType(), Ptr,
11421142 DAG.getIntPtrConstant(IncrementSize));
11431143 SVOffset += IncrementSize;
11441144
11451145 if (isTruncating)
1146 Hi = DAG.getTruncStore(Ch, dl, Hi, Ptr, N->getSrcValue(), SVOffset,
1146 Hi = DAG.getTruncStore(Ch, DL, Hi, Ptr, N->getSrcValue(), SVOffset,
11471147 HiMemVT, isVol, isNT, Alignment);
11481148 else
1149 Hi = DAG.getStore(Ch, dl, Hi, Ptr, N->getSrcValue(), SVOffset,
1149 Hi = DAG.getStore(Ch, DL, Hi, Ptr, N->getSrcValue(), SVOffset,
11501150 isVol, isNT, Alignment);
11511151
1152 return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo, Hi);
1152 return DAG.getNode(ISD::TokenFactor, DL, MVT::Other, Lo, Hi);
1153 }
1154
1155 SDValue DAGTypeLegalizer::SplitVecOp_CONCAT_VECTORS(SDNode *N) {
1156 DebugLoc DL = N->getDebugLoc();
1157
1158 // The input operands all must have the same type, and we know the result the
1159 // result type is valid. Convert this to a buildvector which extracts all the
1160 // input elements.
1161 // TODO: If the input elements are power-two vectors, we could convert this to
1162 // a new CONCAT_VECTORS node with elements that are half-wide.
1163 SmallVector Elts;
1164 EVT EltVT = N->getValueType(0).getVectorElementType();
1165 for (unsigned op = 0, e = N->getNumOperands(); op != e; ++op) {
1166 SDValue Op = N->getOperand(op);
1167 for (unsigned i = 0, e = Op.getValueType().getVectorNumElements();
1168 i != e; ++i) {
1169 Elts.push_back(DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, EltVT,
1170 Op, DAG.getIntPtrConstant(i)));
1171
1172 }
1173 }
1174
1175 return DAG.getNode(ISD::BUILD_VECTOR, DL, N->getValueType(0),
1176 &Elts[0], Elts.size());
11531177 }
11541178
11551179
22222246
22232247 // Check if we can load the element with one instruction
22242248 if (LdWidth <= NewVTWidth) {
2225 if (NewVT.isVector()) {
2226 if (NewVT != WidenVT) {
2227 assert(WidenWidth % NewVTWidth == 0);
2228 unsigned NumConcat = WidenWidth / NewVTWidth;
2229 SmallVector ConcatOps(NumConcat);
2230 SDValue UndefVal = DAG.getUNDEF(NewVT);
2231 ConcatOps[0] = LdOp;
2232 for (unsigned i = 1; i != NumConcat; ++i)
2233 ConcatOps[i] = UndefVal;
2234 return DAG.getNode(ISD::CONCAT_VECTORS, dl, WidenVT, &ConcatOps[0],
2235 NumConcat);
2236 } else
2237 return LdOp;
2238 } else {
2249 if (!NewVT.isVector()) {
22392250 unsigned NumElts = WidenWidth / NewVTWidth;
22402251 EVT NewVecVT = EVT::getVectorVT(*DAG.getContext(), NewVT, NumElts);
22412252 SDValue VecOp = DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, NewVecVT, LdOp);
22422253 return DAG.getNode(ISD::BIT_CONVERT, dl, WidenVT, VecOp);
22432254 }
2255 if (NewVT == WidenVT)
2256 return LdOp;
2257
2258 assert(WidenWidth % NewVTWidth == 0);
2259 unsigned NumConcat = WidenWidth / NewVTWidth;
2260 SmallVector ConcatOps(NumConcat);
2261 SDValue UndefVal = DAG.getUNDEF(NewVT);
2262 ConcatOps[0] = LdOp;
2263 for (unsigned i = 1; i != NumConcat; ++i)
2264 ConcatOps[i] = UndefVal;
2265 return DAG.getNode(ISD::CONCAT_VECTORS, dl, WidenVT, &ConcatOps[0],
2266 NumConcat);
22442267 }
22452268
22462269 // Load vector by using multiple loads from largest vector to scalar
22732296
22742297 // Build the vector from the loads operations
22752298 unsigned End = LdOps.size();
2276 if (LdOps[0].getValueType().isVector()) {
2277 // If the load contains vectors, build the vector using concat vector.
2278 // All of the vectors used to loads are power of 2 and the scalars load
2279 // can be combined to make a power of 2 vector.
2280 SmallVector ConcatOps(End);
2281 int i = End - 1;
2282 int Idx = End;
2283 EVT LdTy = LdOps[i].getValueType();
2284 // First combine the scalar loads to a vector
2285 if (!LdTy.isVector()) {
2286 for (--i; i >= 0; --i) {
2287 LdTy = LdOps[i].getValueType();
2288 if (LdTy.isVector())
2289 break;
2290 }
2291 ConcatOps[--Idx] = BuildVectorFromScalar(DAG, LdTy, LdOps, i+1, End);
2299 if (!LdOps[0].getValueType().isVector())
2300 // All the loads are scalar loads.
2301 return BuildVectorFromScalar(DAG, WidenVT, LdOps, 0, End);
2302
2303 // If the load contains vectors, build the vector using concat vector.
2304 // All of the vectors used to loads are power of 2 and the scalars load
2305 // can be combined to make a power of 2 vector.
2306 SmallVector ConcatOps(End);
2307 int i = End - 1;
2308 int Idx = End;
2309 EVT LdTy = LdOps[i].getValueType();
2310 // First combine the scalar loads to a vector
2311 if (!LdTy.isVector()) {
2312 for (--i; i >= 0; --i) {
2313 LdTy = LdOps[i].getValueType();
2314 if (LdTy.isVector())
2315 break;
2316 }
2317 ConcatOps[--Idx] = BuildVectorFromScalar(DAG, LdTy, LdOps, i+1, End);
2318 }
2319 ConcatOps[--Idx] = LdOps[i];
2320 for (--i; i >= 0; --i) {
2321 EVT NewLdTy = LdOps[i].getValueType();
2322 if (NewLdTy != LdTy) {
2323 // Create a larger vector
2324 ConcatOps[End-1] = DAG.getNode(ISD::CONCAT_VECTORS, dl, NewLdTy,
2325 &ConcatOps[Idx], End - Idx);
2326 Idx = End - 1;
2327 LdTy = NewLdTy;
22922328 }
22932329 ConcatOps[--Idx] = LdOps[i];
2294 for (--i; i >= 0; --i) {
2295 EVT NewLdTy = LdOps[i].getValueType();
2296 if (NewLdTy != LdTy) {
2297 // Create a larger vector
2298 ConcatOps[End-1] = DAG.getNode(ISD::CONCAT_VECTORS, dl, NewLdTy,
2299 &ConcatOps[Idx], End - Idx);
2300 Idx = End - 1;
2301 LdTy = NewLdTy;
2302 }
2303 ConcatOps[--Idx] = LdOps[i];
2304 }
2305
2306 if (WidenWidth != LdTy.getSizeInBits()*(End - Idx)) {
2307 // We need to fill the rest with undefs to build the vector
2308 unsigned NumOps = WidenWidth / LdTy.getSizeInBits();
2309 SmallVector WidenOps(NumOps);
2310 SDValue UndefVal = DAG.getUNDEF(LdTy);
2311 unsigned i = 0;
2312 for (; i != End-Idx; ++i)
2313 WidenOps[i] = ConcatOps[Idx+i];
2314 for (; i != NumOps; ++i)
2315 WidenOps[i] = UndefVal;
2316 return DAG.getNode(ISD::CONCAT_VECTORS, dl, WidenVT, &WidenOps[0],NumOps);
2317 } else
2318 return DAG.getNode(ISD::CONCAT_VECTORS, dl, WidenVT,
2319 &ConcatOps[Idx], End - Idx);
2320 } else // All the loads are scalar loads.
2321 return BuildVectorFromScalar(DAG, WidenVT, LdOps, 0, End);
2330 }
2331
2332 if (WidenWidth == LdTy.getSizeInBits()*(End - Idx))
2333 return DAG.getNode(ISD::CONCAT_VECTORS, dl, WidenVT,
2334 &ConcatOps[Idx], End - Idx);
2335
2336 // We need to fill the rest with undefs to build the vector
2337 unsigned NumOps = WidenWidth / LdTy.getSizeInBits();
2338 SmallVector WidenOps(NumOps);
2339 SDValue UndefVal = DAG.getUNDEF(LdTy);
2340 {
2341 unsigned i = 0;
2342 for (; i != End-Idx; ++i)
2343 WidenOps[i] = ConcatOps[Idx+i];
2344 for (; i != NumOps; ++i)
2345 WidenOps[i] = UndefVal;
2346 }
2347 return DAG.getNode(ISD::CONCAT_VECTORS, dl, WidenVT, &WidenOps[0],NumOps);
23222348 }
23232349
23242350 SDValue
13191319 // llvm-gcc has never done it right and no one has noticed, so this
13201320 // should be OK for now.
13211321 if (ValVT == MVT::f64 &&
1322 (Subtarget->is64Bit() && !Subtarget->hasSSE2())) {
1322 (Subtarget->is64Bit() && !Subtarget->hasSSE2()))
13231323 report_fatal_error("SSE2 register return with SSE2 disabled");
1324 }
13251324
13261325 // Returns in ST0/ST1 are handled specially: these are pushed as operands to
13271326 // the RET instruction and handled by the FP Stackifier.
55 ; CHECK: test1
66 ret <8 x i16> zeroinitializer
77 }
8
9 define <8 x i16> @test2(<8 x i32> %a) nounwind {
10 ; CHECK: test2
11 %c = trunc <8 x i32> %a to <8 x i16> ; <<8 x i16>> [#uses=1]
12 ret <8 x i16> %c
13 }