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 @@ -107,6 +107,8 @@ ImmToIdxMap[PPC::STFS] = PPC::STFSX; ImmToIdxMap[PPC::STFD] = PPC::STFDX; ImmToIdxMap[PPC::ADDI] = PPC::ADD4; ImmToIdxMap[PPC::LWA_32] = PPC::LWAX_32; + ImmToIdxMap[PPC::LQ] = PPC::LQX_PSEUDO; + ImmToIdxMap[PPC::STQ] = PPC::STQX_PSEUDO; // 64-bit ImmToIdxMap[PPC::LHA8] = PPC::LHAX8; ImmToIdxMap[PPC::LBZ8] = PPC::LBZX8; @@ -489,6 +491,14 @@ LLVM_DEBUG(dbgs() << "TRUE - Memory operand is X-Form.\n"); return true; } + + // This is a spill/restore of a quadword. + if ((Opcode == PPC::RESTORE_QUADWORD) || (Opcode == PPC::SPILL_QUADWORD)) { + LLVM_DEBUG(dbgs() << "Memory Operand: " << InstrInfo->getName(Opcode) + << " for register " << printReg(Reg, this) << ".\n"); + LLVM_DEBUG(dbgs() << "TRUE - Memory operand is a quadword.\n"); + return true; + } } LLVM_DEBUG(dbgs() << "FALSE - Scavenging is not required.\n"); return false; diff --git a/llvm/test/CodeGen/PowerPC/LQ-STQ-32bit-offset.ll b/llvm/test/CodeGen/PowerPC/LQ-STQ-32bit-offset.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/PowerPC/LQ-STQ-32bit-offset.ll @@ -0,0 +1,34 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -mcpu=pwr8 -verify-machineinstrs -mtriple=powerpc64le-unknown-linux-gnu \ +; RUN: -ppc-asm-full-reg-names -o - %s | FileCheck %s + +%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 + +define dso_local void @test() #0 { +; CHECK-LABEL: test: +; CHECK: # %bb.0: # %entry +; CHECK: lis [[REG1:r[0-9]+]], {{[0-9]+}} +; CHECK-NEXT: ori [[REG1]], [[REG1]], {{[0-9]+}} +; CHECK-NEXT: add [[REG2:r[0-9]+]], r31, [[REG1]] +; CHECK: sync +; CHECK-NEXT: stq r{{[0-9]+}}, [[OFF:[0-9]+]]([[REG2]]) +; CHECK-NEXT: sync +; CHECK-NEXT: lq r{{[0-9]+}}, [[OFF]]([[REG2]]) +entry: + %s2 = alloca %struct.StructA, align 16 + %s3 = alloca %struct.StructA, align 16 + %arr = alloca [90100 x i32], align 4 + %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 +} + +declare void @llvm.memcpy.p0.p0.i64(ptr noalias nocapture writeonly, ptr noalias nocapture readonly, i64, i1 immarg) + +attributes #0 = { noinline nounwind optnone uwtable "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="pwr10" "target-features"="+altivec,+bpermd,+crbits,+crypto,+direct-move,+extdiv,+isa-v206-instructions,+isa-v207-instructions,+isa-v30-instructions,+isa-v31-instructions,+mma,+paired-vector-memops,+pcrelative-memops,+power10-vector,+power8-vector,+power9-vector,+prefix-instrs,+quadword-atomics,+vsx,-htm,-privileged,-rop-protect,-spe" } diff --git a/llvm/test/CodeGen/PowerPC/LQ-STQ.ll b/llvm/test/CodeGen/PowerPC/LQ-STQ.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/PowerPC/LQ-STQ.ll @@ -0,0 +1,27 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -mcpu=pwr8 -verify-machineinstrs -mtriple=powerpc64le-unknown-linux-gnu \ +; RUN: -ppc-asm-full-reg-names -o - %s | FileCheck %s + +%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 + +define dso_local void @test() { +; CHECK-LABEL: test: +; CHECK: # %bb.0: # %entry +; CHECK: stq r{{[0-9]+}}, -[[OFF:[0-9]+]](r1) +; CHECK-NEXT: sync +; CHECK-NEXT: lq r{{[0-9]+}}, -[[OFF]](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 +} + +declare void @llvm.memcpy.p0.p0.i64(ptr noalias nocapture writeonly, ptr noalias nocapture readonly, i64, i1 immarg)