[llvm] r295973 - [ARM] GlobalISel: Lower call returns

Diana Picus via llvm-commits llvm-commits at lists.llvm.org
Thu Feb 23 06:18:43 PST 2017


Author: rovka
Date: Thu Feb 23 08:18:41 2017
New Revision: 295973

URL: http://llvm.org/viewvc/llvm-project?rev=295973&view=rev
Log:
[ARM] GlobalISel: Lower call returns

Introduce a common ValueHandler for call returns and formal arguments, and
inherit two different versions for handling the differences (at the moment the
only difference is the way physical registers are marked as used).

Modified:
    llvm/trunk/lib/Target/ARM/ARMCallLowering.cpp
    llvm/trunk/test/CodeGen/ARM/GlobalISel/arm-irtranslator.ll

Modified: llvm/trunk/lib/Target/ARM/ARMCallLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMCallLowering.cpp?rev=295973&r1=295972&r2=295973&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMCallLowering.cpp (original)
+++ llvm/trunk/lib/Target/ARM/ARMCallLowering.cpp Thu Feb 23 08:18:41 2017
@@ -175,9 +175,11 @@ bool ARMCallLowering::lowerReturn(Machin
 }
 
 namespace {
-struct FormalArgHandler : public CallLowering::ValueHandler {
-  FormalArgHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI,
-                   CCAssignFn AssignFn)
+/// Helper class for values coming in through an ABI boundary (used for handling
+/// formal arguments and call return values).
+struct IncomingValueHandler : public CallLowering::ValueHandler {
+  IncomingValueHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI,
+                       CCAssignFn AssignFn)
       : ValueHandler(MIRBuilder, MRI, AssignFn) {}
 
   unsigned getStackAddress(uint64_t Size, int64_t Offset,
@@ -204,8 +206,8 @@ struct FormalArgHandler : public CallLow
 
     if (VA.getLocInfo() == CCValAssign::SExt ||
         VA.getLocInfo() == CCValAssign::ZExt) {
-      // If the argument is zero- or sign-extended by the caller, its size
-      // becomes 4 bytes, so that's what we should load.
+      // If the value is zero- or sign-extended, its size becomes 4 bytes, so
+      // that's what we should load.
       Size = 4;
       assert(MRI.getType(ValVReg).isScalar() && "Only scalars supported atm");
       MRI.setType(ValVReg, LLT::scalar(32));
@@ -224,8 +226,9 @@ struct FormalArgHandler : public CallLow
     assert(VA.getValVT().getSizeInBits() <= 64 && "Unsupported value size");
     assert(VA.getLocVT().getSizeInBits() <= 64 && "Unsupported location size");
 
-    // The caller should handle all necesary extensions.
-    MIRBuilder.getMBB().addLiveIn(PhysReg);
+    // The necesary extensions are handled on the other side of the ABI
+    // boundary.
+    markPhysRegUsed(PhysReg);
     MIRBuilder.buildCopy(ValVReg, PhysReg);
   }
 
@@ -259,6 +262,21 @@ struct FormalArgHandler : public CallLow
 
     return 1;
   }
+
+  /// Marking a physical register as used is different between formal
+  /// parameters, where it's a basic block live-in, and call returns, where it's
+  /// an implicit-def of the call instruction.
+  virtual void markPhysRegUsed(unsigned PhysReg) = 0;
+};
+
+struct FormalArgHandler : public IncomingValueHandler {
+  FormalArgHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI,
+                   CCAssignFn AssignFn)
+      : IncomingValueHandler(MIRBuilder, MRI, AssignFn) {}
+
+  void markPhysRegUsed(unsigned PhysReg) override {
+    MIRBuilder.getMBB().addLiveIn(PhysReg);
+  }
 };
 } // End anonymous namespace
 
@@ -307,6 +325,20 @@ bool ARMCallLowering::lowerFormalArgumen
   return handleAssignments(MIRBuilder, ArgInfos, ArgHandler);
 }
 
+namespace {
+struct CallReturnHandler : public IncomingValueHandler {
+  CallReturnHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI,
+                    MachineInstrBuilder MIB, CCAssignFn *AssignFn)
+      : IncomingValueHandler(MIRBuilder, MRI, AssignFn), MIB(MIB) {}
+
+  void markPhysRegUsed(unsigned PhysReg) override {
+    MIB.addDef(PhysReg, RegState::Implicit);
+  }
+
+  MachineInstrBuilder MIB;
+};
+} // End anonymous namespace.
+
 bool ARMCallLowering::lowerCall(MachineIRBuilder &MIRBuilder,
                                 const MachineOperand &Callee,
                                 const ArgInfo &OrigRet,
@@ -320,10 +352,6 @@ bool ARMCallLowering::lowerCall(MachineI
   if (MF.getSubtarget<ARMSubtarget>().genLongCalls())
     return false;
 
-  // FIXME: Support calling functions with return types.
-  if (!OrigRet.Ty->isVoidTy())
-    return false;
-
   MIRBuilder.buildInstr(ARM::ADJCALLSTACKDOWN)
       .addImm(0)
       .add(predOps(ARMCC::AL));
@@ -356,6 +384,19 @@ bool ARMCallLowering::lowerCall(MachineI
   // Now we can add the actual call instruction to the correct basic block.
   MIRBuilder.insertInstr(MIB);
 
+  if (!OrigRet.Ty->isVoidTy()) {
+    if (!isSupportedType(DL, TLI, OrigRet.Ty))
+      return false;
+
+    ArgInfos.clear();
+    splitToValueTypes(OrigRet, ArgInfos, DL, MRI);
+
+    auto RetAssignFn = TLI.CCAssignFnForReturn(CallConv, /*IsVarArg=*/false);
+    CallReturnHandler RetHandler(MIRBuilder, MRI, MIB, RetAssignFn);
+    if (!handleAssignments(MIRBuilder, ArgInfos, RetHandler))
+      return false;
+  }
+
   MIRBuilder.buildInstr(ARM::ADJCALLSTACKUP)
       .addImm(0)
       .addImm(0)

Modified: llvm/trunk/test/CodeGen/ARM/GlobalISel/arm-irtranslator.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/GlobalISel/arm-irtranslator.ll?rev=295973&r1=295972&r2=295973&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/ARM/GlobalISel/arm-irtranslator.ll (original)
+++ llvm/trunk/test/CodeGen/ARM/GlobalISel/arm-irtranslator.ll Thu Feb 23 08:18:41 2017
@@ -359,25 +359,28 @@ entry:
   ret void
 }
 
-declare arm_aapcscc void @simple_params_target(i32, i32*)
+declare arm_aapcscc i32* @simple_params_target(i32, i32*)
 
-define arm_aapcscc void @test_call_simple_params(i32 *%a, i32 %b) {
+define arm_aapcscc i32* @test_call_simple_params(i32 *%a, i32 %b) {
 ; CHECK-LABEL: name: test_call_simple_params
 ; CHECK-DAG: [[AVREG:%[0-9]+]](p0) = COPY %r0
 ; CHECK-DAG: [[BVREG:%[0-9]+]](s32) = COPY %r1
 ; CHECK: ADJCALLSTACKDOWN 0, 14, _, implicit-def %sp, implicit %sp
 ; CHECK-DAG: %r0 = COPY [[BVREG]]
 ; CHECK-DAG: %r1 = COPY [[AVREG]]
-; CHECK: BLX @simple_params_target, csr_aapcs, implicit-def %lr, implicit %sp, implicit %r0, implicit %r1
+; CHECK: BLX @simple_params_target, csr_aapcs, implicit-def %lr, implicit %sp, implicit %r0, implicit %r1, implicit-def %r0
+; CHECK: [[RVREG:%[0-9]+]](p0) = COPY %r0
 ; CHECK: ADJCALLSTACKUP 0, 0, 14, _, implicit-def %sp, implicit %sp
+; CHECK: %r0 = COPY [[RVREG]]
+; CHECK: BX_RET 14, _, implicit %r0
 entry:
-  notail call arm_aapcscc void @simple_params_target(i32 %b, i32 *%a)
-  ret void
+  %r = notail call arm_aapcscc i32 *@simple_params_target(i32 %b, i32 *%a)
+  ret i32 *%r
 }
 
-declare arm_aapcscc void @ext_target(i8 signext, i8 zeroext, i16 signext, i16 zeroext)
+declare arm_aapcscc signext i16 @ext_target(i8 signext, i8 zeroext, i16 signext, i16 zeroext)
 
-define arm_aapcscc void @test_call_ext_params(i8 %a, i16 %b) {
+define arm_aapcscc signext i16 @test_call_ext_params(i8 %a, i16 %b) {
 ; CHECK-LABEL: name: test_call_ext_params
 ; CHECK-DAG: [[AVREG:%[0-9]+]](s8) = COPY %r0
 ; CHECK-DAG: [[BVREG:%[0-9]+]](s16) = COPY %r1
@@ -390,32 +393,39 @@ define arm_aapcscc void @test_call_ext_p
 ; CHECK-DAG: %r2 = COPY [[SEXTB]]
 ; CHECK-DAG: [[ZEXTB:%[0-9]+]](s32) = G_ZEXT [[BVREG]](s16)
 ; CHECK-DAG: %r3 = COPY [[ZEXTB]]
-; CHECK: BLX @ext_target, csr_aapcs, implicit-def %lr, implicit %sp, implicit %r0, implicit %r1, implicit %r2, implicit %r3
+; CHECK: BLX @ext_target, csr_aapcs, implicit-def %lr, implicit %sp, implicit %r0, implicit %r1, implicit %r2, implicit %r3, implicit-def %r0
+; CHECK: [[RVREG:%[0-9]+]](s16) = COPY %r0
 ; CHECK: ADJCALLSTACKUP 0, 0, 14, _, implicit-def %sp, implicit %sp
+; CHECK: [[RExtVREG:%[0-9]+]](s32) = G_SEXT [[RVREG]]
+; CHECK: %r0 = COPY [[RExtVREG]]
+; CHECK: BX_RET 14, _, implicit %r0
 entry:
-  notail call arm_aapcscc void @ext_target(i8 signext %a, i8 zeroext %a, i16 signext %b, i16 zeroext %b)
-  ret void
+  %r = notail call arm_aapcscc signext i16 @ext_target(i8 signext %a, i8 zeroext %a, i16 signext %b, i16 zeroext %b)
+  ret i16 %r
 }
 
-declare arm_aapcs_vfpcc void @vfpcc_fp_target(float, double)
+declare arm_aapcs_vfpcc double @vfpcc_fp_target(float, double)
 
-define arm_aapcs_vfpcc void @test_call_vfpcc_fp_params(double %a, float %b) {
+define arm_aapcs_vfpcc double @test_call_vfpcc_fp_params(double %a, float %b) {
 ; CHECK-LABEL: name: test_call_vfpcc_fp_params
 ; CHECK-DAG: [[AVREG:%[0-9]+]](s64) = COPY %d0
 ; CHECK-DAG: [[BVREG:%[0-9]+]](s32) = COPY %s2
 ; CHECK: ADJCALLSTACKDOWN 0, 14, _, implicit-def %sp, implicit %sp
 ; CHECK-DAG: %s0 = COPY [[BVREG]]
 ; CHECK-DAG: %d1 = COPY [[AVREG]]
-; CHECK: BLX @vfpcc_fp_target, csr_aapcs, implicit-def %lr, implicit %sp, implicit %s0, implicit %d1
+; CHECK: BLX @vfpcc_fp_target, csr_aapcs, implicit-def %lr, implicit %sp, implicit %s0, implicit %d1, implicit-def %d0
+; CHECK: [[RVREG:%[0-9]+]](s64) = COPY %d0
 ; CHECK: ADJCALLSTACKUP 0, 0, 14, _, implicit-def %sp, implicit %sp
+; CHECK: %d0 = COPY [[RVREG]]
+; CHECK: BX_RET 14, _, implicit %d0
 entry:
-  notail call arm_aapcs_vfpcc void @vfpcc_fp_target(float %b, double %a)
-  ret void
+  %r = notail call arm_aapcs_vfpcc double @vfpcc_fp_target(float %b, double %a)
+  ret double %r
 }
 
-declare arm_aapcscc void @aapcscc_fp_target(float, double)
+declare arm_aapcscc double @aapcscc_fp_target(float, double)
 
-define arm_aapcscc void @test_call_aapcs_fp_params(double %a, float %b) {
+define arm_aapcscc double @test_call_aapcs_fp_params(double %a, float %b) {
 ; CHECK-LABEL: name: test_call_aapcs_fp_params
 ; CHECK-DAG: [[A1:%[0-9]+]](s32) = COPY %r0
 ; CHECK-DAG: [[A2:%[0-9]+]](s32) = COPY %r1
@@ -429,9 +439,19 @@ define arm_aapcscc void @test_call_aapcs
 ; LITTLE-DAG: %r3 = COPY [[A2]]
 ; BIG-DAG: %r2 = COPY [[A2]]
 ; BIG-DAG: %r3 = COPY [[A1]]
-; CHECK: BLX @aapcscc_fp_target, csr_aapcs, implicit-def %lr, implicit %sp, implicit %r0, implicit %r2, implicit %r3
+; CHECK: BLX @aapcscc_fp_target, csr_aapcs, implicit-def %lr, implicit %sp, implicit %r0, implicit %r2, implicit %r3, implicit-def %r0, implicit-def %r1
+; CHECK-DAG: [[R1:%[0-9]+]](s32) = COPY %r0
+; CHECK-DAG: [[R2:%[0-9]+]](s32) = COPY %r1
+; LITTLE: [[RVREG:%[0-9]+]](s64) = G_SEQUENCE [[R1]](s32), 0, [[R2]](s32), 32
+; BIG: [[RVREG:%[0-9]+]](s64) = G_SEQUENCE [[R2]](s32), 0, [[R1]](s32), 32
 ; CHECK: ADJCALLSTACKUP 0, 0, 14, _, implicit-def %sp, implicit %sp
+; CHECK: [[R1:%[0-9]+]](s32), [[R2:%[0-9]+]](s32) = G_EXTRACT [[RVREG]](s64), 0, 32
+; LITTLE-DAG: %r0 = COPY [[R1]]
+; LITTLE-DAG: %r1 = COPY [[R2]]
+; BIG-DAG: %r0 = COPY [[R2]]
+; BIG-DAG: %r1 = COPY [[R1]]
+; CHECK: BX_RET 14, _, implicit %r0, implicit %r1
 entry:
-  notail call arm_aapcscc void @aapcscc_fp_target(float %b, double %a)
-  ret void
+  %r = notail call arm_aapcscc double @aapcscc_fp_target(float %b, double %a)
+  ret double %r
 }




More information about the llvm-commits mailing list