[PATCH] D24077: [mips] LLVM PR/30197 - Tail call incorrectly clobbers arguments

Simon Dardis via llvm-commits llvm-commits at lists.llvm.org
Wed Aug 31 06:45:32 PDT 2016


sdardis created this revision.
sdardis added a reviewer: vkalintiris.
sdardis added a subscriber: llvm-commits.
sdardis set the repository for this revision to rL LLVM.
Herald added a subscriber: sdardis.

The postRA scheduler performs alias analysis to determine if stores+loads can
moved past each other. When a function has more arguments than the calling
convention permits, excess arguments are spilled onto the stack. LLVM by
default assumes that argument slots are immutable, unless the function
contains a tail call. Without the knowledge of that a function contains a
tail call site, stores and loads to fixed stack slots may be re-ordered
causing the out-going arguments to clobber the incoming arguments before
the incoming arguments are supposed to be dead.

Repository:
  rL LLVM

https://reviews.llvm.org/D24077

Files:
  lib/Target/Mips/MipsISelLowering.cpp
  test/CodeGen/Mips/tailcall/tail-call-arguments-clobber.ll

Index: test/CodeGen/Mips/tailcall/tail-call-arguments-clobber.ll
===================================================================
--- /dev/null
+++ test/CodeGen/Mips/tailcall/tail-call-arguments-clobber.ll
@@ -0,0 +1,49 @@
+; RUN: llc -march=mips -mcpu=mips32 -O3 < %s | FileCheck %s \
+; RUN:     -check-prefix=MIPS32
+; RUN: llc -march=mips64 -mcpu=mips64 -target-abi n64 < %s | FileCheck %s \
+; RUN:     -check-prefix=MIPS64
+; RUN: llc -march=mips64 -mcpu=mips64 -target-abi n32 < %s | FileCheck %s \
+; RUN:     -check-prefix=MIPS64
+
+
+; LLVM PR/30197
+; Test that the scheduler does not order loads and stores of arguments that
+; are passed on the stack such that the arguments of the caller are clobbered
+; too early.
+
+; O32 case: The last two arguments should appear at 16(sp), 20(sp). The order
+;           of the loads doesn't matter, but they have to become before the
+;           stores
+declare i32 @func2(i32, i32, i32, i32, i32, i32)
+
+define i32 @func1(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e, i32 %f){
+
+; MIPS32: lw ${{[0-9]+}}, {{[0-9]+}}($sp)
+; MIPS32: lw ${{[0-9]+}}, {{[0-9]+}}($sp)
+; MIPS32: sw ${{[0-9]+}}, {{[0-9]+}}($sp)
+; MIPS32: sw ${{[0-9]+}}, {{[0-9]+}}($sp)
+  %retval = tail call i32 @func1(i32 %a, i32 %f, i32 %c, i32 %d, i32 %e, i32 %b)
+
+  ret i32 %retval
+}
+
+; N64, N32 cases: N64 and N32 both pass 8 arguments in registers. The order
+;           of the loads doesn't matter, but they have to become before the
+;           stores
+
+declare i64 @func4(i64, i64, i64, i64, i64, i64, i64, i64, i64, i64)
+
+define i64 @func3(i64 %a, i64 %b, i64 %c, i64 %d,
+                  i64 %e, i64 %f, i64 %g, i64 %h,
+                  i64 %i, i64 %j){
+
+; MIPS64: ld ${{[0-9]+}}, {{[0-9]+}}($sp)
+; MIPS64: ld ${{[0-9]+}}, {{[0-9]+}}($sp)
+; MIPS64: sd ${{[0-9]+}}, {{[0-9]+}}($sp)
+; MIPS64: sd ${{[0-9]+}}, {{[0-9]+}}($sp)
+  %retval = tail call i64 @func4(i64 %a, i64 %j, i64 %c, i64 %d, i64 %e, i64 %f, i64 %g, i64 %h, i64 %i, i64 %b)
+
+  ret i64 %retval
+}
+
+
Index: lib/Target/Mips/MipsISelLowering.cpp
===================================================================
--- lib/Target/Mips/MipsISelLowering.cpp
+++ lib/Target/Mips/MipsISelLowering.cpp
@@ -2870,8 +2870,10 @@
   getOpndList(Ops, RegsToPass, IsPICCall, GlobalOrExternal, InternalLinkage,
               IsCallReloc, CLI, Callee, Chain);
 
-  if (IsTailCall)
+  if (IsTailCall) {
+    MF.getFrameInfo().setHasTailCall();
     return DAG.getNode(MipsISD::TailCall, DL, MVT::Other, Ops);
+  }
 
   Chain = DAG.getNode(MipsISD::JmpLink, DL, NodeTys, Ops);
   SDValue InFlag = Chain.getValue(1);


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D24077.69843.patch
Type: text/x-patch
Size: 2613 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20160831/0a4c8f35/attachment-0001.bin>


More information about the llvm-commits mailing list