[PATCH] D86844: [LoopDeletion] Allows deletion of possibly infinite side-effect free loops

2022-10-03 Thread Mikael Holmén via Phabricator via cfe-commits
uabelho added a comment.
Herald added a project: All.

I wrote
 https://github.com/llvm/llvm-project/issues/58123
about a crash that I bisected to this patch.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D86844/new/

https://reviews.llvm.org/D86844

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D86844: [LoopDeletion] Allows deletion of possibly infinite side-effect free loops

2021-01-07 Thread Johannes Doerfert via Phabricator via cfe-commits
jdoerfert added a comment.

In D86844#2484679 , @xbolva00 wrote:

> In D86844#2484639 , @atmnpatel wrote:
>
>> In D86844#2484568 , @fhahn wrote:
>>
>>> In D86844#2481922 , @xbolva00 
>>> wrote:
>>>
   int a, b;
   
   int f(void) {
   while (1) {
   if (a != b) return 1;
   }
   return 0;
   }
   
   int g(int a, int b) {
   while (1) {
   if (a != b) return 1;
   }
   return 0;
   }

 LLVM does not catch these cases; gcc does.

 https://godbolt.org/z/jW7son
>>>
>>> Looks like `must progress` does not get added? If it gets added to the IR 
>>> the loops get removed: https://godbolt.org/z/77v17P
>>
>> I might be misunderstanding the standard here but since 1 is a non-zero 
>> constant expression, it can't be assumed to terminate by the implementation 
>> right? The relevant section from C11 at least is "An iteration statement 
>> whose controlling expression is not a constant expression that performs 
>> [explanation of what it deems as progress] may be assumed by the 
>> implementation to terminate" (C11 6.8.5 p6). I think these cases fall 
>> outside of the scope of this particular change ...
>
> For C yes, but are there such rules for C++? GCC in c++ mode does not check 
> for non-zero constant expr and happily performs this optimization.

@xbolva00 want to provide a follow up patch then :) ?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D86844/new/

https://reviews.llvm.org/D86844

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D86844: [LoopDeletion] Allows deletion of possibly infinite side-effect free loops

2021-01-07 Thread Dávid Bolvanský via Phabricator via cfe-commits
xbolva00 added a comment.

In D86844#2484639 , @atmnpatel wrote:

> In D86844#2484568 , @fhahn wrote:
>
>> In D86844#2481922 , @xbolva00 wrote:
>>
>>>   int a, b;
>>>   
>>>   int f(void) {
>>>   while (1) {
>>>   if (a != b) return 1;
>>>   }
>>>   return 0;
>>>   }
>>>   
>>>   int g(int a, int b) {
>>>   while (1) {
>>>   if (a != b) return 1;
>>>   }
>>>   return 0;
>>>   }
>>>
>>> LLVM does not catch these cases; gcc does.
>>>
>>> https://godbolt.org/z/jW7son
>>
>> Looks like `must progress` does not get added? If it gets added to the IR 
>> the loops get removed: https://godbolt.org/z/77v17P
>
> I might be misunderstanding the standard here but since 1 is a non-zero 
> constant expression, it can't be assumed to terminate by the implementation 
> right? The relevant section from C11 at least is "An iteration statement 
> whose controlling expression is not a constant expression that performs 
> [explanation of what it deems as progress] may be assumed by the 
> implementation to terminate" (C11 6.8.5 p6). I think these cases fall outside 
> of the scope of this particular change ...

For C yes, but are there such rules for C++? GCC in c++ mode does not check for 
non-zero constant expr and happily performs this optimization.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D86844/new/

https://reviews.llvm.org/D86844

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D86844: [LoopDeletion] Allows deletion of possibly infinite side-effect free loops

2021-01-07 Thread Florian Hahn via Phabricator via cfe-commits
fhahn added a comment.

In D86844#2484639 , @atmnpatel wrote:

> I might be misunderstanding the standard here but since 1 is a non-zero 
> constant expression, it can't be assumed to terminate by the implementation 
> right? The relevant section from C11 at least is "An iteration statement 
> whose controlling expression is not a constant expression that performs 
> [explanation of what it deems as progress] may be assumed by the 
> implementation to terminate" (C11 6.8.5 p6). I think these cases fall outside 
> of the scope of this particular change ...

The source is C++, so the C11 standard should be irrelevant. I left a comment 
at D86841 , this seems more appropriate to 
discuss the issue, as it is unrelated to `-loop-deletion`.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D86844/new/

https://reviews.llvm.org/D86844

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D86844: [LoopDeletion] Allows deletion of possibly infinite side-effect free loops

2021-01-07 Thread Atmn Patel via Phabricator via cfe-commits
atmnpatel added a comment.

In D86844#2484568 , @fhahn wrote:

> In D86844#2481922 , @xbolva00 wrote:
>
>>   int a, b;
>>   
>>   int f(void) {
>>   while (1) {
>>   if (a != b) return 1;
>>   }
>>   return 0;
>>   }
>>   
>>   int g(int a, int b) {
>>   while (1) {
>>   if (a != b) return 1;
>>   }
>>   return 0;
>>   }
>>
>> LLVM does not catch these cases; gcc does.
>>
>> https://godbolt.org/z/jW7son
>
> Looks like `must progress` does not get added? If it gets added to the IR the 
> loops get removed: https://godbolt.org/z/77v17P

I might be misunderstanding the standard here but since 1 is a non-zero 
constant expression, it can't be assumed to terminate by the implementation 
right? The relevant section from C11 at least is "An iteration statement whose 
controlling expression is not a constant expression that performs [explanation 
of what it deems as progress] may be assumed by the implementation to 
terminate" (C11 6.8.5 p6).


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D86844/new/

https://reviews.llvm.org/D86844

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D86844: [LoopDeletion] Allows deletion of possibly infinite side-effect free loops

2021-01-07 Thread Florian Hahn via Phabricator via cfe-commits
fhahn added a comment.

In D86844#2481922 , @xbolva00 wrote:

>   int a, b;
>   
>   int f(void) {
>   while (1) {
>   if (a != b) return 1;
>   }
>   return 0;
>   }
>   
>   int g(int a, int b) {
>   while (1) {
>   if (a != b) return 1;
>   }
>   return 0;
>   }
>
> LLVM does not catch these cases; gcc does.
>
> https://godbolt.org/z/jW7son

Looks like `must progress` does not get added? If it gets added to the IR the 
loops get removed: https://godbolt.org/z/77v17P


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D86844/new/

https://reviews.llvm.org/D86844

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D86844: [LoopDeletion] Allows deletion of possibly infinite side-effect free loops

2021-01-06 Thread Dávid Bolvanský via Phabricator via cfe-commits
xbolva00 added a comment.

  int a, b;
  
  int f(void) {
  while (1) {
  if (a != b) return 1;
  }
  return 0;
  }
  
  int g(int a, int b) {
  while (1) {
  if (a != b) return 1;
  }
  return 0;
  }

LLVM does not catch these cases; gcc does.

https://godbolt.org/z/jW7son


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D86844/new/

https://reviews.llvm.org/D86844

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D86844: [LoopDeletion] Allows deletion of possibly infinite side-effect free loops

2021-01-05 Thread Florian Hahn via Phabricator via cfe-commits
fhahn added a comment.

Now that the test is fixed, this could be re-landed, right?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D86844/new/

https://reviews.llvm.org/D86844

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D86844: [LoopDeletion] Allows deletion of possibly infinite side-effect free loops

2020-12-31 Thread Atmn Patel via Phabricator via cfe-commits
atmnpatel added a comment.

In D86844#2475552 , @xbolva00 wrote:

> Do you plan to implement gcc’s option in Clang as followup?

I was not planning on it but I can if no one is planning on it and doesn't mind 
waiting a bit.

Also, clang/test/Misc/loop-opt-setup.c had a bad run line, it's being fixed in 
D93952 , and I'll try to land it again after 
that.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D86844/new/

https://reviews.llvm.org/D86844

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D86844: [LoopDeletion] Allows deletion of possibly infinite side-effect free loops

2020-12-30 Thread Dávid Bolvanský via Phabricator via cfe-commits
xbolva00 added a comment.

Do you plan to implement gcc’s option in Clang as followup?

-ffinite-loops / -fno-finite-loops
Assume that a loop with an exit will eventually take the exit and not loop 
indefinitely. This allows the compiler to remove loops that otherwise have no 
side-effects, not considering eventual endless looping as such.

This option is enabled by default at -O2 for C++ with -std=c++11 or higher.

?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D86844/new/

https://reviews.llvm.org/D86844

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D86844: [LoopDeletion] Allows deletion of possibly infinite side-effect free loops

2020-12-30 Thread Atmn Patel via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG6f1503d59854: [LoopDeletion] Allows deletion of possibly 
infinite side-effect free loops (authored by atmnpatel, committed by adpatel6).

Changed prior to commit:
  https://reviews.llvm.org/D86844?vs=313593=314159#toc

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/Transforms/LoopDeletion/mustprogress.ll
  llvm/test/Transforms/LoopDeletion/no-exit-blocks.ll

Index: llvm/test/Transforms/LoopDeletion/no-exit-blocks.ll
===
--- llvm/test/Transforms/LoopDeletion/no-exit-blocks.ll
+++ llvm/test/Transforms/LoopDeletion/no-exit-blocks.ll
@@ -5,14 +5,7 @@
 ; CHECK: Function Attrs: mustprogress
 ; CHECK-LABEL: define {{[^@]+}}@f
 ; CHECK-SAME: () [[ATTR0:#.*]] {
-; CHECK-NEXT:br label [[TMP1:%.*]]
-; CHECK:   1:
-; CHECK-NEXT:[[DOT01:%.*]] = phi i32 [ 1, [[TMP0:%.*]] ], [ [[TMP3:%.*]], [[TMP2:%.*]] ]
-; CHECK-NEXT:[[DOT0:%.*]] = phi i32 [ 1, [[TMP0]] ], [ [[TMP3]], [[TMP2]] ]
-; CHECK-NEXT:br label [[TMP2]]
-; CHECK:   2:
-; CHECK-NEXT:[[TMP3]] = add nsw i32 [[DOT01]], [[DOT0]]
-; CHECK-NEXT:br label [[TMP1]]
+; CHECK-NEXT:unreachable
 ;
   br label %1
 
Index: llvm/test/Transforms/LoopDeletion/mustprogress.ll
===
--- /dev/null
+++ llvm/test/Transforms/LoopDeletion/mustprogress.ll
@@ -0,0 +1,237 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes
+; RUN: opt < %s -loop-deletion -verify-dom-info -S | FileCheck %s
+
+;; Original C Code:
+;;  void unknown_tripcount_mustprogress_attr_mustprogress_loopmd(int a, int b) {
+;;for (; a < b;) ;
+;;for (;;) ;
+;;  }
+
+define void @unknown_tripcount_mustprogress_attr_mustprogress_loopmd(i32 %a, i32 %b) #0 {
+; CHECK: Function Attrs: mustprogress
+; CHECK-LABEL: define {{[^@]+}}@unknown_tripcount_mustprogress_attr_mustprogress_loopmd
+; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]]) [[ATTR0:#.*]] {
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:br label [[FOR_END:%.*]]
+; CHECK:   for.end:
+; CHECK-NEXT:unreachable
+;
+entry:
+  br label %for.cond
+for.cond:
+  %cmp = icmp slt i32 %a, %b
+  br i1 %cmp, label %for.body, label %for.end
+for.body:
+  br label %for.cond, !llvm.loop !2
+for.end:
+  br label %for.cond1
+for.cond1:
+  br label %for.cond1
+}
+
+;; Original C Code:
+;;  void unknown_tripcount_mustprogress_attr_no_mustprogress_loopmd(int a, int b) {
+;;for (; a < b;) ;
+;;for (;;) ;
+;;  }
+;;  => Removed mustprogress loop attribute
+
+define void @unknown_tripcount_mustprogress_attr_no_mustprogess_loopmd(i32 %a, i32 %b) #0 {
+; CHECK: Function Attrs: mustprogress
+; CHECK-LABEL: define {{[^@]+}}@unknown_tripcount_mustprogress_attr_no_mustprogess_loopmd
+; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]]) [[ATTR0]] {
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:br label [[FOR_END:%.*]]
+; CHECK:   for.end:
+; CHECK-NEXT:unreachable
+;
+entry:
+  br label %for.cond
+for.cond:
+  %cmp = icmp slt i32 %a, %b
+  br i1 %cmp, label %for.body, label %for.end
+for.body:
+  br label %for.cond
+for.end:
+  br label %for.cond1
+for.cond1:
+  br label %for.cond1
+}
+
+;; Original C Code:
+;;  void known_tripcount_no_mustprogress_attr_no_mustprogress_loopmd() {
+;;for (int i = 0; i < 5; i++) ;
+;;  }
+
+define void @known_tripcount_no_mustprogress_attr_no_mustprogress_loopmd() {
+; CHECK-LABEL: define {{[^@]+}}@known_tripcount_no_mustprogress_attr_no_mustprogress_loopmd() {
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:br label [[FOR_END:%.*]]
+; CHECK:   for.end:
+; CHECK-NEXT:ret void
+;
+entry:
+  br label %for.cond
+for.cond:
+  %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.inc ]
+  %cmp = icmp slt i32 %i.0, 5
+  br i1 %cmp, label %for.body, label %for.end
+for.body:
+  br label %for.inc
+for.inc:
+  %inc = add nsw i32 %i.0, 1
+  br label %for.cond
+for.end:
+  ret void
+}
+
+;; Original C Code:
+;;  void known_tripcount_no_mustprogress_attr_mustprogress_loopmd() {
+;;for (int i = 0; i < 5; i++) ;
+;;  }
+;;  => Added mustprogress loop attribute
+
+define void @known_tripcount_no_mustprogress_attr_mustprogress_loopmd() {
+; CHECK-LABEL: define {{[^@]+}}@known_tripcount_no_mustprogress_attr_mustprogress_loopmd() {
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:br label [[FOR_END:%.*]]
+; CHECK:   for.end:
+; CHECK-NEXT:ret void
+;
+entry:
+  br label %for.cond
+for.cond:
+  %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.inc ]
+  %cmp = icmp slt i32 %i.0, 5
+  br i1 %cmp, label %for.body, label %for.end
+for.body:
+  br label %for.inc
+for.inc:
+  %inc = add 

[PATCH] D86844: [LoopDeletion] Allows deletion of possibly infinite side-effect free loops

2020-12-28 Thread Florian Hahn via Phabricator via cfe-commits
fhahn accepted this revision.
fhahn added a comment.
This revision is now accepted and ready to land.

LGTM, thanks!




Comment at: clang/test/Misc/loop-opt-setup.c:26
 
 // Check br i1 to make sure the loop is gone, there will still be a label 
branch for the infinite loop.
 // CHECK-LABEL: Helper

fhahn wrote:
> This comment needs updating, there's no loop there now. Or better, add a 
> run-line with a C standard version that does not have the forward progress 
> guarantee, e.g. `-std=c99` and one with an explicit standard that has it and 
> have different check lines for the 2 cases.
Can you also explain the C99 case in the comment?



Comment at: llvm/lib/Transforms/Utils/LoopUtils.cpp:621
   }
 }
 

atmnpatel wrote:
> nikic wrote:
> > Unrelated, but why do these updates happen before the branch from preheader 
> > to exit is added in IR? Shouldn't it be the other way around according to 
> > the DTU contract?
> Isn't that branch added on line 602? My understanding was the changes on line 
> 640 onwards are for removing, not introducing a branch.
> Shouldn't it be the other way around according to the DTU contract?

Yes I think so. Perhaps a missing case in the DTU validator. Probably good to 
check/fix separately.



Comment at: llvm/test/Transforms/LoopDeletion/mustprogress.ll:2
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 
UTC_ARGS: --function-signature --check-attributes
+; RUN: opt < %s -loop-deletion -S | FileCheck %s
+

probably good to also add `-verify-dom-info`



Comment at: llvm/test/Transforms/LoopDeletion/mustprogress.ll:5
+;; Original C Code:
+;;  void unknown_tripcount_mustprogress_attr_mustprogress_loopmd(int a, int b) 
{
+;;for (; a < b;) ;

FWIW, I don't think the C code doesn't add much, but I don't have any strong 
feelings about it. The IR is what is key and it's really small.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D86844/new/

https://reviews.llvm.org/D86844

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D86844: [LoopDeletion] Allows deletion of possibly infinite side-effect free loops

2020-12-23 Thread Atmn Patel via Phabricator via cfe-commits
atmnpatel added a comment.

Yep, sorry, I'm just waiting for a final stamp of approval from one of the 
reviewers.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D86844/new/

https://reviews.llvm.org/D86844

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D86844: [LoopDeletion] Allows deletion of possibly infinite side-effect free loops

2020-12-23 Thread Dávid Bolvanský via Phabricator via cfe-commits
xbolva00 added a comment.

Can you reland this patch now?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D86844/new/

https://reviews.llvm.org/D86844

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D86844: [LoopDeletion] Allows deletion of possibly infinite side-effect free loops

2020-12-23 Thread Atmn Patel via Phabricator via cfe-commits
atmnpatel updated this revision to Diff 313593.
atmnpatel added a comment.

As expected, @fhahn was right, adding willreturn to all those tests was an 
artifact from previous revisions of this patch and it passed the tests so I 
didn't pay them any mind, but I removed them now.


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/Transforms/LoopDeletion/mustprogress.ll
  llvm/test/Transforms/LoopDeletion/no-exit-blocks.ll

Index: llvm/test/Transforms/LoopDeletion/no-exit-blocks.ll
===
--- llvm/test/Transforms/LoopDeletion/no-exit-blocks.ll
+++ llvm/test/Transforms/LoopDeletion/no-exit-blocks.ll
@@ -5,14 +5,7 @@
 ; CHECK: Function Attrs: mustprogress
 ; CHECK-LABEL: define {{[^@]+}}@f
 ; CHECK-SAME: () [[ATTR0:#.*]] {
-; CHECK-NEXT:br label [[TMP1:%.*]]
-; CHECK:   1:
-; CHECK-NEXT:[[DOT01:%.*]] = phi i32 [ 1, [[TMP0:%.*]] ], [ [[TMP3:%.*]], [[TMP2:%.*]] ]
-; CHECK-NEXT:[[DOT0:%.*]] = phi i32 [ 1, [[TMP0]] ], [ [[TMP3]], [[TMP2]] ]
-; CHECK-NEXT:br label [[TMP2]]
-; CHECK:   2:
-; CHECK-NEXT:[[TMP3]] = add nsw i32 [[DOT01]], [[DOT0]]
-; CHECK-NEXT:br label [[TMP1]]
+; CHECK-NEXT:unreachable
 ;
   br label %1
 
Index: llvm/test/Transforms/LoopDeletion/mustprogress.ll
===
--- /dev/null
+++ llvm/test/Transforms/LoopDeletion/mustprogress.ll
@@ -0,0 +1,237 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes
+; RUN: opt < %s -loop-deletion -S | FileCheck %s
+
+;; Original C Code:
+;;  void unknown_tripcount_mustprogress_attr_mustprogress_loopmd(int a, int b) {
+;;for (; a < b;) ;
+;;for (;;) ;
+;;  }
+
+define void @unknown_tripcount_mustprogress_attr_mustprogress_loopmd(i32 %a, i32 %b) #0 {
+; CHECK: Function Attrs: mustprogress
+; CHECK-LABEL: define {{[^@]+}}@unknown_tripcount_mustprogress_attr_mustprogress_loopmd
+; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]]) [[ATTR0:#.*]] {
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:br label [[FOR_END:%.*]]
+; CHECK:   for.end:
+; CHECK-NEXT:unreachable
+;
+entry:
+  br label %for.cond
+for.cond:
+  %cmp = icmp slt i32 %a, %b
+  br i1 %cmp, label %for.body, label %for.end
+for.body:
+  br label %for.cond, !llvm.loop !2
+for.end:
+  br label %for.cond1
+for.cond1:
+  br label %for.cond1
+}
+
+;; Original C Code:
+;;  void unknown_tripcount_mustprogress_attr_no_mustprogress_loopmd(int a, int b) {
+;;for (; a < b;) ;
+;;for (;;) ;
+;;  }
+;;  => Removed mustprogress loop attribute
+
+define void @unknown_tripcount_mustprogress_attr_no_mustprogess_loopmd(i32 %a, i32 %b) #0 {
+; CHECK: Function Attrs: mustprogress
+; CHECK-LABEL: define {{[^@]+}}@unknown_tripcount_mustprogress_attr_no_mustprogess_loopmd
+; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]]) [[ATTR0]] {
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:br label [[FOR_END:%.*]]
+; CHECK:   for.end:
+; CHECK-NEXT:unreachable
+;
+entry:
+  br label %for.cond
+for.cond:
+  %cmp = icmp slt i32 %a, %b
+  br i1 %cmp, label %for.body, label %for.end
+for.body:
+  br label %for.cond
+for.end:
+  br label %for.cond1
+for.cond1:
+  br label %for.cond1
+}
+
+;; Original C Code:
+;;  void known_tripcount_no_mustprogress_attr_no_mustprogress_loopmd() {
+;;for (int i = 0; i < 5; i++) ;
+;;  }
+
+define void @known_tripcount_no_mustprogress_attr_no_mustprogress_loopmd() {
+; CHECK-LABEL: define {{[^@]+}}@known_tripcount_no_mustprogress_attr_no_mustprogress_loopmd() {
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:br label [[FOR_END:%.*]]
+; CHECK:   for.end:
+; CHECK-NEXT:ret void
+;
+entry:
+  br label %for.cond
+for.cond:
+  %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.inc ]
+  %cmp = icmp slt i32 %i.0, 5
+  br i1 %cmp, label %for.body, label %for.end
+for.body:
+  br label %for.inc
+for.inc:
+  %inc = add nsw i32 %i.0, 1
+  br label %for.cond
+for.end:
+  ret void
+}
+
+;; Original C Code:
+;;  void known_tripcount_no_mustprogress_attr_mustprogress_loopmd() {
+;;for (int i = 0; i < 5; i++) ;
+;;  }
+;;  => Added mustprogress loop attribute
+
+define void @known_tripcount_no_mustprogress_attr_mustprogress_loopmd() {
+; CHECK-LABEL: define {{[^@]+}}@known_tripcount_no_mustprogress_attr_mustprogress_loopmd() {
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:br label [[FOR_END:%.*]]
+; CHECK:   for.end:
+; CHECK-NEXT:ret void
+;
+entry:
+  br label %for.cond
+for.cond:
+  %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.inc ]
+  %cmp = icmp slt i32 %i.0, 5
+  br i1 %cmp, label %for.body, label %for.end
+for.body:
+  br label %for.inc
+for.inc:
+  %inc = add nsw i32 %i.0, 1
+  br label %for.cond, !llvm.loop 

[PATCH] D86844: [LoopDeletion] Allows deletion of possibly infinite side-effect free loops

2020-12-23 Thread Florian Hahn via Phabricator via cfe-commits
fhahn added inline comments.



Comment at: llvm/test/Other/loop-deletion-printer.ll:17
 
-define void @deleteme() {
+define void @deleteme() willreturn {
 entry:

atmnpatel wrote:
> fhahn wrote:
> > Is this change related to the patch? Same for the other test changes that 
> > just add `willreturn`?
> Yep, if these test functions aren't marked willreturn, we won't delete the 
> loop because it could be a legal infinite loop from C/C++.
I don't think that is the case here. The trip count of the loop here is 
constant, so it cannot be infinite. Also, the existing code already removes the 
loop, without `willreturn`, as implied by no changes to the check lines? 

I did not check all other cases, but I would expect that `willreturn` does not 
need to be added to cases where the trip count is a known constant and that 
already get removed.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D86844/new/

https://reviews.llvm.org/D86844

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D86844: [LoopDeletion] Allows deletion of possibly infinite side-effect free loops

2020-12-22 Thread Atmn Patel via Phabricator via cfe-commits
atmnpatel added inline comments.



Comment at: llvm/lib/Transforms/Utils/LoopUtils.cpp:621
   }
 }
 

nikic wrote:
> Unrelated, but why do these updates happen before the branch from preheader 
> to exit is added in IR? Shouldn't it be the other way around according to the 
> DTU contract?
Isn't that branch added on line 602? My understanding was the changes on line 
640 onwards are for removing, not introducing a branch.



Comment at: llvm/test/Other/loop-deletion-printer.ll:17
 
-define void @deleteme() {
+define void @deleteme() willreturn {
 entry:

fhahn wrote:
> Is this change related to the patch? Same for the other test changes that 
> just add `willreturn`?
Yep, if these test functions aren't marked willreturn, we won't delete the loop 
because it could be a legal infinite loop from C/C++.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D86844/new/

https://reviews.llvm.org/D86844

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D86844: [LoopDeletion] Allows deletion of possibly infinite side-effect free loops

2020-12-22 Thread Atmn Patel via Phabricator via cfe-commits
atmnpatel updated this revision to Diff 313484.
atmnpatel added a comment.

Addressed comments


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/no-exit-blocks.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/no-exit-blocks.ll
===
--- llvm/test/Transforms/LoopDeletion/no-exit-blocks.ll
+++ llvm/test/Transforms/LoopDeletion/no-exit-blocks.ll
@@ -5,14 +5,7 @@
 ; CHECK: Function Attrs: mustprogress
 ; CHECK-LABEL: define {{[^@]+}}@f
 ; CHECK-SAME: () [[ATTR0:#.*]] {
-; CHECK-NEXT:br label [[TMP1:%.*]]
-; CHECK:   1:
-; CHECK-NEXT:[[DOT01:%.*]] = phi i32 [ 1, [[TMP0:%.*]] ], [ [[TMP3:%.*]], [[TMP2:%.*]] ]
-; CHECK-NEXT:[[DOT0:%.*]] = phi i32 [ 1, [[TMP0]] ], [ [[TMP3]], [[TMP2]] ]
-; CHECK-NEXT:br label [[TMP2]]
-; CHECK:   2:
-; CHECK-NEXT:[[TMP3]] = add nsw i32 [[DOT01]], [[DOT0]]
-; CHECK-NEXT:br label [[TMP1]]
+; CHECK-NEXT:unreachable
 ;
   br label %1
 
Index: llvm/test/Transforms/LoopDeletion/mustprogress.ll

[PATCH] D86844: [LoopDeletion] Allows deletion of possibly infinite side-effect free loops

2020-12-22 Thread Jonas Paulsson via Phabricator via cfe-commits
jonpa added inline comments.



Comment at: llvm/lib/Transforms/Scalar/LoopDeletion.cpp:132
 /// A loop is considered dead if it does not impact the observable behavior of
 /// the program other than finite running time. This never removes a loop that
 /// might be infinite (unless it is never executed), as doing so could change

Seems like it would be nice to update this comment.



Comment at: llvm/lib/Transforms/Scalar/LoopDeletion.cpp:211
   // 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);

and also this comment..?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D86844/new/

https://reviews.llvm.org/D86844

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D86844: [LoopDeletion] Allows deletion of possibly infinite side-effect free loops

2020-12-22 Thread Florian Hahn via Phabricator via cfe-commits
fhahn added inline comments.



Comment at: clang/test/Misc/loop-opt-setup.c:26
 
 // Check br i1 to make sure the loop is gone, there will still be a label 
branch for the infinite loop.
 // CHECK-LABEL: Helper

This comment needs updating, there's no loop there now. Or better, add a 
run-line with a C standard version that does not have the forward progress 
guarantee, e.g. `-std=c99` and one with an explicit standard that has it and 
have different check lines for the 2 cases.



Comment at: llvm/test/Other/loop-deletion-printer.ll:17
 
-define void @deleteme() {
+define void @deleteme() willreturn {
 entry:

Is this change related to the patch? Same for the other test changes that just 
add `willreturn`?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D86844/new/

https://reviews.llvm.org/D86844

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D86844: [LoopDeletion] Allows deletion of possibly infinite side-effect free loops

2020-12-20 Thread Nikita Popov via Phabricator via cfe-commits
nikic added a comment.

In D86844#2465027 , @jdoerfert wrote:

> @nikic Is this OK or do you want it split?

After looking again, I assume this can't really be split, because prior to this 
change we would never delete a loop without an exit block, so the code was not 
reachable before. So this looks fine to me.




Comment at: llvm/lib/Transforms/Utils/LoopUtils.cpp:621
   }
 }
 

Unrelated, but why do these updates happen before the branch from preheader to 
exit is added in IR? Shouldn't it be the other way around according to the DTU 
contract?



Comment at: llvm/lib/Transforms/Utils/LoopUtils.cpp:661
+  }
+}
   }

jdoerfert wrote:
> atmnpatel wrote:
> > nikic wrote:
> > > These fixes look unrelated. Is it possible to test them separately?
> > So my understanding is that the actual line that fixes the compile time 
> > error is 651, that is, just having that line fixes the compile time error. 
> > I would assume its because before I didn't tell the dominator tree to 
> > remove the edge connecting the preheader and header, and not having that 
> > cascade, GVN was unable to iterate properly in some cases over the (now) 
> > dead blocks because it wasn't updated in LLVM's internal structures. The 
> > actual error was from the iteration in GVN::assignValNumForDeadCode() where 
> > it would try to iterate through a block that partially existed but didn't 
> > really.
> > 
> > The lines 652-660 that update MemorySSA I added because in the other more 
> > general case above, we seem to update MemorySSA right after updating the 
> > Dominator Tree.
> Nit: Move DTU into the conditional
You might also move this code after the if/else, as it's the same in both 
branches. As the update strategy is eager, reusing the same DTU object 
shouldn't make a difference. (Feel free to leave as is though.)


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D86844/new/

https://reviews.llvm.org/D86844

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D86844: [LoopDeletion] Allows deletion of possibly infinite side-effect free loops

2020-12-20 Thread Johannes Doerfert via Phabricator via cfe-commits
jdoerfert added a comment.

@nikic Is this OK or do you want it split?




Comment at: llvm/lib/Transforms/Utils/LoopUtils.cpp:661
+  }
+}
   }

atmnpatel wrote:
> nikic wrote:
> > These fixes look unrelated. Is it possible to test them separately?
> So my understanding is that the actual line that fixes the compile time error 
> is 651, that is, just having that line fixes the compile time error. I would 
> assume its because before I didn't tell the dominator tree to remove the edge 
> connecting the preheader and header, and not having that cascade, GVN was 
> unable to iterate properly in some cases over the (now) dead blocks because 
> it wasn't updated in LLVM's internal structures. The actual error was from 
> the iteration in GVN::assignValNumForDeadCode() where it would try to iterate 
> through a block that partially existed but didn't really.
> 
> The lines 652-660 that update MemorySSA I added because in the other more 
> general case above, we seem to update MemorySSA right after updating the 
> Dominator Tree.
Nit: Move DTU into the conditional


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D86844/new/

https://reviews.llvm.org/D86844

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D86844: [LoopDeletion] Allows deletion of possibly infinite side-effect free loops

2020-11-30 Thread Atmn Patel via Phabricator via cfe-commits
atmnpatel added inline comments.



Comment at: llvm/lib/Transforms/Utils/LoopUtils.cpp:661
+  }
+}
   }

nikic wrote:
> These fixes look unrelated. Is it possible to test them separately?
So my understanding is that the actual line that fixes the compile time error 
is 651, that is, just having that line fixes the compile time error. I would 
assume its because before I didn't tell the dominator tree to remove the edge 
connecting the preheader and header, and not having that cascade, GVN was 
unable to iterate properly in some cases over the (now) dead blocks because it 
wasn't updated in LLVM's internal structures. The actual error was from the 
iteration in GVN::assignValNumForDeadCode() where it would try to iterate 
through a block that partially existed but didn't really.

The lines 652-660 that update MemorySSA I added because in the other more 
general case above, we seem to update MemorySSA right after updating the 
Dominator Tree.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D86844/new/

https://reviews.llvm.org/D86844

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D86844: [LoopDeletion] Allows deletion of possibly infinite side-effect free loops

2020-11-30 Thread Nikita Popov via Phabricator via cfe-commits
nikic added inline comments.



Comment at: llvm/lib/Transforms/Utils/LoopUtils.cpp:661
+  }
+}
   }

These fixes look unrelated. Is it possible to test them separately?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D86844/new/

https://reviews.llvm.org/D86844

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D86844: [LoopDeletion] Allows deletion of possibly infinite side-effect free loops

2020-11-29 Thread Atmn Patel via Phabricator via cfe-commits
atmnpatel updated this revision to Diff 308249.
atmnpatel added a comment.

I believe this happened becase when I removed the loop, I did not update 
MemorySSA. The exact error was from GVN, but this update seems to fix the stage 
2 build compile time error locally (I checked by running the build bot script).


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/no-exit-blocks.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/no-exit-blocks.ll
===
--- llvm/test/Transforms/LoopDeletion/no-exit-blocks.ll
+++ llvm/test/Transforms/LoopDeletion/no-exit-blocks.ll
@@ -5,14 +5,7 @@
 ; CHECK: Function Attrs: mustprogress
 ; CHECK-LABEL: define {{[^@]+}}@f
 ; CHECK-SAME: () [[ATTR0:#.*]] {
-; CHECK-NEXT:br label [[TMP1:%.*]]
-; CHECK:   1:
-; CHECK-NEXT:[[DOT01:%.*]] = phi i32 [ 1, [[TMP0:%.*]] ], [ [[TMP3:%.*]], [[TMP2:%.*]] ]
-; CHECK-NEXT:[[DOT0:%.*]] = phi i32 [ 1, [[TMP0]] ], [ [[TMP3]], [[TMP2]] ]
-; CHECK-NEXT:br label [[TMP2]]
-; CHECK:  

[PATCH] D86844: [LoopDeletion] Allows deletion of possibly infinite side-effect free loops

2020-11-29 Thread Atmn Patel via Phabricator via cfe-commits
atmnpatel reopened this revision.
atmnpatel added a comment.
This revision is now accepted and ready to land.

This introduced a compile-time error that showed up during a stage 2 build.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D86844/new/

https://reviews.llvm.org/D86844

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D86844: [LoopDeletion] Allows deletion of possibly infinite side-effect free loops

2020-11-06 Thread Atmn Patel via Phabricator via cfe-commits
This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rG0b17c6e4479d: [LoopDeletion] Allows deletion of possibly 
infinite side-effect free loops (authored by atmnpatel).

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/no-exit-blocks.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/no-exit-blocks.ll
===
--- llvm/test/Transforms/LoopDeletion/no-exit-blocks.ll
+++ llvm/test/Transforms/LoopDeletion/no-exit-blocks.ll
@@ -5,14 +5,7 @@
 ; CHECK: Function Attrs: mustprogress
 ; CHECK-LABEL: define {{[^@]+}}@f
 ; CHECK-SAME: () [[ATTR0:#.*]] {
-; CHECK-NEXT:br label [[TMP1:%.*]]
-; CHECK:   1:
-; CHECK-NEXT:[[DOT01:%.*]] = phi i32 [ 1, [[TMP0:%.*]] ], [ [[TMP3:%.*]], [[TMP2:%.*]] ]
-; CHECK-NEXT:[[DOT0:%.*]] = phi i32 [ 1, [[TMP0]] ], [ [[TMP3]], [[TMP2]] ]
-; CHECK-NEXT:br label [[TMP2]]
-; CHECK:   2:
-; CHECK-NEXT:[[TMP3]] = add nsw i32 

[PATCH] D86844: [LoopDeletion] Allows deletion of possibly infinite side-effect free loops

2020-11-06 Thread Atmn Patel via Phabricator via cfe-commits
atmnpatel updated this revision to Diff 303597.
atmnpatel added a comment.

final fixes.


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/no-exit-blocks.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/no-exit-blocks.ll
===
--- llvm/test/Transforms/LoopDeletion/no-exit-blocks.ll
+++ llvm/test/Transforms/LoopDeletion/no-exit-blocks.ll
@@ -5,14 +5,7 @@
 ; CHECK: Function Attrs: mustprogress
 ; CHECK-LABEL: define {{[^@]+}}@f
 ; CHECK-SAME: () [[ATTR0:#.*]] {
-; CHECK-NEXT:br label [[TMP1:%.*]]
-; CHECK:   1:
-; CHECK-NEXT:[[DOT01:%.*]] = phi i32 [ 1, [[TMP0:%.*]] ], [ [[TMP3:%.*]], [[TMP2:%.*]] ]
-; CHECK-NEXT:[[DOT0:%.*]] = phi i32 [ 1, [[TMP0]] ], [ [[TMP3]], [[TMP2]] ]
-; CHECK-NEXT:br label [[TMP2]]
-; CHECK:   2:
-; CHECK-NEXT:[[TMP3]] = add nsw i32 [[DOT01]], [[DOT0]]
-; CHECK-NEXT:br label [[TMP1]]
+; CHECK-NEXT:unreachable
 ;
   br label %1
 
Index: llvm/test/Transforms/LoopDeletion/mustprogress.ll

[PATCH] D86844: [LoopDeletion] Allows deletion of possibly infinite side-effect free loops

2020-10-25 Thread Atmn Patel via Phabricator via cfe-commits
atmnpatel updated this revision to Diff 300559.
atmnpatel added a comment.

Added word back in.


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
===
--- /dev/null
+++ llvm/test/Transforms/LoopDeletion/mustprogress.ll
@@ -0,0 +1,241 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes
+; RUN: opt < %s -loop-deletion -S | FileCheck %s
+
+;; Original C Code:
+;;  void unknown_tripcount_mustprogress_attr_mustprogress_loopmd(int a, int b) {
+;;for (; a < b;) ;
+;;for (;;) ;
+;;  }
+
+define void @unknown_tripcount_mustprogress_attr_mustprogress_loopmd(i32 %a, i32 %b) #0 {
+; CHECK: Function Attrs: mustprogress
+; CHECK-LABEL: define {{[^@]+}}@unknown_tripcount_mustprogress_attr_mustprogress_loopmd
+; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]]) [[ATTR0:#.*]] {
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:br label [[FOR_END:%.*]]
+; CHECK:   for.end:
+; 

[PATCH] D86844: [LoopDeletion] Allows deletion of possibly infinite side-effect free loops

2020-10-25 Thread Johannes Doerfert via Phabricator via cfe-commits
jdoerfert accepted this revision.
jdoerfert added a comment.
This revision is now accepted and ready to land.

LGTM.




Comment at: llvm/lib/Transforms/Scalar/LoopDeletion.cpp:60
+// Make sure all exiting blocks produce the same incoming value for the
+// block. If there are different incoming values for different exiting
 // blocks, then it is impossible to statically determine which value should

Nit: add the word back.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D86844/new/

https://reviews.llvm.org/D86844

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D86844: [LoopDeletion] Allows deletion of possibly infinite side-effect free loops

2020-10-16 Thread Atmn Patel via Phabricator via cfe-commits
atmnpatel updated this revision to Diff 298740.
atmnpatel added a comment.

fixed splice.


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
===
--- /dev/null
+++ llvm/test/Transforms/LoopDeletion/mustprogress.ll
@@ -0,0 +1,241 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes
+; RUN: opt < %s -loop-deletion -S | FileCheck %s
+
+;; Original C Code:
+;;  void unknown_tripcount_mustprogress_attr_mustprogress_loopmd(int a, int b) {
+;;for (; a < b;) ;
+;;for (;;) ;
+;;  }
+
+define void @unknown_tripcount_mustprogress_attr_mustprogress_loopmd(i32 %a, i32 %b) #0 {
+; CHECK: Function Attrs: mustprogress
+; CHECK-LABEL: define {{[^@]+}}@unknown_tripcount_mustprogress_attr_mustprogress_loopmd
+; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]]) [[ATTR0:#.*]] {
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:br label [[FOR_END:%.*]]
+; CHECK:   for.end:
+; 

[PATCH] D86844: [LoopDeletion] Allows deletion of possibly infinite side-effect free loops

2020-10-16 Thread Atmn Patel via Phabricator via cfe-commits
atmnpatel updated this revision to Diff 298736.
atmnpatel added a comment.

nit.


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
===

[PATCH] D86844: [LoopDeletion] Allows deletion of possibly infinite side-effect free loops

2020-10-16 Thread Atmn Patel via Phabricator via cfe-commits
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

[PATCH] D86844: [LoopDeletion] Allows deletion of possibly infinite side-effect free loops

2020-10-08 Thread Johannes Doerfert via Phabricator via cfe-commits
jdoerfert added a comment.

The new code/functionality wrt. no exit blocks should be a separate commit.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D86844/new/

https://reviews.llvm.org/D86844

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D86844: [LoopDeletion] Allows deletion of possibly infinite side-effect free loops

2020-10-08 Thread Atmn Patel via Phabricator via cfe-commits
atmnpatel updated this revision to Diff 297069.
atmnpatel added a comment.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Fixes.


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/Analysis/LoopInfo.h
  llvm/include/llvm/Analysis/LoopInfoImpl.h
  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
===
--- /dev/null
+++ llvm/test/Transforms/LoopDeletion/mustprogress.ll
@@ -0,0 +1,237 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes
+; RUN: opt < %s -loop-deletion -S | FileCheck %s
+
+;; Original C Code:
+;;  void unknown_tripcount_mustprogress_attr_mustprogress_loopmd(int a, int b) {
+;;for (; a < b;) ;
+;;for (;;) ;
+;;  }
+
+define void @unknown_tripcount_mustprogress_attr_mustprogress_loopmd(i32 %a, i32 %b) #0 {
+; CHECK: Function Attrs: mustprogress
+; CHECK-LABEL: define {{[^@]+}}@unknown_tripcount_mustprogress_attr_mustprogress_loopmd
+; CHECK-SAME: