llvm.org GIT mirror llvm / 4ad9ccc
[GlobalISel] Handle <1 x T> vector return types properly. After support for dealing with types that need to be extended in some way was added in r358032 we didn't correctly handle <1 x T> return types. These types don't have a GISel direct representation, instead we just see them as scalars. When we need to pad them into <2 x T> types however we need to use a G_BUILD_VECTOR instead of trying to do a G_CONCAT_VECTOR. This fixes PR41738. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@360068 91177308-0d34-0410-b5e6-96231b3b80d8 Amara Emerson 1 year, 5 months ago
2 changed file(s) with 47 addition(s) and 11 deletion(s). Raw diff Collapse all Expand all
285285 LLT OldLLT(MVT::getVT(CurArgInfo.Ty));
286286 CurArgInfo.Ty = EVT(NewVT).getTypeForEVT(Ctx);
287287 // Instead of an extend, we might have a vector type which needs
288 // padding with more elements, e.g. <2 x half> -> <4 x half>
289 if (NewVT.isVector() &&
290 NewLLT.getNumElements() > OldLLT.getNumElements()) {
291 // We don't handle VA types which are not exactly twice the size,
292 // but can easily be done in future.
293 if (NewLLT.getNumElements() != OldLLT.getNumElements() * 2) {
294 LLVM_DEBUG(dbgs() << "Outgoing vector ret has too many elts");
288 // padding with more elements, e.g. <2 x half> -> <4 x half>.
289 if (NewVT.isVector()) {
290 if (OldLLT.isVector()) {
291 if (NewLLT.getNumElements() > OldLLT.getNumElements()) {
292 // We don't handle VA types which are not exactly twice the
293 // size, but can easily be done in future.
294 if (NewLLT.getNumElements() != OldLLT.getNumElements() * 2) {
295 LLVM_DEBUG(dbgs() << "Outgoing vector ret has too many elts");
296 return false;
297 }
298 auto Undef = MIRBuilder.buildUndef({OldLLT});
299 CurVReg =
300 MIRBuilder.buildMerge({NewLLT}, {CurVReg, Undef.getReg(0)})
301 .getReg(0);
302 } else {
303 // Just do a vector extend.
304 CurVReg = MIRBuilder.buildInstr(ExtendOp, {NewLLT}, {CurVReg})
305 .getReg(0);
306 }
307 } else if (NewLLT.getNumElements() == 2) {
308 // We need to pad a <1 x S> type to <2 x S>. Since we don't have
309 // <1 x S> vector types in GISel we use a build_vector instead
310 // of a vector merge/concat.
311 auto Undef = MIRBuilder.buildUndef({OldLLT});
312 CurVReg =
313 MIRBuilder
314 .buildBuildVector({NewLLT}, {CurVReg, Undef.getReg(0)})
315 .getReg(0);
316 } else {
317 LLVM_DEBUG(dbgs() << "Could not handle ret ty");
295318 return false;
296319 }
297 auto Undef = MIRBuilder.buildUndef({OldLLT});
298 CurVReg =
299 MIRBuilder.buildMerge({NewLLT}, {CurVReg, Undef.getReg(0)})
300 .getReg(0);
301320 } else {
321 // A scalar extend.
302322 CurVReg =
303323 MIRBuilder.buildInstr(ExtendOp, {NewLLT}, {CurVReg}).getReg(0);
304324 }
0 ; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
1 ; RUN: llc -mtriple=aarch64-linux-gnu -O0 -global-isel -stop-after=irtranslator -o - %s | FileCheck %s
2
3 define <1 x float> @foo(<1 x float> %v) {
4 ; CHECK-LABEL: name: foo
5 ; CHECK: bb.1 (%ir-block.0):
6 ; CHECK: liveins: $d0
7 ; CHECK: [[COPY:%[0-9]+]]:_(<2 x s32>) = COPY $d0
8 ; CHECK: [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[COPY]](<2 x s32>)
9 ; CHECK: [[COPY1:%[0-9]+]]:_(s32) = COPY [[UV]](s32)
10 ; CHECK: [[DEF:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
11 ; CHECK: [[BUILD_VECTOR:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[COPY1]](s32), [[DEF]](s32)
12 ; CHECK: $d0 = COPY [[BUILD_VECTOR]](<2 x s32>)
13 ; CHECK: RET_ReallyLR implicit $d0
14 ret <1 x float> %v
15 }