diff --git a/llvm/lib/Target/PowerPC/PPCTargetTransformInfo.h b/llvm/lib/Target/PowerPC/PPCTargetTransformInfo.h --- a/llvm/lib/Target/PowerPC/PPCTargetTransformInfo.h +++ b/llvm/lib/Target/PowerPC/PPCTargetTransformInfo.h @@ -68,6 +68,7 @@ bool canSaveCmp(Loop *L, BranchInst **BI, ScalarEvolution *SE, LoopInfo *LI, DominatorTree *DT, AssumptionCache *AC, TargetLibraryInfo *LibInfo); + bool getTgtMemIntrinsic(IntrinsicInst *Inst, MemIntrinsicInfo &Info); void getUnrollingPreferences(Loop *L, ScalarEvolution &SE, TTI::UnrollingPreferences &UP); void getPeelingPreferences(Loop *L, ScalarEvolution &SE, diff --git a/llvm/lib/Target/PowerPC/PPCTargetTransformInfo.cpp b/llvm/lib/Target/PowerPC/PPCTargetTransformInfo.cpp --- a/llvm/lib/Target/PowerPC/PPCTargetTransformInfo.cpp +++ b/llvm/lib/Target/PowerPC/PPCTargetTransformInfo.cpp @@ -1203,3 +1203,45 @@ else return TargetTransformInfoImplBase::isLSRCostLess(C1, C2); } + +bool PPCTTIImpl::getTgtMemIntrinsic(IntrinsicInst *Inst, + MemIntrinsicInfo &Info) { + switch (Inst->getIntrinsicID()) { + case Intrinsic::ppc_altivec_lvx: + case Intrinsic::ppc_altivec_lvxl: + case Intrinsic::ppc_altivec_lvebx: + case Intrinsic::ppc_altivec_lvehx: + case Intrinsic::ppc_altivec_lvewx: + case Intrinsic::ppc_vsx_lxvd2x: + case Intrinsic::ppc_vsx_lxvw4x: + case Intrinsic::ppc_vsx_lxvd2x_be: + case Intrinsic::ppc_vsx_lxvw4x_be: + case Intrinsic::ppc_vsx_lxvl: + case Intrinsic::ppc_vsx_lxvll: { + Info.PtrVal = Inst->getArgOperand(0); + Info.ReadMem = true; + Info.WriteMem = false; + return true; + } + case Intrinsic::ppc_altivec_stvx: + case Intrinsic::ppc_altivec_stvxl: + case Intrinsic::ppc_altivec_stvebx: + case Intrinsic::ppc_altivec_stvehx: + case Intrinsic::ppc_altivec_stvewx: + case Intrinsic::ppc_vsx_stxvd2x: + case Intrinsic::ppc_vsx_stxvw4x: + case Intrinsic::ppc_vsx_stxvd2x_be: + case Intrinsic::ppc_vsx_stxvw4x_be: + case Intrinsic::ppc_vsx_stxvl: + case Intrinsic::ppc_vsx_stxvll: { + Info.PtrVal = Inst->getArgOperand(1); + Info.ReadMem = false; + Info.WriteMem = true; + return true; + } + default: + break; + } + + return false; +} diff --git a/llvm/test/Transforms/LoopStrengthReduce/Power/memory-intrinsic.ll b/llvm/test/Transforms/LoopStrengthReduce/Power/memory-intrinsic.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Transforms/LoopStrengthReduce/Power/memory-intrinsic.ll @@ -0,0 +1,38 @@ +; REQUIRES: asserts +; RUN: opt -loop-reduce -debug-only=loop-reduce -S < %s 2>&1 | FileCheck %s + +target datalayout = "e-m:e-i64:64-n32:64" +target triple = "powerpc64le-unknown-linux-gnu" + +; CHECK: LSR Use: Kind=Address +; CHECK: LSR Use: Kind=Address +; CHECK-NOT: LSR Use: Kind=Basic +; CHECK-NOT: LSR Use: Kind=Basic + +declare <4 x i32> @llvm.ppc.altivec.lvx(i8*) +declare void @llvm.ppc.altivec.stvx(<4 x i32>, i8*) + +; Function Attrs: nofree norecurse nounwind +define void @foo(<4 x i32>* %0, <4 x i32>* %1, i32 signext %2) { + %4 = icmp sgt i32 %2, 0 + br i1 %4, label %5, label %7 + +5: ; preds = %3 + %6 = zext i32 %2 to i64 + br label %8 + +7: ; preds = %8, %3 + ret void + +8: ; preds = %5, %8 + %9 = phi i64 [ 0, %5 ], [ %15, %8 ] + %10 = getelementptr inbounds <4 x i32>, <4 x i32>* %1, i64 %9 + %11 = bitcast <4 x i32>* %10 to i8* + %12 = call <4 x i32> @llvm.ppc.altivec.lvx(i8* %11) + %13 = getelementptr inbounds <4 x i32>, <4 x i32>* %0, i64 %9 + %14 = bitcast <4 x i32>* %13 to i8* + call void @llvm.ppc.altivec.stvx(<4 x i32> %12, i8* %14) + %15 = add nuw nsw i64 %9, 10 + %16 = icmp ult i64 %15, %6 + br i1 %16, label %8, label %7 +}