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 cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits