/// should be initialized to an appropriate description of the
/// address created.
virtual Register getStackAddress(uint64_t Size, int64_t Offset,
- MachinePointerInfo &MPO) = 0;
+ MachinePointerInfo &MPO,
+ ISD::ArgFlagsTy Flags) = 0;
/// The specified value has been assigned to a physical register,
/// handle the appropriate COPY (either to or from) and mark any
: LocVT.getStoreSize();
unsigned Offset = VA.getLocMemOffset();
MachinePointerInfo MPO;
- Register StackAddr = Handler.getStackAddress(MemSize, Offset, MPO);
+ Register StackAddr =
+ Handler.getStackAddress(MemSize, Offset, MPO, Flags);
Handler.assignValueToAddress(Args[i], Part, StackAddr, MemSize, MPO,
VA);
continue;
continue;
MachinePointerInfo MPO;
- Register StackAddr = Handler.getStackAddress(Flags.getByValSize(),
- VA.getLocMemOffset(), MPO);
+ Register StackAddr = Handler.getStackAddress(
+ Flags.getByValSize(), VA.getLocMemOffset(), MPO, Flags);
assert(Args[i].Regs.size() == 1 &&
"didn't expect split byval pointer");
MIRBuilder.buildCopy(Args[i].Regs[0], StackAddr);
: IncomingValueHandler(MIRBuilder, MRI, AssignFn), StackUsed(0) {}
Register getStackAddress(uint64_t Size, int64_t Offset,
- MachinePointerInfo &MPO) override {
+ MachinePointerInfo &MPO,
+ ISD::ArgFlagsTy Flags) override {
auto &MFI = MIRBuilder.getMF().getFrameInfo();
- int FI = MFI.CreateFixedObject(Size, Offset, true);
+
+ // Byval is assumed to be writable memory, but other stack passed arguments
+ // are not.
+ const bool IsImmutable = !Flags.isByVal();
+
+ int FI = MFI.CreateFixedObject(Size, Offset, IsImmutable);
MPO = MachinePointerInfo::getFixedStack(MIRBuilder.getMF(), FI);
auto AddrReg = MIRBuilder.buildFrameIndex(LLT::pointer(0, 64), FI);
StackUsed = std::max(StackUsed, Size + Offset);
StackSize(0), SPReg(0) {}
Register getStackAddress(uint64_t Size, int64_t Offset,
- MachinePointerInfo &MPO) override {
+ MachinePointerInfo &MPO,
+ ISD::ArgFlagsTy Flags) override {
MachineFunction &MF = MIRBuilder.getMF();
LLT p0 = LLT::pointer(0, 64);
LLT s64 = LLT::scalar(64);
if (IsTailCall) {
+ assert(!Flags.isByVal() && "byval unhandled with tail calls");
+
Offset += FPDiff;
int FI = MF.getFrameInfo().CreateFixedObject(Size, Offset, true);
auto FIReg = MIRBuilder.buildFrameIndex(p0, FI);
MachineInstrBuilder MIB;
Register getStackAddress(uint64_t Size, int64_t Offset,
- MachinePointerInfo &MPO) override {
+ MachinePointerInfo &MPO,
+ ISD::ArgFlagsTy Flags) override {
llvm_unreachable("not implemented");
}
: IncomingValueHandler(B, MRI, AssignFn) {}
Register getStackAddress(uint64_t Size, int64_t Offset,
- MachinePointerInfo &MPO) override {
+ MachinePointerInfo &MPO,
+ ISD::ArgFlagsTy Flags) override {
auto &MFI = MIRBuilder.getMF().getFrameInfo();
- int FI = MFI.CreateFixedObject(Size, Offset, true);
+
+ // Byval is assumed to be writable memory, but other stack passed arguments
+ // are not.
+ const bool IsImmutable = !Flags.isByVal();
+ int FI = MFI.CreateFixedObject(Size, Offset, IsImmutable);
MPO = MachinePointerInfo::getFixedStack(MIRBuilder.getMF(), FI);
auto AddrReg = MIRBuilder.buildFrameIndex(
LLT::pointer(AMDGPUAS::PRIVATE_ADDRESS, 32), FI);
}
Register getStackAddress(uint64_t Size, int64_t Offset,
- MachinePointerInfo &MPO) override {
+ MachinePointerInfo &MPO,
+ ISD::ArgFlagsTy Flags) override {
MachineFunction &MF = MIRBuilder.getMF();
const LLT PtrTy = LLT::pointer(AMDGPUAS::PRIVATE_ADDRESS, 32);
const LLT S32 = LLT::scalar(32);
: OutgoingValueHandler(MIRBuilder, MRI, AssignFn), MIB(MIB) {}
Register getStackAddress(uint64_t Size, int64_t Offset,
- MachinePointerInfo &MPO) override {
+ MachinePointerInfo &MPO,
+ ISD::ArgFlagsTy Flags) override {
assert((Size == 1 || Size == 2 || Size == 4 || Size == 8) &&
"Unsupported size");
: IncomingValueHandler(MIRBuilder, MRI, AssignFn) {}
Register getStackAddress(uint64_t Size, int64_t Offset,
- MachinePointerInfo &MPO) override {
+ MachinePointerInfo &MPO,
+ ISD::ArgFlagsTy Flags) override {
assert((Size == 1 || Size == 2 || Size == 4 || Size == 8) &&
"Unsupported size");
auto &MFI = MIRBuilder.getMF().getFrameInfo();
- int FI = MFI.CreateFixedObject(Size, Offset, true);
+ // Byval is assumed to be writable memory, but other stack passed arguments
+ // are not.
+ const bool IsImmutable = !Flags.isByVal();
+
+ int FI = MFI.CreateFixedObject(Size, Offset, IsImmutable);
MPO = MachinePointerInfo::getFixedStack(MIRBuilder.getMF(), FI);
return MIRBuilder.buildFrameIndex(LLT::pointer(MPO.getAddrSpace(), 32), FI)
unsigned Offset = VA.getLocMemOffset();
MachineFrameInfo &MFI = MF.getFrameInfo();
+ // FIXME: This should only be immutable for non-byval memory arguments.
int FI = MFI.CreateFixedObject(Size, Offset, true);
MachinePointerInfo MPO =
MachinePointerInfo::getFixedStack(MIRBuilder.getMF(), FI);
STI(MIRBuilder.getMF().getSubtarget<X86Subtarget>()) {}
Register getStackAddress(uint64_t Size, int64_t Offset,
- MachinePointerInfo &MPO) override {
+ MachinePointerInfo &MPO,
+ ISD::ArgFlagsTy Flags) override {
LLT p0 = LLT::pointer(0, DL.getPointerSizeInBits(0));
LLT SType = LLT::scalar(DL.getPointerSizeInBits(0));
auto SPReg =
DL(MIRBuilder.getMF().getDataLayout()) {}
Register getStackAddress(uint64_t Size, int64_t Offset,
- MachinePointerInfo &MPO) override {
+ MachinePointerInfo &MPO,
+ ISD::ArgFlagsTy Flags) override {
auto &MFI = MIRBuilder.getMF().getFrameInfo();
- int FI = MFI.CreateFixedObject(Size, Offset, true);
+
+ // Byval is assumed to be writable memory, but other stack passed arguments
+ // are not.
+ const bool IsImmutable = !Flags.isByVal();
+
+ int FI = MFI.CreateFixedObject(Size, Offset, IsImmutable);
MPO = MachinePointerInfo::getFixedStack(MIRBuilder.getMF(), FI);
return MIRBuilder
--- /dev/null
+; RUN: llc -global-isel -mtriple=aarch64-unknown-unknown -stop-after=irtranslator -verify-machineinstrs %s -o - | FileCheck %s
+
+; The byval object should not be immutable, but the non-byval stack
+; passed argument should be.
+
+; CHECK-LABEL: name: stack_passed_i64
+; CHECK: fixedStack:
+; CHECK: - { id: 0, type: default, offset: 8, size: 8, alignment: 8, stack-id: default,
+; CHECK-NEXT: isImmutable: false, isAliased: false,
+; CHECK: - { id: 1, type: default, offset: 0, size: 8, alignment: 16, stack-id: default,
+; CHECK-NEXT: isImmutable: true, isAliased: false,
+define void @stack_passed_i64(i64 %arg, i64 %arg1, i64 %arg2, i64 %arg3, i64 %arg4, i64 %arg5, i64 %arg6,
+ i64 %arg7, i64 %arg8, i64* byval(i64) %arg9) {
+ ; CHECK: bb.1 (%ir-block.0):
+ ; CHECK: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.1
+ ; CHECK: [[LOAD:%[0-9]+]]:_(s64) = G_LOAD [[FRAME_INDEX]](p0) :: (invariant load 8 from %fixed-stack.1, align 16)
+ ; CHECK: [[FRAME_INDEX1:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.0
+ ; CHECK: [[COPY8:%[0-9]+]]:_(p0) = COPY [[FRAME_INDEX1]](p0)
+ ; CHECK: [[LOAD1:%[0-9]+]]:_(s64) = G_LOAD [[COPY8]](p0) :: (dereferenceable load 8 from %ir.arg9)
+ ; CHECK: [[ADD:%[0-9]+]]:_(s64) = G_ADD [[LOAD1]], [[LOAD]]
+ ; CHECK: G_STORE [[ADD]](s64), [[COPY8]](p0) :: (volatile store 8 into %ir.arg9)
+ ; CHECK: RET_ReallyLR
+ %load = load i64, i64* %arg9
+ %add = add i64 %load, %arg8
+ store volatile i64 %add, i64* %arg9
+ ret void
+}
; CHECK: frameInfo:
; CHECK: maxAlignment: 64
; CHECK: fixedStack:
- ; CHECK: - { id: 0, type: default, offset: 64, size: 4, alignment: 16, stack-id: default,
- ; CHECK-NEXT: isImmutable: true, isAliased: false, callee-saved-register: '', callee-saved-restored: true,
- ; CHECK: - { id: 1, type: default, offset: 0, size: 4, alignment: 16, stack-id: default,
- ; CHECK-NEXT: isImmutable: true, isAliased: false, callee-saved-register: '', callee-saved-restored: true,
+ ; CHECK: - { id: 0, type: default, offset: 64, size: 2, alignment: 16, stack-id: default,
+ ; CHECK-NEXT: isImmutable: false, isAliased: false, callee-saved-register: '',
+ ; CHECK: - { id: 1, type: default, offset: 0, size: 1, alignment: 16, stack-id: default,
+ ; CHECK-NEXT: isImmutable: false, isAliased: false, callee-saved-register: '',
; CHECK: bb.1 (%ir-block.0):
; CHECK: liveins: $sgpr30_sgpr31
; CHECK: [[FRAME_INDEX:%[0-9]+]]:_(p5) = G_FRAME_INDEX %fixed-stack.1
; CHECK: frameInfo:
; CHECK: maxAlignment: 128
; CHECK: fixedStack:
- ; CHECK-NEXT: - { id: 0, type: default, offset: 64, size: 4, alignment: 16, stack-id: default,
- ; CHECK-NEXT: isImmutable: true, isAliased: false, callee-saved-register: '', callee-saved-restored: true,
- ; CHECK: - { id: 1, type: default, offset: 0, size: 4, alignment: 16, stack-id: default,
- ; CHECK-NEXT: isImmutable: true, isAliased: false, callee-saved-register: '', callee-saved-restored: true,
+ ; CHECK-NEXT: - { id: 0, type: default, offset: 64, size: 2, alignment: 16, stack-id: default,
+ ; CHECK-NEXT: isImmutable: false, isAliased: false, callee-saved-register: '',
+ ; CHECK: - { id: 1, type: default, offset: 0, size: 12, alignment: 16, stack-id: default,
+ ; CHECK-NEXT: isImmutable: false, isAliased: false, callee-saved-register: '',
; CHECK: bb.1 (%ir-block.0):
; CHECK: liveins: $sgpr30_sgpr31
; CHECK: [[FRAME_INDEX:%[0-9]+]]:_(p5) = G_FRAME_INDEX %fixed-stack.1
; CHECK: frameInfo:
; CHECK: maxAlignment: 8
; CHECK: fixedStack:
- ; CHECK: - { id: 0, type: default, offset: 8, size: 4, alignment: 8, stack-id: default,
- ; CHECK-NEXT: isImmutable: true, isAliased: false, callee-saved-register: '', callee-saved-restored: true,
+ ; CHECK: - { id: 0, type: default, offset: 8, size: 1, alignment: 8, stack-id: default,
+ ; CHECK-NEXT: isImmutable: false, isAliased: false, callee-saved-register: '',
; CHECK: - { id: 1, type: default, offset: 0, size: 4, alignment: 16, stack-id: default,
- ; CHECK-NEXT: isImmutable: true, isAliased: false, callee-saved-register: '', callee-saved-restored: true,
+ ; CHECK-NEXT: isImmutable: true, isAliased: false, callee-saved-register: '',
; CHECK: bb.1 (%ir-block.0):
; CHECK: liveins: $vgpr0, $vgpr1, $vgpr2, $vgpr3, $vgpr4, $vgpr5, $vgpr6, $vgpr7, $vgpr8, $vgpr9, $vgpr10, $vgpr11, $vgpr12, $vgpr13, $vgpr14, $vgpr15, $vgpr16, $vgpr17, $vgpr18, $vgpr19, $vgpr20, $vgpr21, $vgpr22, $vgpr23, $vgpr24, $vgpr25, $vgpr26, $vgpr27, $vgpr28, $vgpr29, $vgpr30, $vgpr31, $sgpr30_sgpr31
; CHECK: [[COPY:%[0-9]+]]:_(s32) = COPY $vgpr0
; CHECK: maxAlignment: 4
; CHECK: fixedStack:
; CHECK-NEXT: - { id: 0, type: default, offset: 4, size: 4, alignment: 4, stack-id: default,
- ; CHECK-NEXT: isImmutable: true, isAliased: false, callee-saved-register: '', callee-saved-restored: true,
- ; CHECK: - { id: 1, type: default, offset: 0, size: 4, alignment: 16, stack-id: default,
- ; CHECK-NEXT: isImmutable: true, isAliased: false, callee-saved-register: '', callee-saved-restored: true,
+ ; CHECK-NEXT: isImmutable: true, isAliased: false, callee-saved-register: '',
+ ; CHECK: - { id: 1, type: default, offset: 0, size: 1, alignment: 16, stack-id: default,
+ ; CHECK-NEXT: isImmutable: false, isAliased: false, callee-saved-register: '',
; CHECK: bb.1 (%ir-block.0):
; CHECK: liveins: $vgpr0, $vgpr1, $vgpr2, $vgpr3, $vgpr4, $vgpr5, $vgpr6, $vgpr7, $vgpr8, $vgpr9, $vgpr10, $vgpr11, $vgpr12, $vgpr13, $vgpr14, $vgpr15, $vgpr16, $vgpr17, $vgpr18, $vgpr19, $vgpr20, $vgpr21, $vgpr22, $vgpr23, $vgpr24, $vgpr25, $vgpr26, $vgpr27, $vgpr28, $vgpr29, $vgpr30, $vgpr31, $sgpr30_sgpr31
; CHECK: [[COPY:%[0-9]+]]:_(s32) = COPY $vgpr0