Skip to content

Conversation

@folkertdev
Copy link
Contributor

@folkertdev folkertdev commented Nov 20, 2025

fixes #56891
fixes #72390

Currently the x86 backend miscompiles straightforward tail calls when the stack is used for argument passing. This program segfaults on any optimization level:

https://godbolt.org/z/5xr99jr4v

typedef struct {
    uint64_t x;
    uint64_t y;
    uint64_t z;
} S;

__attribute__((noinline))
uint64_t callee(S s) {
    return s.x + s.y + s.z;
}

__attribute__((noinline))
uint64_t caller(S s) {
    [[clang::musttail]]
    return callee(s);
}

The immediate issue is that caller decides to shuffle values around on the stack, and in the process writes to *rsp, which contains the return address. With the return address trashed, the ret in callee jumps to an invalid address.

caller:
        mov     rax, qword ptr [rsp + 24]
        mov     qword ptr [rsp + 16], rax
        movaps  xmm0, xmmword ptr [rsp + 8]
        movups  xmmword ptr [rsp], xmm0 ; <-- that is just all kinds of wrong
        movaps  xmmword ptr [rsp + 8], xmm0
        mov     qword ptr [rsp + 24], rax
        jmp     callee

However, I think the actual problem is that the x86 backend never considers musttail calls to be sibcalls. For sibcalls, no stack reshuffling is required at all, circumventing the problem here.

This PR essentially copies https://reviews.llvm.org/D131034 (cc @huangjd), but this time I hope we can actually land this, and solve this problem.

The aarch64 backend also miscompiled this example, but they appear to have fixed it in LLVM 20.

Tail calls just not working for any sort of non-trivial argument types is a blocker for tail call support in rust, see rust-lang/rust#144855 (comment).

@llvmbot
Copy link
Member

llvmbot commented Nov 20, 2025

@llvm/pr-subscribers-backend-x86

Author: Folkert de Vries (folkertdev)

Changes

fixes #56891
fixes #72390

Currently the x86 backend miscompiles straightforward tail calls when the stack is used for argument passing. This program segfaults on any optimization level:

https://godbolt.org/z/5xr99jr4v

typedef struct {
    uint64_t x;
    uint64_t y;
    uint64_t z;
} S;

__attribute__((noinline))
uint64_t callee(S s) {
    return s.x + s.y + s.z;
}

__attribute__((noinline))
uint64_t caller(S s) {
    [[clang::musttail]]
    return callee(s);
}

The immediate issue is that caller decides to shuffle values around on the stack, and in the process writes to *rsp, which contains the return address. With the return address trashed, the ret in callee jumps to an invalid address.

caller:
        mov     rax, qword ptr [rsp + 24]
        mov     qword ptr [rsp + 16], rax
        movaps  xmm0, xmmword ptr [rsp + 8]
        movups  xmmword ptr [rsp], xmm0 ; &lt;-- that is just all kinds of wrong
        movaps  xmmword ptr [rsp + 8], xmm0
        mov     qword ptr [rsp + 24], rax
        jmp     callee

However, I think the actual problem is that the x86 backend never considers musttail calls to be sibcalls. For sibcalls, no stack reshuffling is required at all, circumventing the problem here.

This PR essentially copies https://reviews.llvm.org/D131034, but this time I hope we can actually land this, and solve this problem.

The aarch64 backend also miscompiled this example, but they appear to have fixed it in LLVM 20.

Tail calls just not working for any sort of non-trivial argument types is a blocker for tail call support in rust, see rust-lang/rust#144855 (comment).


Full diff: https://github.com/llvm/llvm-project/pull/168956.diff

4 Files Affected:

  • (modified) llvm/lib/Target/X86/X86ISelLoweringCall.cpp (+12-8)
  • (added) llvm/test/CodeGen/X86/musttail-struct.ll (+57)
  • (modified) llvm/test/CodeGen/X86/musttail-tailcc.ll (-18)
  • (modified) llvm/test/CodeGen/X86/swifttailcc-store-ret-address-aliasing-stack-slot.ll (+2-4)
diff --git a/llvm/lib/Target/X86/X86ISelLoweringCall.cpp b/llvm/lib/Target/X86/X86ISelLoweringCall.cpp
index 37d77728882b1..e53e5a2a02cb4 100644
--- a/llvm/lib/Target/X86/X86ISelLoweringCall.cpp
+++ b/llvm/lib/Target/X86/X86ISelLoweringCall.cpp
@@ -2098,15 +2098,18 @@ X86TargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
       isTailCall = false;
   }
 
-  if (isTailCall && !IsMustTail) {
+  if (isTailCall) {
     // Check if it's really possible to do a tail call.
-    isTailCall = IsEligibleForTailCallOptimization(CLI, CCInfo, ArgLocs,
-                                                   IsCalleePopSRet);
+    IsSibcall = IsEligibleForTailCallOptimization(CLI, CCInfo, ArgLocs,
+                                                  IsCalleePopSRet);
+
+    if (!IsMustTail) {
+      isTailCall = IsSibcall;
 
-    // Sibcalls are automatically detected tailcalls which do not require
-    // ABI changes.
-    if (!IsGuaranteeTCO && isTailCall)
-      IsSibcall = true;
+      // Sibcalls are automatically detected tailcalls which do not require
+      // ABI changes.
+      IsSibcall = IsSibcall && !IsGuaranteeTCO;
+    }
 
     if (isTailCall)
       ++NumTailCalls;
@@ -2128,8 +2131,9 @@ X86TargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
   else if (IsGuaranteeTCO && canGuaranteeTCO(CallConv))
     NumBytes = GetAlignedArgumentStackSize(NumBytes, DAG);
 
+  // A sibcall is ABI-compatible and does not need to adjust the stack pointer.
   int FPDiff = 0;
-  if (isTailCall &&
+  if (isTailCall && !IsSibcall &&
       shouldGuaranteeTCO(CallConv,
                          MF.getTarget().Options.GuaranteedTailCallOpt)) {
     // Lower arguments at fp - stackoffset + fpdiff.
diff --git a/llvm/test/CodeGen/X86/musttail-struct.ll b/llvm/test/CodeGen/X86/musttail-struct.ll
new file mode 100644
index 0000000000000..0ae6b91d4fc02
--- /dev/null
+++ b/llvm/test/CodeGen/X86/musttail-struct.ll
@@ -0,0 +1,57 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: llc < %s -mtriple=x86_64-unknown-unknown | FileCheck %s
+; RUN: llc < %s -mtriple=i686-unknown-unknown | FileCheck %s
+
+; Test correct handling of a musttail call with a byval struct argument.
+
+%struct.1xi32 = type { [1 x i32] }
+%struct.3xi32 = type { [3 x i32] }
+%struct.5xi32 = type { [5 x i32] }
+
+declare dso_local i32 @Func1(ptr byval(%struct.1xi32) %0)
+declare dso_local i32 @Func3(ptr byval(%struct.3xi32) %0)
+declare dso_local i32 @Func5(ptr byval(%struct.5xi32) %0)
+declare dso_local i32 @FuncManyArgs(i32 %0, i32 %1, i32 %2, i32 %3, i32 %4, i32 %5, i8 %6, ptr byval(%struct.5xi32) %7)
+
+define dso_local i32 @test1(ptr byval(%struct.1xi32) %0) {
+; CHECK-LABEL: test1:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    jmp Func1 # TAILCALL
+  %r = musttail call i32 @Func1(ptr byval(%struct.1xi32) %0)
+  ret i32 %r
+}
+
+define dso_local i32 @test3(ptr byval(%struct.3xi32) %0) {
+; CHECK-LABEL: test3:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    jmp Func3 # TAILCALL
+  %r = musttail call i32 @Func3(ptr byval(%struct.3xi32) %0)
+  ret i32 %r
+}
+
+; sizeof(%struct.5xi32) > 16, in x64 this is passed on stack.
+define dso_local i32 @test5(ptr byval(%struct.5xi32) %0) {
+; CHECK-LABEL: test5:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    jmp Func5 # TAILCALL
+  %r = musttail call i32 @Func5(ptr byval(%struct.5xi32) %0)
+  ret i32 %r
+}
+
+; Test passing multiple arguments with different sizes on stack. In x64 Linux
+; the first 6 are passed by register.
+define dso_local i32 @testManyArgs(i32 %0, i32 %1, i32 %2, i32 %3, i32 %4, i32 %5, i8 %6, ptr byval(%struct.5xi32) %7) {
+; CHECK-LABEL: testManyArgs:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    jmp FuncManyArgs # TAILCALL
+  %r = musttail call i32 @FuncManyArgs(i32 %0, i32 %1, i32 %2, i32 %3, i32 %4, i32 %5, i8 %6, ptr byval(%struct.5xi32) %7)
+  ret i32 %r
+}
+
+define dso_local i32 @testRecursion(i32 %0, i32 %1, i32 %2, i32 %3, i32 %4, i32 %5, i8 %6, ptr byval(%struct.5xi32) %7) {
+; CHECK-LABEL: testRecursion:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    jmp testRecursion # TAILCALL
+  %r = musttail call i32 @testRecursion(i32 %0, i32 %1, i32 %2, i32 %3, i32 %4, i32 %5, i8 %6, ptr byval(%struct.5xi32) %7)
+  ret i32 %r
+}
diff --git a/llvm/test/CodeGen/X86/musttail-tailcc.ll b/llvm/test/CodeGen/X86/musttail-tailcc.ll
index fae698d53b927..f1ffbcb1142c5 100644
--- a/llvm/test/CodeGen/X86/musttail-tailcc.ll
+++ b/llvm/test/CodeGen/X86/musttail-tailcc.ll
@@ -55,15 +55,6 @@ define dso_local tailcc void @void_test(i32, i32, i32, i32) {
 ;
 ; X86-LABEL: void_test:
 ; X86:       # %bb.0: # %entry
-; X86-NEXT:    pushl %esi
-; X86-NEXT:    .cfi_def_cfa_offset 8
-; X86-NEXT:    .cfi_offset %esi, -8
-; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
-; X86-NEXT:    movl {{[0-9]+}}(%esp), %esi
-; X86-NEXT:    movl %esi, {{[0-9]+}}(%esp)
-; X86-NEXT:    movl %eax, {{[0-9]+}}(%esp)
-; X86-NEXT:    popl %esi
-; X86-NEXT:    .cfi_def_cfa_offset 4
 ; X86-NEXT:    jmp void_test # TAILCALL
   entry:
    musttail call tailcc void @void_test( i32 %0, i32 %1, i32 %2, i32 %3)
@@ -77,15 +68,6 @@ define dso_local tailcc i1 @i1test(i32, i32, i32, i32) {
 ;
 ; X86-LABEL: i1test:
 ; X86:       # %bb.0: # %entry
-; X86-NEXT:    pushl %esi
-; X86-NEXT:    .cfi_def_cfa_offset 8
-; X86-NEXT:    .cfi_offset %esi, -8
-; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
-; X86-NEXT:    movl {{[0-9]+}}(%esp), %esi
-; X86-NEXT:    movl %esi, {{[0-9]+}}(%esp)
-; X86-NEXT:    movl %eax, {{[0-9]+}}(%esp)
-; X86-NEXT:    popl %esi
-; X86-NEXT:    .cfi_def_cfa_offset 4
 ; X86-NEXT:    jmp i1test # TAILCALL
   entry:
   %4 = musttail call tailcc i1 @i1test( i32 %0, i32 %1, i32 %2, i32 %3)
diff --git a/llvm/test/CodeGen/X86/swifttailcc-store-ret-address-aliasing-stack-slot.ll b/llvm/test/CodeGen/X86/swifttailcc-store-ret-address-aliasing-stack-slot.ll
index cd669768705e5..b901d22f66392 100644
--- a/llvm/test/CodeGen/X86/swifttailcc-store-ret-address-aliasing-stack-slot.ll
+++ b/llvm/test/CodeGen/X86/swifttailcc-store-ret-address-aliasing-stack-slot.ll
@@ -1,3 +1,4 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
 ; RUN: llc %s -o - | FileCheck %s
 
 target triple = "x86_64-apple-macosx"
@@ -24,9 +25,7 @@ define swifttailcc void @test(ptr %0, ptr swiftasync %1, i64 %2, i64 %3, ptr %4,
 ; CHECK-NEXT:    movq {{[0-9]+}}(%rsp), %r15
 ; CHECK-NEXT:    callq _foo
 ; CHECK-NEXT:    movq %r14, (%rax)
-; CHECK-NEXT:    movl [[OFF:[0-9]+]](%rsp), %edx
-; CHECK-NEXT:    movq {{[0-9]+}}(%rsp), %rcx
-; CHECK-NEXT:    movq %rcx, [[OFF]](%rsp)
+; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %edx
 ; CHECK-NEXT:    movq %rax, %r14
 ; CHECK-NEXT:    movq %r13, %rdi
 ; CHECK-NEXT:    movq %r15, %rsi
@@ -34,7 +33,6 @@ define swifttailcc void @test(ptr %0, ptr swiftasync %1, i64 %2, i64 %3, ptr %4,
 ; CHECK-NEXT:    addq $8, %rsp
 ; CHECK-NEXT:    popq %rbx
 ; CHECK-NEXT:    popq %r15
-; CHECK-NEXT:    addq $16, %rsp
 ; CHECK-NEXT:    jmp _tc_fn ## TAILCALL
 entry:
   %res = tail call ptr @foo()

@folkertdev folkertdev changed the title fix x86 musttail sibcall miscompilation x86: fix musttail sibcall miscompilation Nov 20, 2025
@github-actions
Copy link

github-actions bot commented Nov 20, 2025

🐧 Linux x64 Test Results

  • 166236 tests passed
  • 2857 tests skipped
  • 4 tests failed

Failed Tests

(click on a test name to see its output)

LLVM

LLVM.CodeGen/X86/musttail-inalloca.ll
Exit Code: 1

Command Output (stdout):
--
# RUN: at line 2
/home/gha/actions-runner/_work/llvm-project/llvm-project/build/bin/llc /home/gha/actions-runner/_work/llvm-project/llvm-project/llvm/test/CodeGen/X86/musttail-inalloca.ll -o - | /home/gha/actions-runner/_work/llvm-project/llvm-project/build/bin/FileCheck /home/gha/actions-runner/_work/llvm-project/llvm-project/llvm/test/CodeGen/X86/musttail-inalloca.ll
# executed command: /home/gha/actions-runner/_work/llvm-project/llvm-project/build/bin/llc /home/gha/actions-runner/_work/llvm-project/llvm-project/llvm/test/CodeGen/X86/musttail-inalloca.ll -o -
# note: command had no output on stdout or stderr
# executed command: /home/gha/actions-runner/_work/llvm-project/llvm-project/build/bin/FileCheck /home/gha/actions-runner/_work/llvm-project/llvm-project/llvm/test/CodeGen/X86/musttail-inalloca.ll
# .---command stderr------------
# | /home/gha/actions-runner/_work/llvm-project/llvm-project/llvm/test/CodeGen/X86/musttail-inalloca.ll:21:15: error: CHECK-NEXT: is not on the line after the previous match
# | ; CHECK-NEXT: movl %ecx, %esi
# |               ^
# | <stdin>:18:2: note: 'next' match was here
# |  movl %ecx, %esi
# |  ^
# | <stdin>:16:12: note: previous match ended here
# |  pushl %esi
# |            ^
# | <stdin>:17:1: note: non-matching line after previous match is here
# |  subl $20, %esp
# | ^
# | 
# | Input file: <stdin>
# | Check file: /home/gha/actions-runner/_work/llvm-project/llvm-project/llvm/test/CodeGen/X86/musttail-inalloca.ll
# | 
# | -dump-input=help explains the following input dump.
# | 
# | Input was:
# | <<<<<<
# |          .
# |          .
# |          .
# |         13:  .globl _methodWithVtorDisp_thunk # -- Begin function methodWithVtorDisp_thunk 
# |         14: _methodWithVtorDisp_thunk: # @methodWithVtorDisp_thunk 
# |         15: # %bb.0: 
# |         16:  pushl %esi 
# |         17:  subl $20, %esp 
# |         18:  movl %ecx, %esi 
# | next:21      !~~~~~~~~~~~~~~  error: match on wrong line
# |         19:  subl -4(%ecx), %esi 
# |         20:  pushl 24(%esp) 
# |         21:  pushl $_methodWithVtorDisp_thunk 
# |         22:  calll ___cyg_profile_func_exit 
# |         23:  addl $8, %esp 
# |          .
# |          .
# |          .
# | >>>>>>
# `-----------------------------
# error: command failed with exit status: 1

--

LLVM.CodeGen/X86/musttail-struct.ll
Exit Code: 1

Command Output (stdout):
--
# RUN: at line 2
/home/gha/actions-runner/_work/llvm-project/llvm-project/build/bin/llc < /home/gha/actions-runner/_work/llvm-project/llvm-project/llvm/test/CodeGen/X86/musttail-struct.ll -mtriple=x86_64-unknown-unknown -x86-asm-syntax=intel | /home/gha/actions-runner/_work/llvm-project/llvm-project/build/bin/FileCheck /home/gha/actions-runner/_work/llvm-project/llvm-project/llvm/test/CodeGen/X86/musttail-struct.ll
# executed command: /home/gha/actions-runner/_work/llvm-project/llvm-project/build/bin/llc -mtriple=x86_64-unknown-unknown -x86-asm-syntax=intel
# note: command had no output on stdout or stderr
# executed command: /home/gha/actions-runner/_work/llvm-project/llvm-project/build/bin/FileCheck /home/gha/actions-runner/_work/llvm-project/llvm-project/llvm/test/CodeGen/X86/musttail-struct.ll
# note: command had no output on stdout or stderr
# RUN: at line 3
/home/gha/actions-runner/_work/llvm-project/llvm-project/build/bin/llc < /home/gha/actions-runner/_work/llvm-project/llvm-project/llvm/test/CodeGen/X86/musttail-struct.ll -mtriple=i686-unknown-unknown | /home/gha/actions-runner/_work/llvm-project/llvm-project/build/bin/FileCheck /home/gha/actions-runner/_work/llvm-project/llvm-project/llvm/test/CodeGen/X86/musttail-struct.ll
# executed command: /home/gha/actions-runner/_work/llvm-project/llvm-project/build/bin/llc -mtriple=i686-unknown-unknown
# note: command had no output on stdout or stderr
# executed command: /home/gha/actions-runner/_work/llvm-project/llvm-project/build/bin/FileCheck /home/gha/actions-runner/_work/llvm-project/llvm-project/llvm/test/CodeGen/X86/musttail-struct.ll
# .---command stderr------------
# | /home/gha/actions-runner/_work/llvm-project/llvm-project/llvm/test/CodeGen/X86/musttail-struct.ll:19:15: error: CHECK-NEXT: is not on the line after the previous match
# | ; CHECK-NEXT: jmp Func1 # TAILCALL
# |               ^
# | <stdin>:13:2: note: 'next' match was here
# |  jmp Func1 # TAILCALL
# |  ^
# | <stdin>:8:9: note: previous match ended here
# | # %bb.0:
# |         ^
# | <stdin>:9:1: note: non-matching line after previous match is here
# |  pushl %eax
# | ^
# | /home/gha/actions-runner/_work/llvm-project/llvm-project/llvm/test/CodeGen/X86/musttail-struct.ll:62:15: error: CHECK-NEXT: expected string not found in input
# | ; CHECK-NEXT: mov eax, dword ptr [rsp + 8]
# |               ^
# | <stdin>:67:18: note: scanning from here
# | # %bb.0: # %entry
# |                  ^
# | <stdin>:68:2: note: possible intended match here
# |  movl 4(%esp), %eax
# |  ^
# | /home/gha/actions-runner/_work/llvm-project/llvm-project/llvm/test/CodeGen/X86/musttail-struct.ll:77:15: error: CHECK-NEXT: expected string not found in input
# | ; CHECK-NEXT: mov eax, dword ptr [rsp + 8]
# |               ^
# | <stdin>:80:9: note: scanning from here
# | # %bb.0:
# |         ^
# | <stdin>:84:2: note: possible intended match here
# |  movl %eax, (%esp)
# |  ^
# | /home/gha/actions-runner/_work/llvm-project/llvm-project/llvm/test/CodeGen/X86/musttail-struct.ll:115:15: error: CHECK-NEXT: expected string not found in input
# | ; CHECK-NEXT: movabs rax, 4294967296
# |               ^
# | <stdin>:112:18: note: scanning from here
# | # %bb.0: # %entry
# |                  ^
# | <stdin>:116:2: note: possible intended match here
# |  movl $1, 24(%esp)
# |  ^
# | /home/gha/actions-runner/_work/llvm-project/llvm-project/llvm/test/CodeGen/X86/musttail-struct.ll:146:15: error: CHECK-NEXT: expected string not found in input
# | ; CHECK-NEXT: mov eax, dword ptr [rsp + 24]
# |               ^
# | <stdin>:142:18: note: scanning from here
# | # %bb.0: # %entry
# |                  ^
# | <stdin>:146:2: note: possible intended match here
# |  movl %eax, 16(%esp)
# |  ^
# | /home/gha/actions-runner/_work/llvm-project/llvm-project/llvm/test/CodeGen/X86/musttail-struct.ll:178:15: error: CHECK-NEXT: expected string not found in input
# | ; CHECK-NEXT: jmp shift_byval_callee@PLT # TAILCALL
# |               ^
# | <stdin>:197:18: note: scanning from here
# | # %bb.0: # %entry
# |                  ^
# | <stdin>:219:4: note: possible intended match here
# |  calll shift_byval_callee@PLT
# |    ^
# | /home/gha/actions-runner/_work/llvm-project/llvm-project/llvm/test/CodeGen/X86/musttail-struct.ll:190:15: error: CHECK-NEXT: expected string not found in input
# | ; CHECK-NEXT: mov rax, qword ptr [rip + large_global@GOTPCREL]
# |               ^
# | <stdin>:236:18: note: scanning from here
# | # %bb.0: # %entry
# |                  ^
# | <stdin>:237:2: note: possible intended match here
# |  movl large_global+16, %eax
# |  ^
# | 
# | Input file: <stdin>
# | Check file: /home/gha/actions-runner/_work/llvm-project/llvm-project/llvm/test/CodeGen/X86/musttail-struct.ll
# | 
# | -dump-input=help explains the following input dump.
# | 
# | Input was:
# | <<<<<<
# |             .
# |             .
# |             .
# |             8: # %bb.0: 
# |             9:  pushl %eax 
# |            10:  .cfi_def_cfa_offset 8 
# |            11:  popl %eax 
# |            12:  .cfi_def_cfa_offset 4 
# |            13:  jmp Func1 # TAILCALL 
# | next:19         !~~~~~~~~~~~~~~~~~~~  error: match on wrong line
# |            14: .Lfunc_end0: 
# |            15:  .size test1, .Lfunc_end0-test1 
# |            16:  .cfi_endproc 
# |            17:  # -- End function 
# |            18:  .globl test3 # -- Begin function test3 
# |             .
# |             .
# |             .
# |            62:  .globl swap # -- Begin function swap 
# |            63:  .p2align 4 
# |            64:  .type swap,@function 
# |            65: swap: # @swap 
# |            66:  .cfi_startproc 
# |            67: # %bb.0: # %entry 
# | next:62'0                       X error: no match found
# |            68:  movl 4(%esp), %eax 
# | next:62'0      ~~~~~~~~~~~~~~~~~~~~
# | next:62'1       ?                   possible intended match
# |            69:  addl 8(%esp), %eax 
# | next:62'0      ~~~~~~~~~~~~~~~~~~~~
# |            70:  retl 
# | next:62'0      ~~~~~~
# |            71: .Lfunc_end5: 
# | next:62'0      ~~~~~~~~~~~~~
# |            72:  .size swap, .Lfunc_end5-swap 
# | next:62'0      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# |            73:  .cfi_endproc 
# | next:62'0      ~~~~~~~~~~~~~~
# |            74:  # -- End function 
# | next:62'0      ~~~~~~~~~~~~~~~~~~~
# |            75:  .globl swapByValArguments # -- Begin function swapByValArguments 
# | next:62'0      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# |            76:  .p2align 4 
# | next:62'0      ~~~~~~~~~~~~
# |            77:  .type swapByValArguments,@function 
# | next:62'0      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# |            78: swapByValArguments: # @swapByValArguments 
# | next:62'0      ~~~~~~~~~~~~~~~~~~~
# |            79:  .cfi_startproc 
# |            80: # %bb.0: 
# | next:77'0              X error: no match found
# |            81:  subl $8, %esp 
# | next:77'0      ~~~~~~~~~~~~~~~
# |            82:  .cfi_def_cfa_offset 12 
# | next:77'0      ~~~~~~~~~~~~~~~~~~~~~~~~
# |            83:  movl 12(%esp), %eax 
# | next:77'0      ~~~~~~~~~~~~~~~~~~~~~
# |            84:  movl %eax, (%esp) 
# | next:77'0      ~~~~~~~~~~~~~~~~~~~
# | next:77'1       ?                  possible intended match
# |            85:  movl 16(%esp), %ecx 
# | next:77'0      ~~~~~~~~~~~~~~~~~~~~~
# |            86:  movl %ecx, 4(%esp) 
# | next:77'0      ~~~~~~~~~~~~~~~~~~~~
# |            87:  movl %ecx, 12(%esp) 
# | next:77'0      ~~~~~~~~~~~~~~~~~~~~~
# |            88:  movl %eax, 16(%esp) 
# | next:77'0      ~~~~~~~~~~~~~~~~~~~~~
# |            89:  addl $8, %esp 
# | next:77'0      ~~~~~~~~~~~~~~~
# |             .
# |             .
# |             .
# |           107:  .globl large_caller_new_value # -- Begin function large_caller_new_value 
# |           108:  .p2align 4 
# |           109:  .type large_caller_new_value,@function 
# |           110: large_caller_new_value: # @large_caller_new_value 
# |           111:  .cfi_startproc 
# |           112: # %bb.0: # %entry 
# | next:115'0                      X error: no match found
# |           113:  subl $40, %esp 
# | next:115'0     ~~~~~~~~~~~~~~~~
# |           114:  .cfi_def_cfa_offset 44 
# | next:115'0     ~~~~~~~~~~~~~~~~~~~~~~~~
# |           115:  movl $0, 20(%esp) 
# | next:115'0     ~~~~~~~~~~~~~~~~~~~
# |           116:  movl $1, 24(%esp) 
# | next:115'0     ~~~~~~~~~~~~~~~~~~~
# | next:115'1      ?                  possible intended match
# |           117:  movl $2, 28(%esp) 
# | next:115'0     ~~~~~~~~~~~~~~~~~~~
# |           118:  movl $3, 32(%esp) 
# | next:115'0     ~~~~~~~~~~~~~~~~~~~
# |           119:  movl $4, 36(%esp) 
# | next:115'0     ~~~~~~~~~~~~~~~~~~~
# |           120:  movl $0, (%esp) 
# | next:115'0     ~~~~~~~~~~~~~~~~~
# |           121:  movl $1, 4(%esp) 
# | next:115'0     ~~~~~~~~~~~~~~~~~~
# |             .
# |             .
# |             .
# |           137:  .globl swap_byvals # -- Begin function swap_byvals 
# | next:115'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# |           138:  .p2align 4 
# | next:115'0     ~~~~~~~~~~~~
# |           139:  .type swap_byvals,@function 
# | next:115'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# |           140: swap_byvals: # @swap_byvals 
# | next:115'0     ~~~~~~~~~~~~
# |           141:  .cfi_startproc 
# |           142: # %bb.0: # %entry 
# | next:146'0                      X error: no match found
# |           143:  subl $40, %esp 
# | next:146'0     ~~~~~~~~~~~~~~~~
# |           144:  .cfi_def_cfa_offset 44 
# | next:146'0     ~~~~~~~~~~~~~~~~~~~~~~~~
# |           145:  movl 60(%esp), %eax 
# | next:146'0     ~~~~~~~~~~~~~~~~~~~~~
# |           146:  movl %eax, 16(%esp) 
# | next:146'0     ~~~~~~~~~~~~~~~~~~~~~
# | next:146'1      ?                    possible intended match
# |           147:  movl 56(%esp), %eax 
# | next:146'0     ~~~~~~~~~~~~~~~~~~~~~
# |           148:  movl %eax, 12(%esp) 
# | next:146'0     ~~~~~~~~~~~~~~~~~~~~~
# |           149:  movl 52(%esp), %eax 
# | next:146'0     ~~~~~~~~~~~~~~~~~~~~~
# |           150:  movl %eax, 8(%esp) 
# | next:146'0     ~~~~~~~~~~~~~~~~~~~~
# |           151:  movl 44(%esp), %eax 
# | next:146'0     ~~~~~~~~~~~~~~~~~~~~~
# |             .
# |             .
# |             .
# |           192:  .globl shift_byval # -- Begin function shift_byval 
# | next:146'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# |           193:  .p2align 4 
# | next:146'0     ~~~~~~~~~~~~
# |           194:  .type shift_byval,@function 
# | next:146'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# |           195: shift_byval: # @shift_byval 
# | next:146'0     ~~~~~~~~~~~~
# |           196:  .cfi_startproc 
# |           197: # %bb.0: # %entry 
# | next:178'0                      X error: no match found
# |           198:  pushl %edi 
# | next:178'0     ~~~~~~~~~~~~
# |           199:  .cfi_def_cfa_offset 8 
# | next:178'0     ~~~~~~~~~~~~~~~~~~~~~~~
# |           200:  pushl %esi 
# | next:178'0     ~~~~~~~~~~~~
# |           201:  .cfi_def_cfa_offset 12 
# | next:178'0     ~~~~~~~~~~~~~~~~~~~~~~~~
# |           202:  .cfi_offset %esi, -12 
# | next:178'0     ~~~~~~~~~~~~~~~~~~~~~~~
# |             .
# |             .
# |             .
# |           214:  .cfi_adjust_cfa_offset 4 
# | next:178'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~
# |           215:  pushl %edi 
# | next:178'0     ~~~~~~~~~~~~
# |           216:  .cfi_adjust_cfa_offset 4 
# | next:178'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~
# |           217:  pushl %esi 
# | next:178'0     ~~~~~~~~~~~~
# |           218:  .cfi_adjust_cfa_offset 4 
# | next:178'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~
# |           219:  calll shift_byval_callee@PLT 
# | next:178'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# | next:178'1        ?                           possible intended match
# |           220:  addl $20, %esp 
# | next:178'0     ~~~~~~~~~~~~~~~~
# |           221:  .cfi_adjust_cfa_offset -20 
# | next:178'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# |           222:  popl %esi 
# | next:178'0     ~~~~~~~~~~~
# |           223:  .cfi_def_cfa_offset 8 
# | next:178'0     ~~~~~~~~~~~~~~~~~~~~~~~
# |           224:  popl %edi 
# | next:178'0     ~~~~~~~~~~~
# |             .
# |             .
# |             .
# |           231:  .globl large_caller_from_global # -- Begin function large_caller_from_global 
# | next:178'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# |           232:  .p2align 4 
# | next:178'0     ~~~~~~~~~~~~
# |           233:  .type large_caller_from_global,@function 
# | next:178'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# |           234: large_caller_from_global: # @large_caller_from_global 
# | next:178'0     ~~~~~~~~~~~~~~~~~~~~~~~~~
# |           235:  .cfi_startproc 
# |           236: # %bb.0: # %entry 
# | next:190'0                      X error: no match found
# |           237:  movl large_global+16, %eax 
# | next:190'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# | next:190'1      ?                           possible intended match
# |           238:  movl %eax, 20(%esp) 
# | next:190'0     ~~~~~~~~~~~~~~~~~~~~~
# |           239:  movl large_global+12, %eax 
# | next:190'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# |           240:  movl %eax, 16(%esp) 
# | next:190'0     ~~~~~~~~~~~~~~~~~~~~~
# |           241:  movl large_global+8, %eax 
# | next:190'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~
# |           242:  movl %eax, 12(%esp) 
# | next:190'0     ~~~~~~~~~~~~~~~~~~~~~
# |             .
# |             .
# |             .
# | >>>>>>
# `-----------------------------
# error: command failed with exit status: 1

--

LLVM.CodeGen/X86/sibcall.ll
Exit Code: 1

Command Output (stdout):
--
# RUN: at line 2
/home/gha/actions-runner/_work/llvm-project/llvm-project/build/bin/llc -verify-machineinstrs < /home/gha/actions-runner/_work/llvm-project/llvm-project/llvm/test/CodeGen/X86/sibcall.ll -mtriple=i686-linux   -mcpu=core2 -mattr=+sse2 | /home/gha/actions-runner/_work/llvm-project/llvm-project/build/bin/FileCheck /home/gha/actions-runner/_work/llvm-project/llvm-project/llvm/test/CodeGen/X86/sibcall.ll --check-prefix=X86
# executed command: /home/gha/actions-runner/_work/llvm-project/llvm-project/build/bin/llc -verify-machineinstrs -mtriple=i686-linux -mcpu=core2 -mattr=+sse2
# note: command had no output on stdout or stderr
# executed command: /home/gha/actions-runner/_work/llvm-project/llvm-project/build/bin/FileCheck /home/gha/actions-runner/_work/llvm-project/llvm-project/llvm/test/CodeGen/X86/sibcall.ll --check-prefix=X86
# .---command stderr------------
# | /home/gha/actions-runner/_work/llvm-project/llvm-project/llvm/test/CodeGen/X86/sibcall.ll:298:13: error: X86-NEXT: is not on the line after the previous match
# | ; X86-NEXT: cmpl $0, {{[0-9]+}}(%esp)
# |             ^
# | <stdin>:142:2: note: 'next' match was here
# |  cmpl $0, 24(%esp)
# |  ^
# | <stdin>:140:18: note: previous match ended here
# | # %bb.0: # %entry
# |                  ^
# | <stdin>:141:1: note: non-matching line after previous match is here
# |  subl $20, %esp
# | ^
# | 
# | Input file: <stdin>
# | Check file: /home/gha/actions-runner/_work/llvm-project/llvm-project/llvm/test/CodeGen/X86/sibcall.ll
# | 
# | -dump-input=help explains the following input dump.
# | 
# | Input was:
# | <<<<<<
# |           .
# |           .
# |           .
# |         137:  .p2align 4 
# |         138:  .type t12,@function 
# |         139: t12: # @t12 
# |         140: # %bb.0: # %entry 
# |         141:  subl $20, %esp 
# |         142:  cmpl $0, 24(%esp) 
# | next:298      !~~~~~~~~~~~~~~~~  error: match on wrong line
# |         143:  je .LBB12_1 
# |         144: # %bb.2: # %bb 
# |         145:  addl $20, %esp 
# |         146:  jmp foo6 # TAILCALL 
# |         147: .LBB12_1: # %bb2 
# |           .
# |           .
# |           .
# | >>>>>>
# `-----------------------------
# error: command failed with exit status: 1

--

lldb-api

lldb-api.tools/lldb-dap/output/TestDAP_output.py
Script:
--
/usr/bin/python3 /home/gha/actions-runner/_work/llvm-project/llvm-project/lldb/test/API/dotest.py -u CXXFLAGS -u CFLAGS --env LLVM_LIBS_DIR=/home/gha/actions-runner/_work/llvm-project/llvm-project/build/./lib --env LLVM_INCLUDE_DIR=/home/gha/actions-runner/_work/llvm-project/llvm-project/build/include --env LLVM_TOOLS_DIR=/home/gha/actions-runner/_work/llvm-project/llvm-project/build/./bin --libcxx-include-dir /home/gha/actions-runner/_work/llvm-project/llvm-project/build/include/c++/v1 --libcxx-include-target-dir /home/gha/actions-runner/_work/llvm-project/llvm-project/build/include/x86_64-unknown-linux-gnu/c++/v1 --libcxx-library-dir /home/gha/actions-runner/_work/llvm-project/llvm-project/build/./lib/x86_64-unknown-linux-gnu --arch x86_64 --build-dir /home/gha/actions-runner/_work/llvm-project/llvm-project/build/lldb-test-build.noindex --lldb-module-cache-dir /home/gha/actions-runner/_work/llvm-project/llvm-project/build/lldb-test-build.noindex/module-cache-lldb/lldb-api --clang-module-cache-dir /home/gha/actions-runner/_work/llvm-project/llvm-project/build/lldb-test-build.noindex/module-cache-clang/lldb-api --executable /home/gha/actions-runner/_work/llvm-project/llvm-project/build/./bin/lldb --compiler /home/gha/actions-runner/_work/llvm-project/llvm-project/build/./bin/clang --dsymutil /home/gha/actions-runner/_work/llvm-project/llvm-project/build/./bin/dsymutil --make /usr/bin/gmake --llvm-tools-dir /home/gha/actions-runner/_work/llvm-project/llvm-project/build/./bin --lldb-obj-root /home/gha/actions-runner/_work/llvm-project/llvm-project/build/tools/lldb --lldb-libs-dir /home/gha/actions-runner/_work/llvm-project/llvm-project/build/./lib --cmake-build-type Release /home/gha/actions-runner/_work/llvm-project/llvm-project/lldb/test/API/tools/lldb-dap/output -p TestDAP_output.py
--
Exit Code: 1

Command Output (stdout):
--
lldb version 22.0.0git (https://github.com/llvm/llvm-project revision 2e953353c4a59b1158532e80900f48a6631db84a)
  clang revision 2e953353c4a59b1158532e80900f48a6631db84a
  llvm revision 2e953353c4a59b1158532e80900f48a6631db84a
Skipping the following test categories: ['msvcstl', 'dsym', 'pdb', 'gmodules', 'debugserver', 'objc']

--
Command Output (stderr):
--
/home/gha/actions-runner/_work/llvm-project/llvm-project/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py:394: UserWarning: received a malformed packet, expected 'seq != 0' for {'body': {'$__lldb_version': 'lldb version 22.0.0git (https://github.com/llvm/llvm-project revision 2e953353c4a59b1158532e80900f48a6631db84a)\n  clang revision 2e953353c4a59b1158532e80900f48a6631db84a\n  llvm revision 2e953353c4a59b1158532e80900f48a6631db84a', 'completionTriggerCharacters': ['.', ' ', '\t'], 'exceptionBreakpointFilters': [{'description': 'C++ Catch', 'filter': 'cpp_catch', 'label': 'C++ Catch', 'supportsCondition': True}, {'description': 'C++ Throw', 'filter': 'cpp_throw', 'label': 'C++ Throw', 'supportsCondition': True}, {'description': 'Objective-C Catch', 'filter': 'objc_catch', 'label': 'Objective-C Catch', 'supportsCondition': True}, {'description': 'Objective-C Throw', 'filter': 'objc_throw', 'label': 'Objective-C Throw', 'supportsCondition': True}], 'supportTerminateDebuggee': True, 'supportsBreakpointLocationsRequest': True, 'supportsCancelRequest': True, 'supportsCompletionsRequest': True, 'supportsConditionalBreakpoints': True, 'supportsConfigurationDoneRequest': True, 'supportsDataBreakpoints': True, 'supportsDelayedStackTraceLoading': True, 'supportsDisassembleRequest': True, 'supportsEvaluateForHovers': True, 'supportsExceptionFilterOptions': True, 'supportsExceptionInfoRequest': True, 'supportsFunctionBreakpoints': True, 'supportsHitConditionalBreakpoints': True, 'supportsInstructionBreakpoints': True, 'supportsLogPoints': True, 'supportsModuleSymbolsRequest': True, 'supportsModulesRequest': True, 'supportsReadMemoryRequest': True, 'supportsSetVariable': True, 'supportsSteppingGranularity': True, 'supportsValueFormattingOptions': True, 'supportsWriteMemoryRequest': True}, 'command': 'initialize', 'request_seq': 1, 'seq': 0, 'success': True, 'type': 'response'}
  warnings.warn(
========= DEBUG ADAPTER PROTOCOL LOGS =========
1763909105.254004717 (stdio) --> {"command":"initialize","type":"request","arguments":{"adapterID":"lldb-native","clientID":"vscode","columnsStartAt1":true,"linesStartAt1":true,"locale":"en-us","pathFormat":"path","supportsRunInTerminalRequest":true,"supportsVariablePaging":true,"supportsVariableType":true,"supportsStartDebuggingRequest":true,"supportsProgressReporting":true,"supportsInvalidatedEvent":true,"supportsMemoryEvent":true,"$__lldb_sourceInitFile":false},"seq":1}
1763909105.254084110 (stdio) queued (command=initialize seq=1)
1763909105.256346226 (stdio) <-- {"body":{"$__lldb_version":"lldb version 22.0.0git (https://github.com/llvm/llvm-project revision 2e953353c4a59b1158532e80900f48a6631db84a)\n  clang revision 2e953353c4a59b1158532e80900f48a6631db84a\n  llvm revision 2e953353c4a59b1158532e80900f48a6631db84a","completionTriggerCharacters":["."," ","\t"],"exceptionBreakpointFilters":[{"description":"C++ Catch","filter":"cpp_catch","label":"C++ Catch","supportsCondition":true},{"description":"C++ Throw","filter":"cpp_throw","label":"C++ Throw","supportsCondition":true},{"description":"Objective-C Catch","filter":"objc_catch","label":"Objective-C Catch","supportsCondition":true},{"description":"Objective-C Throw","filter":"objc_throw","label":"Objective-C Throw","supportsCondition":true}],"supportTerminateDebuggee":true,"supportsBreakpointLocationsRequest":true,"supportsCancelRequest":true,"supportsCompletionsRequest":true,"supportsConditionalBreakpoints":true,"supportsConfigurationDoneRequest":true,"supportsDataBreakpoints":true,"supportsDelayedStackTraceLoading":true,"supportsDisassembleRequest":true,"supportsEvaluateForHovers":true,"supportsExceptionFilterOptions":true,"supportsExceptionInfoRequest":true,"supportsFunctionBreakpoints":true,"supportsHitConditionalBreakpoints":true,"supportsInstructionBreakpoints":true,"supportsLogPoints":true,"supportsModuleSymbolsRequest":true,"supportsModulesRequest":true,"supportsReadMemoryRequest":true,"supportsSetVariable":true,"supportsSteppingGranularity":true,"supportsValueFormattingOptions":true,"supportsWriteMemoryRequest":true},"command":"initialize","request_seq":1,"seq":0,"success":true,"type":"response"}
1763909105.257359266 (stdio) --> {"command":"launch","type":"request","arguments":{"program":"/home/gha/actions-runner/_work/llvm-project/llvm-project/build/lldb-test-build.noindex/tools/lldb-dap/output/TestDAP_output.test_output/a.out","initCommands":["settings clear --all","settings set symbols.enable-external-lookup false","settings set target.inherit-tcc true","settings set target.disable-aslr false","settings set target.detach-on-error false","settings set target.auto-apply-fixits false","settings set plugin.process.gdb-remote.packet-timeout 60","settings set symbols.clang-modules-cache-path \"/home/gha/actions-runner/_work/llvm-project/llvm-project/build/lldb-test-build.noindex/module-cache-lldb/lldb-api\"","settings set use-color false","settings set show-statusline false"],"exitCommands":["?script print('out\\0\\0', end='\\r\\n', file=sys.stdout)","?script print('err\\0\\0', end='\\r\\n', file=sys.stderr)"],"disableASLR":false,"enableAutoVariableSummaries":false,"enableSyntheticChildDebugging":false,"displayExtendedBacktrace":false},"seq":2}
1763909105.257419109 (stdio) queued (command=launch seq=2)
1763909105.257755995 (stdio) <-- {"body":{"category":"console","output":"Running initCommands:\n"},"event":"output","seq":1,"type":"event"}
1763909105.257781029 (stdio) <-- {"body":{"category":"console","output":"(lldb) settings clear --all\n"},"event":"output","seq":2,"type":"event"}
1763909105.257792950 (stdio) <-- {"body":{"category":"console","output":"(lldb) settings set symbols.enable-external-lookup false\n"},"event":"output","seq":3,"type":"event"}
1763909105.257805347 (stdio) <-- {"body":{"category":"console","output":"(lldb) settings set target.inherit-tcc true\n"},"event":"output","seq":4,"type":"event"}
1763909105.257816315 (stdio) <-- {"body":{"category":"console","output":"(lldb) settings set target.disable-aslr false\n"},"event":"output","seq":5,"type":"event"}
1763909105.257838249 (stdio) <-- {"body":{"category":"console","output":"(lldb) settings set target.detach-on-error false\n"},"event":"output","seq":6,"type":"event"}
1763909105.257849932 (stdio) <-- {"body":{"category":"console","output":"(lldb) settings set target.auto-apply-fixits false\n"},"event":"output","seq":7,"type":"event"}
1763909105.257863522 (stdio) <-- {"body":{"category":"console","output":"(lldb) settings set plugin.process.gdb-remote.packet-timeout 60\n"},"event":"output","seq":8,"type":"event"}
1763909105.257878304 (stdio) <-- {"body":{"category":"console","output":"(lldb) settings set symbols.clang-modules-cache-path \"/home/gha/actions-runner/_work/llvm-project/llvm-project/build/lldb-test-build.noindex/module-cache-lldb/lldb-api\"\n"},"event":"output","seq":9,"type":"event"}
1763909105.257892847 (stdio) <-- {"body":{"category":"console","output":"(lldb) settings set use-color false\n"},"event":"output","seq":10,"type":"event"}
1763909105.257905960 (stdio) <-- {"body":{"category":"console","output":"(lldb) settings set show-statusline false\n"},"event":"output","seq":11,"type":"event"}
1763909105.290851116 (stdio) <-- {"body":{"module":{"addressRange":"0x78ce4b3a3000","id":"520E0587-8220-FB2F-C6D2-8FF46B63B3FD-5D48E763","name":"ld-linux-x86-64.so.2","path":"/usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2","symbolStatus":"Symbols not found."},"reason":"new"},"event":"module","seq":12,"type":"event"}
1763909105.291045666 (stdio) <-- {"body":{"module":{"addressRange":"0x7ffcd8fec000","id":"DCC023B4-0034-9A37-4105-76387E6AA419-3EC4BB45","name":"[vdso]","path":"[vdso]","symbolStatus":"Symbols not found."},"reason":"new"},"event":"module","seq":13,"type":"event"}
1763909105.291194439 (stdio) <-- {"body":{"module":{"addressRange":"0x56e5ebb71000","debugInfoSize":"1.1KB","id":"B8B5F609","name":"a.out","path":"/home/gha/actions-runner/_work/llvm-project/llvm-project/build/lldb-test-build.noindex/tools/lldb-dap/output/TestDAP_output.test_output/a.out","symbolFilePath":"/home/gha/actions-runner/_work/llvm-project/llvm-project/build/lldb-test-build.noindex/tools/lldb-dap/output/TestDAP_output.test_output/a.out","symbolStatus":"Symbols loaded."},"reason":"new"},"event":"module","seq":14,"type":"event"}
1763909105.291265726 (stdio) <-- {"command":"launch","request_seq":2,"seq":15,"success":true,"type":"response"}
1763909105.291296721 (stdio) <-- {"event":"initialized","seq":16,"type":"event"}
1763909105.291736603 (stdio) --> {"command":"setBreakpoints","type":"request","arguments":{"source":{"path":"main.c"},"sourceModified":false,"lines":[10],"breakpoints":[{"line":10}]},"seq":3}
1763909105.291797161 (stdio) queued (command=setBreakpoints seq=3)
1763909105.293781757 (stdio) <-- {"body":{"breakpoints":[{"column":3,"id":1,"instructionReference":"0x56E5EBB72189","line":10,"source":{"name":"main.c","path":"/home/gha/actions-runner/_work/llvm-project/llvm-project/lldb/test/API/tools/lldb-dap/output/main.c"},"verified":true}]},"command":"setBreakpoints","request_seq":3,"seq":17,"success":true,"type":"response"}
1763909105.293986082 (stdio) <-- {"body":{"breakpoint":{"column":3,"id":1,"instructionReference":"0x56E5EBB72189","line":10,"verified":true},"reason":"changed"},"event":"breakpoint","seq":18,"type":"event"}
1763909105.294171095 (stdio) --> {"command":"configurationDone","type":"request","arguments":{},"seq":4}
1763909105.294209480 (stdio) queued (command=configurationDone seq=4)
1763909105.294302464 (stdio) <-- {"body":{"capabilities":{"supportsModuleSymbolsRequest":true,"supportsRestartRequest":true,"supportsStepInTargetsRequest":true}},"event":"capabilities","seq":19,"type":"event"}
1763909105.294382334 (stdio) <-- {"body":{"isLocalProcess":true,"name":"/home/gha/actions-runner/_work/llvm-project/llvm-project/build/lldb-test-build.noindex/tools/lldb-dap/output/TestDAP_output.test_output/a.out","pointerSize":64,"startMethod":"launch","systemProcessId":1571119},"event":"process","seq":20,"type":"event"}
1763909105.294536114 (stdio) <-- {"command":"configurationDone","request_seq":4,"seq":21,"success":true,"type":"response"}
1763909105.294813633 (stdio) --> {"command":"threads","type":"request","arguments":{},"seq":5}
1763909105.294841051 (stdio) queued (command=threads seq=5)
1763909105.294938803 (stdio) <-- {"body":{"threads":[{"id":1571119,"name":"a.out"}]},"command":"threads","request_seq":5,"seq":22,"success":true,"type":"response"}
1763909105.314837694 (stdio) <-- {"body":{"module":{"addressRange":"0x78ce4b291000","id":"6D1388DB","name":"libc++.so.1","path":"/home/gha/actions-runner/_work/llvm-project/llvm-project/build/lib/x86_64-unknown-linux-gnu/libc++.so.1","symbolFilePath":"/home/gha/actions-runner/_work/llvm-project/llvm-project/build/lib/x86_64-unknown-linux-gnu/libc++.so.1","symbolStatus":"Symbols loaded."},"reason":"new"},"event":"module","seq":23,"type":"event"}
1763909105.314912796 (stdio) <-- {"body":{"module":{"addressRange":"0x78ce4b14c000","id":"F834D730-8D26-6021-8ED4-F7486A58E28C-8464FE4B","name":"libm.so.6","path":"/lib/x86_64-linux-gnu/libm.so.6","symbolStatus":"Symbols not found."},"reason":"new"},"event":"module","seq":24,"type":"event"}
1763909105.314969540 (stdio) <-- {"body":{"module":{"addressRange":"0x78ce4b248000","id":"68887FA8","name":"libc++abi.so.1","path":"/home/gha/actions-runner/_work/llvm-project/llvm-project/build/lib/x86_64-unknown-linux-gnu/libc++abi.so.1","symbolFilePath":"/home/gha/actions-runner/_work/llvm-project/llvm-project/build/lib/x86_64-unknown-linux-gnu/libc++abi.so.1","symbolStatus":"Symbols loaded."},"reason":"new"},"event":"module","seq":25,"type":"event"}
1763909105.314998865 (stdio) <-- {"body":{"module":{"addressRange":"0x78ce4b11e000","id":"30724452-88DD-2ABA-348B-F583C65F7050-9AAB8141","name":"libgcc_s.so.1","path":"/lib/x86_64-linux-gnu/libgcc_s.so.1","symbolStatus":"Symbols not found."},"reason":"new"},"event":"module","seq":26,"type":"event"}
1763909105.315025806 (stdio) <-- {"body":{"module":{"addressRange":"0x78ce4af0a000","id":"274EEC48-8D23-0825-A136-FA9C4D85370F-ED7A0A5E","name":"libc.so.6","path":"/lib/x86_64-linux-gnu/libc.so.6","symbolStatus":"Symbols not found."},"reason":"new"},"event":"module","seq":27,"type":"event"}
1763909105.315053225 (stdio) <-- {"body":{"module":{"addressRange":"0x78ce4aeff000","id":"D2D793C5-CDFA-B4C2-E083-F41AAF689B69-4B62EACD","name":"libatomic.so.1","path":"/lib/x86_64-linux-gnu/libatomic.so.1","symbolStatus":"Symbols not found."},"reason":"new"},"event":"module","seq":28,"type":"event"}
1763909105.315101862 (stdio) <-- {"body":{"module":{"addressRange":"0x78ce4b238000","id":"066DDA31","name":"libunwind.so.1","path":"/home/gha/actions-runner/_work/llvm-project/llvm-project/build/lib/x86_64-unknown-linux-gnu/libunwind.so.1","symbolFilePath":"/home/gha/actions-runner/_work/llvm-project/llvm-project/build/lib/x86_64-unknown-linux-gnu/libunwind.so.1","symbolStatus":"Symbols loaded."},"reason":"new"},"event":"module","seq":29,"type":"event"}
1763909105.317746878 (stdio) <-- {"body":{"category":"stdout","output":"abcdefghi\r\n"},"event":"output","seq":30,"type":"event"}
1763909105.318130493 (stdio) <-- {"body":{"allThreadsStopped":true,"description":"breakpoint 1.1","hitBreakpointIds":[1],"preserveFocusHint":false,"reason":"breakpoint","threadCausedFocus":true,"threadId":1571119},"event":"stopped","seq":31,"type":"event"}
1763909105.568600416 (stdio) --> {"command":"threads","type":"request","arguments":{},"seq":6}
1763909105.568668365 (stdio) queued (command=threads seq=6)
1763909105.568807840 (stdio) <-- {"body":{"threads":[{"id":1571119,"name":"a.out"}]},"command":"threads","request_seq":6,"seq":32,"success":true,"type":"response"}
1763909105.569100142 (stdio) --> {"command":"continue","type":"request","arguments":{"threadId":1571119},"seq":7}
1763909105.569124460 (stdio) queued (command=continue seq=7)
1763909105.569546223 (stdio) <-- {"body":{"allThreadsContinued":true},"command":"continue","request_seq":7,"seq":33,"success":true,"type":"response"}
1763909105.569609165 (stdio) <-- {"body":{"allThreadsContinued":true,"threadId":1571119},"event":"continued","seq":34,"type":"event"}
1763909105.571389675 (stdio) <-- {"body":{"category":"stdout","output":"hello world\r\n"},"event":"output","seq":35,"type":"event"}
1763909105.571436405 (stdio) <-- {"body":{"category":"stdout","output":"finally\u0000\u0000"},"event":"output","seq":36,"type":"event"}
1763909105.571929693 (stdio) <-- {"body":{"category":"console","output":"Process 1571119 exited with status = 0 (0x00000000) \n"},"event":"output","seq":37,"type":"event"}
1763909105.606371641 (stdio) <-- {"body":{"category":"console","output":"out\u0000\u0000\r\n"},"event":"output","seq":38,"type":"event"}
1763909105.607188225 (stdio) <-- {"body":{"exitCode":0},"event":"exited","seq":39,"type":"event"}
1763909105.609311342 (stdio) --> {"command":"disconnect","type":"request","arguments":{},"seq":8}
1763909105.609346867 (stdio) queued (command=disconnect seq=8)
1763909105.610314846 (stdio) <-- {"body":{"$__lldb_statistics":{"commands":"{\"settings clear\":1}","memory":"{\"strings\":{\"bytesTotal\":1056768,\"bytesUnused\":427907,\"bytesUsed\":628861}}","plugins":"{\"abi\":[{\"enabled\":true,\"name\":\"SysV-arm64\"},{\"enabled\":true,\"name\":\"ABIMacOSX_arm64\"},{\"enabled\":true,\"name\":\"SysV-arm\"},{\"enabled\":true,\"name\":\"macosx-arm\"},{\"enabled\":true,\"name\":\"sysv-hexagon\"},{\"enabled\":true,\"name\":\"sysv-loongarch\"},{\"enabled\":true,\"name\":\"sysv-mips\"},{\"enabled\":true,\"name\":\"sysv-mips64\"},{\"enabled\":true,\"name\":\"sysv-msp430\"},{\"enabled\":true,\"name\":\"sysv-ppc\"},{\"enabled\":true,\"name\":\"sysv-ppc64\"},{\"enabled\":true,\"name\":\"sysv-riscv\"},{\"enabled\":true,\"name\":\"sysv-s390x\"},{\"enabled\":true,\"name\":\"abi.macosx-i386\"},{\"enabled\":true,\"name\":\"sysv-i386\"},{\"enabled\":true,\"name\":\"sysv-x86_64\"},{\"enabled\":true,\"name\":\"windows-x86_64\"}],\"architecture\":[{\"enabled\":true,\"name\":\"arm\"},{\"enabled\":true,\"name\":\"mips\"},{\"enabled\":true,\"name\":\"ppc64\"},{\"enabled\":true,\"name\":\"aarch64\"}],\"disassembler\":[{\"enabled\":true,\"name\":\"llvm-mc\"}],\"dynamic-loader\":[{\"enabled\":true,\"name\":\"darwin-kernel\"},{\"enabled\":true,\"name\":\"freebsd-kernel\"},{\"enabled\":true,\"name\":\"macosx-dyld\"},{\"enabled\":true,\"name\":\"macos-dyld\"},{\"enabled\":true,\"name\":\"posix-dyld\"},{\"enabled\":true,\"name\":\"static\"},{\"enabled\":true,\"name\":\"hexagon-dyld\"},{\"enabled\":true,\"name\":\"windows-dyld\"},{\"enabled\":true,\"name\":\"wasm-dyld\"}],\"emulate-instruction\":[{\"enabled\":true,\"name\":\"arm\"},{\"enabled\":true,\"name\":\"arm64\"},{\"enabled\":true,\"name\":\"LoongArch\"},{\"enabled\":true,\"name\":\"mips32\"},{\"enabled\":true,\"name\":\"mips64\"},{\"enabled\":true,\"name\":\"ppc64\"},{\"enabled\":true,\"name\":\"riscv\"}],\"instrumentation-runtime\":[{\"enabled\":true,\"name\":\"AddressSanitizer\"},{\"enabled\":true,\"name\":\"Libsanitizers-ASan\"},{\"enabled\":true,\"name\":\"MainThreadChecker\"},{\"enabled\":true,\"name\":\"ThreadSanitizer\"},{\"enabled\":true,\"name\":\"UndefinedBehaviorSanitizer\"}],\"jit-loader\":[{\"enabled\":true,\"name\":\"gdb\"}],\"language\":[{\"enabled\":true,\"name\":\"cplusplus\"},{\"enabled\":true,\"name\":\"objc\"},{\"enabled\":true,\"name\":\"objcplusplus\"}],\"language-runtime\":[{\"enabled\":true,\"name\":\"itanium\"},{\"enabled\":true,\"name\":\"apple-objc-v2\"},{\"enabled\":true,\"name\":\"apple-objc-v1\"},{\"enabled\":true,\"name\":\"gnustep-objc-libobjc2\"}],\"memory-history\":[{\"enabled\":true,\"name\":\"asan\"}],\"object-container\":[{\"enabled\":true,\"name\":\"bsd-archive\"},{\"enabled\":true,\"name\":\"mach-o\"},{\"enabled\":true,\"name\":\"mach-o-fileset\"}],\"object-file\":[{\"enabled\":true,\"name\":\"breakpad\"},{\"enabled\":true,\"name\":\"COFF\"},{\"enabled\":true,\"name\":\"elf\"},{\"enabled\":true,\"name\":\"JSON\"},{\"enabled\":true,\"name\":\"mach-o\"},{\"enabled\":true,\"name\":\"minidump\"},{\"enabled\":true,\"name\":\"pdb\"},{\"enabled\":true,\"name\":\"pe-coff\"},{\"enabled\":true,\"name\":\"xcoff\"},{\"enabled\":true,\"name\":\"wasm\"}],\"operating-system\":[{\"enabled\":true,\"name\":\"python\"}],\"platform\":[{\"enabled\":true,\"name\":\"remote-AIX\"},{\"enabled\":true,\"name\":\"remote-linux\"},{\"enabled\":true,\"name\":\"remote-android\"},{\"enabled\":true,\"name\":\"remote-freebsd\"},{\"enabled\":true,\"name\":\"remote-gdb-server\"},{\"enabled\":true,\"name\":\"darwin\"},{\"enabled\":true,\"name\":\"remote-ios\"},{\"enabled\":true,\"name\":\"remote-macosx\"},{\"enabled\":true,\"name\":\"host\"},{\"enabled\":true,\"name\":\"remote-netbsd\"},{\"enabled\":true,\"name\":\"remote-openbsd\"},{\"enabled\":true,\"name\":\"qemu-user\"},{\"enabled\":true,\"name\":\"remote-windows\"}],\"process\":[{\"enabled\":true,\"name\":\"ScriptedProcess\"},{\"enabled\":true,\"name\":\"elf-core\"},{\"enabled\":true,\"name\":\"mach-o-core\"},{\"enabled\":true,\"name\":\"minidump\"},{\"enabled\":true,\"name\":\"wasm\"},{\"enabled\":true,\"name\":\"gdb-remote\"}],\"register-type-builder\":[{\"enabled\":true,\"name\":\"register-types-clang\"}],\"repl\":[{\"enabled\":true,\"name\":\"ClangREPL\"}],\"script-interpreter\":[{\"enabled\":true,\"name\":\"script-none\"},{\"enabled\":true,\"name\":\"script-python\"}],\"scripted-interface\":[{\"enabled\":true,\"name\":\"OperatingSystemPythonInterface\"},{\"enabled\":true,\"name\":\"ScriptedPlatformPythonInterface\"},{\"enabled\":true,\"name\":\"ScriptedProcessPythonInterface\"},{\"enabled\":true,\"name\":\"ScriptedStopHookPythonInterface\"},{\"enabled\":true,\"name\":\"ScriptedBreakpointPythonInterface\"},{\"enabled\":true,\"name\":\"ScriptedThreadPlanPythonInterface\"}],\"structured-data\":[{\"enabled\":true,\"name\":\"darwin-log\"}],\"symbol-file\":[{\"enabled\":true,\"name\":\"breakpad\"},{\"enabled\":true,\"name\":\"CTF\"},{\"enabled\":true,\"name\":\"dwarf\"},{\"enabled\":true,\"name\":\"dwarf-debugmap\"},{\"enabled\":true,\"name\":\"JSON\"},{\"enabled\":true,\"name\":\"native-pdb\"},{\"enabled\":true,\"name\":\"pdb\"},{\"enabled\":true,\"name\":\"symtab\"}],\"symbol-locator\":[{\"enabled\":true,\"name\":\"debuginfod\"},{\"enabled\":true,\"name\":\"Default\"}],\"symbol-vendor\":[{\"enabled\":true,\"name\":\"ELF\"},{\"enabled\":true,\"name\":\"PE-COFF\"},{\"enabled\":true,\"name\":\"WASM\"}],\"system-runtime\":[{\"enabled\":true,\"name\":\"systemruntime-macosx\"}],\"trace-exporter\":[{\"enabled\":true,\"name\":\"ctf\"}],\"type-system\":[{\"enabled\":true,\"name\":\"clang\"}],\"unwind-assembly\":[{\"enabled\":true,\"name\":\"inst-emulation\"},{\"enabled\":true,\"name\":\"x86\"}]}","targets":"[{\"breakpoints\":[{\"details\":{\"Breakpoint\":{\"BKPTOptions\":{\"AutoContinue\":false,\"ConditionText\":\"\",\"EnabledState\":true,\"IgnoreCount\":0,\"OneShotState\":false},\"BKPTResolver\":{\"Options\":{\"Column\":0,\"Exact\":false,\"FileName\":\"/home/gha/actions-runner/_work/llvm-project/llvm-project/lldb/test/API/tools/lldb-dap/output/main.c\",\"Inlines\":true,\"LineNumber\":10,\"Offset\":0,\"SkipPrologue\":true},\"Type\":\"FileAndLine\"},\"Hardware\":false,\"Names\":[\"dap\"],\"SearchFilter\":{\"Options\":{},\"Type\":\"Unconstrained\"}}},\"hitCount\":1,\"id\":1,\"internal\":false,\"numLocations\":1,\"numResolvedLocations\":1,\"resolveTime\":0.001096},{\"details\":{\"Breakpoint\":{\"BKPTOptions\":{\"AutoContinue\":false,\"ConditionText\":\"\",\"EnabledState\":true,\"IgnoreCount\":0,\"OneShotState\":false},\"BKPTResolver\":{\"Options\":{\"Language\":\"c\",\"NameMask\":[4,4,4,4,4,4],\"Offset\":0,\"SkipPrologue\":false,\"SymbolNames\":[\"_dl_debug_state\",\"rtld_db_dlactivity\",\"__dl_rtld_db_dlactivity\",\"r_debug_state\",\"_r_debug_state\",\"_rtld_debug_state\"]},\"Type\":\"SymbolName\"},\"Hardware\":false,\"SearchFilter\":{\"Options\":{\"ModuleList\":[\"/usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2\"]},\"Type\":\"Modules\"}}},\"hitCount\":2,\"id\":-1,\"internal\":true,\"kindDescription\":\"shared-library-event\",\"numLocations\":1,\"numResolvedLocations\":1,\"resolveTime\":0.000145}],\"dyldPluginName\":\"posix-dyld\",\"expressionEvaluation\":{\"failures\":0,\"successes\":0},\"firstStopTime\":0.017677515000000001,\"frameVariable\":{\"failures\":0,\"successes\":0},\"launchOrAttachTime\":0.014045663,\"moduleIdentifiers\":[178959040,179548032,177843520,134589511109712,134589578218512,134589444001104,134589846655792,134589309782976,134588907129792,134589108456384],\"signals\":[{\"SIGSTOP\":1}],\"sourceMapDeduceCount\":0,\"sourceRealpathAttemptCount\":0,\"sourceRealpathCompatibleCount\":0,\"stopCount\":8,\"summaryProviderStatistics\":[],\"targetCreateTime\":0.014109999999999999,\"totalBreakpointResolveTime\":0.0012409999999999999,\"totalSharedLibraryEventHitCount\":2}]","totalDebugInfoByteSize":1165,"totalDebugInfoEnabled":1,"totalDebugInfoIndexLoadedFromCache":0,"totalDebugInfoIndexSavedToCache":0,"totalDebugInfoIndexTime":0.012600999999999999,"totalDebugInfoParseTime":0.000111,"totalDwoErrorCount":0,"totalDwoFileCount":0,"totalLoadedDwoFileCount":0,"totalModuleCount":10,"totalModuleCountHasDebugInfo":1,"totalModuleCountWithIncompleteTypes":0,"totalModuleCountWithVariableErrors":0,"totalSymbolLocatorTime":"{\"Default\":0.0040379999999999999,\"debuginfod\":0}","totalSymbolTableIndexTime":0.0072390000000000015,"totalSymbolTableParseTime":0.041769000000000001,"totalSymbolTableStripped":0,"totalSymbolTableSymbolCount":12630,"totalSymbolTablesLoaded":10,"totalSymbolTablesLoadedFromCache":0,"totalSymbolTablesSavedToCache":0}},"event":"terminated","seq":40,"type":"event"}
1763909105.610524178 (stdio) <-- {"command":"disconnect","request_seq":8,"seq":41,"success":true,"type":"response"}
1763909105.610593081 (stdio) <-- {"body":{"category":"console","output":"err\u0000\u0000\r\n"},"event":"output","seq":42,"type":"event"}

========= END =========
FAIL: LLDB (/home/gha/actions-runner/_work/llvm-project/llvm-project/build/bin/clang-x86_64) :: test_output (TestDAP_output.TestDAP_output.test_output)
======================================================================
FAIL: test_output (TestDAP_output.TestDAP_output.test_output)
   Test output handling for the running process.
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/gha/actions-runner/_work/llvm-project/llvm-project/lldb/test/API/tools/lldb-dap/output/TestDAP_output.py", line 49, in test_output
    self.assertIn(
AssertionError: 'out\x00\x00\r\nerr\x00\x00\r\n' not found in 'Running initCommands:\n(lldb) settings clear --all\n(lldb) settings set symbols.enable-external-lookup false\n(lldb) settings set target.inherit-tcc true\n(lldb) settings set target.disable-aslr false\n(lldb) settings set target.detach-on-error false\n(lldb) settings set target.auto-apply-fixits false\n(lldb) settings set plugin.process.gdb-remote.packet-timeout 60\n(lldb) settings set symbols.clang-modules-cache-path "/home/gha/actions-runner/_work/llvm-project/llvm-project/build/lldb-test-build.noindex/module-cache-lldb/lldb-api"\n(lldb) settings set use-color false\n(lldb) settings set show-statusline false\nProcess 1571119 exited with status = 0 (0x00000000) \nout\x00\x00\r\n' : full console message not found
Config=x86_64-/home/gha/actions-runner/_work/llvm-project/llvm-project/build/bin/clang
----------------------------------------------------------------------
Ran 1 test in 0.737s

FAILED (failures=1)

--

If these failures are unrelated to your changes (for example tests are broken or flaky at HEAD), please open an issue at https://github.com/llvm/llvm-project/issues and add the infrastructure label.

@efriedma-quic
Copy link
Collaborator

As discussed in https://reviews.llvm.org/D131034, this is still broken in cases where the argument lists don't match. If you want an example of how to handle this case, see #109943.

@folkertdev
Copy link
Contributor Author

As discussed in https://reviews.llvm.org/D131034, this is still broken in cases where the argument lists don't match. If you want an example of how to handle this case, see #109943.

Interesting, I had been looking for something like that. However, #168506 appears to use a different, simpler approach to order the reads and writes. Does that look right (and perhaps preferable) to you?

@efriedma-quic
Copy link
Collaborator

As far as I can tell, LoongArchTargetLowering::LowerCall always copies byval arguments to a temporary, then copies them into the argument list. Which is a legal implementation, but not really optimized.

@folkertdev
Copy link
Contributor Author

Allright, so generally you'd like to see an x86 implementation that resembles the arm one more? Because currently the x86 implementation is quite different (and, as established, very broken).

This will be tough (for me) but I'm willing to give that a go.

@efriedma-quic
Copy link
Collaborator

I'd prefer the more optimized implementation... but really, I'd be okay with any complete implementation that doesn't regress non-musttail cases. I just don't want to leave a lurking miscompile.

In particular, we don't need to bother with shuffling arguments around
on the stack, because in the x86 backend, only functions that do not
need to move arguments around on the stack are considered sibcalls.
Comment on lines +2035 to +2040
// Can only analyse frame index nodes, conservatively assume we need a
// temporary.
auto *SrcFrameIdxNode = dyn_cast<FrameIndexSDNode>(Src);
auto *DstFrameIdxNode = dyn_cast<FrameIndexSDNode>(Dst);
if (!SrcFrameIdxNode || !DstFrameIdxNode)
return CopyViaTemp;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The function always returns here in my tests so far, is there some sort of setup that isn't happening in the x86 backend?

Comment on lines +2052 to +2058
// // If the source is in the local frame, then the copy to the argument
// memory
// // is always valid.
// bool FixedSrc = MFI.isFixedObjectIndex(SrcFI);
// if (!FixedSrc ||
// (FixedSrc && SrcOffset < -(int64_t)AFI->getArgRegsSaveSize()))
// return CopyOnce;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure how to implement getArgRegsSaveSize for x86, basically this bit of code

AFI->setArgRegsSaveSize(0);
// Calculate the amount of stack space that we need to allocate to store
// byval and variadic arguments that are passed in registers.
// We need to know this before we allocate the first byval or variadic
// argument, as they will be allocated a stack slot below the CFA (Canonical
// Frame Address, the stack pointer at entry to the function).
unsigned ArgRegBegin = ARM::R4;
for (const CCValAssign &VA : ArgLocs) {
if (CCInfo.getInRegsParamsProcessed() >= CCInfo.getInRegsParamsCount())
break;
unsigned Index = VA.getValNo();
ISD::ArgFlagsTy Flags = Ins[Index].Flags;
if (!Flags.isByVal())
continue;
assert(VA.isMemLoc() && "unexpected byval pointer in reg");
unsigned RBegin, REnd;
CCInfo.getInRegsParamInfo(CCInfo.getInRegsParamsProcessed(), RBegin, REnd);
ArgRegBegin = std::min(ArgRegBegin, RBegin);
CCInfo.nextInRegsParam();
}
CCInfo.rewindByValRegsInfo();
int lastInsIndex = -1;
if (isVarArg && MFI.hasVAStart()) {
unsigned RegIdx = CCInfo.getFirstUnallocated(GPRArgRegs);
if (RegIdx != std::size(GPRArgRegs))
ArgRegBegin = std::min(ArgRegBegin, (unsigned)GPRArgRegs[RegIdx]);
}
unsigned TotalArgRegsSaveSize = 4 * (ARM::R4 - ArgRegBegin);
AFI->setArgRegsSaveSize(TotalArgRegsSaveSize);
auto PtrVT = getPointerTy(DAG.getDataLayout());

Is this not already tracked somewhere?

Comment on lines -2101 to +2159
if (isTailCall && !IsMustTail) {
if (isTailCall) {
// Check if it's really possible to do a tail call.
isTailCall = IsEligibleForTailCallOptimization(CLI, CCInfo, ArgLocs,
IsCalleePopSRet);
IsSibcall = IsEligibleForTailCallOptimization(CLI, CCInfo, ArgLocs,
IsCalleePopSRet);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

these changes to the sibcall logic are still needed to optimize to just a jmp in the case where arguments are just passed on (i.e. no stack shuffling is needed).

Comment on lines +2212 to +2217
// If we are doing a tail-call, any byval arguments will be written to stack
// space which was used for incoming arguments. If any the values being used
// are incoming byval arguments to this function, then they might be
// overwritten by the stores of the outgoing arguments. To avoid this, we
// need to make a temporary copy of them in local stack space, then copy back
// to the argument area.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sort of as a general question: wouldn't more code sharing between backends be a good idea? each backend reinventing this wheel just seems kind of unfortunate.

Anyway, this is my best effort of translating this from the arm backend.

Comment on lines +2547 to +2552
auto PtrVT = getPointerTy(DAG.getDataLayout());
SDValue DstAddr = DAG.getFrameIndex(FI, PtrVT);

// Copy the struct contents from ByValSrc to DstAddr.
MemOpChains2.push_back(CreateCopyOfByValArgument(
ByValSrc, DstAddr, Chain, Flags, DAG, dl));
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So in the arm backend this logic is guareded with an if (NeedsStackCopy), but even in my simple cases the ByValTemporaries appears to be empty (that does make sense, given how ByValNeedsCopyForTailCall exits early where I commented), but the CreateCopyOfByValArgument is still needed.

Comment on lines 74 to 88
define dso_local i32 @swapByValArguments(ptr byval(%struct.1xi32) %0, ptr byval(%struct.1xi32) %1) {
; CHECK-LABEL: swapArguments:
; CHECK: # %bb.0:

; CHECK-NEXT: mov eax, dword ptr [rsp + 8]
; CHECK-NEXT: mov dword ptr [rsp - 16], eax
; CHECK-NEXT: mov ecx, dword ptr [rsp + 16]
; CHECK-NEXT: mov dword ptr [rsp - 8], ecx

; CHECK-NEXT: mov dword ptr [rsp + 8], ecx
; CHECK-NEXT: mov dword ptr [rsp + 16], eax
; CHECK-NEXT: jmp swap # TAILCALL
%r = musttail call i32 @swap(ptr byval(%struct.1xi32) %1, ptr byval(%struct.1xi32) %0)
ret i32 %r
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in this case the copy to the stack is not needed, there is sufficient register space. The arm logic doesn't seem to consider that case (likely because in practice by-val parameters are larger, and it's unlikely that there is sufficient space in register?)

@folkertdev folkertdev force-pushed the x86-musttail-sibcalls branch from 839564d to 4636011 Compare November 22, 2025 19:52
@folkertdev
Copy link
Contributor Author

Allright, I gave this a go, but I'll need some help polishing this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Miscompile with [[clang::musttail]] [Backend][X86] Incorrect output + missed optimization for function marked as clang::musttail

3 participants