https://github.com/mcinally created https://github.com/llvm/llvm-project/pull/141380
This patch adds support for the -mprefer-vector-width=<value> command line option. The parsing of this options is equivalent to Clang's and it is implemented by setting the "prefer-vector-width" function attribute. >From 05221439896aabdcadf79d15ae6875dc34f10edd Mon Sep 17 00:00:00 2001 From: Cameron McInally <cmcina...@nvidia.com> Date: Sat, 24 May 2025 13:35:13 -0700 Subject: [PATCH] [flang] Add support for -mprefer-vector-width=<value> This patch adds support for the -mprefer-vector-width=<value> command line option. The parsing of this options is equivalent to Clang's and it is implemented by setting the "prefer-vector-width" function attribute. --- clang/include/clang/Driver/Options.td | 2 +- flang/include/flang/Frontend/CodeGenOptions.h | 3 +++ .../include/flang/Optimizer/Transforms/Passes.td | 4 ++++ flang/include/flang/Tools/CrossToolHelpers.h | 3 +++ flang/lib/Frontend/CompilerInvocation.cpp | 14 ++++++++++++++ flang/lib/Frontend/FrontendActions.cpp | 2 ++ flang/lib/Optimizer/Passes/Pipelines.cpp | 2 +- flang/lib/Optimizer/Transforms/FunctionAttr.cpp | 5 +++++ flang/test/Driver/prefer-vector-width.f90 | 16 ++++++++++++++++ mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td | 1 + mlir/lib/Target/LLVMIR/ModuleImport.cpp | 4 ++++ mlir/lib/Target/LLVMIR/ModuleTranslation.cpp | 3 +++ 12 files changed, 57 insertions(+), 2 deletions(-) create mode 100644 flang/test/Driver/prefer-vector-width.f90 diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 22261621df092..b0b642796010b 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -5480,7 +5480,7 @@ def mrecip_EQ : CommaJoined<["-"], "mrecip=">, Group<m_Group>, "<value> = ( ['!'] ['vec-'] ('rcp'|'sqrt') [('h'|'s'|'d')] [':'<n>] ) | 'all' | 'default' | 'none'">, MarshallingInfoStringVector<CodeGenOpts<"Reciprocals">>; def mprefer_vector_width_EQ : Joined<["-"], "mprefer-vector-width=">, Group<m_Group>, - Visibility<[ClangOption, CC1Option]>, + Visibility<[ClangOption, CC1Option, FlangOption, FC1Option]>, HelpText<"Specifies preferred vector width for auto-vectorization. Defaults to 'none' which allows target specific decisions.">, MarshallingInfoString<CodeGenOpts<"PreferVectorWidth">>; def mstack_protector_guard_EQ : Joined<["-"], "mstack-protector-guard=">, Group<m_Group>, diff --git a/flang/include/flang/Frontend/CodeGenOptions.h b/flang/include/flang/Frontend/CodeGenOptions.h index 2b4e823b3fef4..61e56e51c4bbb 100644 --- a/flang/include/flang/Frontend/CodeGenOptions.h +++ b/flang/include/flang/Frontend/CodeGenOptions.h @@ -53,6 +53,9 @@ class CodeGenOptions : public CodeGenOptionsBase { /// The paths to the pass plugins that were registered using -fpass-plugin. std::vector<std::string> LLVMPassPlugins; + // The prefered vector width, if requested by -mprefer-vector-width. + std::string PreferVectorWidth; + /// List of filenames passed in using the -fembed-offload-object option. These /// are offloading binaries containing device images and metadata. std::vector<std::string> OffloadObjects; diff --git a/flang/include/flang/Optimizer/Transforms/Passes.td b/flang/include/flang/Optimizer/Transforms/Passes.td index b251534e1a8f6..2e932d9ad4a26 100644 --- a/flang/include/flang/Optimizer/Transforms/Passes.td +++ b/flang/include/flang/Optimizer/Transforms/Passes.td @@ -418,6 +418,10 @@ def FunctionAttr : Pass<"function-attr", "mlir::func::FuncOp"> { "module.">, Option<"unsafeFPMath", "unsafe-fp-math", "bool", /*default=*/"false", "Set the unsafe-fp-math attribute on functions in the module.">, + Option<"preferVectorWidth", "prefer-vector-width", "std::string", + /*default=*/"", + "Set the prefer-vector-width attribute on functions in the " + "module.">, Option<"tuneCPU", "tune-cpu", "std::string", /*default=*/"", "Set the tune-cpu attribute on functions in the module.">, ]; diff --git a/flang/include/flang/Tools/CrossToolHelpers.h b/flang/include/flang/Tools/CrossToolHelpers.h index 118695bbe2626..058024a4a04c5 100644 --- a/flang/include/flang/Tools/CrossToolHelpers.h +++ b/flang/include/flang/Tools/CrossToolHelpers.h @@ -102,6 +102,7 @@ struct MLIRToLLVMPassPipelineConfig : public FlangEPCallBacks { UnsafeFPMath = mathOpts.getAssociativeMath() && mathOpts.getReciprocalMath() && NoSignedZerosFPMath && ApproxFuncFPMath && mathOpts.getFPContractEnabled(); + PreferVectorWidth = opts.PreferVectorWidth; if (opts.InstrumentFunctions) { InstrumentFunctionEntry = "__cyg_profile_func_enter"; InstrumentFunctionExit = "__cyg_profile_func_exit"; @@ -126,6 +127,8 @@ struct MLIRToLLVMPassPipelineConfig : public FlangEPCallBacks { bool NoSignedZerosFPMath = false; ///< Set no-signed-zeros-fp-math attribute for functions. bool UnsafeFPMath = false; ///< Set unsafe-fp-math attribute for functions. + std::string PreferVectorWidth = ""; ///< Set prefer-vector-width attribute for + ///< functions. bool NSWOnLoopVarInc = true; ///< Add nsw flag to loop variable increments. bool EnableOpenMP = false; ///< Enable OpenMP lowering. std::string InstrumentFunctionEntry = diff --git a/flang/lib/Frontend/CompilerInvocation.cpp b/flang/lib/Frontend/CompilerInvocation.cpp index ba2531819ee5e..122eb56fa0599 100644 --- a/flang/lib/Frontend/CompilerInvocation.cpp +++ b/flang/lib/Frontend/CompilerInvocation.cpp @@ -309,6 +309,20 @@ static void parseCodeGenArgs(Fortran::frontend::CodeGenOptions &opts, for (auto *a : args.filtered(clang::driver::options::OPT_fpass_plugin_EQ)) opts.LLVMPassPlugins.push_back(a->getValue()); + // -mprefer_vector_width option + if (const llvm::opt::Arg *a = + args.getLastArg(clang::driver::options::OPT_mprefer_vector_width_EQ)) { + llvm::StringRef s = a->getValue(); + unsigned Width; + if (s == "none") + opts.PreferVectorWidth = "none"; + else if (s.getAsInteger(10, Width)) + diags.Report(clang::diag::err_drv_invalid_value) + << a->getAsString(args) << a->getValue(); + else + opts.PreferVectorWidth = s.str(); + } + // -fembed-offload-object option for (auto *a : args.filtered(clang::driver::options::OPT_fembed_offload_object_EQ)) diff --git a/flang/lib/Frontend/FrontendActions.cpp b/flang/lib/Frontend/FrontendActions.cpp index 38dfaadf1dff9..012d0fdfe645f 100644 --- a/flang/lib/Frontend/FrontendActions.cpp +++ b/flang/lib/Frontend/FrontendActions.cpp @@ -741,6 +741,8 @@ void CodeGenAction::generateLLVMIR() { config.VScaleMax = vsr->second; } + config.PreferVectorWidth = opts.PreferVectorWidth; + if (ci.getInvocation().getFrontendOpts().features.IsEnabled( Fortran::common::LanguageFeature::OpenMP)) config.EnableOpenMP = true; diff --git a/flang/lib/Optimizer/Passes/Pipelines.cpp b/flang/lib/Optimizer/Passes/Pipelines.cpp index 77751908e35be..5c1e1b9f77efb 100644 --- a/flang/lib/Optimizer/Passes/Pipelines.cpp +++ b/flang/lib/Optimizer/Passes/Pipelines.cpp @@ -354,7 +354,7 @@ void createDefaultFIRCodeGenPassPipeline(mlir::PassManager &pm, {framePointerKind, config.InstrumentFunctionEntry, config.InstrumentFunctionExit, config.NoInfsFPMath, config.NoNaNsFPMath, config.ApproxFuncFPMath, config.NoSignedZerosFPMath, config.UnsafeFPMath, - ""})); + config.PreferVectorWidth, ""})); if (config.EnableOpenMP) { pm.addNestedPass<mlir::func::FuncOp>( diff --git a/flang/lib/Optimizer/Transforms/FunctionAttr.cpp b/flang/lib/Optimizer/Transforms/FunctionAttr.cpp index 43e4c1a7af3cd..13f447cf738b4 100644 --- a/flang/lib/Optimizer/Transforms/FunctionAttr.cpp +++ b/flang/lib/Optimizer/Transforms/FunctionAttr.cpp @@ -36,6 +36,7 @@ class FunctionAttrPass : public fir::impl::FunctionAttrBase<FunctionAttrPass> { approxFuncFPMath = options.approxFuncFPMath; noSignedZerosFPMath = options.noSignedZerosFPMath; unsafeFPMath = options.unsafeFPMath; + preferVectorWidth = options.preferVectorWidth; } FunctionAttrPass() {} void runOnOperation() override; @@ -102,6 +103,10 @@ void FunctionAttrPass::runOnOperation() { func->setAttr( mlir::LLVM::LLVMFuncOp::getUnsafeFpMathAttrName(llvmFuncOpName), mlir::BoolAttr::get(context, true)); + if (!preferVectorWidth.empty()) + func->setAttr( + mlir::LLVM::LLVMFuncOp::getPreferVectorWidthAttrName(llvmFuncOpName), + mlir::StringAttr::get(context, preferVectorWidth)); LLVM_DEBUG(llvm::dbgs() << "=== End " DEBUG_TYPE " ===\n"); } diff --git a/flang/test/Driver/prefer-vector-width.f90 b/flang/test/Driver/prefer-vector-width.f90 new file mode 100644 index 0000000000000..d0f5fd28db826 --- /dev/null +++ b/flang/test/Driver/prefer-vector-width.f90 @@ -0,0 +1,16 @@ +! Test that -mprefer-vector-width works as expected. + +! RUN: %flang_fc1 -emit-llvm -o - %s 2>&1| FileCheck %s --check-prefix=CHECK-DEF +! RUN: %flang_fc1 -mprefer-vector-width=none -emit-llvm -o - %s 2>&1| FileCheck %s --check-prefix=CHECK-NONE +! RUN: %flang_fc1 -mprefer-vector-width=128 -emit-llvm -o - %s 2>&1| FileCheck %s --check-prefix=CHECK-128 +! RUN: %flang_fc1 -mprefer-vector-width=256 -emit-llvm -o - %s 2>&1| FileCheck %s --check-prefix=CHECK-256 +! RUN: not %flang_fc1 -mprefer-vector-width=xxx -emit-llvm -o - %s 2>&1| FileCheck %s --check-prefix=CHECK-INVALID + +subroutine func +end subroutine func + +! CHECK-DEF-NOT: attributes #0 = { "prefer-vector-width"={{.*}} } +! CHECK-NONE: attributes #0 = { "prefer-vector-width"="none" } +! CHECK-128: attributes #0 = { "prefer-vector-width"="128" } +! CHECK-256: attributes #0 = { "prefer-vector-width"="256" } +! CHECK-INVALID:error: invalid value 'xxx' in '-mprefer-vector-width=xxx' diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td index 6fde45ce5c556..c0324d561b77b 100644 --- a/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td +++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td @@ -1893,6 +1893,7 @@ def LLVM_LLVMFuncOp : LLVM_Op<"func", [ OptionalAttr<FramePointerKindAttr>:$frame_pointer, OptionalAttr<StrAttr>:$target_cpu, OptionalAttr<StrAttr>:$tune_cpu, + OptionalAttr<StrAttr>:$prefer_vector_width, OptionalAttr<LLVM_TargetFeaturesAttr>:$target_features, OptionalAttr<BoolAttr>:$unsafe_fp_math, OptionalAttr<BoolAttr>:$no_infs_fp_math, diff --git a/mlir/lib/Target/LLVMIR/ModuleImport.cpp b/mlir/lib/Target/LLVMIR/ModuleImport.cpp index b049064fbd31c..85417da798b22 100644 --- a/mlir/lib/Target/LLVMIR/ModuleImport.cpp +++ b/mlir/lib/Target/LLVMIR/ModuleImport.cpp @@ -2636,6 +2636,10 @@ void ModuleImport::processFunctionAttributes(llvm::Function *func, funcOp.setTargetFeaturesAttr( LLVM::TargetFeaturesAttr::get(context, attr.getValueAsString())); + if (llvm::Attribute attr = func->getFnAttribute("prefer-vector-width"); + attr.isStringAttribute()) + funcOp.setPreferVectorWidth(attr.getValueAsString()); + if (llvm::Attribute attr = func->getFnAttribute("unsafe-fp-math"); attr.isStringAttribute()) funcOp.setUnsafeFpMath(attr.getValueAsBool()); diff --git a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp index 047e870b7dcd8..2b7f0b11613aa 100644 --- a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp +++ b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp @@ -1540,6 +1540,9 @@ LogicalResult ModuleTranslation::convertOneFunction(LLVMFuncOp func) { if (auto tuneCpu = func.getTuneCpu()) llvmFunc->addFnAttr("tune-cpu", *tuneCpu); + if (auto preferVectorWidth = func.getPreferVectorWidth()) + llvmFunc->addFnAttr("prefer-vector-width", *preferVectorWidth); + if (auto attr = func.getVscaleRange()) llvmFunc->addFnAttr(llvm::Attribute::getWithVScaleRangeArgs( getLLVMContext(), attr->getMinRange().getInt(), _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits