[llvm] r360068 - [GlobalISel] Handle <1 x T> vector return types properly.

Amara Emerson via llvm-commits llvm-commits at lists.llvm.org
Mon May 6 12:41:01 PDT 2019


Author: aemerson
Date: Mon May  6 12:41:01 2019
New Revision: 360068

URL: http://llvm.org/viewvc/llvm-project?rev=360068&view=rev
Log:
[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.

Added:
    llvm/trunk/test/CodeGen/AArch64/GlobalISel/ret-1x-vec.ll
Modified:
    llvm/trunk/lib/Target/AArch64/AArch64CallLowering.cpp

Modified: llvm/trunk/lib/Target/AArch64/AArch64CallLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64CallLowering.cpp?rev=360068&r1=360067&r2=360068&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AArch64/AArch64CallLowering.cpp (original)
+++ llvm/trunk/lib/Target/AArch64/AArch64CallLowering.cpp Mon May  6 12:41:01 2019
@@ -286,20 +286,40 @@ bool AArch64CallLowering::lowerReturn(Ma
           LLT OldLLT(MVT::getVT(CurArgInfo.Ty));
           CurArgInfo.Ty = EVT(NewVT).getTypeForEVT(Ctx);
           // Instead of an extend, we might have a vector type which needs
-          // padding with more elements, e.g. <2 x half> -> <4 x half>
-          if (NewVT.isVector() &&
-              NewLLT.getNumElements() > OldLLT.getNumElements()) {
-            // We don't handle VA types which are not exactly twice the size,
-            // but can easily be done in future.
-            if (NewLLT.getNumElements() != OldLLT.getNumElements() * 2) {
-              LLVM_DEBUG(dbgs() << "Outgoing vector ret has too many elts");
+          // padding with more elements, e.g. <2 x half> -> <4 x half>.
+          if (NewVT.isVector()) {
+            if (OldLLT.isVector()) {
+              if (NewLLT.getNumElements() > OldLLT.getNumElements()) {
+                // We don't handle VA types which are not exactly twice the
+                // size, but can easily be done in future.
+                if (NewLLT.getNumElements() != OldLLT.getNumElements() * 2) {
+                  LLVM_DEBUG(dbgs() << "Outgoing vector ret has too many elts");
+                  return false;
+                }
+                auto Undef = MIRBuilder.buildUndef({OldLLT});
+                CurVReg =
+                    MIRBuilder.buildMerge({NewLLT}, {CurVReg, Undef.getReg(0)})
+                        .getReg(0);
+              } else {
+                // Just do a vector extend.
+                CurVReg = MIRBuilder.buildInstr(ExtendOp, {NewLLT}, {CurVReg})
+                              .getReg(0);
+              }
+            } else if (NewLLT.getNumElements() == 2) {
+              // We need to pad a <1 x S> type to <2 x S>. Since we don't have
+              // <1 x S> vector types in GISel we use a build_vector instead
+              // of a vector merge/concat.
+              auto Undef = MIRBuilder.buildUndef({OldLLT});
+              CurVReg =
+                  MIRBuilder
+                      .buildBuildVector({NewLLT}, {CurVReg, Undef.getReg(0)})
+                      .getReg(0);
+            } else {
+              LLVM_DEBUG(dbgs() << "Could not handle ret ty");
               return false;
             }
-            auto Undef = MIRBuilder.buildUndef({OldLLT});
-            CurVReg =
-                MIRBuilder.buildMerge({NewLLT}, {CurVReg, Undef.getReg(0)})
-                    .getReg(0);
           } else {
+            // A scalar extend.
             CurVReg =
                 MIRBuilder.buildInstr(ExtendOp, {NewLLT}, {CurVReg}).getReg(0);
           }

Added: llvm/trunk/test/CodeGen/AArch64/GlobalISel/ret-1x-vec.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/GlobalISel/ret-1x-vec.ll?rev=360068&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/AArch64/GlobalISel/ret-1x-vec.ll (added)
+++ llvm/trunk/test/CodeGen/AArch64/GlobalISel/ret-1x-vec.ll Mon May  6 12:41:01 2019
@@ -0,0 +1,16 @@
+; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
+; RUN: llc -mtriple=aarch64-linux-gnu -O0 -global-isel -stop-after=irtranslator -o - %s | FileCheck %s
+
+define <1 x float> @foo(<1 x float> %v) {
+  ; CHECK-LABEL: name: foo
+  ; CHECK: bb.1 (%ir-block.0):
+  ; CHECK:   liveins: $d0
+  ; CHECK:   [[COPY:%[0-9]+]]:_(<2 x s32>) = COPY $d0
+  ; CHECK:   [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[COPY]](<2 x s32>)
+  ; CHECK:   [[COPY1:%[0-9]+]]:_(s32) = COPY [[UV]](s32)
+  ; CHECK:   [[DEF:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
+  ; CHECK:   [[BUILD_VECTOR:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[COPY1]](s32), [[DEF]](s32)
+  ; CHECK:   $d0 = COPY [[BUILD_VECTOR]](<2 x s32>)
+  ; CHECK:   RET_ReallyLR implicit $d0
+  ret <1 x float> %v
+}




More information about the llvm-commits mailing list