diff --git a/llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp b/llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp --- a/llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp +++ b/llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp @@ -1491,6 +1491,18 @@ Offset += MFI.getStackSize(); } + // If we encounter an LQ/STQ instruction with an offset that fits + // in the instruction, then generate the instruction with the correct + // offset and base address. + if (((OpC == PPC::LQ && isInt<12>(Offset)) || + (OpC == PPC::STQ && isInt<16>(Offset))) && + ((Offset % offsetMinAlign(MI)) == 0)) { + Register StackReg = MI.getOperand(FIOperandNum).getReg(); + MI.getOperand(1).ChangeToImmediate(Offset); + MI.getOperand(2).ChangeToRegister(StackReg, false); + return; + } + // If we encounter an LXVP/STXVP with an offset that doesn't fit, we can // transform it to the prefixed version so we don't have to use the XForm. if ((OpC == PPC::LXVP || OpC == PPC::STXVP) && diff --git a/llvm/test/CodeGen/PowerPC/load-store-quadword.ll b/llvm/test/CodeGen/PowerPC/load-store-quadword.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/PowerPC/load-store-quadword.ll @@ -0,0 +1,30 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -mcpu=pwr8 -verify-machineinstrs -ppc-asm-full-reg-names -o - %s | FileCheck %s + +target triple = "powerpc64le-unknown-linux-gnu" + +%struct.StructA = type { [16 x i8] } + +@s1 = dso_local global %struct.StructA { [16 x i8] c"\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A" }, align 16 + +; Function Attrs: noinline nounwind optnone uwtable +define dso_local void @test() { +; CHECK-LABEL: test: +; CHECK: # %bb.0: # %entry +; CHECK: stq r4, -16(r1) +; CHECK-NEXT: sync +; CHECK-NEXT: lq r4, -16(r1) +entry: + %s2 = alloca %struct.StructA, align 16 + %s3 = alloca %struct.StructA, align 16 + %agg.tmp.ensured = alloca %struct.StructA, align 16 + call void @llvm.memcpy.p0.p0.i64(ptr align 16 %agg.tmp.ensured, ptr align 16 @s1, i64 16, i1 false) + %0 = load i128, ptr %agg.tmp.ensured, align 16 + store atomic i128 %0, ptr %s2 seq_cst, align 16 + %atomic-load = load atomic i128, ptr %s2 seq_cst, align 16 + store i128 %atomic-load, ptr %s3, align 16 + ret void +} + +; Function Attrs: argmemonly nofree nounwind willreturn +declare void @llvm.memcpy.p0.p0.i64(ptr noalias nocapture writeonly, ptr noalias nocapture readonly, i64, i1 immarg)