diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -5052,6 +5052,11 @@ def fno_automatic : Flag<["-"], "fno-automatic">, Group, HelpText<"Implies the SAVE attribute for non-automatic local objects in subprograms unless RECURSIVE">; +def floop_versioning : Flag<["-"], "floop-versioning">, Group, + HelpText<"Attempt to version loops">; +def fno_loop_versioning : Flag<["-"], "fno-loop-versioning">, Group, + HelpText<"Do not version loops (default)">; + } // let Flags = [FC1Option, FlangOption, FlangOnlyOption] def J : JoinedOrSeparate<["-"], "J">, diff --git a/clang/lib/Driver/ToolChains/Flang.cpp b/clang/lib/Driver/ToolChains/Flang.cpp --- a/clang/lib/Driver/ToolChains/Flang.cpp +++ b/clang/lib/Driver/ToolChains/Flang.cpp @@ -57,6 +57,12 @@ options::OPT_fintrinsic_modules_path, options::OPT_pedantic, options::OPT_std_EQ, options::OPT_W_Joined, options::OPT_fconvert_EQ, options::OPT_fpass_plugin_EQ}); + Arg *loopVersioning = + Args.getLastArg(options::OPT_Ofast, options::OPT_floop_versioning, + options::OPT_fno_loop_versioning); + if (loopVersioning && + !loopVersioning->getOption().matches(options::OPT_fno_loop_versioning)) + CmdArgs.push_back("-floop-versioning"); } void Flang::addPicOptions(const ArgList &Args, ArgStringList &CmdArgs) const { diff --git a/flang/include/flang/Frontend/CodeGenOptions.def b/flang/include/flang/Frontend/CodeGenOptions.def --- a/flang/include/flang/Frontend/CodeGenOptions.def +++ b/flang/include/flang/Frontend/CodeGenOptions.def @@ -24,6 +24,7 @@ CODEGENOPT(DebugPassManager, 1, 0) ///< Prints debug information for the new ///< pass manager. +CODEGENOPT(LoopVersioning, 1, 0) ///< PIC level of the LLVM module. CODEGENOPT(PICLevel, 2, 0) ///< PIC level of the LLVM module. CODEGENOPT(IsPIE, 1, 0) ///< PIE level is the same as PIC Level. diff --git a/flang/lib/Frontend/CompilerInvocation.cpp b/flang/lib/Frontend/CompilerInvocation.cpp --- a/flang/lib/Frontend/CompilerInvocation.cpp +++ b/flang/lib/Frontend/CompilerInvocation.cpp @@ -126,6 +126,11 @@ clang::driver::options::OPT_fno_debug_pass_manager, false)) opts.DebugPassManager = 1; + if (args.hasFlag(clang::driver::options::OPT_floop_versioning, + clang::driver::options::OPT_fno_loop_versioning, false)) { + opts.LoopVersioning = 1; + } + for (auto *a : args.filtered(clang::driver::options::OPT_fpass_plugin_EQ)) opts.LLVMPassPlugins.push_back(a->getValue()); diff --git a/flang/lib/Frontend/FrontendActions.cpp b/flang/lib/Frontend/FrontendActions.cpp --- a/flang/lib/Frontend/FrontendActions.cpp +++ b/flang/lib/Frontend/FrontendActions.cpp @@ -541,7 +541,7 @@ pm.enableVerifier(/*verifyPasses=*/true); // Create the pass pipeline - fir::createMLIRToLLVMPassPipeline(pm, level); + fir::createMLIRToLLVMPassPipeline(pm, opts.LoopVersioning, level); mlir::applyPassManagerCLOptions(pm); // run the pass manager diff --git a/flang/tools/bbc/bbc.cpp b/flang/tools/bbc/bbc.cpp --- a/flang/tools/bbc/bbc.cpp +++ b/flang/tools/bbc/bbc.cpp @@ -273,7 +273,8 @@ pm.addPass(std::make_unique()); // Add O2 optimizer pass pipeline. - fir::createDefaultFIROptimizerPassPipeline(pm, llvm::OptimizationLevel::O2); + fir::createDefaultFIROptimizerPassPipeline(pm, false, + llvm::OptimizationLevel::O2); } if (mlir::succeeded(pm.run(mlirModule))) { diff --git a/flang/tools/tco/tco.cpp b/flang/tools/tco/tco.cpp --- a/flang/tools/tco/tco.cpp +++ b/flang/tools/tco/tco.cpp @@ -122,7 +122,7 @@ fir::createDefaultFIRCodeGenPassPipeline(pm); } else { // Run tco with O2 by default. - fir::createMLIRToLLVMPassPipeline(pm, llvm::OptimizationLevel::O2); + fir::createMLIRToLLVMPassPipeline(pm, false, llvm::OptimizationLevel::O2); } fir::addLLVMDialectToLLVMPass(pm, out.os()); }