atmnpatel updated this revision to Diff 298734.
atmnpatel added a comment.
Reverted to prior diff.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D86844/new/
https://reviews.llvm.org/D86844
Files:
clang/test/Misc/loop-opt-setup.c
llvm/include/llvm/Transforms/Utils/LoopUtils.h
llvm/lib/Transforms/Scalar/LoopDeletion.cpp
llvm/lib/Transforms/Utils/LoopUtils.cpp
llvm/test/Other/loop-deletion-printer.ll
llvm/test/Other/loop-pm-invalidation.ll
llvm/test/Transforms/LICM/2003-02-27-PreheaderProblem.ll
llvm/test/Transforms/LoopDeletion/2017-07-11-incremental-dt.ll
llvm/test/Transforms/LoopDeletion/basic-remark.ll
llvm/test/Transforms/LoopDeletion/diundef.ll
llvm/test/Transforms/LoopDeletion/invalidation.ll
llvm/test/Transforms/LoopDeletion/multiple-exit-conditions.ll
llvm/test/Transforms/LoopDeletion/multiple-exits.ll
llvm/test/Transforms/LoopDeletion/mustprogress.ll
llvm/test/Transforms/LoopDeletion/unreachable-loops.ll
llvm/test/Transforms/LoopDeletion/use-in-unreachable.ll
llvm/test/Transforms/SCCP/calltest.ll
llvm/test/Transforms/SimpleLoopUnswitch/pr37888.ll
Index: llvm/test/Transforms/SimpleLoopUnswitch/pr37888.ll
===================================================================
--- llvm/test/Transforms/SimpleLoopUnswitch/pr37888.ll
+++ llvm/test/Transforms/SimpleLoopUnswitch/pr37888.ll
@@ -7,7 +7,7 @@
target triple = "x86_64-unknown-linux-gnu"
-define void @pr37888() {
+define void @pr37888() willreturn {
; CHECK-LABEL: define void @pr37888()
entry:
%tobool = icmp ne i16 undef, 0
Index: llvm/test/Transforms/SCCP/calltest.ll
===================================================================
--- llvm/test/Transforms/SCCP/calltest.ll
+++ llvm/test/Transforms/SCCP/calltest.ll
@@ -4,7 +4,7 @@
%empty = type {}
declare %empty @has_side_effects()
-define double @test_0(i32 %param) {
+define double @test_0(i32 %param) willreturn {
; CHECK-LABEL: @test_0(
; CHECK-NOT: br
entry:
Index: llvm/test/Transforms/LoopDeletion/use-in-unreachable.ll
===================================================================
--- llvm/test/Transforms/LoopDeletion/use-in-unreachable.ll
+++ llvm/test/Transforms/LoopDeletion/use-in-unreachable.ll
@@ -3,7 +3,7 @@
; Checking that possible users of instruction from the loop in
; unreachable blocks are handled.
-define i64 @foo() {
+define i64 @foo() willreturn {
entry:
br label %invloop
; CHECK-LABEL-NOT: invloop
Index: llvm/test/Transforms/LoopDeletion/unreachable-loops.ll
===================================================================
--- llvm/test/Transforms/LoopDeletion/unreachable-loops.ll
+++ llvm/test/Transforms/LoopDeletion/unreachable-loops.ll
@@ -216,7 +216,7 @@
; Show recursive deletion of loops. Since we start with subloops and progress outward
; to parent loop, we first delete the loop L2. Now loop L1 becomes a non-loop since it's backedge
; from L2's preheader to L1's exit block is never taken. So, L1 gets deleted as well.
-define void @test8(i64 %n) {
+define void @test8(i64 %n) #0 {
; CHECK-LABEL: test8
; CHECK-LABEL: entry:
; CHECK-NEXT: br label %exit
@@ -318,7 +318,7 @@
; deleted.
; In the next iteration, since L2 is never executed and has no subloops, we delete
; L2 as well. Finally, the outermost loop L1 is deleted.
-define void @test11(i64 %n) {
+define void @test11(i64 %n) #0 {
; CHECK-LABEL: test11
; CHECK-LABEL: entry:
; CHECK-NEXT: br label %exit
@@ -355,7 +355,7 @@
; 2 edges from a single exiting block to the exit block.
-define i64 @test12(i64 %n){
+define i64 @test12(i64 %n) #0 {
;CHECK-LABEL: @test12
; CHECK-NOT: L1:
; CHECK-NOT: L1Latch:
@@ -392,7 +392,7 @@
}
; multiple edges to exit block from the same exiting blocks
-define i64 @test13(i64 %n) {
+define i64 @test13(i64 %n) #0 {
; CHECK-LABEL: @test13
; CHECK-NOT: L1:
; CHECK-NOT: L1Latch:
@@ -433,3 +433,5 @@
%y.phi = phi i64 [ 10, %L1Block ], [ 10, %L1Block ], [ %y.next, %L1 ], [ 30, %L1Latch ], [ 30, %L1Latch ]
ret i64 %y.phi
}
+
+attributes #0 = { willreturn }
Index: llvm/test/Transforms/LoopDeletion/mustprogress.ll
===================================================================
--- llvm/test/Transforms/LoopDeletion/mustprogress.ll
+++ llvm/test/Transforms/LoopDeletion/mustprogress.ll
@@ -14,7 +14,9 @@
; CHECK-NEXT: entry:
; CHECK-NEXT: br label [[FOR_END:%.*]]
; CHECK: for.end:
-; CHECK-NEXT: unreachable
+; CHECK-NEXT: br label [[FOR_COND1:%.*]]
+; CHECK: for.cond1:
+; CHECK-NEXT: br label [[FOR_COND1]]
;
entry:
br label %for.cond
@@ -43,7 +45,9 @@
; CHECK-NEXT: entry:
; CHECK-NEXT: br label [[FOR_END:%.*]]
; CHECK: for.end:
-; CHECK-NEXT: unreachable
+; CHECK-NEXT: br label [[FOR_COND1:%.*]]
+; CHECK: for.cond1:
+; CHECK-NEXT: br label [[FOR_COND1]]
;
entry:
br label %for.cond
Index: llvm/test/Transforms/LoopDeletion/multiple-exits.ll
===================================================================
--- llvm/test/Transforms/LoopDeletion/multiple-exits.ll
+++ llvm/test/Transforms/LoopDeletion/multiple-exits.ll
@@ -10,7 +10,7 @@
; RUN: opt < %s -passes=loop-deletion -S | FileCheck %s --check-prefixes=CHECK,AFTER
-define void @foo(i64 %n, i64 %m) nounwind {
+define void @foo(i64 %n, i64 %m) #0 {
; CHECK-LABEL: @foo(
entry:
@@ -43,7 +43,7 @@
; CHECK-NEXT: ret void
}
-define i64 @bar(i64 %n, i64 %m, i64 %maybe_zero) nounwind {
+define i64 @bar(i64 %n, i64 %m, i64 %maybe_zero) #0 {
; CHECK-LABEL: @bar(
entry:
@@ -95,7 +95,7 @@
; This function has a loop which looks like @bar's but that cannot be deleted
; because which path we exit through determines which value is selected.
-define i64 @baz(i64 %n, i64 %m, i64 %maybe_zero) nounwind {
+define i64 @baz(i64 %n, i64 %m, i64 %maybe_zero) #0 {
; CHECK-LABEL: @baz(
entry:
@@ -136,3 +136,5 @@
; CHECK-NEXT: %[[X:.*]] = phi i64 [ 12, %bb ], [ 10, %bb2 ], [ 10, %bb3 ]
; CHECK-NEXT: ret i64 %[[X]]
}
+
+attributes #0 = { nounwind willreturn }
\ No newline at end of file
Index: llvm/test/Transforms/LoopDeletion/multiple-exit-conditions.ll
===================================================================
--- llvm/test/Transforms/LoopDeletion/multiple-exit-conditions.ll
+++ llvm/test/Transforms/LoopDeletion/multiple-exit-conditions.ll
@@ -11,7 +11,7 @@
; CHECK: return:
; CHECK-NEXT: ret void
-define void @foo(i64 %n, i64 %m) nounwind {
+define void @foo(i64 %n, i64 %m) nounwind willreturn {
entry:
br label %bb
Index: llvm/test/Transforms/LoopDeletion/invalidation.ll
===================================================================
--- llvm/test/Transforms/LoopDeletion/invalidation.ll
+++ llvm/test/Transforms/LoopDeletion/invalidation.ll
@@ -8,7 +8,7 @@
; RUN: | FileCheck %s --check-prefixes=CHECK,AFTER
-define void @foo(i64 %n, i64 %m) nounwind {
+define void @foo(i64 %n, i64 %m) nounwind willreturn {
; CHECK-LABEL: @foo(
entry:
Index: llvm/test/Transforms/LoopDeletion/diundef.ll
===================================================================
--- llvm/test/Transforms/LoopDeletion/diundef.ll
+++ llvm/test/Transforms/LoopDeletion/diundef.ll
@@ -5,7 +5,7 @@
@a = common local_unnamed_addr global i32 0, align 4, !dbg !0
-define i32 @b() local_unnamed_addr !dbg !12 {
+define i32 @b() local_unnamed_addr willreturn !dbg !12 {
entry:
call void @llvm.dbg.value(metadata i32 0, metadata !16, metadata !DIExpression()), !dbg !17
br label %for.cond, !dbg !18
Index: llvm/test/Transforms/LoopDeletion/basic-remark.ll
===================================================================
--- llvm/test/Transforms/LoopDeletion/basic-remark.ll
+++ llvm/test/Transforms/LoopDeletion/basic-remark.ll
@@ -10,7 +10,7 @@
; CHECK-NEXT: Args:
; CHECK-NEXT: - String: Loop deleted because it is invariant
; CHECK-NEXT: ...
-define i32 @main() local_unnamed_addr #0 {
+define i32 @main() local_unnamed_addr willreturn {
entry:
br label %for.cond, !dbg !9
Index: llvm/test/Transforms/LoopDeletion/2017-07-11-incremental-dt.ll
===================================================================
--- llvm/test/Transforms/LoopDeletion/2017-07-11-incremental-dt.ll
+++ llvm/test/Transforms/LoopDeletion/2017-07-11-incremental-dt.ll
@@ -14,7 +14,7 @@
; DT: [3] %for.body
; DT: [4] %for.cond3.loopexit
-define i32 @fn1() {
+define i32 @fn1() willreturn {
entry:
br label %for.cond
Index: llvm/test/Transforms/LICM/2003-02-27-PreheaderProblem.ll
===================================================================
--- llvm/test/Transforms/LICM/2003-02-27-PreheaderProblem.ll
+++ llvm/test/Transforms/LICM/2003-02-27-PreheaderProblem.ll
@@ -6,7 +6,7 @@
; RUN: opt < %s -licm -loop-deletion -simplifycfg -S | \
; RUN: not grep "br "
-define i32 @main(i32 %argc) {
+define i32 @main(i32 %argc) willreturn {
; <label>:0
br label %bb5
bb5: ; preds = %bb5, %0
Index: llvm/test/Other/loop-pm-invalidation.ll
===================================================================
--- llvm/test/Other/loop-pm-invalidation.ll
+++ llvm/test/Other/loop-pm-invalidation.ll
@@ -227,7 +227,7 @@
ret void
}
-define void @dead_loop() {
+define void @dead_loop() willreturn {
; CHECK-LOOP-INV: Starting {{.*}}Function pass manager run
; CHECK-LOOP-INV-NEXT: Starting {{.*}}Function pass manager run
; CHECK-LOOP-INV-NEXT: Running pass: LoopSimplifyPass
Index: llvm/test/Other/loop-deletion-printer.ll
===================================================================
--- llvm/test/Other/loop-deletion-printer.ll
+++ llvm/test/Other/loop-deletion-printer.ll
@@ -14,7 +14,7 @@
; DELETED-BUT-PRINTED: IR Dump {{.*}}LoopDeletionPass {{.*invalidated:}}
; DELETED-BUT-PRINTED-NOT: IR Dump {{.*}}LoopInstSimplifyPass
-define void @deleteme() {
+define void @deleteme() willreturn {
entry:
br label %loop
loop:
Index: llvm/lib/Transforms/Utils/LoopUtils.cpp
===================================================================
--- llvm/lib/Transforms/Utils/LoopUtils.cpp
+++ llvm/lib/Transforms/Utils/LoopUtils.cpp
@@ -63,6 +63,7 @@
static const char *LLVMLoopDisableNonforced = "llvm.loop.disable_nonforced";
static const char *LLVMLoopDisableLICM = "llvm.licm.disable";
+static const char *LLVMLoopMustProgress = "llvm.loop.mustprogress";
bool llvm::formDedicatedExitBlocks(Loop *L, DominatorTree *DT, LoopInfo *LI,
MemorySSAUpdater *MSSAU,
@@ -404,6 +405,10 @@
return getBooleanLoopAttribute(L, LLVMLoopDisableLICM);
}
+bool llvm::hasMustProgress(const Loop *L) {
+ return getBooleanLoopAttribute(L, LLVMLoopMustProgress);
+}
+
TransformationMode llvm::hasUnrollTransformation(Loop *L) {
if (getBooleanLoopAttribute(L, "llvm.loop.unroll.disable"))
return TM_SuppressedByUser;
Index: llvm/lib/Transforms/Scalar/LoopDeletion.cpp
===================================================================
--- llvm/lib/Transforms/Scalar/LoopDeletion.cpp
+++ llvm/lib/Transforms/Scalar/LoopDeletion.cpp
@@ -56,10 +56,10 @@
for (PHINode &P : ExitBlock->phis()) {
Value *incoming = P.getIncomingValueForBlock(ExitingBlocks[0]);
- // Make sure all exiting blocks produce the same incoming value for the exit
- // block. If there are different incoming values for different exiting
- // blocks, then it is impossible to statically determine which value should
- // be used.
+ // Make sure all exiting blocks produce the same incoming value for the
+ // exit block. If there are different incoming values for different
+ // exiting blocks, then it is impossible to statically determine which
+ // value should be used.
AllOutgoingValuesSame =
all_of(makeArrayRef(ExitingBlocks).slice(1), [&](BasicBlock *BB) {
return incoming == P.getIncomingValueForBlock(BB);
@@ -199,7 +199,7 @@
// blocks. Otherwise, we'd be in the situation of needing to be able to
// solve statically which exit block will be branched to, or trying to
// preserve the branching logic in a loop invariant manner.
- if (!ExitBlock && L->getNumExitBlocks() != 0) {
+ if (!ExitBlock) {
LLVM_DEBUG(dbgs() << "Deletion requires single exit block\n");
return LoopDeletionResult::Unmodified;
}
@@ -214,8 +214,10 @@
// Don't remove loops for which we can't solve the trip count.
// They could be infinite, in which case we'd be changing program behavior.
const SCEV *S = SE.getConstantMaxBackedgeTakenCount(L);
- if (isa<SCEVCouldNotCompute>(S)) {
- LLVM_DEBUG(dbgs() << "Could not compute SCEV MaxBackedgeTakenCount.\n");
+ if (isa<SCEVCouldNotCompute>(S) &&
+ !L->getHeader()->getParent()->mustProgress() && !hasMustProgress(L)) {
+ LLVM_DEBUG(dbgs() << "Could not compute SCEV MaxBackedgeTakenCount and was "
+ "not required to make progress.\n");
return Changed ? LoopDeletionResult::Modified
: LoopDeletionResult::Unmodified;
}
Index: llvm/include/llvm/Transforms/Utils/LoopUtils.h
===================================================================
--- llvm/include/llvm/Transforms/Utils/LoopUtils.h
+++ llvm/include/llvm/Transforms/Utils/LoopUtils.h
@@ -229,6 +229,9 @@
/// Look for the loop attribute that disables the LICM transformation heuristics.
bool hasDisableLICMTransformsHint(const Loop *L);
+/// Look for the loop attribute that requires progress within the loop.
+bool hasMustProgress(const Loop *L);
+
/// The mode sets how eager a transformation should be applied.
enum TransformationMode {
/// The pass can use heuristics to determine whether a transformation should
Index: clang/test/Misc/loop-opt-setup.c
===================================================================
--- clang/test/Misc/loop-opt-setup.c
+++ clang/test/Misc/loop-opt-setup.c
@@ -24,7 +24,7 @@
}
// Check br i1 to make sure the loop is gone, there will still be a label branch for the infinite loop.
-// CHECK-LABEL: Helper
-// CHECK: br label
+// CHECK-LABEL: Helper
+// CHECK: entry:
// CHECK-NOT: br i1
-// CHECK: br label
+// CHECK-NEXT: ret void
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits