[clang] 51bf4c0 - [clang] Add -ffinite-loops & -fno-finite-loops options.

Florian Hahn via cfe-commits cfe-commits at lists.llvm.org
Fri Feb 12 11:26:59 PST 2021


Author: Florian Hahn
Date: 2021-02-12T19:25:49Z
New Revision: 51bf4c0e6d4cbc6dfa57857fc78003413cbeb17f

URL: https://github.com/llvm/llvm-project/commit/51bf4c0e6d4cbc6dfa57857fc78003413cbeb17f
DIFF: https://github.com/llvm/llvm-project/commit/51bf4c0e6d4cbc6dfa57857fc78003413cbeb17f.diff

LOG: [clang] Add -ffinite-loops & -fno-finite-loops options.

This patch adds 2 new options to control when Clang adds `mustprogress`:

  1. -ffinite-loops: assume all loops are finite; mustprogress is added
     to all loops, regardless of the selected language standard.
  2. -fno-finite-loops: assume no loop is finite; mustprogress is not
     added to any loop or function. We could add mustprogress to
     functions without loops, but we would have to detect that in Clang,
     which is probably not worth it.

Reviewed By: jdoerfert

Differential Revision: https://reviews.llvm.org/D96419

Added: 
    

Modified: 
    clang/include/clang/Basic/CodeGenOptions.def
    clang/include/clang/Basic/CodeGenOptions.h
    clang/include/clang/Driver/Options.td
    clang/lib/CodeGen/CodeGenFunction.h
    clang/lib/Driver/ToolChains/Clang.cpp
    clang/lib/Frontend/CompilerInvocation.cpp
    clang/test/CodeGen/attr-mustprogress.c
    clang/test/CodeGenCXX/attr-mustprogress.cpp

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/Basic/CodeGenOptions.def b/clang/include/clang/Basic/CodeGenOptions.def
index 5c8af65326ed..9d53b5b923bb 100644
--- a/clang/include/clang/Basic/CodeGenOptions.def
+++ b/clang/include/clang/Basic/CodeGenOptions.def
@@ -266,6 +266,9 @@ CODEGENOPT(VectorizeLoop     , 1, 0) ///< Run loop vectorizer.
 CODEGENOPT(VectorizeSLP      , 1, 0) ///< Run SLP vectorizer.
 CODEGENOPT(ProfileSampleAccurate, 1, 0) ///< Sample profile is accurate.
 
+/// Treat loops as finite: language, always, never.
+ENUM_CODEGENOPT(FiniteLoops, FiniteLoopsKind, 2, FiniteLoopsKind::Language)
+
   /// Attempt to use register sized accesses to bit-fields in structures, when
   /// possible.
 CODEGENOPT(UseRegisterSizedBitfieldAccess , 1, 0)

diff  --git a/clang/include/clang/Basic/CodeGenOptions.h b/clang/include/clang/Basic/CodeGenOptions.h
index 38979520b90d..efcb6b16b0f7 100644
--- a/clang/include/clang/Basic/CodeGenOptions.h
+++ b/clang/include/clang/Basic/CodeGenOptions.h
@@ -140,6 +140,12 @@ class CodeGenOptions : public CodeGenOptionsBase {
     All,         // Keep all frame pointers.
   };
 
+  enum FiniteLoopsKind {
+    Language, // Not specified, use language standard.
+    Always,   // All loops are assumed to be finite.
+    Never,    // No loop is assumed to be finite.
+  };
+
   /// The code model to use (-mcmodel).
   std::string CodeModel;
 

diff  --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index 5228396ebcd9..d22956b86c4a 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -2469,6 +2469,11 @@ def fno_unroll_loops : Flag<["-"], "fno-unroll-loops">, Group<f_Group>,
 defm reroll_loops : BoolFOption<"reroll-loops",
   CodeGenOpts<"RerollLoops">, DefaultFalse,
   PosFlag<SetTrue, [CC1Option], "Turn on loop reroller">, NegFlag<SetFalse>>;
+def ffinite_loops: Flag<["-"],  "ffinite-loops">, Group<f_Group>,
+  HelpText<"Assume all loops are finite.">, Flags<[CC1Option]>;
+def fno_finite_loops: Flag<["-"], "fno-finite-loops">, Group<f_Group>,
+  HelpText<"Do not assume that any loop is finite.">, Flags<[CC1Option]>;
+
 def ftrigraphs : Flag<["-"], "ftrigraphs">, Group<f_Group>,
   HelpText<"Process trigraph sequences">, Flags<[CC1Option]>;
 def fno_trigraphs : Flag<["-"], "fno-trigraphs">, Group<f_Group>,

diff  --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h
index dd77d70c21f4..ff9875167ba5 100644
--- a/clang/lib/CodeGen/CodeGenFunction.h
+++ b/clang/lib/CodeGen/CodeGenFunction.h
@@ -507,12 +507,26 @@ class CodeGenFunction : public CodeGenTypeCache {
 
   /// True if the C++ Standard Requires Progress.
   bool CPlusPlusWithProgress() {
+    if (CGM.getCodeGenOpts().getFiniteLoops() ==
+        CodeGenOptions::FiniteLoopsKind::Never)
+      return false;
+    if (CGM.getCodeGenOpts().getFiniteLoops() ==
+        CodeGenOptions::FiniteLoopsKind::Never)
+      return false;
+
     return getLangOpts().CPlusPlus11 || getLangOpts().CPlusPlus14 ||
            getLangOpts().CPlusPlus17 || getLangOpts().CPlusPlus20;
   }
 
   /// True if the C Standard Requires Progress.
   bool CWithProgress() {
+    if (CGM.getCodeGenOpts().getFiniteLoops() ==
+        CodeGenOptions::FiniteLoopsKind::Always)
+      return true;
+    if (CGM.getCodeGenOpts().getFiniteLoops() ==
+        CodeGenOptions::FiniteLoopsKind::Never)
+      return false;
+
     return getLangOpts().C11 || getLangOpts().C17 || getLangOpts().C2x;
   }
 

diff  --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index c2b195a8088f..819f10eb2524 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -5640,6 +5640,9 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
     if (A->getOption().matches(options::OPT_freroll_loops))
       CmdArgs.push_back("-freroll-loops");
 
+  Args.AddLastArg(CmdArgs, options::OPT_ffinite_loops,
+                  options::OPT_fno_finite_loops);
+
   Args.AddLastArg(CmdArgs, options::OPT_fwritable_strings);
   Args.AddLastArg(CmdArgs, options::OPT_funroll_loops,
                   options::OPT_fno_unroll_loops);

diff  --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp
index 53f90cf4aef4..b2ee11a42f57 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -1633,7 +1633,6 @@ bool CompilerInvocation::ParseCodeGenArgsImpl(CodeGenOptions &Opts,
   Opts.UnrollLoops =
       Args.hasFlag(OPT_funroll_loops, OPT_fno_unroll_loops,
                    (Opts.OptimizationLevel > 1));
-
   Opts.BinutilsVersion =
       std::string(Args.getLastArgValue(OPT_fbinutils_version_EQ));
 
@@ -1921,6 +1920,11 @@ bool CompilerInvocation::ParseCodeGenArgsImpl(CodeGenOptions &Opts,
 
   Opts.EmitVersionIdentMetadata = Args.hasFlag(OPT_Qy, OPT_Qn, true);
 
+  if (Args.hasArg(options::OPT_ffinite_loops))
+    Opts.FiniteLoops = CodeGenOptions::FiniteLoopsKind::Always;
+  else if (Args.hasArg(options::OPT_fno_finite_loops))
+    Opts.FiniteLoops = CodeGenOptions::FiniteLoopsKind::Never;
+
   return Success && Diags.getNumErrors() == NumErrorsBefore;
 }
 

diff  --git a/clang/test/CodeGen/attr-mustprogress.c b/clang/test/CodeGen/attr-mustprogress.c
index d1b262d654cd..1f83cd44b308 100644
--- a/clang/test/CodeGen/attr-mustprogress.c
+++ b/clang/test/CodeGen/attr-mustprogress.c
@@ -2,6 +2,9 @@
 // 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
+//
+// 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=c11 -fno-finite-loops -triple=x86_64-unknown-linux-gnu -S -emit-llvm %s -o - | FileCheck --check-prefix=CHECK --check-prefix=C99 %s
 
 int a = 0;
 int b = 0;
@@ -13,7 +16,7 @@ int b = 0;
 // CHECK-NEXT:  entry:
 // CHECK-NEXT:    br label %for.cond
 // CHECK:       for.cond:
-// CHECK-NOT:    br {{.*}}!llvm.loop
+// CHECK-NOT:     br {{.*}}!llvm.loop
 //
 void f0() {
   for (; ;) ;
@@ -45,8 +48,9 @@ void f1() {
 // CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[TMP0]], [[TMP1]]
 // CHECK-NEXT:    br i1 [[CMP]], label %for.body, label %for.end
 // CHECK:       for.body:
-// C99-NOT:      br {{.*}} !llvm.loop
-// C11:          br label %for.cond, !llvm.loop [[LOOP1:!.*]]
+// C99-NOT:       br {{.*}} !llvm.loop
+// C11:           br label %for.cond, !llvm.loop [[LOOP1:!.*]]
+// FINITE:        br label %for.cond, !llvm.loop [[LOOP1:!.*]]
 // CHECK:       for.end:
 // CHECK-NEXT:    ret void
 //
@@ -73,6 +77,7 @@ void f2() {
 // CHECK:       for.body2:
 // C99-NOT:       br {{.*}}, !llvm.loop
 // C11:           br label %for.cond1, !llvm.loop [[LOOP2:!.*]]
+// FINITE:        br label %for.cond1, !llvm.loop [[LOOP2:!.*]]
 // CHECK:       for.end3:
 // CHECK-NEXT:    ret void
 //
@@ -88,7 +93,8 @@ void F() {
 // CHECK-NEXT:  entry:
 // CHECK-NEXT:    br label %while.body
 // CHECK:       while.body:
-// CHECK-NOT:    br {{.*}}, !llvm.loop
+// CHECK-NOT:     br {{.*}}, !llvm.loop
+//
 void w1() {
   while (1) {
   }
@@ -104,8 +110,9 @@ void w1() {
 // CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[TMP0]], [[TMP1]]
 // CHECK-NEXT:    br i1 [[CMP]], label %while.body, label %while.end
 // CHECK:       while.body:
-// C11:           br label %while.cond, [[LOOP5:!llvm.loop !.*]]
 // C99-NOT:       br {{.*}}, !llvm.loop
+// C11:           br label %while.cond, !llvm.loop [[LOOP3:!.*]]
+// FINITE:        br label %while.cond, !llvm.loop [[LOOP3:!.*]]
 // CHECK:       while.end:
 // CHECK-NEXT:    ret void
 //
@@ -125,7 +132,8 @@ void w2() {
 // 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 [[LOOP3:!.*]]
+// C11:           br label %while.cond, !llvm.loop [[LOOP4:!.*]]
+// FINITE:        br label %while.cond, !llvm.loop [[LOOP4:!.*]]
 // CHECK:       while.end:
 // CHECK-NEXT:    br label %while.body2
 // CHECK:       while.body2:
@@ -165,7 +173,8 @@ void d1() {
 // CHECK-NEXT:    [[TMP1:%.*]] = load i32, i32* @b, align 4
 // CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[TMP0]], [[TMP1]]
 // C99-NOT:       br {{.*}}, !llvm.loop
-// C11:           br i1 [[CMP]], label %do.body, label %do.end, !llvm.loop [[LOOP4:!.*]]
+// C11:           br i1 [[CMP]], label %do.body, label %do.end, !llvm.loop [[LOOP5:!.*]]
+// FINITE:        br i1 [[CMP]], label %do.body, label %do.end, !llvm.loop [[LOOP5:!.*]]
 // CHECK:       do.end:
 // CHECK-NEXT:    ret void
 //
@@ -191,7 +200,8 @@ void d2() {
 // CHECK-NEXT:    [[TMP1:%.*]] = load i32, i32* @b, align 4
 // CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[TMP0]], [[TMP1]]
 // C99-NOT:       br {{.*}}, !llvm.loop
-// C11:           br i1 [[CMP]], label %do.body1, label %do.end3, !llvm.loop [[LOOP5:!.*]]
+// C11:           br i1 [[CMP]], label %do.body1, label %do.end3, !llvm.loop [[LOOP6:!.*]]
+// FINITE:        br i1 [[CMP]], label %do.body1, label %do.end3, !llvm.loop [[LOOP6:!.*]]
 // CHECK:       do.end3:
 // CHECK-NEXT:    ret void
 //
@@ -208,3 +218,4 @@ void D() {
 // C11: [[LOOP3]] = distinct !{[[LOOP3]], [[MP]]}
 // C11: [[LOOP4]] = distinct !{[[LOOP4]], [[MP]]}
 // C11: [[LOOP5]] = distinct !{[[LOOP5]], [[MP]]}
+// C11: [[LOOP6]] = distinct !{[[LOOP6]], [[MP]]}

diff  --git a/clang/test/CodeGenCXX/attr-mustprogress.cpp b/clang/test/CodeGenCXX/attr-mustprogress.cpp
index df643ac90f39..93e366b4ca7f 100644
--- a/clang/test/CodeGenCXX/attr-mustprogress.cpp
+++ b/clang/test/CodeGenCXX/attr-mustprogress.cpp
@@ -4,6 +4,12 @@
 // RUN: %clang_cc1 -std=c++17 -triple=x86_64-unknown-linux-gnu -S -emit-llvm %s -o - | FileCheck --check-prefix=CHECK --check-prefix=CXX11 %s
 // RUN: %clang_cc1 -std=c++20 -triple=x86_64-unknown-linux-gnu -S -emit-llvm %s -o - | FileCheck --check-prefix=CHECK --check-prefix=CXX11 %s
 
+// Make sure -ffinite-loops overrides -std=c++98 for loops.
+// RUN: %clang_cc1 -std=c++98 -ffinite-loops -triple=x86_64-unknown-linux-gnu -S -emit-llvm %s -o - | FileCheck --check-prefix=CHECK --check-prefix=FINITE %s
+
+// Make sure -fno_finite-loops overrides -std=c++11
+// RUN: %clang_cc1 -std=c++11 -fno-finite-loops -triple=x86_64-unknown-linux-gnu -S -emit-llvm %s -o - | FileCheck --check-prefix=CHECK --check-prefix=CXX98 %s
+
 int a = 0;
 int b = 0;
 
@@ -11,26 +17,26 @@ int b = 0;
 
 // CXX98-NOT: mustprogress
 // CXX11-NOT: mustprogress
+// FINITE-NOT:     mustprogress
 // CHECK-LABEL: @_Z2f0v(
 // CHECK-NEXT:  entry:
 // CHECK-NEXT:    br label %for.cond
 // CHECK:       for.cond:
-// CXX98-NOT:    br {{.*}} llvm.loop
-// CXX11-NOT:    br {{.*}} llvm.loop
+// CHECK-NOT:    br {{.*}} llvm.loop
 void f0() {
   for (; ;) ;
 }
 
 // CXX98-NOT: mustprogress
 // CXX11-NOT: mustprogress
+// FINITE-NOT: mustprogress
 // CHECK-LABEL: @_Z2f1v(
 // CHECK-NEXT:  entry:
 // CHECK-NEXT:    br label %for.cond
 // CHECK:       for.cond:
 // CHECK-NEXT:    br i1 true, label %for.body, label %for.end
 // CHECK:       for.body:
-// CXX98-NOT:    br {{.*}}, !llvm.loop
-// CXX11-NOT:    br {{.*}}, !llvm.loop
+// CHECK-NOT:    br {{.*}}, !llvm.loop
 // CHECK:       for.end:
 // CHECK-NEXT:    ret void
 //
@@ -41,6 +47,7 @@ void f1() {
 
 // CXX98-NOT: mustprogress
 // CXX11:     mustprogress
+// FINITE-NOT: mustprogress
 // CHECK-LABEL: @_Z2f2v(
 // CHECK-NEXT:  entry:
 // CHECK-NEXT:    br label %for.cond
@@ -52,6 +59,7 @@ void f1() {
 // 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:!.*]]
 // CHECK:       for.end:
 // CHECK-NEXT:    ret void
 //
@@ -62,14 +70,14 @@ void f2() {
 
 // CXX98-NOT: mustprogress
 // CXX11-NOT: mustprogress
+// FINITE-NOT: mustprogress
 // CHECK-LABEL: @_Z1Fv(
 // CHECK-NEXT:  entry:
 // CHECK-NEXT:    br label %for.cond
 // CHECK:       for.cond:
 // CHECK-NEXT:    br i1 true, label %for.body, label %for.end
 // CHECK:       for.body:
-// CXX98-NOT:     br {{.*}}, !llvm.loop
-// CXX11-NOT:     br {{.*}}, !llvm.loop
+// CHECK-NOT:     br {{.*}}, !llvm.loop
 // CHECK:       for.end:
 // CHECK-NEXT:    br label %for.cond1
 // CHECK:       for.cond1:
@@ -78,8 +86,9 @@ void f2() {
 // CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[TMP0]], [[TMP1]]
 // CHECK-NEXT:    br i1 [[CMP]], label %for.body2, label %for.end3
 // CHECK:       for.body2:
-// CXX98-NOT:    br {{.*}}, !llvm.loop
-// CXX11:        br label %for.cond1, !llvm.loop [[LOOP2:!.*]]
+// CXX98-NOT:     br {{.*}}, !llvm.loop
+// CXX11-NEXT:    br label %for.cond1, !llvm.loop [[LOOP2:!.*]]
+// FINITE-NEXT:   br label %for.cond1, !llvm.loop [[LOOP2:!.*]]
 // CHECK:       for.end3:
 // CHECK-NEXT:    ret void
 //
@@ -91,7 +100,8 @@ void F() {
 }
 
 // CXX98-NOT: mustprogress
-// CXX11_NOT: mustprogress
+// CXX11-NOT: mustprogress
+// FINITE-NOT: mustprogress
 // CHECK-LABEL: @_Z2F2v(
 // CHECK-NEXT:  entry:
 // CHECK-NEXT:    br label %for.cond
@@ -102,14 +112,14 @@ void F() {
 // 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
+// CXX11-NEXT:    br label %for.cond, !llvm.loop [[LOOP3:!.*]]
+// FINITE-NEXT:    br label %for.cond, !llvm.loop [[LOOP3:!.*]]
 // 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:
-// CXX98-NOT:     br {{.*}}, !llvm.loop
-// CXX11-NOT:     br {{.*}}, !llvm.loop
+// CHECK-NOT:     br {{.*}}, !llvm.loop
 // CHECK:       for.end3:
 // CHECK-NEXT:    ret void
 //
@@ -122,12 +132,12 @@ void F2() {
 
 // CXX98-NOT: mustprogress
 // CXX11-NOT: mustprogress
+// FINITE-NOT:     mustprogress
 // CHECK-LABEL: @_Z2w1v(
 // CHECK-NEXT:  entry:
 // CHECK-NEXT:    br label %while.body
 // CHECK:       while.body:
-// CXX98-NOT:     br {{.*}}, !llvm.loop
-// CXX11-NOT:     br {{.*}}, !llvm.loop
+// CHECK-NOT:     br {{.*}}, !llvm.loop
 //
 void w1() {
   while (1)
@@ -136,6 +146,7 @@ void w1() {
 
 // CXX98-NOT: mustprogress
 // CXX11:     mustprogress
+// FINITE-NOT: mustprogress
 // CHECK-LABEL: @_Z2w2v(
 // CHECK-NEXT:  entry:
 // CHECK-NEXT:    br label %while.cond
@@ -146,7 +157,8 @@ void w1() {
 // 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 [[LOOP3:!.*]]
+// CXX11-NEXT:    br label %while.cond, !llvm.loop [[LOOP4:!.*]]
+// FINITE-NEXT:   br label %while.cond, !llvm.loop [[LOOP4:!.*]]
 // CHECK:       while.end:
 // CHECK-NEXT:    ret void
 //
@@ -157,6 +169,7 @@ void w2() {
 
 // CXX98-NOT: mustprogress
 // CXX11-NOT: mustprogress
+// FINITE-NOT: mustprogress
 // CHECK-LABEL: @_Z1Wv(
 // CHECK-NEXT:  entry:
 // CHECK-NEXT:    br label %while.cond
@@ -167,12 +180,12 @@ void w2() {
 // 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:!.*]]
+// CXX11-NEXT:    br label %while.cond, !llvm.loop [[LOOP5:!.*]]
+// FINITE-NEXT:   br label %while.cond, !llvm.loop [[LOOP5:!.*]]
 // CHECK:       while.end:
 // CHECK-NEXT:    br label %while.body2
 // CHECK:       while.body2:
-// CXX98-NOT:    br {{.*}}, !llvm.loop
-// CXX11-NOT:    br {{.*}}, !llvm.loop
+// CHECK-NOT:     br {{.*}}, !llvm.loop
 //
 void W() {
   while (a == b)
@@ -183,12 +196,12 @@ void W() {
 
 // CXX98-NOT: mustprogress
 // CXX11-NOT: mustprogress
+// FINITE-NOT: mustprogress
 // CHECK-LABEL: @_Z2W2v(
 // CHECK-NEXT:  entry:
 // CHECK-NEXT:    br label %while.body
 // CHECK:       while.body:
-// CXX98-NOT:     br {{.*}}, !llvm.loop
-// CXX11-NOT:     br {{.*}}, !llvm.loop
+// CHECK-NOT:     br {{.*}}, !llvm.loop
 //
 void W2() {
   while (1)
@@ -199,14 +212,14 @@ void W2() {
 
 // CXX98-NOT: mustprogress
 // CXX11-NOT: mustprogress
+// FINITE-NOT: mustprogress
 // CHECK-LABEL: @_Z2d1v(
 // CHECK-NEXT:  entry:
 // CHECK-NEXT:    br label %do.body
 // CHECK:       do.body:
 // CHECK-NEXT:    br label %do.cond
 // CHECK:       do.cond:
-// CXX98-NOT:     br {{.*}}, !llvm.loop
-// CXX11-NOT:     br {{.*}}, !llvm.loop
+// CHECK-NOT:     br {{.*}}, !llvm.loop
 // CHECK:       do.end:
 // CHECK-NEXT:    ret void
 //
@@ -218,6 +231,7 @@ void d1() {
 
 // CXX98-NOT: mustprogress
 // CXX11:     mustprogress
+// FINITE-NOT:  mustprogress
 // CHECK-LABEL: @_Z2d2v(
 // CHECK-NEXT:  entry:
 // CHECK-NEXT:    br label %do.body
@@ -228,7 +242,8 @@ void d1() {
 // 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 [[LOOP5:!.*]]
+// 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:!.*]]
 // CHECK:       do.end:
 // CHECK-NEXT:    ret void
 //
@@ -240,14 +255,14 @@ void d2() {
 
 // CXX98-NOT: mustprogress
 // CXX11-NOT: 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:
-// CXX98-NOT:     br {{.*}}, !llvm.loop
-// CXX11-NOT:     br {{.*}}, !llvm.loop
+// CHECK-NOT:     br {{.*}}, !llvm.loop
 // CHECK:       do.end:
 // CHECK-NEXT:    br label %do.body1
 // CHECK:       do.body1:
@@ -257,7 +272,8 @@ void d2() {
 // 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 [[LOOP6:!.*]]
+// 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:!.*]]
 // CHECK:       do.end3:
 // CHECK-NEXT:    ret void
 //
@@ -272,6 +288,7 @@ void D() {
 
 // CXX98-NOT: mustprogress
 // CXX11-NOT: mustprogress
+// FINITE-NOT:     mustprogress
 // CHECK-LABEL: @_Z2D2v(
 // CHECK-NEXT:  entry:
 // CHECK-NEXT:    br label %do.body
@@ -282,14 +299,14 @@ void D() {
 // 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 [[LOOP7:!.*]]
+// 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:!.*]]
 // CHECK:       do.end:
 // CHECK-NEXT:    br label %do.body1
 // CHECK:       do.body1:
 // CHECK-NEXT:    br label %do.cond2
 // CHECK:       do.cond2:
-// CXX98-NOT:     br {{.*}}, !llvm.loop
-// CXX11-NOT:     br {{.*}}, !llvm.loop
+// CHECK-NOT:     br {{.*}}, !llvm.loop
 // CHECK:       do.end3:
 // CHECK-NEXT:    ret void
 //
@@ -302,7 +319,6 @@ void D2() {
   while (1);
 }
 
-
 // CXX11: [[LOOP1]] = distinct !{[[LOOP1]], [[MP:!.*]]}
 // CXX11: [[MP]] = !{!"llvm.loop.mustprogress"}
 // CXX11: [[LOOP2]] = distinct !{[[LOOP2]], [[MP]]}
@@ -311,3 +327,4 @@ void D2() {
 // CXX11: [[LOOP5]] = distinct !{[[LOOP5]], [[MP]]}
 // CXX11: [[LOOP6]] = distinct !{[[LOOP6]], [[MP]]}
 // CXX11: [[LOOP7]] = distinct !{[[LOOP7]], [[MP]]}
+// CXX11: [[LOOP8]] = distinct !{[[LOOP8]], [[MP]]}


        


More information about the cfe-commits mailing list