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

Reply via email to