diff --git a/llvm/include/llvm/Transforms/Utils/LoopUtils.h b/llvm/include/llvm/Transforms/Utils/LoopUtils.h --- a/llvm/include/llvm/Transforms/Utils/LoopUtils.h +++ b/llvm/include/llvm/Transforms/Utils/LoopUtils.h @@ -271,6 +271,9 @@ void addStringMetadataToLoop(Loop *TheLoop, const char *MDString, unsigned V = 0); +/// Returns true if Name is applied to TheLoop and enabled. +bool getBooleanLoopAttribute(const Loop *TheLoop, StringRef Name); + /// Returns a loop's estimated trip count based on branch weight metadata. /// In addition if \p EstimatedLoopInvocationWeight is not null it is /// initialized with weight of loop's latch leading to the exit. diff --git a/llvm/lib/Target/ARM/ARMTargetTransformInfo.cpp b/llvm/lib/Target/ARM/ARMTargetTransformInfo.cpp --- a/llvm/lib/Target/ARM/ARMTargetTransformInfo.cpp +++ b/llvm/lib/Target/ARM/ARMTargetTransformInfo.cpp @@ -1946,6 +1946,10 @@ if (ST->hasBranchPredictor() && L->getNumBlocks() > 4) return; + // Don't unroll vectorized loops, including the remainder loop + if (getBooleanLoopAttribute(L, "llvm.loop.isvectorized")) + return; + // Scan the loop: don't unroll loops with calls as this could prevent // inlining. unsigned Cost = 0; diff --git a/llvm/lib/Transforms/Utils/LoopUtils.cpp b/llvm/lib/Transforms/Utils/LoopUtils.cpp --- a/llvm/lib/Transforms/Utils/LoopUtils.cpp +++ b/llvm/lib/Transforms/Utils/LoopUtils.cpp @@ -297,7 +297,7 @@ llvm_unreachable("unexpected number of options"); } -static bool getBooleanLoopAttribute(const Loop *TheLoop, StringRef Name) { +bool llvm::getBooleanLoopAttribute(const Loop *TheLoop, StringRef Name) { return getOptionalBoolLoopAttribute(TheLoop, Name).getValueOr(false); } diff --git a/llvm/test/Transforms/LoopUnroll/ARM/mve-nounroll.ll b/llvm/test/Transforms/LoopUnroll/ARM/mve-nounroll.ll --- a/llvm/test/Transforms/LoopUnroll/ARM/mve-nounroll.ll +++ b/llvm/test/Transforms/LoopUnroll/ARM/mve-nounroll.ll @@ -70,15 +70,11 @@ ; CHECK-LABEL: @remainder ; CHECK: vector.body: -; CHECK: br i1 %13, label %middle.block, label %vector.body, !llvm.loop !0 +; CHECK: br i1 %7, label %middle.block, label %vector.body, !llvm.loop !0 ; CHECK: middle.block: ; CHECK: br i1 %cmp.n, label %for.cond.cleanup, label %for.body.preheader13 ; CHECK: for.body: -; CHECK: br i1 %exitcond.3, label %for.cond.cleanup.loopexit.unr-lcssa, label %for.body, !llvm.loop !0 -; CHECK: for.body.prol.1: -; CHECK: br i1 %prol.iter.cmp.1, label %for.body.prol.2, label %for.body.prol.loopexit.unr-lcssa -; CHECK: for.body.prol.2: -; CHECK: br label %for.body.prol.loopexit.unr-lcssa +; CHECK: br i1 %exitcond, label %for.cond.cleanup.loopexit, label %for.body, !llvm.loop !0 define void @remainder(float* %s1, float* %s2, float* %d, i32 %n) { entry: