[llvm-branch-commits] [llvm] release/22.x: [LoongArch] Fix incorrect indexing of incoming byval arguments in tail call eligibility check (#188006) (PR #188666)
via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Wed Mar 25 19:49:40 PDT 2026
https://github.com/heiher created https://github.com/llvm/llvm-project/pull/188666
Backport only the LoongArch part of ab17b5408ac83a03807b6f0ea22f51dfb84b0b8a, skip the RISC-V part due to unresolvable conflicts.
Requested by: @heiher
>From 692e4b087bf47ac670c272fd781be1c1e5ce3c98 Mon Sep 17 00:00:00 2001
From: hev <wangrui at loongson.cn>
Date: Wed, 25 Mar 2026 23:26:08 +0800
Subject: [PATCH] [LoongArch] Fix incorrect indexing of incoming byval
arguments in tail call eligibility check (#188006)
The loop that validates byval arguments in
`isEligibleForTailCallOptimization()` incorrectly used the loop index
`i` when accessing `getIncomingByValArgs()`, even though `j` is the
index tracking the number of encountered byval arguments.
This mismatch could lead to out-of-bounds access or incorrect type
comparisons when non-byval arguments are interleaved with byval
arguments, causing the tail call eligibility check to fail or behave
incorrectly.
Fix this by using `j` consistently as the index into the incoming byval
argument list and only incrementing it after the bounds check.
Fixes #187832
(cherry picked from commit ab17b5408ac83a03807b6f0ea22f51dfb84b0b8a)
---
.../LoongArch/LoongArchISelLowering.cpp | 7 +--
llvm/test/CodeGen/LoongArch/issue187832.ll | 48 +++++++++++++++++++
2 files changed, 52 insertions(+), 3 deletions(-)
create mode 100644 llvm/test/CodeGen/LoongArch/issue187832.ll
diff --git a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
index 755e2afa2bf04..8b0754599f13d 100644
--- a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
+++ b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
@@ -8358,13 +8358,14 @@ bool LoongArchTargetLowering::isEligibleForTailCallOptimization(
return false;
// Do not tail call opt if caller's and callee's byval arguments do not match.
- for (unsigned i = 0, j = 0; i < Outs.size(); i++) {
+ for (unsigned i = 0, j = 0; i < Outs.size(); ++i) {
if (!Outs[i].Flags.isByVal())
continue;
- if (j++ >= LoongArchFI->getIncomingByValArgsSize())
+ if (j >= LoongArchFI->getIncomingByValArgsSize())
return false;
- if (LoongArchFI->getIncomingByValArgs(i).getValueType() != Outs[i].ArgVT)
+ if (LoongArchFI->getIncomingByValArgs(j).getValueType() != Outs[i].ArgVT)
return false;
+ ++j;
}
// The callee has to preserve all registers the caller needs to preserve.
diff --git a/llvm/test/CodeGen/LoongArch/issue187832.ll b/llvm/test/CodeGen/LoongArch/issue187832.ll
new file mode 100644
index 0000000000000..b483a7640e171
--- /dev/null
+++ b/llvm/test/CodeGen/LoongArch/issue187832.ll
@@ -0,0 +1,48 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
+; RUN: llc -mtriple=loongarch32 %s -o - | FileCheck %s --check-prefix=LA32
+; RUN: llc -mtriple=loongarch64 %s -o - | FileCheck %s --check-prefix=LA64
+
+%Box = type { i32, i32, i32, i8, [3 x i8], i32, i8, [1 x i8], i16, i16, i8, [5 x i8], { i64, ptr }, { i64, ptr }, { i64, ptr } }
+
+define void @test(ptr byval(%Box) %0) nounwind {
+; LA32-LABEL: test:
+; LA32: # %bb.0:
+; LA32-NEXT: addi.w $sp, $sp, -112
+; LA32-NEXT: st.w $ra, $sp, 108 # 4-byte Folded Spill
+; LA32-NEXT: st.w $fp, $sp, 104 # 4-byte Folded Spill
+; LA32-NEXT: addi.w $fp, $sp, 24
+; LA32-NEXT: ori $a2, $zero, 80
+; LA32-NEXT: move $a0, $fp
+; LA32-NEXT: move $a1, $zero
+; LA32-NEXT: bl memcpy
+; LA32-NEXT: st.w $zero, $sp, 8
+; LA32-NEXT: st.w $zero, $sp, 4
+; LA32-NEXT: st.w $zero, $sp, 0
+; LA32-NEXT: move $a0, $zero
+; LA32-NEXT: move $a1, $zero
+; LA32-NEXT: move $a2, $zero
+; LA32-NEXT: move $a3, $fp
+; LA32-NEXT: move $a4, $zero
+; LA32-NEXT: move $a5, $zero
+; LA32-NEXT: move $a6, $zero
+; LA32-NEXT: move $a7, $zero
+; LA32-NEXT: jirl $ra, $zero, 0
+; LA32-NEXT: ld.w $fp, $sp, 104 # 4-byte Folded Reload
+; LA32-NEXT: ld.w $ra, $sp, 108 # 4-byte Folded Reload
+; LA32-NEXT: addi.w $sp, $sp, 112
+; LA32-NEXT: ret
+;
+; LA64-LABEL: test:
+; LA64: # %bb.0:
+; LA64-NEXT: movgr2fr.d $fa0, $zero
+; LA64-NEXT: move $a0, $zero
+; LA64-NEXT: move $a1, $zero
+; LA64-NEXT: move $a2, $zero
+; LA64-NEXT: move $a3, $zero
+; LA64-NEXT: move $a4, $zero
+; LA64-NEXT: move $a5, $zero
+; LA64-NEXT: move $a6, $zero
+; LA64-NEXT: jr $a0
+ tail call void null(ptr null, double 0.000000e+00, ptr byval(%Box) null, { i64, ptr } zeroinitializer, i32 0, i64 0, i1 false)
+ ret void
+}
More information about the llvm-branch-commits
mailing list