From 3f4bad5eadacfc5322817eaa062dd272b52cfc54 Mon Sep 17 00:00:00 2001 From: Stelios Ioannou Date: Wed, 5 May 2021 11:02:33 +0100 Subject: [PATCH] [AArch64] Fix for the pre-indexed paired load/store optimization. MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit 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 --- .../Target/AArch64/AArch64LoadStoreOptimizer.cpp | 8 ++++++- llvm/test/CodeGen/AArch64/strpre-str-merge.mir | 27 ++++++++++++++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/llvm/lib/Target/AArch64/AArch64LoadStoreOptimizer.cpp b/llvm/lib/Target/AArch64/AArch64LoadStoreOptimizer.cpp index 012bbd7..bf042c8 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 ff08acc..d7f3e17 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 + +... -- 2.7.4