[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