atmnpatel updated this revision to Diff 315641.
atmnpatel added a comment.
Update CommandLineReference.rst to also include `-fno-finite-loops`
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D94367/new/
https://reviews.llvm.org/D94367
Files:
clang/docs/ClangCommandLineReference.rst
clang/include/clang/Basic/CodeGenOptions.def
clang/include/clang/Basic/CodeGenOptions.h
clang/include/clang/Driver/Options.td
clang/lib/CodeGen/CGStmt.cpp
clang/lib/Driver/ToolChains/Clang.cpp
clang/lib/Frontend/CompilerInvocation.cpp
clang/test/CodeGen/finite-loops.c
clang/test/CodeGenCXX/finite-loops.cpp
clang/test/Driver/clang_f_opts.c
Index: clang/test/Driver/clang_f_opts.c
===================================================================
--- clang/test/Driver/clang_f_opts.c
+++ clang/test/Driver/clang_f_opts.c
@@ -52,6 +52,15 @@
// CHECK-REROLL-LOOPS: "-freroll-loops"
// CHECK-NO-REROLL-LOOPS-NOT: "-freroll-loops"
+// RUN: %clang -### -S -ffinite-loops %s 2>&1 | FileCheck -check-prefix=CHECK-FINITE-LOOPS %s
+// RUN: %clang -### -S -fno-finite-loops %s 2>&1 | FileCheck -check-prefix=CHECK-NO-FINITE-LOOPS %s
+// RUN: %clang -### -S -fno-finite-loops -ffinite-loops %s 2>&1 | FileCheck -check-prefix=CHECK-FINITE-LOOPS %s
+// RUN: %clang -### -S -ffinite-loops -fno-finite-loops %s 2>&1 | FileCheck -check-prefix=CHECK-NO-FINITE-LOOPS %s
+// CHECK-FINITE-LOOPS: "-ffinite-loops"
+// CHECK-FINITE-LOOPS-NOT: "-fno-finite-loops"
+// CHECK-NO-FINITE-LOOPS: "-fno-finite-loops"
+// CHECK-NO-FINITE-LOOPS-NOT: "-ffinite-loops"
+
// RUN: %clang -### -S -fprofile-sample-accurate %s 2>&1 | FileCheck -check-prefix=CHECK-PROFILE-SAMPLE-ACCURATE %s
// CHECK-PROFILE-SAMPLE-ACCURATE: "-fprofile-sample-accurate"
@@ -292,6 +301,7 @@
// RUN: -malign-functions=100 \
// RUN: -malign-loops=100 \
// RUN: -malign-jumps=100 \
+// RUN: -ffinite-loops -fno-finite-loops \
// RUN: %s 2>&1 | FileCheck --check-prefix=IGNORE %s
// IGNORE-NOT: error: unknown argument
Index: clang/test/CodeGenCXX/finite-loops.cpp
===================================================================
--- /dev/null
+++ clang/test/CodeGenCXX/finite-loops.cpp
@@ -0,0 +1,99 @@
+// RUN: %clang_cc1 -triple x86_64 -S -emit-llvm -std=c++03 -o - %s | FileCheck %s -check-prefix=CHECK-CPP03-LOOPS
+// RUN: %clang_cc1 -triple x86_64 -S -emit-llvm -std=c++03 -ffinite-loops -o - %s | FileCheck %s -check-prefix=CHECK-FINITE-LOOPS
+// RUN: %clang_cc1 -triple x86_64 -S -emit-llvm -std=c++03 -fno-finite-loops -o - %s | FileCheck %s -check-prefix=CHECK-INFINITE-LOOPS
+// RUN: %clang_cc1 -triple x86_64 -S -emit-llvm -std=c++11 -o - %s | FileCheck %s -check-prefix=CHECK-CPP11-LOOPS
+// RUN: %clang_cc1 -triple x86_64 -S -emit-llvm -std=c++11 -ffinite-loops -o - %s | FileCheck %s -check-prefix=CHECK-FINITE-LOOPS
+// RUN: %clang_cc1 -triple x86_64 -S -emit-llvm -std=c++11 -fno-finite-loops -o - %s | FileCheck %s -check-prefix=CHECK-INFINITE-LOOPS
+
+// CHECK-CPP03-LOOPS: Function Attrs: noinline nounwind optnone
+// CHECK-CPP03-LOOPS-LABEL: @_Z1fii(
+// CHECK-CPP03-LOOPS-NOT: {{.*}} !llvm.loop !
+//
+// CHECK-FINITE-LOOPS: Function Attrs: noinline nounwind optnone mustprogress
+// CHECK-FINITE-LOOPS-LABEL: @_Z1fii(
+// CHECK-FINITE-LOOPS: {{.*}} !llvm.loop !
+// CHECK-FINITE-LOOPS: {{.*}} !llvm.loop !
+//
+// CHECK-INFINITE-LOOPS: Function Attrs: noinline nounwind optnone
+// CHECK-INFINITE-LOOPS-LABEL: @_Z1fii(
+// CHECK-INFINITE-LOOPS-NOT: {{.*}} !llvm.loop !
+//
+// CHECK-CPP11-LOOPS: Function Attrs: noinline nounwind optnone
+// CHECK-CPP11-LOOPS-LABEL: @_Z1fii(
+// CHECK-CPP11-LOOPS: {{.*}} !llvm.loop !
+// CHECK-CPP11-LOOPS: {{.*}} !llvm.loop !
+//
+int f(int a, int b) {
+ for (; a != b; ) {
+ if (a == b)
+ return 1;
+ }
+
+ for (;;) {
+ if (a != b)
+ return 1;
+ }
+ return 0;
+}
+
+// CHECK-CPP03-LOOPS: Function Attrs: noinline nounwind optnone
+// CHECK-CPP03-LOOPS-LABEL: @_Z2dwii(
+// CHECK-CPP03-LOOPS-NOT: {{.*}} !llvm.loop !
+//
+// CHECK-FINITE-LOOPS: Function Attrs: noinline nounwind optnone mustprogress
+// CHECK-FINITE-LOOPS-LABEL: @_Z2dwii(
+// CHECK-FINITE-LOOPS: {{.*}} !llvm.loop !
+// CHECK-FINITE-LOOPS: {{.*}} !llvm.loop !
+//
+// CHECK-INFINITE-LOOPS: Function Attrs: noinline nounwind optnone
+// CHECK-INFINITE-LOOPS-LABEL: @_Z2dwii(
+// CHECK-INFINITE-LOOPS-NOT: {{.*}} !llvm.loop !
+//
+// CHECK-CPP11-LOOPS: Function Attrs: noinline nounwind optnone
+// CHECK-CPP11-LOOPS-LABEL: @_Z2dwii(
+// CHECK-CPP11-LOOPS: {{.*}} !llvm.loop !
+// CHECK-CPP11-LOOPS: {{.*}} !llvm.loop !
+//
+int dw(int a, int b) {
+ do {
+ if (a == b)
+ return 1;
+ } while (a != b);
+
+ do {
+ if (a != b)
+ return 1;
+ } while (1);
+ return 0;
+}
+
+// CHECK-CPP03-LOOPS: Function Attrs: noinline nounwind optnone
+// CHECK-CPP03-LOOPS-LABEL: @_Z1wii(
+// CHECK-CPP03-LOOPS-NOT: {{.*}} !llvm.loop !
+//
+// CHECK-FINITE-LOOPS: Function Attrs: noinline nounwind optnone mustprogress
+// CHECK-FINITE-LOOPS-LABEL: @_Z1wii(
+// CHECK-FINITE-LOOPS: {{.*}} !llvm.loop !
+// CHECK-FINITE-LOOPS: {{.*}} !llvm.loop !
+//
+// CHECK-INFINITE-LOOPS: Function Attrs: noinline nounwind optnone
+// CHECK-INFINITE-LOOPS-LABEL: @_Z1wii(
+// CHECK-INFINITE-LOOPS-NOT: {{.*}} !llvm.loop !
+//
+// CHECK-CPP11-LOOPS: Function Attrs: noinline nounwind optnone
+// CHECK-CPP11-LOOPS-LABEL: @_Z1wii(
+// CHECK-CPP11-LOOPS: {{.*}} !llvm.loop !
+// CHECK-CPP11-LOOPS: {{.*}} !llvm.loop !
+//
+int w(int a, int b) {
+ while(a != b) {
+ if (a == b) return 2;
+ }
+
+ while(1) {
+ if (a != b)
+ return 1;
+ }
+ return 0;
+}
+
Index: clang/test/CodeGen/finite-loops.c
===================================================================
--- /dev/null
+++ clang/test/CodeGen/finite-loops.c
@@ -0,0 +1,99 @@
+// RUN: %clang_cc1 -triple x86_64 -S -emit-llvm -std=c99 -o - %s | FileCheck %s -check-prefix=CHECK-C99-LOOPS
+// RUN: %clang_cc1 -triple x86_64 -S -emit-llvm -std=c99 -ffinite-loops -o - %s | FileCheck %s -check-prefix=CHECK-FINITE-LOOPS
+// RUN: %clang_cc1 -triple x86_64 -S -emit-llvm -std=c99 -fno-finite-loops -o - %s | FileCheck %s -check-prefix=CHECK-INFINITE-LOOPS
+// RUN: %clang_cc1 -triple x86_64 -S -emit-llvm -std=c11 -o - %s | FileCheck %s -check-prefix=CHECK-C11-LOOPS
+// RUN: %clang_cc1 -triple x86_64 -S -emit-llvm -std=c11 -ffinite-loops -o - %s | FileCheck %s -check-prefix=CHECK-FINITE-LOOPS
+// RUN: %clang_cc1 -triple x86_64 -S -emit-llvm -std=c11 -fno-finite-loops -o - %s | FileCheck %s -check-prefix=CHECK-INFINITE-LOOPS
+
+// CHECK-C99-LOOPS: Function Attrs: noinline nounwind optnone
+// CHECK-C99-LOOPS-LABEL: @f(
+// CHECK-C99-LOOPS-NOT: {{.}} !llvm.loop !
+//
+// CHECK-FINITE-LOOPS: Function Attrs: noinline nounwind optnone mustprogress
+// CHECK-FINITE-LOOPS-LABEL: @f(
+// CHECK-FINITE-LOOPS: {{.}} !llvm.loop !
+// CHECK-FINITE-LOOPS: {{.}} !llvm.loop !
+//
+// CHECK-INFINITE-LOOPS: Function Attrs: noinline nounwind optnone
+// CHECK-INFINITE-LOOPS-LABEL: @f(
+// CHECK-INFINITE-LOOPS-NOT: {{.}} !llvm.loop !
+//
+// CHECK-C11-LOOPS: Function Attrs: noinline nounwind optnone
+// CHECK-C11-LOOPS-LABEL: @f(
+// CHECK-C11-LOOPS: {{.}} !llvm.loop !
+// CHECK-C11-LOOPS-NOT: {{.}} !llvm.loop !
+//
+int f(int a, int b) {
+ for (; a != b; ) {
+ if (a == b)
+ return 1;
+ }
+
+ for (;;) {
+ if (a != b)
+ return 1;
+ }
+ return 0;
+}
+
+// CHECK-C99-LOOPS: Function Attrs: noinline nounwind optnone
+// CHECK-C99-LOOPS-LABEL: @dw(
+// CHECK-C99-LOOPS-NOT: {{.}} !llvm.loop !
+//
+// CHECK-FINITE-LOOPS: Function Attrs: noinline nounwind optnone mustprogress
+// CHECK-FINITE-LOOPS-LABEL: @dw(
+// CHECK-FINITE-LOOPS: {{.}} !llvm.loop !
+// CHECK-FINITE-LOOPS: {{.}} !llvm.loop !
+//
+// CHECK-INFINITE-LOOPS: Function Attrs: noinline nounwind optnone
+// CHECK-INFINITE-LOOPS-LABEL: @dw(
+// CHECK-INFINITE-LOOPS-NOT: {{.}} !llvm.loop !
+//
+// CHECK-C11-LOOPS: Function Attrs: noinline nounwind optnone
+// CHECK-C11-LOOPS-LABEL: @dw(
+// CHECK-C11-LOOPS: {{.}} !llvm.loop !
+// CHECK-C11-LOOPS-NOT: {{.}} !llvm.loop !
+//
+int dw(int a, int b) {
+ do {
+ if (a == b)
+ return 1;
+ } while (a != b);
+
+ do {
+ if (a != b)
+ return 1;
+ } while (1);
+ return 0;
+}
+
+// CHECK-C99-LOOPS: Function Attrs: noinline nounwind optnone
+// CHECK-C99-LOOPS-LABEL: @w(
+// CHECK-C99-LOOPS-NOT: {{.}} !llvm.loop !
+//
+// CHECK-FINITE-LOOPS: Function Attrs: noinline nounwind optnone mustprogress
+// CHECK-FINITE-LOOPS-LABEL: @w(
+// CHECK-FINITE-LOOPS: {{.}} !llvm.loop !
+// CHECK-FINITE-LOOPS: {{.}} !llvm.loop !
+//
+// CHECK-INFINITE-LOOPS: Function Attrs: noinline nounwind optnone
+// CHECK-INFINITE-LOOPS-LABEL: @w(
+// CHECK-INFINITE-LOOPS-NOT: {{.}} !llvm.loop !
+//
+// CHECK-C11-LOOPS: Function Attrs: noinline nounwind optnone
+// CHECK-C11-LOOPS-LABEL: @w(
+// CHECK-C11-LOOPS: {{.}} !llvm.loop !
+// CHECK-C11-LOOPS-NOT: {{.}} !llvm.loop !
+//
+int w(int a, int b) {
+ while(a != b) {
+ if (a == b) return 2;
+ }
+
+ while(1) {
+ if (a != b)
+ return 1;
+ }
+ return 0;
+}
+
Index: clang/lib/Frontend/CompilerInvocation.cpp
===================================================================
--- clang/lib/Frontend/CompilerInvocation.cpp
+++ clang/lib/Frontend/CompilerInvocation.cpp
@@ -981,6 +981,11 @@
Opts.UnrollLoops =
Args.hasFlag(OPT_funroll_loops, OPT_fno_unroll_loops,
(Opts.OptimizationLevel > 1));
+ Opts.FiniteLoops = Args.hasArg(OPT_ffinite_loops)
+ ? CodeGenOptions::FiniteLoopsKind::Enforce
+ : (Args.hasArg(OPT_fno_finite_loops)
+ ? CodeGenOptions::FiniteLoopsKind::NeverEnforce
+ : CodeGenOptions::FiniteLoopsKind::Default);
Opts.DebugNameTable = static_cast<unsigned>(
Args.hasArg(OPT_ggnu_pubnames)
Index: clang/lib/Driver/ToolChains/Clang.cpp
===================================================================
--- clang/lib/Driver/ToolChains/Clang.cpp
+++ clang/lib/Driver/ToolChains/Clang.cpp
@@ -5587,8 +5587,9 @@
Args.AddLastArg(CmdArgs, options::OPT_fwritable_strings);
Args.AddLastArg(CmdArgs, options::OPT_funroll_loops,
options::OPT_fno_unroll_loops);
-
Args.AddLastArg(CmdArgs, options::OPT_pthread);
+ Args.AddLastArg(CmdArgs, options::OPT_ffinite_loops,
+ options::OPT_fno_finite_loops);
if (Args.hasFlag(options::OPT_mspeculative_load_hardening,
options::OPT_mno_speculative_load_hardening, false))
Index: clang/lib/CodeGen/CGStmt.cpp
===================================================================
--- clang/lib/CodeGen/CGStmt.cpp
+++ clang/lib/CodeGen/CGStmt.cpp
@@ -804,6 +804,16 @@
} else if (LanguageRequiresProgress())
LoopMustProgress = true;
+ if (CGM.getCodeGenOpts().FiniteLoops ==
+ CodeGenOptions::FiniteLoopsKind::Enforce) {
+ FnIsMustProgress = true;
+ LoopMustProgress = true;
+ } else if (CGM.getCodeGenOpts().FiniteLoops ==
+ CodeGenOptions::FiniteLoopsKind::NeverEnforce) {
+ FnIsMustProgress = false;
+ LoopMustProgress = false;
+ }
+
const SourceRange &R = S.getSourceRange();
LoopStack.push(LoopHeader.getBlock(), CGM.getContext(), CGM.getCodeGenOpts(),
WhileAttrs, SourceLocToDebugLoc(R.getBegin()),
@@ -907,6 +917,16 @@
} else if (LanguageRequiresProgress())
LoopMustProgress = true;
+ if (CGM.getCodeGenOpts().FiniteLoops ==
+ CodeGenOptions::FiniteLoopsKind::Enforce) {
+ FnIsMustProgress = true;
+ LoopMustProgress = true;
+ } else if (CGM.getCodeGenOpts().FiniteLoops ==
+ CodeGenOptions::FiniteLoopsKind::NeverEnforce) {
+ FnIsMustProgress = false;
+ LoopMustProgress = false;
+ }
+
const SourceRange &R = S.getSourceRange();
LoopStack.push(LoopBody, CGM.getContext(), CGM.getCodeGenOpts(), DoAttrs,
SourceLocToDebugLoc(R.getBegin()),
@@ -959,6 +979,14 @@
LoopMustProgress = true;
}
+ if (CGM.getCodeGenOpts().FiniteLoops ==
+ CodeGenOptions::FiniteLoopsKind::Enforce) {
+ LoopMustProgress = true;
+ } else if (CGM.getCodeGenOpts().FiniteLoops ==
+ CodeGenOptions::FiniteLoopsKind::NeverEnforce) {
+ LoopMustProgress = false;
+ }
+
const SourceRange &R = S.getSourceRange();
LoopStack.push(CondBlock, CGM.getContext(), CGM.getCodeGenOpts(), ForAttrs,
SourceLocToDebugLoc(R.getBegin()),
@@ -1017,6 +1045,14 @@
}
incrementProfileCounter(&S);
+ if (CGM.getCodeGenOpts().FiniteLoops ==
+ CodeGenOptions::FiniteLoopsKind::Enforce) {
+ FnIsMustProgress = true;
+ } else if (CGM.getCodeGenOpts().FiniteLoops ==
+ CodeGenOptions::FiniteLoopsKind::NeverEnforce) {
+ FnIsMustProgress = false;
+ }
+
{
// Create a separate cleanup scope for the body, in case it is not
// a compound statement.
Index: clang/include/clang/Driver/Options.td
===================================================================
--- clang/include/clang/Driver/Options.td
+++ clang/include/clang/Driver/Options.td
@@ -2402,6 +2402,8 @@
defm reroll_loops : BoolFOption<"reroll-loops",
"CodeGenOpts.RerollLoops", DefaultsToFalse,
ChangedBy<PosFlag, [], "Turn on loop reroller">, ResetBy<NegFlag>>;
+def ffinite_loops : Flag<["-"], "ffinite-loops">, Group<f_Group>, HelpText<"Assume that loops terminate">, Flags<[CC1Option]>;
+def fno_finite_loops : Flag<["-"], "fno-finite-loops">, Group<f_Group>, HelpText<"Don't assume that loops terminate">, 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
@@ -134,6 +134,12 @@
All, // Keep all frame pointers.
};
+ enum FiniteLoopsKind {
+ Default, // Follow the language standard
+ Enforce, // Enforce finite loops
+ NeverEnforce, // Never enforce finite loops
+ };
+
/// 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
@@ -260,6 +260,7 @@
///< traced by time profiler
CODEGENOPT(UnrollLoops , 1, 0) ///< Control whether loops are unrolled.
CODEGENOPT(RerollLoops , 1, 0) ///< Control whether loops are rerolled.
+CODEGENOPT(FiniteLoops , 2, 0) ///< Control whether loops are assumed to terminate.
CODEGENOPT(NoUseJumpTables , 1, 0) ///< Set when -fno-jump-tables is enabled.
CODEGENOPT(UnwindTables , 1, 0) ///< Emit unwind tables.
CODEGENOPT(VectorizeLoop , 1, 0) ///< Run loop vectorizer.
Index: clang/docs/ClangCommandLineReference.rst
===================================================================
--- clang/docs/ClangCommandLineReference.rst
+++ clang/docs/ClangCommandLineReference.rst
@@ -2285,6 +2285,10 @@
Turn on loop unroller
+.. option:: -ffinite-loops, -fno-finite-loops
+
+Assume that all loops terminate or never assume that they do. This takes precedence over the language standard.
+
.. option:: -funsafe-math-optimizations, -fno-unsafe-math-optimizations
.. option:: -funsigned-bitfields
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits