Index: llvm/lib/Target/AArch64/AArch64LoadStoreOptimizer.cpp =================================================================== --- llvm/lib/Target/AArch64/AArch64LoadStoreOptimizer.cpp +++ llvm/lib/Target/AArch64/AArch64LoadStoreOptimizer.cpp @@ -1569,6 +1569,14 @@ !UsedRegUnits.available(getLdStRegOp(MI).getReg())) && !mayAlias(MI, MemInsns, AA)) { + // If the BaseReg has been modified, then cannot do the optimization. + // for example, in the following pattern + // ldr x1 [x2] + // ldr x2 [x3] + // ldr x4 [x2, #8], + // the first and third ldr cannot be converted to ldp x1, x4, [x2] + if (!ModifiedRegUnits.available(BaseReg)) + return E; Flags.setMergeForward(false); Flags.clearRenameReg(); return MBBI; @@ -1583,6 +1591,8 @@ !mayAlias(FirstMI, MemInsns, AA)) { if (ModifiedRegUnits.available(getLdStRegOp(FirstMI).getReg())) { + if (!ModifiedRegUnits.available(BaseReg)) + return E; Flags.setMergeForward(true); Flags.clearRenameReg(); return MBBI; Index: llvm/test/CodeGen/AArch64/aarch64-ldst-modified-baseReg.mir =================================================================== --- /dev/null +++ llvm/test/CodeGen/AArch64/aarch64-ldst-modified-baseReg.mir @@ -0,0 +1,31 @@ +# RUN: llc -mtriple=aarch64-linux-gnu -verify-machineinstrs -run-pass=aarch64-ldst-opt %s -o - | FileCheck %s +# +# The test below test that when the AArch64 Load Store Optimization pass tries to +# convert to load instructions into an ldp instruction, and when the base register of +# the second ldr instruction has been modified in between these two ldr instructions, +# the convertion should not occur. +# +# For example, for the following pattern: +# ldr x9 [x10] +# ldr x10 [x8] +# ldr x10 [x10, 8], +# the first and third ldr instructions cannot be converted to ldp x9, x10, [x10]. +# +# CHECK-NOT: LDP +# CHECK: $x9 = LDRXui $x10, 1 :: (load 8) +# CHECK: $x10 = LDURXi $x8, 1 :: (load 8) +# CHECK: $x10 = LDRXui $x10, 0 :: (load 8) +# CHECK: RET + +--- +name: main +tracksRegLiveness: true +body: | + bb.0: + liveins: $x8, $x10 + + $x9 = LDRXui $x10, 1 :: (load 8) + $x10 = LDURXi $x8, 1 :: (load 8) + $x10 = LDRXui $x10, 0 :: (load 8) + RET undef $lr, implicit undef $w0 +...