From 68081f41fafc13e194dfa639a3219b21c176489f Mon Sep 17 00:00:00 2001 From: Sanjoy Das Date: Sat, 6 Jun 2015 05:24:10 +0000 Subject: [PATCH] [LoopUnroll] Fix truncation bug in canUnrollCompletely. Summary: canUnrollCompletely takes `unsigned` values for `UnrolledCost` and `RolledDynamicCost` but is passed in `uint64_t`s that are silently truncated. Because of this, when `UnrolledSize` is a large integer that has a small remainder with UINT32_MAX, LLVM tries to completely unroll loops with high trip counts. Reviewers: mzolotukhin, chandlerc Subscribers: llvm-commits Differential Revision: http://reviews.llvm.org/D10293 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@239218 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Transforms/Scalar/LoopUnrollPass.cpp | 6 +- .../LoopUnroll/full-unroll-bad-cost.ll | 58 +++++++++++++++++++ 2 files changed, 61 insertions(+), 3 deletions(-) create mode 100644 test/Transforms/LoopUnroll/full-unroll-bad-cost.ll diff --git a/lib/Transforms/Scalar/LoopUnrollPass.cpp b/lib/Transforms/Scalar/LoopUnrollPass.cpp index d8ba9648b95..e831d834070 100644 --- a/lib/Transforms/Scalar/LoopUnrollPass.cpp +++ b/lib/Transforms/Scalar/LoopUnrollPass.cpp @@ -227,7 +227,7 @@ namespace { bool canUnrollCompletely(Loop *L, unsigned Threshold, unsigned PercentDynamicCostSavedThreshold, unsigned DynamicCostSavingsDiscount, - unsigned UnrolledCost, unsigned RolledDynamicCost); + uint64_t UnrolledCost, uint64_t RolledDynamicCost); }; } @@ -768,8 +768,8 @@ static void SetLoopAlreadyUnrolled(Loop *L) { bool LoopUnroll::canUnrollCompletely(Loop *L, unsigned Threshold, unsigned PercentDynamicCostSavedThreshold, unsigned DynamicCostSavingsDiscount, - unsigned UnrolledCost, - unsigned RolledDynamicCost) { + uint64_t UnrolledCost, + uint64_t RolledDynamicCost) { if (Threshold == NoThreshold) { DEBUG(dbgs() << " Can fully unroll, because no threshold is set.\n"); diff --git a/test/Transforms/LoopUnroll/full-unroll-bad-cost.ll b/test/Transforms/LoopUnroll/full-unroll-bad-cost.ll new file mode 100644 index 00000000000..e5694fbeb0c --- /dev/null +++ b/test/Transforms/LoopUnroll/full-unroll-bad-cost.ll @@ -0,0 +1,58 @@ +; RUN: opt -S -loop-unroll < %s | FileCheck %s + +; LLVM should not try to fully unroll this loop. + +declare void @f() +declare void @g() +declare void @h() + +define void @trivial_loop() { +; CHECK-LABEL: @trivial_loop( + entry: + br label %loop + + loop: + %idx = phi i32 [ 0, %entry ], [ %idx.inc, %loop ] + %idx.inc = add i32 %idx, 1 + call void @f() + call void @g() + call void @h() + call void @f() + call void @g() + call void @h() + call void @f() + call void @g() + call void @h() + call void @f() + call void @g() + call void @h() + call void @f() + call void @g() + call void @h() + %be = icmp slt i32 %idx, 268435456 + br i1 %be, label %loop, label %exit + +; CHECK: loop: +; CHECK-NEXT: %idx = phi i32 [ 0, %entry ], [ %idx.inc, %loop ] +; CHECK-NEXT: %idx.inc = add i32 %idx, 1 +; CHECK-NEXT: call void @f() +; CHECK-NEXT: call void @g() +; CHECK-NEXT: call void @h() +; CHECK-NEXT: call void @f() +; CHECK-NEXT: call void @g() +; CHECK-NEXT: call void @h() +; CHECK-NEXT: call void @f() +; CHECK-NEXT: call void @g() +; CHECK-NEXT: call void @h() +; CHECK-NEXT: call void @f() +; CHECK-NEXT: call void @g() +; CHECK-NEXT: call void @h() +; CHECK-NEXT: call void @f() +; CHECK-NEXT: call void @g() +; CHECK-NEXT: call void @h() +; CHECK-NEXT: %be = icmp slt i32 %idx, 268435456 +; CHECK-NEXT: br i1 %be, label %loop, label %exit + + exit: + ret void +} -- 2.34.1