130 Commits

Author SHA1 Message Date
Philip Reames
8603a7b21f [RISCV] Add a query for exact VLEN to RISCVSubtarget [nfc]
We've now got enough of these in tree that we can see which patterns
appear to be idiomatic.  As such, extract a helper for checking
if we know the exact VLEN.
2024-02-20 17:27:47 -08:00
Craig Topper
0de2b26942
[RISCV] Register fixed stack slots for callee saved registers for -msave-restore/Zcmp (#81392)
PEI previously used fake frame indices for these callee saved registers.
These fake frame indices are not register with MachineFrameInfo. This
required them to be deleted form CalleeSavedInfo after PEI to avoid
breaking later passes. See #79535

Unfortunately, removing the registers from CalleeSavedInfo pessimizes
Interprocedural Register Allocation. The RegUsageInfoCollector pass runs
after PEI and uses CalleeSavedInfo.

This patch replaces #79535 by properly creating fixed stack objects
through MachineFrameInfo. This changes the stack size and offsets
returned by MachineFrameInfo which requires changes to how
RISCVFrameLowering uses that information.

In addition to the individual object for each register, I've also create
a single large fixed object that covers the entire stack area covered by
cm.push or the libcalls. cm.push must always push a multiple of 16 bytes
and the save restore libcall pushes a multiple of stack align. I think
this leaves holes in the stack where we could spill other registers, but
it matches what we did previously. Maybe we can optimize this in the
future.

The only test changes are due to stack alignment handling after the
callee save registers. Since we now have the fixed objects, on the stack
the offset is non-zero when an aligned object is processed so the offset
gets rounded up, increasing the stack size.

I suspect we might need some more updates for RVV related code. There is
very little or maybe even no testing of RVV mixed with Zcmp and
save-restore.
2024-02-13 14:59:28 -08:00
Yeting Kuo
59037c0975
[RISCV] Add Zicfiss support to the shadow call stack implementation. (#68075)
This patch enable hardware shadow stack with `Zicifss` and
`mno-forced-sw-shadow-stack`. New feature forced-sw-shadow-stack
disables hardware shadow stack even when `Zicfiss` enabled.
2024-02-10 22:18:46 +08:00
Craig Topper
c08b90c50b [RISCV] Lower the TransientStackAlignment to the ABI alignment for rv32e/rv64e.
I don't think the transient alignment needs to be larger than the
ABI alignment.
2024-02-09 21:48:11 -08:00
Craig Topper
647010a06f [RISCV] Remove unnecessary check for RVE from determineCalleeSaves. NFCI
The SavedRegs BitVector is checks against the CSR list later. We have
a separate CSR list for RVE that excludes X16-31 so we don't need
to filter here.

If it was needed, it would be needed for the next block of code too
which didn't have an RVE check.
2024-02-09 11:00:38 -08:00
Craig Topper
f78c9b88b7 [RISCV] Use MCPhysReg for AllPopRegs. NFC
MCPhysReg is 2 bytes, while Register is 4 bytes.
2024-02-08 13:50:44 -08:00
Visoiu Mistrih Francis
69a661cbae
[RISCV] Remove CalleeSavedInfo for Zcmp/save-restore-libcalls registers (#79535)
Registers that are pushed/popped by Zcmp or libcalls have pre-defined
frame indices that are never allocated in MachineFrameInfo. They're
being used throughout PEI, but the rest of codegen doesn't work that way
and expects each frame index to be a valid index in MFI.

This patch keeps it local to PEI and removes them from the
CalleeSavedInfo list at the end of the pass.

Before this pass, any MIR testing post-PEI is broken and asserts (see
issue #79491).
2024-02-06 18:18:49 -08:00
Craig Topper
c8a97c0f30
[RISCV] Use hasStdExtCOrZca instead of hasStdExtC in estimateFunctionSizeInBytes. (#80905) 2024-02-06 13:47:36 -08:00
Wang Pengcheng
3ac9fe69f7
[RISCV] CodeGen of RVE and ilp32e/lp64e ABIs (#76777)
This commit includes the necessary changes to clang and LLVM to support
codegen of `RVE` and the `ilp32e`/`lp64e` ABIs.

The differences between `RVE` and `RVI` are:
* `RVE` reduces the integer register count to 16(x0-x16).
* The ABI should be `ilp32e` for 32 bits and `lp64e` for 64 bits.

`RVE` can be combined with all current standard extensions.

The central changes in ilp32e/lp64e ABI, compared to ilp32/lp64 are:
* Only 6 integer argument registers (rather than 8).
* Only 2 callee-saved registers (rather than 12).
* A Stack Alignment of 32bits (rather than 128bits).
* ilp32e isn't compatible with D ISA extension.

If `ilp32e` or `lp64` is used with an ISA that has any of the registers
x16-x31 and f0-f31, then these registers are considered temporaries.

To be compatible with the implementation of ilp32e in GCC, we don't use
aligned registers to pass variadic arguments and set stack alignment\
to 4-bytes for types with length of 2*XLEN.

FastCC is also supported on RVE, while GHC isn't since there is only one
avaiable register.

Differential Revision: https://reviews.llvm.org/D70401
2024-01-16 20:44:30 +08:00
Craig Topper
3d89f2ac16
[RISCV] Remove null terminator from CSRegs in determineCalleeSaves. NFC (#74131)
Presumably this was done to make it similar to the getCalleeSavedRegs
list in RegInfo, but its simpler to use a range based for loop over the
array.
2023-12-01 14:05:55 -08:00
Nemanja Ivanovic
227607190e
[RISCV] Fix crash in PEI with empty entry block with Zcmp (#72117)
We check the opcode of the first instruction in the block where the
prologue is inserted without checking if the iterator points to any
instructions. When the basic block is empty, that causes a crash. One
way the prologue block can be empty is when it starts with a call to
__builtin_readcyclecounter on RV32 since that produces a loop.

Co-authored-by: Nemanja Ivanovic <nemanja@synopsys.com>
2023-11-17 16:18:44 +01:00
Yeting Kuo
7c70e50b8e
[RISCV] Fix wrong offset use caused by missing the size of Zcmp push. (#66613)
This fixes two wrong offset uses,
1. .cfi_offset of callee saves are not pushed by cm.push.
2. Reference of frame objests by frame pointer.
2023-09-25 12:05:05 +08:00
Yeting Kuo
976df42e6a
[RISCV] Fix bugs about register list of Zcmp push/pop. (#66073)
The pr does two things. One is to fix internal compiler error when we
need to spill callee saves but none of them is GPR, another is to fix
wrong register number for pushed registers are {ra, s0-s11}.
2023-09-20 15:20:13 +08:00
Yeting Kuo
6af39d914c
[RISCV][NFC] Simplify the sp-offset reduction by spimm of CM.PUSH/POP. (#66667)
When inserting prolgue/epilogue, we use the spimm of CM.PUSH/POP to
reduce the following offset for sp. Previously, we tried to use the free
space of the push stack to minimize the following sp-offset. But it's
useless, since the free space must be less than 16 and required stack should
be aligned to 16 before/after the adjustment.
2023-09-19 11:01:47 +08:00
laichunfeng
71b5f57f0d [RISCV] Adjust first sp size to use c.addi16sp.
addi sp, sp, 512 may be used to recover the sp in the epilogue
when stack size is larger than 2047(2^11 - 1), however, it can
not be compressed using C extension, and addi sp, sp, 496 is
able to be compressed, so try to use 496 as the ajust amount of
the fisrt sp if function doesn't need extra instructions after
adjust.

Reviewed By: wangpc

Differential Revision: https://reviews.llvm.org/D159431
2023-09-06 14:26:52 +08:00
Garvit Gupta
fdef7952cb [RISCV] Fix assertion failure when zcmp extension is enabled.
Before accessing "getOpcode" thorugh machine instruction, check if the iterator
has reached the end of Machine basic block otherwise we will crash at the
assertion `!NodePtr->isKnownSentinel()`.

The above assertion is hit in "Prologue/Epilogue Insertion & Frame Finalization
pass".

Reviewed By: craig.topper, wangpc

Differential Revision: https://reviews.llvm.org/D158256
2023-08-29 22:06:30 -07:00
laichunfeng
13454a6e87 [RISCV] Compress stack insts by adjust offset.
For callee saved/restored operations, they mostly use the
following inst patterns,
sw rs2, offset(x2)
sd rs2, offset(x2)
fsw rs2, offset(x2)
fsd rs2, offset(x2)

lw rd, offset(x2)
ld rd, offset(x2)
flw rd, offset(x2)
fld rd, offset(x2)
and offset decides whether the instructions can be compressed.
now offset 2032 will be set by default if stacksize is bigger
than 2^12-1 to save and restore callee saved register, so it
will prevent all the callee saved/restored stack insts be
compressed.
Allocating proper offset for stack insts is useful to make
them be compressed.

Reviewed By: craig.topper, wangpc

Differential Revision: https://reviews.llvm.org/D157373
2023-08-18 10:49:53 +08:00
Jim Lin
5f94f3b7ea [RISCV] Refine getMaxPushPopReg like getLibCallID. NFC.
If save/restore libcall or Zcmp push/pop are enabled, callee-saved registers including ra would be
assigned a negative frame index (-1 for ra, -2 for s0, ..., -13 for s11) by RISCVRegisterInfo::hasReservedSpillSlot.

getLibCallID would find a callee-saved register that has max register id and with assigned negative frame index.
And use this max register to get which save/restore libcall should be selected.

In getMaxPushPopReg (for Zcmp push/pop, similar getLibCallID), it uses extra register class (PGPR) to
check the saved register is in ra, s0-s11 instead of checking the frame index is negative.

This patch just changes the checking for the saved register from `is contained in PGPR` to `has a negative frame index`.

Reviewed By: fakepaper56

Differential Revision: https://reviews.llvm.org/D156393
2023-08-07 15:16:22 +08:00
Yeting Kuo
f68c6879ad [RISCV] Use max pushed register to get pushed register number.
Previously we used the number of registers needed saved and pushable as the
number of pushed registers. We also use pushed register number to caculate
the stack size. It is not correct because Zcmp pushes registers from $ra to the
max register needed saved and there is no gurantee that the needed saved
registers are a sequenced list from $ra.

There is an example about that. PushPopRegs should be 6 (ra,s0 - s4)= instead of 1.
```
; llc -mtriple=riscv32 -mattr=+zcmp
define void @foo() {
entry:
; Old:    .cfi_def_cfa_offset 16
; New:    .cfi_def_cfa_offset 32
  tail call void asm sideeffect "li s4, 0", "~{s4}"()
  ret void
}
```

Reviewed By: Jim, kito-cheng

Differential Revision: https://reviews.llvm.org/D156407
2023-08-03 14:49:15 +08:00
Jim Lin
d6a48a348a [RISCV] Fix the CFI offset for callee-saved registers stored by Zcmp push.
Issue mentioned: https://github.com/riscv/riscv-code-size-reduction/issues/182

The order of callee-saved registers stored by Zcmp push in memory is reversed.

Pseudo code for cm.push in https://github.com/riscv/riscv-code-size-reduction/releases/download/v1.0.4-1/Zc.1.0.4-1.pdf

```
if (XLEN==32) bytes=4; else bytes=8;

addr=sp-bytes;
for(i in 27,26,25,24,23,22,21,20,19,18,9,8,1)  {
  //if register i is in xreg_list
  if (xreg_list[i]) {
    switch(bytes) {
      4:  asm("sw x[i], 0(addr)");
      8:  asm("sd x[i], 0(addr)");
    }
    addr-=bytes;
  }
}
```

The placement order for push is s11, s10, ..., ra.

CFI offset should be calculed as reversed order for correct stack unwinding.

Reviewed By: fakepaper56, kito-cheng

Differential Revision: https://reviews.llvm.org/D156437
2023-08-02 13:03:21 +08:00
Jim Lin
5555b9f739 [RISCV] Reuse FrameIdx for emitting cfi offset. NFC. 2023-07-26 08:33:58 +08:00
WuXinlong
6269ed24cf [RISCV] Readjusting the framestack for Zcmp
This patch readjusts the frame stack for the push and pop instructions

co-author: @Lukacma

Reviewed By: craig.topper

Differential Revision: https://reviews.llvm.org/D134599
2023-07-07 11:24:21 +08:00
Fangrui Song
665ccc19d3 [MC] Add SMLoc to MCCFIInstruction
to help debug and report better diagnostics for functions like
relaxDwarfCallFrameFragment (D153167).

In MCStreamer, some emitCFI* functions already take a SMLoc argument. Add a
SMLoc argument to the remaining functions that generate a MCCFIInstruction.
2023-06-26 17:58:29 -07:00
Paul Kirth
bface3947e [RISCV] Make SCS prologue interrupt safe on RISC-V
Prior to this patch the SCS prologue used the following instruction
sequence.

```
s[w|d]  ra, 0(gp)
addi    gp, gp, [4|8]
```

The problem with this sequence is that an interrupt occurring between the
store and the increment could clobber the value just written to the SCS.

https://reviews.llvm.org/D84414#inline-813203 pointed out a similar
issues that could have affected the epilogue.

This patch changes the instruction sequence in the prologue to:

```
addi    gp, gp, [4|8]
s[w|d]  ra, -[4|8](gp)
```

The downside to this is that there is now a data dependency between the
add and the store.

Reviewed By: asb

Differential Revision: https://reviews.llvm.org/D149099
2023-04-26 15:58:09 +00:00
Paul Kirth
aa1d2693c2 [CodeGen][RISCV] Change Shadow Call Stack Register to X3
ShadowCallStack implementation uses s2 register on RISC-V, but that
choice is problematic for reasons described in:

https://lists.riscv.org/g/sig-toolchains/message/544,
https://github.com/riscv-non-isa/riscv-elf-psabi-doc/issues/370, and
https://github.com/google/android-riscv64/issues/72

The concern over the register choice was also brought up in
https://reviews.llvm.org/D84414.

https://reviews.llvm.org/D84414#2228666 said:

```
  "If the register choice is the only concern about this work, then I think
  we can probably land it as-is and fixup the register choice if we see
  major drawbacks later. Yes, it's an ABI issue, but on the other hand the
  shadow call stack is not a standard ABI anyway.""
```

Since we have now found a sufficient reason to fixup the register
choice, we should go ahead and update the implementation. We propose
using x3(gp) which is now the platform register in the RISC-V ABI.

Reviewed By: asb, hiraditya, mcgrathr, craig.topper

Differential Revision: https://reviews.llvm.org/D146463
2023-04-12 21:06:22 +00:00
Craig Topper
29463612d2 [RISCV] Replace RISCV -> RISC-V in comments. NFC
To be consistent with RISC-V branding guidelines
https://riscv.org/about/risc-v-branding-guidelines/
Think we should be using RISC-V where possible.

More patches will follow.

Reviewed By: asb

Differential Revision: https://reviews.llvm.org/D146449
2023-03-27 09:50:17 -07:00
Paul Kirth
ade336d6e1 [codegen][riscv] Emit CFI directives when using shadow call stack
Currently we don't emit any CFI instructions for the SCS register when
enabling SCS on RISCV. This causes problems when unwinding, since the
SCS register isn't being handled properly.

Reviewed By: mcgrathr

Differential Revision: https://reviews.llvm.org/D145205
2023-03-15 17:10:23 +00:00
Christudasan Devadasan
b5efec4b27 [CodeGen] Additional Register argument to storeRegToStackSlot/loadRegFromStackSlot
With D134950, targets get notified when a virtual register is created and/or
cloned. Targets can do the needful with the delegate callback. AMDGPU propagates
the virtual register flags maintained in the target file itself. They are useful
to identify a certain type of machine operands while inserting spill stores and
reloads. Since RegAllocFast spills the physical register itself, there is no way
its virtual register can be mapped back to retrieve the flags. It can be solved
by passing the virtual register as an additional argument. This argument has no
use when the spill interfaces are called during the greedy allocator or even the
PrologEpilogInserter and can pass a null register in such cases.

Reviewed By: arsenm

Differential Revision: https://reviews.llvm.org/D138656
2022-12-17 11:55:34 +05:30
Sergey Kachkov
132dc442ba [RISCV] Generate .cfi_def_cfa_expression for RVV stack adjustment
Cannonical frame address after RVV stack adjustment is sp + StackSize +
RVVStackSize * vlenb, and since vlenb is unknown at compile-time (but it
is a constant for particular HW implementation), emit
.cfi_def_cfa_expression so libunwind can read VLENB CSR register at
run-time and obtain correct frame address.

Fixes https://github.com/llvm/llvm-project/issues/58356 (but additional
run-time support for reading CSR may be required)

Differential Revision: https://reviews.llvm.org/D136263
2022-12-06 12:45:59 +03:00
Philip Reames
14d993435b [RISCV] Inline RISCVFrameLowering::adjustReg out of existance [nfc]
This was requested by a reviewer in D138926.
2022-11-30 11:07:45 -08:00
Philip Reames
c0692c08ee [RISCV] Adjust code to fallthrough to a single adjustReg callsite [nfc]
Note that we have to now pass alignment to that callsite because the wrapper previously did that for us for fixed offsets.
2022-11-30 10:45:55 -08:00
Philip Reames
1f04ac54f9 [RISCV] Merge two versions of adjustReg on TRI [nfc]
After ac1ec9e, the version with the StackOffset param has a strict superset of behavior.  As a result, we can switch callers to use it, and then inline the other version into the now-single caller.
2022-11-30 10:12:40 -08:00
Philip Reames
80fcf992b7 [RISCV] Reuse and generalize adjustReg from another spot in frame lowering [nfc]
Differential Revision: https://reviews.llvm.org/D138926
2022-11-30 09:43:14 -08:00
Philip Reames
ac1ec9e290 [RISCV] Share code for fixed offsets adjustRegs (thus materializing fewer constants)
This reuses the existing optimized implementation of adjustReg, and commons up code. This has the effect of enabling two code changes for the new caller. First, we enable the "split andi" lowering (with no alignment requirement), and second we use a sub with smaller constant in register instead of a add with negative constant in register.

Differential Revision: https://reviews.llvm.org/D132839
2022-11-30 09:28:29 -08:00
Philip Reames
1a5be5265c [RISCV] Move implementation of adjustReg from frame lowering to register info [nfc]
Putting both variants of this function in the same place, in advance of code resuse.  Note that I tweaked the API slightly in advance of additional callers without the alignment requirement.  Some of the existing callers may also be okay with weaker alignment requirements, but that should be it's own set of changes.
2022-11-28 12:41:00 -08:00
Philip Reames
06e2b44c46 [RISCV] Optimize scalable frame setup when VLEN is precisely known
If we know the exact value of VLEN, the frame offset adjustment for scalable stack slots becomes a fixed constant. This avoids the need to read vlenb, and may allow the offset to be folded into the immediate field of an add/sub.

We could go further here, and fold the offset into a single larger frame adjustment - instead of having a separate scalable adjustment step - but that requires a bit more code reorganization. I may (or may not) return to that in a future patch.

Differential Revision: https://reviews.llvm.org/D137593
2022-11-18 15:30:39 -08:00
Craig Topper
2c82080f09 [MachineFrameInfo][RISCV] Call ensureStackAlignment for objects created with scalable vector stack id.
This is an alternative to fix PR57939 for RISC-V. It definitely
can be argued that the stack temporaries for RISC-V are being created
with an unnecessarily large alignment. But ignoring the alignment
in MachineFrameInfo also seems bad.

Looking at the test update that go with the current ID==0 check,
it was intending to exclude things like the NoAlloc stackid. So I'm
not sure if scalable vectors are intentionally being excluded.

Reviewed By: reames

Differential Revision: https://reviews.llvm.org/D135913
2022-10-20 14:05:46 -07:00
Craig Topper
31bca38ad1 [RISCV] Pass the destination register to getVLENFactoredAmount instead of returning it. NFC
This is a refactor for another patch. For now we move the vreg
creation to the caller.

Reviewed By: frasercrmck

Differential Revision: https://reviews.llvm.org/D135008
2022-10-03 10:59:35 -07:00
ZHU Zijia
9c85382ade [RISCV] Handle register spill in branch relaxation
In branch relaxation pass, `j`'s with offset over 1MiB will be relaxed
to `jump` pseudo-instructions.

This patch allocates a stack slot for functions with a size greater than
1MiB. If the register scavenger cannot find a scratch register for
`jump`, spill a register to the slot before the jump and restore it
after the jump.

.mbb:
        foo
        j       .dest_bb
        bar
        bar
        bar
.dest_bb:
        baz

The above code will be relaxed to the following code.

.mbb:
        foo
        sd      s11, 0(sp)
        jump    .restore_bb, s11
        bar
        bar
        bar
        j       .dest_bb
.restore_bb:
        ld      s11, 0(sp)
.dest_bb:
        baz

Depends on D129999.

Reviewed By: StephenFan

Differential Revision: https://reviews.llvm.org/D130560
2022-08-24 13:27:56 +08:00
Kazu Hirata
f5a68feab3 Use llvm::none_of (NFC) 2022-08-14 16:25:39 -07:00
Alex Bradbury
5ad59c9e59 [RISCV][NFCI] Set TransientStackAlignment and rely on it rather than RVV-specific logic on RVV-less functions
* TargetFrameLowering has a TransientStackAlignment field that "returns
  the number of bytes to which the stack pointer must be aligned at all
  times, even between calls.
  * As explained in the [RISC-V calling
    convention](https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/master/riscv-cc.adoc),
    the stack pointer must remain fully aligned throughout execution for
    compliant code. This is important for embedded targets that might avoid
    realigning the stack pointer for interrupt service routines. Systems
    running full OSes may always realign the stack anyway.
* TransientStackAlignment is used in estimateStackSize in
  MachineFrameInfo and in PEI::calculateFrameObjectOffsets.
  * estimateStackSize is only used in the RISC-V backend for scavenging
    slots. It may be possible to craft a function where the difference
    is observable, but it wouldn't be a meaningful test.
  * calculateFrameObjectOffsets makes use of TransientStackAlignment,
    but then sets the stack alignment to the max of that alignment and
    MaxAlign, which is unconditionally set to 16 in
    RISCVFrameLowering::processFunctionBeforeFrameFinalized
  * I've changed this logic to only set MaxAlign if there are RVV frame
    objects. There should be no functional change here for either RVV
    targets (MaxAlign is set as before) or non-RVV targets
    (TransientStackAlign is now 16 anyway).

Differential Revision: https://reviews.llvm.org/D130068
2022-08-02 09:46:06 +01:00
Fraser Cormack
b336cf856e [RISCV] Add early-exit to RVV stack computation. NFCI.
This patch was split off from D126465, where an early-exit is necessary
as it checks the VLEN and that asserts that V instructions are present.

Since this makes logical sense on its own, I think it's worth landing
regardless of D126465.

Reviewed By: kito-cheng

Differential Revision: https://reviews.llvm.org/D129617
2022-07-13 08:50:08 +01:00
luxufan
0f45eaf0da [RISCV] Add a scavenge spill slot when use ADDI to compute scalable stack offset
Computing scalable offset needs up to two scrach registers. We add
scavenge spill slots according to the result of `RISCV::isRVVSpill`
and `RVVStackSize`. Since ADDI is not included in `RISCV::isRVVSpill`,
PEI doesn't add scavenge spill slots for scrach registers when using
ADDI to get scalable stack offsets.

The ADDI instruction has a destination register which can be used as
a scrach register. So one scavenge spil slot is sufficient for
computing scalable stack offsets.

Differential Revision: https://reviews.llvm.org/D128188
2022-07-03 20:18:13 +08:00
Yeting Kuo
5744b9cb79 [RISCV] Restore "Enable shrink wrap by default"
This reverts commit 7af3d4ab3d5da07256e1a7a0438e7308e14b9fd5.

RISC-V reverted the shrink wrap patch for bug 53662. Since the bug is fixed
by D123679, the commit re-enable it.

Reviewed By: reames

Differential Revision: https://reviews.llvm.org/D128965
2022-07-02 11:13:13 +08:00
Craig Topper
d63b66840f [RISCV] Move some methods out of RISCVInstrInfo and into RISCV namespace.
These methods don't access any state from RISCVInstrInfo. Make them
free functions in the RISCV namespace.

Reviewed By: frasercrmck

Differential Revision: https://reviews.llvm.org/D127583
2022-06-12 10:47:21 -07:00
Kito Cheng
4b11f90903 [RISCV] Fix missing stack pointer recover
In order to make sure the stack point is right through the EH region,
we also need to restore stack pointer from the frame pointer if we
don't preserve stack space within prologue/epilogue for outgoing variables,
normally it's just checking the variable sized object is present or not
is enough, but we also don't preserve that at prologue/epilogue when
have vector objects in stack.

Example to show what happened:
```
try {
  sp adjust for outgoing args. // 1. Sp changed.
  func_call  // 2. Exception raised
  sp restore // Oh, not restored
} catch {
  // 3. And now we are here.
}

// 4. Prepare to return!, restore return address from stack, but...sp is wrong.
// 5. Screw up!
```

Reviewed By: rogfer01

Differential Revision: https://reviews.llvm.org/D126861
2022-06-09 23:38:50 +08:00
Craig Topper
1b2de79ff4 [RISCV] Use two ADDIs to do some stack pointer adjustments.
If the adjustment doesn't fit in 12 bits, try to break it into
two 12 bit values before falling back to movImm+add/sub.

This is based on a similar idea from isel.

Reviewed By: luismarques, reames

Differential Revision: https://reviews.llvm.org/D126392
2022-05-31 10:25:28 -07:00
Philip Reames
d58cc0839e [RISCV] reorganize getFrameIndexReference to reduce code duplication [nfc]
This change reorganizes the majority of frame index resolution into a two strep process.

    Step 1 - Select which base register we're going to use.
    Step 2 - Compute the offset from that base register.

The key point is that this allows us to share the step 2 logic for the SP case. This reduces the code duplication, and (I think) makes the code much easier to follow.

I also went ahead and added assertions into phase 2 to catch errors where we select an illegal base pointer. In general, we can't index from a base register to a stack location if that requires crossing a variable and unknown region. In practice, we have two such cases: dynamic stack realign and var sized objects. Note that crossing the scalable region is fine since while variable, it's a known variability which can be expressed in the offset.

Differential Revision: https://reviews.llvm.org/D126403
2022-05-26 09:44:58 -07:00
Philip Reames
dd336b6891 [RISCV] Restructure comment and add clarifying assert to getFrameIndexReference [NFC]
Differential Revision: https://reviews.llvm.org/D126088
2022-05-25 07:59:27 -07:00
Fraser Cormack
fd93736657 [RISCV] Replace untested code with assert
We found untested code where negative frame indices were ostensibly
handled despite it being in a block guarded by !MFI.isFixedObjectIndex.

While the implementation of MachineFrameInfo::isFixedObjectIndex
suggests this is possible (i.e., if a frame index was more negative - less than the
number of fixed objects), I couldn't find any test in tree -- for any
target -- where a negative frame index wasn't also a fixed object
offset. I couldn't find a way of creating such a object with the
public MachineFrameInfo creation APIs. Even
MachineFrameInfo::getObjectIndexBegin starts counting at the negative
number of fixed objects, so such frame indices wouldn't be covered by
loops using the provided begin/end methods.

Given all this, an assert that any object encountered in the block is
non-negative seems reasonable.

Reviewed By: StephenFan, kito-cheng

Differential Revision: https://reviews.llvm.org/D126278
2022-05-25 05:03:53 +01:00