[llvm] 7452212 - [M68k] Override `CanLowerReturn` to fix assertion with large return

Min-Yih Hsu via llvm-commits llvm-commits at lists.llvm.org
Sat Apr 22 12:24:06 PDT 2023


Author: Ian Douglas Scott
Date: 2023-04-22T12:23:04-07:00
New Revision: 745221268125e86b1543a7aa643414e9cc8cb2d2

URL: https://github.com/llvm/llvm-project/commit/745221268125e86b1543a7aa643414e9cc8cb2d2
DIFF: https://github.com/llvm/llvm-project/commit/745221268125e86b1543a7aa643414e9cc8cb2d2.diff

LOG: [M68k] Override `CanLowerReturn` to fix assertion with large return

If it couldn't fit the return value in two registers, this caused an
error during codegen. It seems this method is implemented in other
backends but not here, and allows it to pass return values in memory
when it isn't able to do so in registers.

Seems to fix compilation of Rust code with certain return types:
https://github.com/rust-lang/rust/issues/89498

Differential Revision: https://reviews.llvm.org/D148856

Added: 
    llvm/test/CodeGen/M68k/multiple-return.ll

Modified: 
    llvm/lib/Target/M68k/M68kISelLowering.cpp
    llvm/lib/Target/M68k/M68kISelLowering.h

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/M68k/M68kISelLowering.cpp b/llvm/lib/Target/M68k/M68kISelLowering.cpp
index 0ee3a07e15f4..c37ec304bf19 100644
--- a/llvm/lib/Target/M68k/M68kISelLowering.cpp
+++ b/llvm/lib/Target/M68k/M68kISelLowering.cpp
@@ -1058,6 +1058,14 @@ SDValue M68kTargetLowering::LowerFormalArguments(
 //              Return Value Calling Convention Implementation
 //===----------------------------------------------------------------------===//
 
+bool M68kTargetLowering::CanLowerReturn(
+    CallingConv::ID CCID, MachineFunction &MF, bool IsVarArg,
+    const SmallVectorImpl<ISD::OutputArg> &Outs, LLVMContext &Context) const {
+  SmallVector<CCValAssign, 16> RVLocs;
+  CCState CCInfo(CCID, IsVarArg, MF, RVLocs, Context);
+  return CCInfo.CheckReturn(Outs, RetCC_M68k);
+}
+
 SDValue
 M68kTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CCID,
                                 bool IsVarArg,

diff  --git a/llvm/lib/Target/M68k/M68kISelLowering.h b/llvm/lib/Target/M68k/M68kISelLowering.h
index f9037e7ff497..d43160fe48d2 100644
--- a/llvm/lib/Target/M68k/M68kISelLowering.h
+++ b/llvm/lib/Target/M68k/M68kISelLowering.h
@@ -257,6 +257,11 @@ class M68kTargetLowering : public TargetLowering {
   SDValue LowerCall(CallLoweringInfo &CLI,
                     SmallVectorImpl<SDValue> &InVals) const override;
 
+  bool CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF,
+                      bool isVarArg,
+                      const SmallVectorImpl<ISD::OutputArg> &Outs,
+                      LLVMContext &Context) const override;
+
   /// Lower the result values of a call into the
   /// appropriate copies out of appropriate physical registers.
   SDValue LowerReturn(SDValue Chain, CallingConv::ID CCID, bool IsVarArg,

diff  --git a/llvm/test/CodeGen/M68k/multiple-return.ll b/llvm/test/CodeGen/M68k/multiple-return.ll
new file mode 100644
index 000000000000..f52f422b194f
--- /dev/null
+++ b/llvm/test/CodeGen/M68k/multiple-return.ll
@@ -0,0 +1,20 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc < %s -mtriple=m68k-linux -verify-machineinstrs | FileCheck %s
+
+define { i32, i32, i32, i32 } @test() {
+; CHECK-LABEL: test:
+; CHECK:         .cfi_startproc
+; CHECK-NEXT:  ; %bb.0: ; %start
+; CHECK-NEXT:    move.l (4,%sp), %a0
+; CHECK-NEXT:    move.l #23, (12,%a0)
+; CHECK-NEXT:    move.l #19, (8,%a0)
+; CHECK-NEXT:    move.l #17, (4,%a0)
+; CHECK-NEXT:    move.l #13, (%a0)
+; CHECK-NEXT:    move.l %a0, %d0
+; CHECK-NEXT:    move.l (%sp), %a1
+; CHECK-NEXT:    adda.l #4, %sp
+; CHECK-NEXT:    move.l %a1, (%sp)
+; CHECK-NEXT:    rts
+start:
+  ret { i32, i32, i32, i32 } { i32 13, i32 17, i32 19, i32 23 }
+}


        


More information about the llvm-commits mailing list