[flang-commits] [flang] 9914ee6 - [flang] Fix -debug crash from VScaleAttrPass (#180234)

via flang-commits flang-commits at lists.llvm.org
Tue Feb 10 02:46:10 PST 2026


Author: Philipp Rados
Date: 2026-02-10T11:46:06+01:00
New Revision: 9914ee6ef4b78d62055734290afe879a7ae1a036

URL: https://github.com/llvm/llvm-project/commit/9914ee6ef4b78d62055734290afe879a7ae1a036
DIFF: https://github.com/llvm/llvm-project/commit/9914ee6ef4b78d62055734290afe879a7ae1a036.diff

LOG: [flang] Fix -debug crash from VScaleAttrPass (#180234)

This pass splits up the `vscaleRange` pass-option from the
`VScaleAttrPass` into `vscaleMin` and `vscaleMax` respectively, since a
`std::pair<>` cannot be used as a cli-option and crashes when running
`flang -march=rv64gcv -O3 file.f90 -mmlir -debug`.

Since the options can now be set individually I added some error
checking following the semantics described in the langref
https://llvm.org/docs/LangRef.html#function-attributes.

I also added tests since there were none for only this pass before.

Added: 
    flang/test/Transforms/vscale-attr.fir

Modified: 
    flang/include/flang/Optimizer/Transforms/Passes.td
    flang/lib/Optimizer/Passes/Pipelines.cpp
    flang/lib/Optimizer/Transforms/VScaleAttr.cpp

Removed: 
    


################################################################################
diff  --git a/flang/include/flang/Optimizer/Transforms/Passes.td b/flang/include/flang/Optimizer/Transforms/Passes.td
index 090a1ce24fd8b..e96476a9b6bde 100644
--- a/flang/include/flang/Optimizer/Transforms/Passes.td
+++ b/flang/include/flang/Optimizer/Transforms/Passes.td
@@ -399,10 +399,10 @@ def VScaleAttr : Pass<"vscale-attr", "mlir::func::FuncOp"> {
      Set an attribute for the vscale range on functions, to allow scalable
      vector operations to be used on processors with variable vector length.
   }];
-  let options = [
-    Option<"vscaleRange", "vscale-range",
-           "std::pair<unsigned, unsigned>", /*default=*/"std::pair<unsigned, unsigned>{}",
-           "vector scale range">,
+  let options = [Option<"vscaleMin", "vscale-min", "unsigned", /*default=*/"1",
+                        "vector scale minimum value. Defaults to \"1\"">,
+                 Option<"vscaleMax", "vscale-max", "unsigned", /*default=*/"0",
+                        "vector scale maximum value. Defaults to \"0\"">,
   ];
 }
 

diff  --git a/flang/lib/Optimizer/Passes/Pipelines.cpp b/flang/lib/Optimizer/Passes/Pipelines.cpp
index f15b0fe20bd9b..d84006fd215dd 100644
--- a/flang/lib/Optimizer/Passes/Pipelines.cpp
+++ b/flang/lib/Optimizer/Passes/Pipelines.cpp
@@ -384,7 +384,7 @@ void createDefaultFIRCodeGenPassPipeline(mlir::PassManager &pm,
   fir::addCompilerGeneratedNamesConversionPass(pm);
 
   if (config.VScaleMin != 0)
-    pm.addPass(fir::createVScaleAttr({{config.VScaleMin, config.VScaleMax}}));
+    pm.addPass(fir::createVScaleAttr({config.VScaleMin, config.VScaleMax}));
 
   // Add function attributes
   mlir::LLVM::framePointerKind::FramePointerKind framePointerKind;

diff  --git a/flang/lib/Optimizer/Transforms/VScaleAttr.cpp b/flang/lib/Optimizer/Transforms/VScaleAttr.cpp
index 54a2456e77366..d0e83effbbc45 100644
--- a/flang/lib/Optimizer/Transforms/VScaleAttr.cpp
+++ b/flang/lib/Optimizer/Transforms/VScaleAttr.cpp
@@ -33,9 +33,11 @@
 #include "mlir/Transforms/GreedyPatternRewriteDriver.h"
 #include "mlir/Transforms/RegionUtils.h"
 #include "llvm/Support/Debug.h"
+#include "llvm/Support/MathExtras.h"
 #include "llvm/Support/raw_ostream.h"
 
 #include <algorithm>
+#include <mlir/IR/Diagnostics.h>
 
 namespace fir {
 #define GEN_PASS_DEF_VSCALEATTR
@@ -49,7 +51,8 @@ namespace {
 class VScaleAttrPass : public fir::impl::VScaleAttrBase<VScaleAttrPass> {
 public:
   VScaleAttrPass(const fir::VScaleAttrOptions &options) {
-    vscaleRange = options.vscaleRange;
+    vscaleMin = options.vscaleMin;
+    vscaleMax = options.vscaleMax;
   }
   VScaleAttrPass() {}
   void runOnOperation() override;
@@ -63,16 +66,28 @@ void VScaleAttrPass::runOnOperation() {
 
   LLVM_DEBUG(llvm::dbgs() << "Func-name:" << func.getSymName() << "\n");
 
+  if (!llvm::isPowerOf2_32(vscaleMin)) {
+    func->emitError(
+        "VScaleAttr: vscaleMin has to be a power-of-two greater than 0\n");
+    return signalPassFailure();
+  }
+
+  if (vscaleMax != 0 &&
+      (!llvm::isPowerOf2_32(vscaleMax) || (vscaleMin > vscaleMax))) {
+    func->emitError("VScaleAttr: vscaleMax has to be a power-of-two "
+                    "greater-than-or-equal to vscaleMin or 0 to signify "
+                    "an unbounded maximum\n");
+    return signalPassFailure();
+  }
+
   auto context = &getContext();
 
   auto intTy = mlir::IntegerType::get(context, 32);
 
-  assert(vscaleRange.first && "VScaleRange minimum should be non-zero");
-
   func->setAttr("vscale_range",
                 mlir::LLVM::VScaleRangeAttr::get(
-                    context, mlir::IntegerAttr::get(intTy, vscaleRange.first),
-                    mlir::IntegerAttr::get(intTy, vscaleRange.second)));
+                    context, mlir::IntegerAttr::get(intTy, vscaleMin),
+                    mlir::IntegerAttr::get(intTy, vscaleMax)));
 
   LLVM_DEBUG(llvm::dbgs() << "=== End " DEBUG_TYPE " ===\n");
 }

diff  --git a/flang/test/Transforms/vscale-attr.fir b/flang/test/Transforms/vscale-attr.fir
new file mode 100644
index 0000000000000..52b6bbba7c9c9
--- /dev/null
+++ b/flang/test/Transforms/vscale-attr.fir
@@ -0,0 +1,24 @@
+// RUN: fir-opt --vscale-attr %s | FileCheck %s --check-prefix=CHECK-DEFAULT
+// RUN: fir-opt --vscale-attr="vscale-min=4" %s | FileCheck %s --check-prefix=CHECK-MIN
+// RUN: fir-opt --vscale-attr="vscale-max=16" %s | FileCheck %s --check-prefix=CHECK-MAX
+// RUN: fir-opt --vscale-attr="vscale-min=8 vscale-max=16" %s | FileCheck %s --check-prefix=CHECK-BOTH
+// RUN: fir-opt --vscale-attr="vscale-min=8 vscale-max=8" %s | FileCheck %s --check-prefix=CHECK-EQUAL
+// RUN: not fir-opt --vscale-attr="vscale-min=0 vscale-max=4" %s 2>&1 | FileCheck %s --check-prefix=VSCALE-MIN-0
+// RUN: not fir-opt --vscale-attr="vscale-min=3 vscale-max=4" %s 2>&1 | FileCheck %s --check-prefix=VSCALE-MIN-NO-PO2
+// RUN: not fir-opt --vscale-attr="vscale-max=6" %s 2>&1 | FileCheck %s --check-prefix=VSCALE-MAX-NO-PO2
+// RUN: not fir-opt --vscale-attr="vscale-min=16 vscale-max=8" %s 2>&1 | FileCheck %s --check-prefix=VSCALE-MIN-GREATER
+
+
+// CHECK-DEFAULT: attributes {vscale_range = #llvm.vscale_range<minRange = 1 : i32, maxRange = 0 : i32>}
+// CHECK-MIN: attributes {vscale_range = #llvm.vscale_range<minRange = 4 : i32, maxRange = 0 : i32>}
+// CHECK-MAX: attributes {vscale_range = #llvm.vscale_range<minRange = 1 : i32, maxRange = 16 : i32>}
+// CHECK-BOTH: attributes {vscale_range = #llvm.vscale_range<minRange = 8 : i32, maxRange = 16 : i32>}
+// CHECK-EQUAL: attributes {vscale_range = #llvm.vscale_range<minRange = 8 : i32, maxRange = 8 : i32>}
+
+// VSCALE-MIN-0:      VScaleAttr: vscaleMin has to be a power-of-two greater than 0
+// VSCALE-MIN-NO-PO2: VScaleAttr: vscaleMin has to be a power-of-two greater than 0
+// VSCALE-MAX-NO-PO2: VScaleAttr: vscaleMax has to be a power-of-two greater-than-or-equal to vscaleMin or 0 to signify an unbounded maximum
+// VSCALE-MIN-GREATER: VScaleAttr: vscaleMax has to be a power-of-two greater-than-or-equal to vscaleMin or 0 to signify an unbounded maximum
+func.func @_QPtest(%arg0: !fir.ref<i32> {fir.bindc_name = "x"}) {
+  return
+}


        


More information about the flang-commits mailing list