GlobalISel: Fix generic handling of single outgoing call arguments
authorMatt Arsenault <Matthew.Arsenault@amd.com>
Tue, 15 Dec 2020 15:39:27 +0000 (10:39 -0500)
committerMatt Arsenault <Matthew.Arsenault@amd.com>
Tue, 15 Dec 2020 22:00:27 +0000 (17:00 -0500)
Simply call the argument handler like is done for the incoming
case. This will allow removal of hacks in the AMDGPU call lowering in
a future change.

llvm/lib/CodeGen/GlobalISel/CallLowering.cpp

index 69ed775..c32811d 100644 (file)
@@ -241,12 +241,20 @@ bool CallLowering::handleAssignments(CCState &CCInfo,
     // we currently support.
     unsigned NumParts = TLI->getNumRegistersForCallingConv(
         F.getContext(), F.getCallingConv(), CurVT);
-    if (NumParts > 1) {
-      // For now only handle exact splits.
-      if (NewVT.getSizeInBits() * NumParts != CurVT.getSizeInBits())
+
+    if (NumParts == 1) {
+      // Try to use the register type if we couldn't assign the VT.
+      if (Handler.assignArg(i, NewVT, NewVT, CCValAssign::Full, Args[i],
+                            Args[i].Flags[0], CCInfo))
         return false;
+      continue;
     }
 
+    assert(NumParts > 1);
+    // For now only handle exact splits.
+    if (NewVT.getSizeInBits() * NumParts != CurVT.getSizeInBits())
+      return false;
+
     // For incoming arguments (physregs to vregs), we could have values in
     // physregs (or memlocs) which we want to extract and copy to vregs.
     // During this, we might have to deal with the LLT being split across
@@ -256,47 +264,36 @@ bool CallLowering::handleAssignments(CCState &CCInfo,
     // vreg with an LLT which we want to assign to a physical location, and
     // we might have to record that the value has to be split later.
     if (Handler.isIncomingArgumentHandler()) {
-      if (NumParts == 1) {
-        // Try to use the register type if we couldn't assign the VT.
+      // We're handling an incoming arg which is split over multiple regs.
+      // E.g. passing an s128 on AArch64.
+      ISD::ArgFlagsTy OrigFlags = Args[i].Flags[0];
+      Args[i].OrigRegs.push_back(Args[i].Regs[0]);
+      Args[i].Regs.clear();
+      Args[i].Flags.clear();
+      LLT NewLLT = getLLTForMVT(NewVT);
+      // For each split register, create and assign a vreg that will store
+      // the incoming component of the larger value. These will later be
+      // merged to form the final vreg.
+      for (unsigned Part = 0; Part < NumParts; ++Part) {
+        Register Reg =
+            MIRBuilder.getMRI()->createGenericVirtualRegister(NewLLT);
+        ISD::ArgFlagsTy Flags = OrigFlags;
+        if (Part == 0) {
+          Flags.setSplit();
+        } else {
+          Flags.setOrigAlign(Align(1));
+          if (Part == NumParts - 1)
+            Flags.setSplitEnd();
+        }
+        Args[i].Regs.push_back(Reg);
+        Args[i].Flags.push_back(Flags);
         if (Handler.assignArg(i, NewVT, NewVT, CCValAssign::Full, Args[i],
-                              Args[i].Flags[0], CCInfo))
+                              Args[i].Flags[Part], CCInfo)) {
+          // Still couldn't assign this smaller part type for some reason.
           return false;
-      } else {
-        // We're handling an incoming arg which is split over multiple regs.
-        // E.g. passing an s128 on AArch64.
-        ISD::ArgFlagsTy OrigFlags = Args[i].Flags[0];
-        Args[i].OrigRegs.push_back(Args[i].Regs[0]);
-        Args[i].Regs.clear();
-        Args[i].Flags.clear();
-        LLT NewLLT = getLLTForMVT(NewVT);
-        // For each split register, create and assign a vreg that will store
-        // the incoming component of the larger value. These will later be
-        // merged to form the final vreg.
-        for (unsigned Part = 0; Part < NumParts; ++Part) {
-          Register Reg =
-              MIRBuilder.getMRI()->createGenericVirtualRegister(NewLLT);
-          ISD::ArgFlagsTy Flags = OrigFlags;
-          if (Part == 0) {
-            Flags.setSplit();
-          } else {
-            Flags.setOrigAlign(Align(1));
-            if (Part == NumParts - 1)
-              Flags.setSplitEnd();
-          }
-          Args[i].Regs.push_back(Reg);
-          Args[i].Flags.push_back(Flags);
-          if (Handler.assignArg(i, NewVT, NewVT, CCValAssign::Full,
-                                Args[i], Args[i].Flags[Part], CCInfo)) {
-            // Still couldn't assign this smaller part type for some reason.
-            return false;
-          }
         }
       }
     } else {
-      // Handling an outgoing arg that might need to be split.
-      if (NumParts < 2)
-        return false; // Don't know how to deal with this type combination.
-
       // This type is passed via multiple registers in the calling convention.
       // We need to extract the individual parts.
       Register LargeReg = Args[i].Regs[0];