fhahn updated this revision to Diff 341863.
fhahn added a comment.

Thanks everyone! I rebased the patch and addressed John's comments. I'll commit 
it shortly.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D96418

Files:
  clang/lib/CodeGen/CGStmt.cpp
  clang/lib/CodeGen/CodeGenFunction.cpp
  clang/lib/CodeGen/CodeGenFunction.h
  clang/test/CodeGen/attr-mustprogress.c
  clang/test/CodeGenCXX/attr-mustprogress.cpp

Index: clang/test/CodeGenCXX/attr-mustprogress.cpp
===================================================================
--- clang/test/CodeGenCXX/attr-mustprogress.cpp
+++ clang/test/CodeGenCXX/attr-mustprogress.cpp
@@ -23,20 +23,22 @@
 
 // CHECK: datalayout
 
-// CXX98-NOT: mustprogress
-// CXX11-NOT: mustprogress
-// FINITE-NOT:     mustprogress
+// CXX98-NOT:  mustprogress
+// CXX11:      mustprogress
+// FINITE-NOT: mustprogress
 // CHECK-LABEL: @_Z2f0v(
 // CHECK-NEXT:  entry:
 // CHECK-NEXT:    br label %for.cond
 // CHECK:       for.cond:
-// CHECK-NOT:    br {{.*}} llvm.loop
+// CXX98-NOT:    br {{.*}} llvm.loop
+// CXX11-NEXT:   br label %for.cond, !llvm.loop [[LOOP1:!.*]]
+// FINITE-NEXT:  br label %for.cond, !llvm.loop [[LOOP1:!.*]]
 void f0() {
   for (; ;) ;
 }
 
-// CXX98-NOT: mustprogress
-// CXX11-NOT: mustprogress
+// CXX98-NOT:  mustprogress
+// CXX11:      mustprogress
 // FINITE-NOT: mustprogress
 // CHECK-LABEL: @_Z2f1v(
 // CHECK-NEXT:  entry:
@@ -44,7 +46,9 @@
 // CHECK:       for.cond:
 // CHECK-NEXT:    br i1 true, label %for.body, label %for.end
 // CHECK:       for.body:
-// CHECK-NOT:    br {{.*}}, !llvm.loop
+// CXX98-NOT:     br {{.*}}, !llvm.loop
+// CXX11-NEXT:    br label %for.cond, !llvm.loop [[LOOP2:!.*]]
+// FINITE-NEXT:  br label %for.cond, !llvm.loop [[LOOP2:!.*]]
 // CHECK:       for.end:
 // CHECK-NEXT:    ret void
 //
@@ -53,8 +57,8 @@
     ;
 }
 
-// CXX98-NOT: mustprogress
-// CXX11:     mustprogress
+// CXX98-NOT:  mustprogress
+// CXX11:      mustprogress
 // FINITE-NOT: mustprogress
 // CHECK-LABEL: @_Z2f2v(
 // CHECK-NEXT:  entry:
@@ -66,8 +70,8 @@
 // CHECK-NEXT:    br i1 [[CMP]], label %for.body, label %for.end
 // CHECK:       for.body:
 // CXX98-NOT:    br {{.*}}, !llvm.loop
-// CXX11:        br label %for.cond, !llvm.loop [[LOOP1:!.*]]
-// FINITE-NEXT:   br label %for.cond, !llvm.loop [[LOOP1:!.*]]
+// CXX11:        br label %for.cond, !llvm.loop [[LOOP3:!.*]]
+// FINITE-NEXT:  br label %for.cond, !llvm.loop [[LOOP3:!.*]]
 // CHECK:       for.end:
 // CHECK-NEXT:    ret void
 //
@@ -76,8 +80,8 @@
     ;
 }
 
-// CXX98-NOT: mustprogress
-// CXX11-NOT: mustprogress
+// CXX98-NOT:  mustprogress
+// CXX11:      mustprogress
 // FINITE-NOT: mustprogress
 // CHECK-LABEL: @_Z1Fv(
 // CHECK-NEXT:  entry:
@@ -85,7 +89,9 @@
 // CHECK:       for.cond:
 // CHECK-NEXT:    br i1 true, label %for.body, label %for.end
 // CHECK:       for.body:
-// CHECK-NOT:     br {{.*}}, !llvm.loop
+// CXX98-NOT:     br {{.*}}, !llvm.loop
+// CXX11-NEXT:    br label %for.cond, !llvm.loop [[LOOP4:!.*]]
+// FINITE-NEXT:   br label %for.cond, !llvm.loop [[LOOP4:!.*]]
 // CHECK:       for.end:
 // CHECK-NEXT:    br label %for.cond1
 // CHECK:       for.cond1:
@@ -95,8 +101,8 @@
 // CHECK-NEXT:    br i1 [[CMP]], label %for.body2, label %for.end3
 // CHECK:       for.body2:
 // CXX98-NOT:     br {{.*}}, !llvm.loop
-// CXX11-NEXT:    br label %for.cond1, !llvm.loop [[LOOP2:!.*]]
-// FINITE-NEXT:   br label %for.cond1, !llvm.loop [[LOOP2:!.*]]
+// CXX11-NEXT:    br label %for.cond1, !llvm.loop [[LOOP5:!.*]]
+// FINITE-NEXT:   br label %for.cond1, !llvm.loop [[LOOP5:!.*]]
 // CHECK:       for.end3:
 // CHECK-NEXT:    ret void
 //
@@ -107,8 +113,8 @@
     ;
 }
 
-// CXX98-NOT: mustprogress
-// CXX11-NOT: mustprogress
+// CXX98-NOT:  mustprogress
+// CXX11:      mustprogress
 // FINITE-NOT: mustprogress
 // CHECK-LABEL: @_Z2F2v(
 // CHECK-NEXT:  entry:
@@ -120,14 +126,16 @@
 // CHECK-NEXT:    br i1 [[CMP]], label %for.body, label %for.end
 // CHECK:       for.body:
 // CXX98_NOT:     br {{.*}} !llvm.loop
-// CXX11-NEXT:    br label %for.cond, !llvm.loop [[LOOP3:!.*]]
-// FINITE-NEXT:    br label %for.cond, !llvm.loop [[LOOP3:!.*]]
+// CXX11-NEXT:    br label %for.cond, !llvm.loop [[LOOP6:!.*]]
+// FINITE-NEXT:   br label %for.cond, !llvm.loop [[LOOP6:!.*]]
 // CHECK:       for.end:
 // CHECK-NEXT:    br label %for.cond1
 // CHECK:       for.cond1:
 // CHECK-NEXT:    br i1 true, label %for.body2, label %for.end3
 // CHECK:       for.body2:
-// CHECK-NOT:     br {{.*}}, !llvm.loop
+// CXX98-NOT:     br {{.*}}, !llvm.loop
+// CXX11-NEXT:    br label %for.cond1, !llvm.loop [[LOOP7:!.*]]
+// FINITE-NEXT:   br label %for.cond1, !llvm.loop [[LOOP7:!.*]]
 // CHECK:       for.end3:
 // CHECK-NEXT:    ret void
 //
@@ -138,22 +146,24 @@
     ;
 }
 
-// CXX98-NOT: mustprogress
-// CXX11-NOT: mustprogress
-// FINITE-NOT:     mustprogress
+// CXX98-NOT:  mustprogress
+// CXX11:      mustprogress
+// FINITE-NOT: mustprogress
 // CHECK-LABEL: @_Z2w1v(
 // CHECK-NEXT:  entry:
 // CHECK-NEXT:    br label %while.body
 // CHECK:       while.body:
-// CHECK-NOT:     br {{.*}}, !llvm.loop
+// CXX98-NOT:     br {{.*}}, !llvm.loop
+// CXX11-NEXT:    br label %while.body, !llvm.loop [[LOOP8:!.*]]
+// FINITE-NEXT:   br label %while.body, !llvm.loop [[LOOP8:!.*]]
 //
 void w1() {
   while (1)
     ;
 }
 
-// CXX98-NOT: mustprogress
-// CXX11:     mustprogress
+// CXX98-NOT:  mustprogress
+// CXX11:      mustprogress
 // FINITE-NOT: mustprogress
 // CHECK-LABEL: @_Z2w2v(
 // CHECK-NEXT:  entry:
@@ -165,8 +175,8 @@
 // CHECK-NEXT:    br i1 [[CMP]], label %while.body, label %while.end
 // CHECK:       while.body:
 // CXX98-NOT:     br {{.*}}, !llvm.loop
-// CXX11-NEXT:    br label %while.cond, !llvm.loop [[LOOP4:!.*]]
-// FINITE-NEXT:   br label %while.cond, !llvm.loop [[LOOP4:!.*]]
+// CXX11-NEXT:    br label %while.cond, !llvm.loop [[LOOP9:!.*]]
+// FINITE-NEXT:   br label %while.cond, !llvm.loop [[LOOP9:!.*]]
 // CHECK:       while.end:
 // CHECK-NEXT:    ret void
 //
@@ -175,8 +185,8 @@
     ;
 }
 
-// CXX98-NOT: mustprogress
-// CXX11-NOT: mustprogress
+// CXX98-NOT:  mustprogress
+// CXX11:      mustprogress
 // FINITE-NOT: mustprogress
 // CHECK-LABEL: @_Z1Wv(
 // CHECK-NEXT:  entry:
@@ -188,12 +198,14 @@
 // CHECK-NEXT:    br i1 [[CMP]], label %while.body, label %while.end
 // CHECK:       while.body:
 // CXX98-NOT:     br {{.*}}, !llvm.loop
-// CXX11-NEXT:    br label %while.cond, !llvm.loop [[LOOP5:!.*]]
-// FINITE-NEXT:   br label %while.cond, !llvm.loop [[LOOP5:!.*]]
+// CXX11-NEXT:    br label %while.cond, !llvm.loop [[LOOP10:!.*]]
+// FINITE-NEXT:   br label %while.cond, !llvm.loop [[LOOP10:!.*]]
 // CHECK:       while.end:
 // CHECK-NEXT:    br label %while.body2
 // CHECK:       while.body2:
-// CHECK-NOT:     br {{.*}}, !llvm.loop
+// CXX98-NOT:    br {{.*}}, !llvm.loop
+// CXX11-NEXT:   br label %while.body2, !llvm.loop [[LOOP11:!.*]]
+// FINITE-NEXT:  br label %while.body2, !llvm.loop [[LOOP11:!.*]]
 //
 void W() {
   while (a == b)
@@ -202,14 +214,16 @@
     ;
 }
 
-// CXX98-NOT: mustprogress
-// CXX11-NOT: mustprogress
+// CXX98-NOT:  mustprogress
+// CXX11:      mustprogress
 // FINITE-NOT: mustprogress
 // CHECK-LABEL: @_Z2W2v(
 // CHECK-NEXT:  entry:
 // CHECK-NEXT:    br label %while.body
 // CHECK:       while.body:
-// CHECK-NOT:     br {{.*}}, !llvm.loop
+// CXX98-NOT:     br {{.*}}, !llvm.loop
+// CXX11-NEXT:    br label %while.body, !llvm.loop [[LOOP12:!.*]]
+// FINITE-NEXT:   br label %while.body, !llvm.loop [[LOOP12:!.*]]
 //
 void W2() {
   while (1)
@@ -218,8 +232,8 @@
     ;
 }
 
-// CXX98-NOT: mustprogress
-// CXX11-NOT: mustprogress
+// CXX98-NOT:  mustprogress
+// CXX11:      mustprogress
 // FINITE-NOT: mustprogress
 // CHECK-LABEL: @_Z2d1v(
 // CHECK-NEXT:  entry:
@@ -227,7 +241,9 @@
 // CHECK:       do.body:
 // CHECK-NEXT:    br label %do.cond
 // CHECK:       do.cond:
-// CHECK-NOT:     br {{.*}}, !llvm.loop
+// CXX98-NOT:     br {{.*}}, !llvm.loop
+// CXX11-NEXT:    br i1 true, label %do.body, label %do.end, !llvm.loop [[LOOP13:!.*]]
+// FINITE-NEXT:   br i1 true, label %do.body, label %do.end, !llvm.loop [[LOOP13:!.*]]
 // CHECK:       do.end:
 // CHECK-NEXT:    ret void
 //
@@ -237,9 +253,9 @@
   while (1);
 }
 
-// CXX98-NOT: mustprogress
-// CXX11:     mustprogress
-// FINITE-NOT:  mustprogress
+// CXX98-NOT:  mustprogress
+// CXX11:      mustprogress
+// FINITE-NOT: mustprogress
 // CHECK-LABEL: @_Z2d2v(
 // CHECK-NEXT:  entry:
 // CHECK-NEXT:    br label %do.body
@@ -250,8 +266,8 @@
 // CHECK-NEXT:    [[TMP1:%.*]] = load i32, i32* @b, align 4
 // CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[TMP0]], [[TMP1]]
 // CXX98-NOT:     br {{.*}}, !llvm.loop
-// CXX11-NEXT:    br i1 [[CMP]], label %do.body, label %do.end, !llvm.loop [[LOOP6:!.*]]
-// FINITE-NEXT:   br i1 [[CMP]], label %do.body, label %do.end, !llvm.loop [[LOOP6:!.*]]
+// CXX11-NEXT:    br i1 [[CMP]], label %do.body, label %do.end, !llvm.loop [[LOOP14:!.*]]
+// FINITE-NEXT:   br i1 [[CMP]], label %do.body, label %do.end, !llvm.loop [[LOOP14:!.*]]
 // CHECK:       do.end:
 // CHECK-NEXT:    ret void
 //
@@ -261,16 +277,18 @@
   while (a == b);
 }
 
-// CXX98-NOT: mustprogress
-// CXX11-NOT: mustprogress
-// FINITE-NOT:     mustprogress
+// CXX98-NOT:  mustprogress
+// CXX11:      mustprogress
+// FINITE-NOT: mustprogress
 // CHECK-LABEL: @_Z1Dv(
 // CHECK-NEXT:  entry:
 // CHECK-NEXT:    br label %do.body
 // CHECK:       do.body:
 // CHECK-NEXT:    br label %do.cond
 // CHECK:       do.cond:
-// CHECK-NOT:     br {{.*}}, !llvm.loop
+// CXX98-NOT:     br {{.*}}, !llvm.loop
+// CXX11-NEXT:    br i1 true, label %do.body, label %do.end, !llvm.loop [[LOOP15:!.*]]
+// FINITE-NEXT:   br i1 true, label %do.body, label %do.end, !llvm.loop [[LOOP15:!.*]]
 // CHECK:       do.end:
 // CHECK-NEXT:    br label %do.body1
 // CHECK:       do.body1:
@@ -280,8 +298,8 @@
 // CHECK-NEXT:    [[TMP1:%.*]] = load i32, i32* @b, align 4
 // CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[TMP0]], [[TMP1]]
 // CXX98-NOT:     br {{.*}}, !llvm.loop
-// CXX11-NEXT:    br i1 [[CMP]], label %do.body1, label %do.end3, !llvm.loop [[LOOP7:!.*]]
-// FINITE-NEXT:   br i1 [[CMP]], label %do.body1, label %do.end3, !llvm.loop [[LOOP7:!.*]]
+// CXX11-NEXT:    br i1 [[CMP]], label %do.body1, label %do.end3, !llvm.loop [[LOOP16:!.*]]
+// FINITE-NEXT:   br i1 [[CMP]], label %do.body1, label %do.end3, !llvm.loop [[LOOP16:!.*]]
 // CHECK:       do.end3:
 // CHECK-NEXT:    ret void
 //
@@ -294,9 +312,9 @@
   while (a == b);
 }
 
-// CXX98-NOT: mustprogress
-// CXX11-NOT: mustprogress
-// FINITE-NOT:     mustprogress
+// CXX98-NOT : mustprogress
+// CXX11:      mustprogress
+// FINITE-NOT: mustprogress
 // CHECK-LABEL: @_Z2D2v(
 // CHECK-NEXT:  entry:
 // CHECK-NEXT:    br label %do.body
@@ -307,14 +325,16 @@
 // CHECK-NEXT:    [[TMP1:%.*]] = load i32, i32* @b, align 4
 // CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[TMP0]], [[TMP1]]
 // CXX98-NOT:     br {{.*}}, !llvm.loop
-// CXX11-NEXT:    br i1 [[CMP]], label %do.body, label %do.end, !llvm.loop [[LOOP8:!.*]]
-// FINITE-NEXT:   br i1 [[CMP]], label %do.body, label %do.end, !llvm.loop [[LOOP8:!.*]]
+// CXX11-NEXT:    br i1 [[CMP]], label %do.body, label %do.end, !llvm.loop [[LOOP17:!.*]]
+// FINITE-NEXT:   br i1 [[CMP]], label %do.body, label %do.end, !llvm.loop [[LOOP17:!.*]]
 // CHECK:       do.end:
 // CHECK-NEXT:    br label %do.body1
 // CHECK:       do.body1:
 // CHECK-NEXT:    br label %do.cond2
 // CHECK:       do.cond2:
-// CHECK-NOT:     br {{.*}}, !llvm.loop
+// CXX98-NOT:     br {{.*}}, !llvm.loop
+// CXX11-NEXT:    br i1 true, label %do.body1, label %do.end3, !llvm.loop [[LOOP18:!.*]]
+// FINITE-NEXT:   br i1 true, label %do.body1, label %do.end3, !llvm.loop [[LOOP18:!.*]]
 // CHECK:       do.end3:
 // CHECK-NEXT:    ret void
 //
@@ -336,3 +356,13 @@
 // CXX11: [[LOOP6]] = distinct !{[[LOOP6]], [[MP]]}
 // CXX11: [[LOOP7]] = distinct !{[[LOOP7]], [[MP]]}
 // CXX11: [[LOOP8]] = distinct !{[[LOOP8]], [[MP]]}
+// CXX11: [[LOOP9]] = distinct !{[[LOOP9]], [[MP]]}
+// CXX11: [[LOOP10]] = distinct !{[[LOOP10]], [[MP]]}
+// CXX11: [[LOOP11]] = distinct !{[[LOOP11]], [[MP]]}
+// CXX11: [[LOOP12]] = distinct !{[[LOOP12]], [[MP]]}
+// CXX11: [[LOOP13]] = distinct !{[[LOOP13]], [[MP]]}
+// CXX11: [[LOOP14]] = distinct !{[[LOOP14]], [[MP]]}
+// CXX11: [[LOOP15]] = distinct !{[[LOOP15]], [[MP]]}
+// CXX11: [[LOOP16]] = distinct !{[[LOOP16]], [[MP]]}
+// CXX11: [[LOOP17]] = distinct !{[[LOOP17]], [[MP]]}
+// CXX11: [[LOOP18]] = distinct !{[[LOOP18]], [[MP]]}
Index: clang/test/CodeGen/attr-mustprogress.c
===================================================================
--- clang/test/CodeGen/attr-mustprogress.c
+++ clang/test/CodeGen/attr-mustprogress.c
@@ -1,15 +1,18 @@
+// RUN: %clang_cc1 -std=c89 -triple=x86_64-unknown-linux-gnu -S -emit-llvm %s -o - | FileCheck --check-prefix=CHECK --check-prefix=C99 %s
 // RUN: %clang_cc1 -std=c99 -triple=x86_64-unknown-linux-gnu -S -emit-llvm %s -o - | FileCheck --check-prefix=CHECK --check-prefix=C99 %s
 // RUN: %clang_cc1 -std=c11 -triple=x86_64-unknown-linux-gnu -S -emit-llvm %s -o - | FileCheck --check-prefix=CHECK --check-prefix=C11 %s
 // RUN: %clang_cc1 -std=c18 -triple=x86_64-unknown-linux-gnu -S -emit-llvm %s -o - | FileCheck --check-prefix=CHECK --check-prefix=C11 %s
 // RUN: %clang_cc1 -std=c2x -triple=x86_64-unknown-linux-gnu -S -emit-llvm %s -o - | FileCheck --check-prefix=CHECK --check-prefix=C11 %s
 //
 // Check -ffinite-loops option in combination with various standard versions.
+// RUN: %clang_cc1 -std=c89 -ffinite-loops -triple=x86_64-unknown-linux-gnu -S -emit-llvm %s -o - | FileCheck --check-prefix=CHECK --check-prefix=FINITE %s
 // RUN: %clang_cc1 -std=c99 -ffinite-loops -triple=x86_64-unknown-linux-gnu -S -emit-llvm %s -o - | FileCheck --check-prefix=CHECK --check-prefix=FINITE %s
 // RUN: %clang_cc1 -std=c11 -ffinite-loops -triple=x86_64-unknown-linux-gnu -S -emit-llvm %s -o - | FileCheck --check-prefix=CHECK --check-prefix=FINITE %s
 // RUN: %clang_cc1 -std=c18 -ffinite-loops -triple=x86_64-unknown-linux-gnu -S -emit-llvm %s -o - | FileCheck --check-prefix=CHECK --check-prefix=FINITE %s
 // RUN: %clang_cc1 -std=c2x -ffinite-loops -triple=x86_64-unknown-linux-gnu -S -emit-llvm %s -o - | FileCheck --check-prefix=CHECK --check-prefix=FINITE %s
 //
 // Check -fno-finite-loops option in combination with various standard versions.
+// RUN: %clang_cc1 -std=c89 -fno-finite-loops -triple=x86_64-unknown-linux-gnu -S -emit-llvm %s -o - | FileCheck --check-prefix=CHECK --check-prefix=C99 %s
 // RUN: %clang_cc1 -std=c99 -fno-finite-loops -triple=x86_64-unknown-linux-gnu -S -emit-llvm %s -o - | FileCheck --check-prefix=CHECK --check-prefix=C99 %s
 // RUN: %clang_cc1 -std=c11 -fno-finite-loops -triple=x86_64-unknown-linux-gnu -S -emit-llvm %s -o - | FileCheck --check-prefix=CHECK --check-prefix=C99 %s
 // RUN: %clang_cc1 -std=c18 -fno-finite-loops -triple=x86_64-unknown-linux-gnu -S -emit-llvm %s -o - | FileCheck --check-prefix=CHECK --check-prefix=C99 %s
@@ -25,7 +28,9 @@
 // CHECK-NEXT:  entry:
 // CHECK-NEXT:    br label %for.cond
 // CHECK:       for.cond:
-// CHECK-NOT:     br {{.*}}!llvm.loop
+// C99-NOT:       br {{.*}}!llvm.loop
+// C11-NOT:       br {{.*}}!llvm.loop
+// FINITE-NEXT:   br {{.*}}!llvm.loop
 //
 void f0() {
   for (; ;) ;
@@ -38,7 +43,9 @@
 // CHECK:       for.cond:
 // CHECK-NEXT:    br i1 true, label %for.body, label %for.end
 // CHECK:       for.body:
-// CHECK-NOT:     br {{.*}}, !llvm.loop
+// C99-NOT:       br {{.*}}, !llvm.loop
+// C11-NOT:       br {{.*}}, !llvm.loop
+// FINITE-NEXT:   br {{.*}}, !llvm.loop
 // CHECK:       for.end:
 // CHECK-NEXT:    ret void
 //
@@ -75,7 +82,9 @@
 // CHECK:       for.cond:
 // CHECK-NEXT:    br i1 true, label %for.body, label %for.end
 // CHECK:       for.body:
-// CHECK-NOT:     br {{.*}}, !llvm.loop
+// C99-NOT:       br {{.*}}, !llvm.loop
+// C11-NOT:       br {{.*}}, !llvm.loop
+// FINITE-NEXT:   br {{.*}}, !llvm.loop
 // CHECK:       for.end:
 // CHECK-NEXT:    br label %for.cond1
 // CHECK:       for.cond1:
@@ -102,7 +111,9 @@
 // CHECK-NEXT:  entry:
 // CHECK-NEXT:    br label %while.body
 // CHECK:       while.body:
-// CHECK-NOT:     br {{.*}}, !llvm.loop
+// C99-NOT:       br {{.*}}, !llvm.loop
+// C11-NOT:       br {{.*}}, !llvm.loop
+// FINITE-NEXT:   br {{.*}}, !llvm.loop
 //
 void w1() {
   while (1) {
@@ -141,12 +152,14 @@
 // CHECK-NEXT:    br i1 [[CMP]], label %while.body, label %while.end
 // CHECK:       while.body:
 // C99-NOT:       br {{.*}} !llvm.loop
-// C11:           br label %while.cond, !llvm.loop [[LOOP4:!.*]]
-// FINITE:        br label %while.cond, !llvm.loop [[LOOP4:!.*]]
+// C11-NEXT:      br label %while.cond, !llvm.loop [[LOOP4:!.*]]
+// FINITE-NEXT:   br label %while.cond, !llvm.loop [[LOOP4:!.*]]
 // CHECK:       while.end:
 // CHECK-NEXT:    br label %while.body2
 // CHECK:       while.body2:
-// CHECK-NOT:     br {{.*}} !llvm.loop
+// C99-NOT:       br {{.*}} !llvm.loop
+// C11-NOT:       br {{.*}} !llvm.loop
+// FINITE-NEXT:   br {{.*}} !llvm.loop
 //
 void W() {
   while (a == b) {
@@ -162,7 +175,9 @@
 // CHECK:       do.body:
 // CHECK-NEXT:    br label %do.cond
 // CHECK:       do.cond:
-// CHECK-NOT:     br {{.*}}, !llvm.loop
+// C99-NOT:       br {{.*}}, !llvm.loop
+// C11-NOT:       br {{.*}}, !llvm.loop
+// FINITE-NEXT:   br {{.*}}, !llvm.loop
 // CHECK:       do.end:
 // CHECK-NEXT:    ret void
 //
Index: clang/lib/CodeGen/CodeGenFunction.h
===================================================================
--- clang/lib/CodeGen/CodeGenFunction.h
+++ clang/lib/CodeGen/CodeGenFunction.h
@@ -524,21 +524,28 @@
   // applies to.  nullptr if there is no 'musttail' on the current statement.
   const CallExpr *MustTailCall = nullptr;
 
-  /// True if the current function should be marked mustprogress.
-  bool FnIsMustProgress = false;
-
-  /// True if the C++ Standard Requires Progress.
-  bool CPlusPlusWithProgress() {
+  /// Returns true if a function must make progress, which means the
+  /// mustprogress attribute can be added.
+  bool checkIfFunctionMustProgress() {
     if (CGM.getCodeGenOpts().getFiniteLoops() ==
         CodeGenOptions::FiniteLoopsKind::Never)
       return false;
 
-    return getLangOpts().CPlusPlus11 || getLangOpts().CPlusPlus14 ||
-           getLangOpts().CPlusPlus17 || getLangOpts().CPlusPlus20;
+    // C++11 and later guarantees that a thread eventually will do one of the
+    // following (6.9.2.3.1 in C++11):
+    // - terminate,
+    //  - make a call to a library I/O function,
+    //  - perform an access through a volatile glvalue, or
+    //  - perform a synchronization operation or an atomic operation.
+    //
+    // Hence each function is 'mustprogress' in C++11 or later.
+    return getLangOpts().CPlusPlus11;
   }
 
-  /// True if the C Standard Requires Progress.
-  bool CWithProgress() {
+  /// Returns true if a loop must make progress, which means the mustprogress
+  /// attribute can be added. \p HasConstantCond indicates whether the branch
+  /// condition is a known constant.
+  bool checkIfLoopMustProgress(bool HasConstantCond) {
     if (CGM.getCodeGenOpts().getFiniteLoops() ==
         CodeGenOptions::FiniteLoopsKind::Always)
       return true;
@@ -546,13 +553,19 @@
         CodeGenOptions::FiniteLoopsKind::Never)
       return false;
 
-    return getLangOpts().C11 || getLangOpts().C17 || getLangOpts().C2x;
-  }
+    // If the containing function must make progress, loops also must make
+    // progress (as in C++11 and later).
+    if (checkIfFunctionMustProgress())
+      return true;
+
+    // Now apply rules for plain C (see  6.8.5.6 in C11).
+    // Loops with constant conditions do not have to make progress in any C
+    // version.
+    if (HasConstantCond)
+      return false;
 
-  /// True if the language standard requires progress in functions or
-  /// in infinite loops with non-constant conditionals.
-  bool LanguageRequiresProgress() {
-    return CWithProgress() || CPlusPlusWithProgress();
+    // Loops with non-constant conditions must make progress in C11 and later.
+    return getLangOpts().C11;
   }
 
   const CodeGen::CGBlockInfo *BlockInfo = nullptr;
Index: clang/lib/CodeGen/CodeGenFunction.cpp
===================================================================
--- clang/lib/CodeGen/CodeGenFunction.cpp
+++ clang/lib/CodeGen/CodeGenFunction.cpp
@@ -1186,9 +1186,6 @@
 
 void CodeGenFunction::EmitFunctionBody(const Stmt *Body) {
   incrementProfileCounter(Body);
-  if (CPlusPlusWithProgress())
-    FnIsMustProgress = true;
-
   if (const CompoundStmt *S = dyn_cast<CompoundStmt>(Body))
     EmitCompoundStmtWithoutScope(*S);
   else
@@ -1196,7 +1193,7 @@
 
   // This is checked after emitting the function body so we know if there
   // are any permitted infinite loops.
-  if (FnIsMustProgress)
+  if (checkIfFunctionMustProgress())
     CurFn->addFnAttr(llvm::Attribute::MustProgress);
 }
 
Index: clang/lib/CodeGen/CGStmt.cpp
===================================================================
--- clang/lib/CodeGen/CGStmt.cpp
+++ clang/lib/CodeGen/CGStmt.cpp
@@ -816,20 +816,14 @@
 
   // while(1) is common, avoid extra exit blocks.  Be sure
   // to correctly handle break/continue though.
-  bool EmitBoolCondBranch = true;
-  bool LoopMustProgress = false;
-  if (llvm::ConstantInt *C = dyn_cast<llvm::ConstantInt>(BoolCondVal)) {
-    if (C->isOne()) {
-      EmitBoolCondBranch = false;
-      FnIsMustProgress = false;
-    }
-  } else if (LanguageRequiresProgress())
-    LoopMustProgress = true;
-
+  llvm::ConstantInt *C = dyn_cast<llvm::ConstantInt>(BoolCondVal);
+  bool CondIsConstInt = C != nullptr;
+  bool EmitBoolCondBranch = !CondIsConstInt || !C->isOne();
   const SourceRange &R = S.getSourceRange();
   LoopStack.push(LoopHeader.getBlock(), CGM.getContext(), CGM.getCodeGenOpts(),
                  WhileAttrs, SourceLocToDebugLoc(R.getBegin()),
-                 SourceLocToDebugLoc(R.getEnd()), LoopMustProgress);
+                 SourceLocToDebugLoc(R.getEnd()),
+                 checkIfLoopMustProgress(CondIsConstInt));
 
   // As long as the condition is true, go to the loop body.
   llvm::BasicBlock *LoopBody = createBasicBlock("while.body");
@@ -920,20 +914,15 @@
 
   // "do {} while (0)" is common in macros, avoid extra blocks.  Be sure
   // to correctly handle break/continue though.
-  bool EmitBoolCondBranch = true;
-  bool LoopMustProgress = false;
-  if (llvm::ConstantInt *C = dyn_cast<llvm::ConstantInt>(BoolCondVal)) {
-    if (C->isZero())
-      EmitBoolCondBranch = false;
-    else if (C->isOne())
-      FnIsMustProgress = false;
-  } else if (LanguageRequiresProgress())
-    LoopMustProgress = true;
+  llvm::ConstantInt *C = dyn_cast<llvm::ConstantInt>(BoolCondVal);
+  bool CondIsConstInt = C;
+  bool EmitBoolCondBranch = !C || !C->isZero();
 
   const SourceRange &R = S.getSourceRange();
   LoopStack.push(LoopBody, CGM.getContext(), CGM.getCodeGenOpts(), DoAttrs,
                  SourceLocToDebugLoc(R.getBegin()),
-                 SourceLocToDebugLoc(R.getEnd()), LoopMustProgress);
+                 SourceLocToDebugLoc(R.getEnd()),
+                 checkIfLoopMustProgress(CondIsConstInt));
 
   // As long as the condition is true, iterate the loop.
   if (EmitBoolCondBranch) {
@@ -971,20 +960,15 @@
   llvm::BasicBlock *CondBlock = CondDest.getBlock();
   EmitBlock(CondBlock);
 
-  bool LoopMustProgress = false;
   Expr::EvalResult Result;
-  if (LanguageRequiresProgress()) {
-    if (!S.getCond()) {
-      FnIsMustProgress = false;
-    } else if (!S.getCond()->EvaluateAsInt(Result, getContext())) {
-      LoopMustProgress = true;
-    }
-  }
+  bool CondIsConstInt =
+      !S.getCond() || S.getCond()->EvaluateAsInt(Result, getContext());
 
   const SourceRange &R = S.getSourceRange();
   LoopStack.push(CondBlock, CGM.getContext(), CGM.getCodeGenOpts(), ForAttrs,
                  SourceLocToDebugLoc(R.getBegin()),
-                 SourceLocToDebugLoc(R.getEnd()), LoopMustProgress);
+                 SourceLocToDebugLoc(R.getEnd()),
+                 checkIfLoopMustProgress(CondIsConstInt));
 
   // Create a cleanup scope for the condition variable cleanups.
   LexicalScope ConditionScope(*this, S.getSourceRange());
@@ -1033,10 +1017,6 @@
       BoolCondVal = emitCondLikelihoodViaExpectIntrinsic(
           BoolCondVal, Stmt::getLikelihood(S.getBody()));
 
-    if (llvm::ConstantInt *C = dyn_cast<llvm::ConstantInt>(BoolCondVal))
-      if (C->isOne())
-        FnIsMustProgress = false;
-
     Builder.CreateCondBr(BoolCondVal, ForBody, ExitBlock, Weights);
 
     if (ExitBlock != LoopExit.getBlock()) {
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to