[llvm] 3f4bad5 - [AArch64] Fix for the pre-indexed paired load/store optimization.
Stelios Ioannou via llvm-commits
llvm-commits at lists.llvm.org
Wed May 5 07:15:33 PDT 2021
Author: Stelios Ioannou
Date: 2021-05-05T15:15:07+01:00
New Revision: 3f4bad5eadacfc5322817eaa062dd272b52cfc54
URL: https://github.com/llvm/llvm-project/commit/3f4bad5eadacfc5322817eaa062dd272b52cfc54
DIFF: https://github.com/llvm/llvm-project/commit/3f4bad5eadacfc5322817eaa062dd272b52cfc54.diff
LOG: [AArch64] Fix for the pre-indexed paired load/store optimization.
This patch fixes an issue where a pre-indexed store e.g.,
STR x1, [x0, #24]! with a store like STR x0, [x0, #8] are
merged into a single store: STP x1, x0, [x0, #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
Added:
Modified:
llvm/lib/Target/AArch64/AArch64LoadStoreOptimizer.cpp
llvm/test/CodeGen/AArch64/strpre-str-merge.mir
Removed:
################################################################################
diff --git a/llvm/lib/Target/AArch64/AArch64LoadStoreOptimizer.cpp b/llvm/lib/Target/AArch64/AArch64LoadStoreOptimizer.cpp
index 012bbd7eaca9..bf042c83294a 100644
--- a/llvm/lib/Target/AArch64/AArch64LoadStoreOptimizer.cpp
+++ b/llvm/lib/Target/AArch64/AArch64LoadStoreOptimizer.cpp
@@ -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);
diff --git a/llvm/test/CodeGen/AArch64/strpre-str-merge.mir b/llvm/test/CodeGen/AArch64/strpre-str-merge.mir
index ff08acc1225d..d7f3e177cf34 100644
--- a/llvm/test/CodeGen/AArch64/strpre-str-merge.mir
+++ b/llvm/test/CodeGen/AArch64/strpre-str-merge.mir
@@ -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
+
+...
More information about the llvm-commits
mailing list