diff --git a/llvm/lib/Target/AArch64/AArch64LoadStoreOptimizer.cpp b/llvm/lib/Target/AArch64/AArch64LoadStoreOptimizer.cpp --- a/llvm/lib/Target/AArch64/AArch64LoadStoreOptimizer.cpp +++ b/llvm/lib/Target/AArch64/AArch64LoadStoreOptimizer.cpp @@ -1550,10 +1550,12 @@ continue; } } - // If the destination register of the loads is the same register, bail - // and keep looking. A load-pair instruction with both destination - // registers the same is UNPREDICTABLE and will result in an exception. - if (MayLoad && Reg == getLdStRegOp(MI).getReg()) { + // If the destination register of one load is the same register or a + // sub/super register of the other load, bail and keep looking. A + // load-pair instruction with both destination registers the same is + // UNPREDICTABLE and will result in an exception. + if (MayLoad && + TRI->isSuperOrSubRegisterEq(Reg, getLdStRegOp(MI).getReg())) { LiveRegUnits::accumulateUsedDefed(MI, ModifiedRegUnits, UsedRegUnits, TRI); MemInsns.push_back(&MI); diff --git a/llvm/test/CodeGen/AArch64/aarch64-ldst-subsuperReg-no-ldp.mir b/llvm/test/CodeGen/AArch64/aarch64-ldst-subsuperReg-no-ldp.mir new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/AArch64/aarch64-ldst-subsuperReg-no-ldp.mir @@ -0,0 +1,39 @@ +# RUN: llc -mtriple=aarch64-linux-gnu -verify-machineinstrs -run-pass=aarch64-ldst-opt %s -o - | FileCheck %s +# +# The test below tests that when the AArch64 Load Store Optimization pass tries to +# convert load instructions into a ldp instruction, and when the destination +# registers are sub/super register of each other, then the convertion should not occur. +# +# For example, for the following pattern: +# ldr x10 [x9] +# ldr w10 [x9, 8], +# We cannot convert it to an ldp instruction. +# +# CHECK-NOT: LDP +# CHECK: $x10 = LDRSWui $x9, 0 +# CHECK: $w10 = LDRWui $x9, 1 +# CHECK: RET +--- +name: test1 +tracksRegLiveness: true +body: | + bb.0: + liveins: $x9 + $x10 = LDRSWui $x9, 0 :: (load 4) + $w10 = LDRWui $x9, 1 :: (load 4) + RET undef $lr, implicit undef $w0 +... +# CHECK-NOT: LDP +# CHECK: $w10 = LDRWui $x9, 0 +# CHECK: $x10 = LDRSWui $x9, 1 +# CHECK: RET +--- +name: test2 +tracksRegLiveness: true +body: | + bb.0: + liveins: $x9 + $w10 = LDRWui $x9, 0 :: (load 4) + $x10 = LDRSWui $x9, 1 :: (load 4) + RET undef $lr, implicit undef $w0 +...