Skip to content

Commit

Permalink
[AArch64] Fix for the pre-indexed paired load/store optimization.
Browse files Browse the repository at this point in the history
This patch fixes an issue where a pre-indexed store e.g.,
STR x1, [x0, rust-lang#24]! with a store like STR x0, [x0, rust-lang#8] are
merged into a single store: STP x1, x0, [x0, rust-lang#24]!
. They shouldn’t be merged because the second store uses
x0 as both the stored value and the address and so it needs to be using the updated x0.
Therefore, it should not be folded into a STP <>pre.

Additionally a new test case is added to verify this fix.

Differential Revision: https://reviews.llvm.org/D101888

Change-Id: I26f1985ac84e970961e2cdca23c590fa6773851a
  • Loading branch information
stelios-arm committed May 5, 2021
1 parent e994e74 commit 3f4bad5
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 1 deletion.
8 changes: 7 additions & 1 deletion llvm/lib/Target/AArch64/AArch64LoadStoreOptimizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1610,7 +1610,13 @@ AArch64LoadStoreOpt::findMatchingInsn(MachineBasicBlock::iterator I,
!UsedRegUnits.available(getLdStBaseOp(MI).getReg());
bool IsBaseRegModified =
!ModifiedRegUnits.available(getLdStBaseOp(MI).getReg());
if (IsOutOfBounds || IsBaseRegUsed || IsBaseRegModified) {
// If the stored value and the address of the second instruction is
// the same, it needs to be using the updated register and therefore
// it must not be folded.
bool IsMIRegTheSame =
getLdStRegOp(MI).getReg() == getLdStBaseOp(MI).getReg();
if (IsOutOfBounds || IsBaseRegUsed || IsBaseRegModified ||
IsMIRegTheSame) {
LiveRegUnits::accumulateUsedDefed(MI, ModifiedRegUnits,
UsedRegUnits, TRI);
MemInsns.push_back(&MI);
Expand Down
27 changes: 27 additions & 0 deletions llvm/test/CodeGen/AArch64/strpre-str-merge.mir
Original file line number Diff line number Diff line change
Expand Up @@ -424,3 +424,30 @@ body: |
STRSui killed renamable $s1, renamable $x0, 1 :: (store 4)
RET undef $lr, implicit $x0
...

---
name: 16-strxpre-strxui-same-reg-no-merge
alignment: 4
tracksRegLiveness: true
liveins:
- { reg: '$x0' }
- { reg: '$x1' }
- { reg: '$x2' }
frameInfo:
maxAlignment: 1
maxCallFrameSize: 0
machineFunctionInfo:
hasRedZone: false
body: |
bb.0.entry:
liveins: $x0, $x1, $x2
; CHECK-LABEL: name: 16-strxpre-strxui-same-reg-no-merge
; CHECK: liveins: $x0, $x1, $x2
; CHECK: early-clobber renamable $x0 = STRXpre renamable $x1, renamable $x0, 24, implicit $w0 :: (store 8)
; CHECK: STRXui renamable $x0, renamable $x0, 1 :: (store 8)
; CHECK: RET undef $lr, implicit $x0
early-clobber renamable $x0 = STRXpre killed renamable $x1, killed renamable $x0, 24 :: (store 8)
STRXui renamable $x0, renamable $x0, 1 :: (store 8)
RET undef $lr, implicit $x0
...

0 comments on commit 3f4bad5

Please sign in to comment.