fhahn updated this revision to Diff 322683.
fhahn added a comment.
Remove accidentally copied code.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D96419/new/
https://reviews.llvm.org/D96419
Files:
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
Index: clang/test/CodeGenCXX/attr-mustprogress.cpp
===================================================================
--- clang/test/CodeGenCXX/attr-mustprogress.cpp
+++ 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,18 +17,21 @@
// CXX98-NOT: mustprogress
// CXX11: 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-NEXT: br label %for.cond, !llvm.loop [[LOOP1:!.*]]
+// FINITE-NEXT: br label %for.cond, !llvm.loop [[LOOP1:!.*]]
void f0() {
for (; ;) ;
}
// CXX98-NOT: mustprogress
// CXX11: mustprogress
+// FINITE-NOT: mustprogress
// CHECK-LABEL: @_Z2f1v(
// CHECK-NEXT: entry:
// CHECK-NEXT: br label %for.cond
@@ -31,6 +40,7 @@
// CHECK: for.body:
// 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
//
@@ -41,6 +51,7 @@
// CXX98-NOT: mustprogress
// CXX11: mustprogress
+// FINITE-NOT: mustprogress
// CHECK-LABEL: @_Z2f2v(
// CHECK-NEXT: entry:
// CHECK-NEXT: br label %for.cond
@@ -52,6 +63,7 @@
// 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:!.*]]
// CHECK: for.end:
// CHECK-NEXT: ret void
//
@@ -62,6 +74,7 @@
// CXX98-NOT: mustprogress
// CXX11: mustprogress
+// FINITE-NOT: mustprogress
// CHECK-LABEL: @_Z1Fv(
// CHECK-NEXT: entry:
// CHECK-NEXT: br label %for.cond
@@ -70,6 +83,7 @@
// CHECK: for.body:
// 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:
@@ -80,6 +94,7 @@
// CHECK: for.body2:
// CXX98-NOT: br {{.*}}, !llvm.loop
// 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
//
@@ -91,7 +106,8 @@
}
// CXX98-NOT: mustprogress
-// CXX11_NOT: mustprogress
+// CXX11: mustprogress
+// FINITE-NOT: mustprogress
// CHECK-LABEL: @_Z2F2v(
// CHECK-NEXT: entry:
// CHECK-NEXT: br label %for.cond
@@ -103,6 +119,7 @@
// CHECK: for.body:
// CXX98_NOT: br {{.*}} !llvm.loop
// 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:
@@ -110,6 +127,7 @@
// CHECK: for.body2:
// 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
//
@@ -122,12 +140,14 @@
// CXX98-NOT: mustprogress
// CXX11: 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-NEXT: br label %while.body, !llvm.loop [[LOOP8:!.*]]
+// FINITE-NEXT: br label %while.body, !llvm.loop [[LOOP8:!.*]]
//
void w1() {
while (1)
@@ -136,6 +156,7 @@
// CXX98-NOT: mustprogress
// CXX11: mustprogress
+// FINITE-NOT: mustprogress
// CHECK-LABEL: @_Z2w2v(
// CHECK-NEXT: entry:
// CHECK-NEXT: br label %while.cond
@@ -147,6 +168,7 @@
// CHECK: while.body:
// CXX98-NOT: br {{.*}}, !llvm.loop
// 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
//
@@ -157,6 +179,7 @@
// CXX98-NOT: mustprogress
// CXX11: mustprogress
+// FINITE-NOT: mustprogress
// CHECK-LABEL: @_Z1Wv(
// CHECK-NEXT: entry:
// CHECK-NEXT: br label %while.cond
@@ -168,11 +191,13 @@
// CHECK: while.body:
// CXX98-NOT: br {{.*}}, !llvm.loop
// 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:
// 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)
@@ -183,12 +208,14 @@
// CXX98-NOT: mustprogress
// CXX11: 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-NEXT: br label %while.body, !llvm.loop [[LOOP12:!.*]]
+// FINITE-NEXT: br label %while.body, !llvm.loop [[LOOP12:!.*]]
//
void W2() {
while (1)
@@ -199,6 +226,7 @@
// CXX98-NOT: mustprogress
// CXX11: mustprogress
+// FINITE-NOT: mustprogress
// CHECK-LABEL: @_Z2d1v(
// CHECK-NEXT: entry:
// CHECK-NEXT: br label %do.body
@@ -207,6 +235,7 @@
// CHECK: do.cond:
// 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
//
@@ -218,6 +247,7 @@
// CXX98-NOT: mustprogress
// CXX11: mustprogress
+// FINITE-NOT: mustprogress
// CHECK-LABEL: @_Z2d2v(
// CHECK-NEXT: entry:
// CHECK-NEXT: br label %do.body
@@ -229,6 +259,7 @@
// 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 [[LOOP14:!.*]]
+// FINITE-NEXT: br i1 [[CMP]], label %do.body, label %do.end, !llvm.loop [[LOOP14:!.*]]
// CHECK: do.end:
// CHECK-NEXT: ret void
//
@@ -240,6 +271,7 @@
// CXX98-NOT: mustprogress
// CXX11: mustprogress
+// FINITE-NOT: mustprogress
// CHECK-LABEL: @_Z1Dv(
// CHECK-NEXT: entry:
// CHECK-NEXT: br label %do.body
@@ -248,6 +280,7 @@
// CHECK: do.cond:
// 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:
@@ -258,6 +291,7 @@
// 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 [[LOOP16:!.*]]
+// FINITE-NEXT: br i1 [[CMP]], label %do.body1, label %do.end3, !llvm.loop [[LOOP16:!.*]]
// CHECK: do.end3:
// CHECK-NEXT: ret void
//
@@ -272,6 +306,7 @@
// CXX98-NOT: mustprogress
// CXX11: mustprogress
+// FINITE-NOT: mustprogress
// CHECK-LABEL: @_Z2D2v(
// CHECK-NEXT: entry:
// CHECK-NEXT: br label %do.body
@@ -283,6 +318,7 @@
// 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 [[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:
@@ -290,6 +326,7 @@
// CHECK: do.cond2:
// 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
//
Index: clang/test/CodeGen/attr-mustprogress.c
===================================================================
--- clang/test/CodeGen/attr-mustprogress.c
+++ 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,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: br label %for.cond, !llvm.loop
//
void f0() {
for (; ;) ;
@@ -26,7 +31,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: br label %for.cond, !llvm.loop
// CHECK: for.end:
// CHECK-NEXT: ret void
//
@@ -45,8 +52,9 @@
// 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
//
@@ -62,7 +70,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: br label %for.cond, !llvm.loop
// CHECK: for.end:
// CHECK-NEXT: br label %for.cond1
// CHECK: for.cond1:
@@ -88,7 +98,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: br {{.*}}, !llvm.loop
void w1() {
while (1) {
}
@@ -127,7 +139,9 @@
// C99-NOT: br {{.*}} !llvm.loop
// C11-NEXT: br label %while.cond, !llvm.loop [[LOOP4:!.*]]
// CHECK: while.body2:
-// CHECK-NOT: br {{.*}} !llvm.loop
+// C99-NOT: br {{.*}} !llvm.loop
+// C11-NOT: br {{.*}} !llvm.loop
+// FINITE: br label %while.body2, !llvm.loop
//
void W() {
while (a == b) {
@@ -143,7 +157,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: br i1 true, label %do.body, label %do.end, !llvm.loop
// CHECK: do.end:
// CHECK-NEXT: ret void
//
Index: clang/lib/Frontend/CompilerInvocation.cpp
===================================================================
--- clang/lib/Frontend/CompilerInvocation.cpp
+++ clang/lib/Frontend/CompilerInvocation.cpp
@@ -1633,7 +1633,6 @@
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 @@
Opts.EmitVersionIdentMetadata = Args.hasFlag(OPT_Qy, OPT_Qn, true);
+ if (Args.hasArg(options::OPT_ffinite_loops))
+ Opts.FiniteLoops = CodeGenOptions::FiniteLoopsKind::Yes;
+ else if (Args.hasArg(options::OPT_fno_finite_loops))
+ Opts.FiniteLoops = CodeGenOptions::FiniteLoopsKind::No;
+
return Success && Diags.getNumErrors() == NumErrorsBefore;
}
Index: clang/lib/Driver/ToolChains/Clang.cpp
===================================================================
--- clang/lib/Driver/ToolChains/Clang.cpp
+++ clang/lib/Driver/ToolChains/Clang.cpp
@@ -5625,6 +5625,9 @@
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);
Index: clang/lib/CodeGen/CodeGenFunction.h
===================================================================
--- clang/lib/CodeGen/CodeGenFunction.h
+++ clang/lib/CodeGen/CodeGenFunction.h
@@ -507,6 +507,10 @@
/// Returns true if the function must make progress.
bool functionMustProgress() {
+ if (CGM.getCodeGenOpts().getFiniteLoops() ==
+ CodeGenOptions::FiniteLoopsKind::No)
+ return false;
+
return getLangOpts().CPlusPlus11 || getLangOpts().CPlusPlus14 ||
getLangOpts().CPlusPlus17 || getLangOpts().CPlusPlus20;
}
@@ -515,6 +519,13 @@
/// Otherwise return false if the loop condition is a known constant and true
/// if the language standard is C11+.
bool loopMustProgress(bool HasConstantCond) {
+ if (CGM.getCodeGenOpts().getFiniteLoops() ==
+ CodeGenOptions::FiniteLoopsKind::Yes)
+ return true;
+ if (CGM.getCodeGenOpts().getFiniteLoops() ==
+ CodeGenOptions::FiniteLoopsKind::No)
+ return false;
+
if (functionMustProgress())
return true;
if (HasConstantCond)
Index: clang/include/clang/Driver/Options.td
===================================================================
--- clang/include/clang/Driver/Options.td
+++ clang/include/clang/Driver/Options.td
@@ -2467,6 +2467,11 @@
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>,
Index: clang/include/clang/Basic/CodeGenOptions.h
===================================================================
--- clang/include/clang/Basic/CodeGenOptions.h
+++ clang/include/clang/Basic/CodeGenOptions.h
@@ -140,6 +140,12 @@
All, // Keep all frame pointers.
};
+ enum FiniteLoopsKind {
+ None = 0, // Not specified, use language standard.
+ Yes = 1, // All loops are assumed to be finite.
+ No = 2, // No loop is assumed to be finite.
+ };
+
/// The code model to use (-mcmodel).
std::string CodeModel;
Index: clang/include/clang/Basic/CodeGenOptions.def
===================================================================
--- clang/include/clang/Basic/CodeGenOptions.def
+++ clang/include/clang/Basic/CodeGenOptions.def
@@ -266,6 +266,8 @@
CODEGENOPT(VectorizeSLP , 1, 0) ///< Run SLP vectorizer.
CODEGENOPT(ProfileSampleAccurate, 1, 0) ///< Sample profile is accurate.
+ENUM_CODEGENOPT(FiniteLoops, FiniteLoopsKind, 2, FiniteLoopsKind::None) /// finite-loops: none, yes, no
+
/// Attempt to use register sized accesses to bit-fields in structures, when
/// possible.
CODEGENOPT(UseRegisterSizedBitfieldAccess , 1, 0)
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits