aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChen Zheng <czhengsz@cn.ibm.com>2021-07-01 09:41:03 +0000
committerChen Zheng <czhengsz@cn.ibm.com>2021-08-27 01:58:41 +0000
commit324bd467a217d89b5ab84a8ed66c0d3dc431782a (patch)
treee31354a71677c93b5dcd7bbb0197e0aeed282e2d
parent088cc63640f4593a0af1fc81859853d5ee0d00ef (diff)
downloadllvm-324bd467a217d89b5ab84a8ed66c0d3dc431782a.zip
llvm-324bd467a217d89b5ab84a8ed66c0d3dc431782a.tar.gz
llvm-324bd467a217d89b5ab84a8ed66c0d3dc431782a.tar.bz2
[PowerPC][ELF] make sure local variable space does not overlap with parameter save area
Reviewed By: jsji Differential Revision: https://reviews.llvm.org/D105271
-rw-r--r--llvm/lib/Target/PowerPC/PPCISelLowering.cpp26
-rw-r--r--llvm/test/CodeGen/PowerPC/byval.ll11
2 files changed, 22 insertions, 15 deletions
diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
index 6d38b39f..838ac93 100644
--- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
+++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
@@ -3878,7 +3878,8 @@ static Align CalculateStackSlotAlignment(EVT ArgVT, EVT OrigVT,
/// stack slot (instead of being passed in registers). ArgOffset,
/// AvailableFPRs, and AvailableVRs must hold the current argument
/// position, and will be updated to account for this argument.
-static bool CalculateStackSlotUsed(EVT ArgVT, EVT OrigVT, ISD::ArgFlagsTy Flags,
+static bool CalculateStackSlotUsed(const PPCSubtarget &Subtarget, EVT ArgVT,
+ EVT OrigVT, ISD::ArgFlagsTy Flags,
unsigned PtrByteSize, unsigned LinkageSize,
unsigned ParamAreaSize, unsigned &ArgOffset,
unsigned &AvailableFPRs,
@@ -3919,7 +3920,13 @@ static bool CalculateStackSlotUsed(EVT ArgVT, EVT OrigVT, ISD::ArgFlagsTy Flags,
--AvailableVRs;
return false;
}
- }
+ } else if (Subtarget.isPPC64() && Subtarget.isELFv2ABI() &&
+ Flags.getByValSize() >= 8)
+ // For 64-bit ELF v2, passing by value object whose size is no less than 8
+ // bytes will be copied to parameter save area. This is for compatibility
+ // for other compiler which requires byval parameters to be stored in
+ // caller's parameter save area.
+ return true;
return UseMemory;
}
@@ -4262,7 +4269,7 @@ SDValue PPCTargetLowering::LowerFormalArguments_64SVR4(
if (Ins[i].Flags.isNest())
continue;
- if (CalculateStackSlotUsed(Ins[i].VT, Ins[i].ArgVT, Ins[i].Flags,
+ if (CalculateStackSlotUsed(Subtarget, Ins[i].VT, Ins[i].ArgVT, Ins[i].Flags,
PtrByteSize, LinkageSize, ParamAreaSize,
NumBytes, AvailableFPRs, AvailableVRs))
HasParameterArea = true;
@@ -4723,9 +4730,9 @@ needStackSlotPassParameters(const PPCSubtarget &Subtarget,
for (const ISD::OutputArg& Param : Outs) {
if (Param.Flags.isNest()) continue;
- if (CalculateStackSlotUsed(Param.VT, Param.ArgVT, Param.Flags, PtrByteSize,
- LinkageSize, ParamAreaSize, NumBytes,
- AvailableFPRs, AvailableVRs))
+ if (CalculateStackSlotUsed(Subtarget, Param.VT, Param.ArgVT, Param.Flags,
+ PtrByteSize, LinkageSize, ParamAreaSize,
+ NumBytes, AvailableFPRs, AvailableVRs))
return true;
}
return false;
@@ -5961,9 +5968,10 @@ SDValue PPCTargetLowering::LowerCall_64SVR4(
unsigned NumBytesTmp = NumBytes;
for (unsigned i = 0; i != NumOps; ++i) {
if (Outs[i].Flags.isNest()) continue;
- if (CalculateStackSlotUsed(Outs[i].VT, Outs[i].ArgVT, Outs[i].Flags,
- PtrByteSize, LinkageSize, ParamAreaSize,
- NumBytesTmp, AvailableFPRs, AvailableVRs))
+ if (CalculateStackSlotUsed(Subtarget, Outs[i].VT, Outs[i].ArgVT,
+ Outs[i].Flags, PtrByteSize, LinkageSize,
+ ParamAreaSize, NumBytesTmp, AvailableFPRs,
+ AvailableVRs))
HasParameterArea = true;
}
}
diff --git a/llvm/test/CodeGen/PowerPC/byval.ll b/llvm/test/CodeGen/PowerPC/byval.ll
index c67cc10..e6ad0f4 100644
--- a/llvm/test/CodeGen/PowerPC/byval.ll
+++ b/llvm/test/CodeGen/PowerPC/byval.ll
@@ -1,4 +1,3 @@
-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc -verify-machineinstrs < %s | FileCheck %s
target datalayout = "e-m:e-i64:64-n32:64-S128-v256:256:256-v512:512:512"
@@ -9,15 +8,15 @@ target triple = "powerpc64le-unknown-linux-gnu"
declare dso_local i32 @foo1(%struct* byval(%struct) %var)
declare dso_local void @foo(%struct* %var)
-; FIXME: for the byval parameter %x, now the memory for local variable and
-; for parameter save area are overlap.
+; for the byval parameter %x, make sure the memory for local variable and
+; for parameter save area are not overlap.
; For the below case,
-; the local variable space is r1 + 40 ~ r1 + 76
+; the local variable space is r1 + 104 ~ r1 + 140
; the parameter save area is r1 + 32 ~ r1 + 68
define dso_local i32 @bar() {
; CHECK-LABEL: bar:
-; CHECK: addi 30, 1, 40
+; CHECK: addi 30, 1, 104
; CHECK: li 3, 16
; CHECK: lxvd2x 0, 30, 3
; CHECK: li 3, 48
@@ -25,7 +24,7 @@ define dso_local i32 @bar() {
; CHECK: li 3, 32
; CHECK: lxvd2x 0, 0, 30
; CHECK: stxvd2x 0, 1, 3
-; CHECK: lwz 3, 72(1)
+; CHECK: lwz 3, 136(1)
; CHECK: stw 3, 64(1)
entry:
%x = alloca %struct, align 4