Index: llvm/lib/Analysis/LoopAccessAnalysis.cpp =================================================================== --- llvm/lib/Analysis/LoopAccessAnalysis.cpp +++ llvm/lib/Analysis/LoopAccessAnalysis.cpp @@ -2169,6 +2169,8 @@ bool HasComplexMemInst = false; + bool IsConstantVal = true; + // A runtime check is only legal to insert if there are no convergent calls. HasConvergentOp = false; @@ -2301,6 +2303,10 @@ for (StoreInst *ST : Stores) { Value *Ptr = ST->getPointerOperand(); + Value *Val = ST->getValueOperand(); + + if (!isa(Val)) + IsConstantVal = false; if (isUniform(Ptr)) { // Record store instructions to loop invariant addresses @@ -2338,6 +2344,14 @@ return; } + if (IsConstantVal) { + LLVM_DEBUG( + dbgs() << "LAA: There are only constant initial values in a loop, ignore memory dependency " + << "checks.\n"); + CanVecMem = true; + return; + } + for (LoadInst *LD : Loads) { Value *Ptr = LD->getPointerOperand(); // If we did *not* see this pointer before, insert it to the Index: llvm/test/Transforms/LoopVectorize/AArch64/const-value-initialize-small-loop.ll =================================================================== --- /dev/null +++ llvm/test/Transforms/LoopVectorize/AArch64/const-value-initialize-small-loop.ll @@ -0,0 +1,50 @@ +; RUN: opt < %s -loop-vectorize -mtriple=aarch64--linux-gnu -mattr=+sve -disable-output -debug-only=loop-accesses 2>&1 | FileCheck %s +target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128" + +; +; CHECK-LABEL: test +; CHECK: LAA: There are only constant initial values in a loop, ignore memory dependency checks. +; + +define void @test(i8* %excl_flags_buff.1.us, i32* %0, i32* %full_excl.049.us, i64 %indvars.iv, i32* %arrayidx9.us, i8* %excl_flags_buff.050.us) { +for.body.us.preheader: + br label %for.body.us + +for.body.us: ; preds = %if.end.us, %for.body.us.preheader + %excl_flags_buff.050.us1 = phi i8* [ %excl_flags_buff.1.us, %if.end.us ], [ null, %for.body.us.preheader ] + %full_excl.049.us2 = phi i32* [ %0, %if.end.us ], [ null, %for.body.us.preheader ] + br i1 false, label %if.else.us, label %if.then.us + +if.then.us: ; preds = %for.body.us + br i1 false, label %if.end.us, label %for.body7.us.preheader + +for.body7.us.preheader: ; preds = %if.then.us + br label %for.body7.us + +for.body7.us: ; preds = %for.body7.us, %for.body7.us.preheader + %indvars.iv3 = phi i64 [ 0, %for.body7.us.preheader ], [ %indvars.iv.next, %for.body7.us ] + %arrayidx9.us4 = getelementptr inbounds i32, i32* %full_excl.049.us, i64 %indvars.iv + %1 = load i32, i32* %0, align 4 + %idxprom10.us = sext i32 %1 to i64 + %arrayidx11.us = getelementptr inbounds i8, i8* %excl_flags_buff.050.us, i64 %idxprom10.us + store i8 0, i8* %arrayidx11.us, align 1 + %indvars.iv.next = add nuw nsw i64 %indvars.iv3, 1 + br i1 true, label %if.end.us.loopexit, label %for.body7.us + +if.else.us: ; preds = %for.body.us + br label %if.end.us + +if.end.us.loopexit: ; preds = %for.body7.us + br label %if.end.us + +if.end.us: ; preds = %if.end.us.loopexit, %if.else.us, %if.then.us + %excl_flags_buff.1.us5 = phi i8* [ null, %if.else.us ], [ %excl_flags_buff.1.us, %if.then.us ], [ null, %if.end.us.loopexit ] + %2 = load i32*, i32** null, align 8 + br label %for.body.us +} + +; Function Attrs: argmemonly nofree nounwind willreturn writeonly +declare void @llvm.memset.p0i8.i64(i8* nocapture writeonly, i8, i64, i1 immarg) #0 + +attributes #0 = { argmemonly nofree nounwind willreturn writeonly } +