[flang-commits] [flang] [Flang] Return APInt from getIntIfConstant (PR #211233)

via flang-commits flang-commits at lists.llvm.org
Wed Jul 22 04:07:48 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-flang-codegen

Author: Tom Eccles (tblah)

<details>
<summary>Changes</summary>

Preserve the full bit width of integer attributes when extracting constants from FIR values. Return llvm::APInt directly and update fixed-width consumers to use checked signed extraction.

This avoids truncating or asserting on constants wider than 64 bits while retaining existing fallback behavior at int64_t boundaries.

This should be NFC everywhere we didn't have a latent overflow bug. I didn't go so far as updating the interfaces of every function built on top of getIntIfConstant: this is mostly to make an APInt version available because it looks useful for another PR. Fixing the builder API to use APInt would be a larger change - let me know if anyone wants to see that.

Assisted-by: Codex

---

Patch is 28.02 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/211233.diff


19 Files Affected:

- (modified) flang/include/flang/Optimizer/Dialect/FIROpsSupport.h (+3-2) 
- (modified) flang/lib/Lower/ConvertExprToHLFIR.cpp (+5-3) 
- (modified) flang/lib/Lower/OpenMP/ClauseProcessor.cpp (+10-1) 
- (modified) flang/lib/Lower/OpenMP/OpenMP.cpp (+3-2) 
- (modified) flang/lib/Optimizer/Analysis/ArraySectionAnalyzer.cpp (+11-8) 
- (modified) flang/lib/Optimizer/Builder/Character.cpp (+2-1) 
- (modified) flang/lib/Optimizer/Builder/FIRBuilder.cpp (+1-1) 
- (modified) flang/lib/Optimizer/Builder/HLFIRTools.cpp (+9-5) 
- (modified) flang/lib/Optimizer/Builder/IntrinsicCall.cpp (+18-15) 
- (modified) flang/lib/Optimizer/CodeGen/CodeGen.cpp (+8-5) 
- (modified) flang/lib/Optimizer/Dialect/FIROps.cpp (+12-10) 
- (modified) flang/lib/Optimizer/HLFIR/IR/HLFIROps.cpp (+11-3) 
- (modified) flang/lib/Optimizer/HLFIR/Transforms/BufferizeHLFIR.cpp (+1-2) 
- (modified) flang/lib/Optimizer/HLFIR/Transforms/LowerHLFIROrderedAssignments.cpp (+3-1) 
- (modified) flang/lib/Optimizer/HLFIR/Transforms/SimplifyHLFIRIntrinsics.cpp (+10-3) 
- (modified) flang/lib/Optimizer/OpenACC/Support/FIROpenACCTypeInterfaces.cpp (+4-3) 
- (modified) flang/lib/Optimizer/OpenACC/Support/FIROpenACCUtils.cpp (+8-4) 
- (modified) flang/lib/Optimizer/Transforms/DebugTypeGenerator.cpp (+10-4) 
- (modified) flang/lib/Optimizer/Transforms/FIRToMemRef.cpp (+4-1) 


``````````diff
diff --git a/flang/include/flang/Optimizer/Dialect/FIROpsSupport.h b/flang/include/flang/Optimizer/Dialect/FIROpsSupport.h
index 944b9926387d8..a354f7aef511b 100644
--- a/flang/include/flang/Optimizer/Dialect/FIROpsSupport.h
+++ b/flang/include/flang/Optimizer/Dialect/FIROpsSupport.h
@@ -12,6 +12,7 @@
 #include "flang/Optimizer/Dialect/FIROps.h"
 #include "mlir/Dialect/Func/IR/FuncOps.h"
 #include "mlir/IR/BuiltinOps.h"
+#include "llvm/ADT/APInt.h"
 
 namespace fir {
 
@@ -188,8 +189,8 @@ bool valueMayHaveFirAttributes(mlir::Value value,
 /// function has any host associations, for example.
 bool anyFuncArgsHaveAttr(mlir::func::FuncOp func, llvm::StringRef attr);
 
-/// Unwrap integer constant from an mlir::Value.
-std::optional<std::int64_t> getIntIfConstant(mlir::Value value);
+/// Unwrap an integer constant from an mlir::Value as an APInt.
+std::optional<llvm::APInt> getIntIfConstant(mlir::Value value);
 
 static constexpr llvm::StringRef getAdaptToByRefAttrName() {
   return "adapt.valuebyref";
diff --git a/flang/lib/Lower/ConvertExprToHLFIR.cpp b/flang/lib/Lower/ConvertExprToHLFIR.cpp
index 6f718a8eb5926..936616ccbaa6e 100644
--- a/flang/lib/Lower/ConvertExprToHLFIR.cpp
+++ b/flang/lib/Lower/ConvertExprToHLFIR.cpp
@@ -2338,9 +2338,11 @@ HlfirDesignatorBuilder::genSubscript(const Fortran::evaluate::Expr<T> &expr) {
   // IR harder to read: directly use index constants for constant subscripts.
   mlir::Type idxTy = builder.getIndexType();
   if (!loweredExpr.isArray() && loweredExpr.getType() != idxTy)
-    if (auto cstIndex = fir::getIntIfConstant(loweredExpr))
-      return hlfir::EntityWithAttributes{
-          builder.createIntegerConstant(getLoc(), idxTy, *cstIndex)};
+    if (std::optional<llvm::APInt> cstIndex =
+            fir::getIntIfConstant(loweredExpr))
+      if (std::optional<std::int64_t> cstIndex64 = cstIndex->trySExtValue())
+        return hlfir::EntityWithAttributes{
+            builder.createIntegerConstant(getLoc(), idxTy, *cstIndex64)};
   return hlfir::loadTrivialScalar(loc, builder, loweredExpr);
 }
 
diff --git a/flang/lib/Lower/OpenMP/ClauseProcessor.cpp b/flang/lib/Lower/OpenMP/ClauseProcessor.cpp
index 318bdaa4f2f30..5a554def351ea 100644
--- a/flang/lib/Lower/OpenMP/ClauseProcessor.cpp
+++ b/flang/lib/Lower/OpenMP/ClauseProcessor.cpp
@@ -1098,7 +1098,16 @@ addAlignedClause(lower::AbstractConverter &converter,
           std::get<std::optional<Aligned::Alignment>>(clause.t)) {
     mlir::Value operand = fir::getBase(
         converter.genExprValue(*alignmentValueParserExpr, stmtCtx));
-    alignment = *fir::getIntIfConstant(operand);
+    std::optional<llvm::APInt> constantAlignment =
+        fir::getIntIfConstant(operand);
+    if (!constantAlignment)
+      fir::emitFatalError(operand.getLoc(), "alignment must be a constant");
+    std::optional<std::int64_t> constantAlignment64 =
+        constantAlignment->trySExtValue();
+    if (!constantAlignment64)
+      fir::emitFatalError(operand.getLoc(),
+                          "alignment does not fit in a 64-bit integer");
+    alignment = *constantAlignment64;
   } else {
     llvm::StringMap<bool> featuresMap = getTargetFeatures(builder.getModule());
     llvm::Triple triple = fir::getTargetTriple(builder.getModule());
diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp b/flang/lib/Lower/OpenMP/OpenMP.cpp
index a3acc2e991307..2e45f99172d3b 100644
--- a/flang/lib/Lower/OpenMP/OpenMP.cpp
+++ b/flang/lib/Lower/OpenMP/OpenMP.cpp
@@ -1057,8 +1057,9 @@ static void genCollapsedLoopNestBody(lower::AbstractConverter &converter,
   // Last value the induction variable at \p lvl actually takes:
   // lb + ((ub - lb) / step) * step. For unit steps this is exactly ub.
   auto computeLastIV = [&](const int lvl) -> mlir::Value {
-    const auto constStep = fir::getIntIfConstant(steps[lvl]);
-    if (constStep && (*constStep == 1 || *constStep == -1))
+    const std::optional<llvm::APInt> constStep =
+        fir::getIntIfConstant(steps[lvl]);
+    if (constStep && (constStep->isOne() || constStep->isAllOnes()))
       return ubs[lvl];
     const mlir::Value lb = lbs[lvl];
     const mlir::Value ub = ubs[lvl];
diff --git a/flang/lib/Optimizer/Analysis/ArraySectionAnalyzer.cpp b/flang/lib/Optimizer/Analysis/ArraySectionAnalyzer.cpp
index 6eec184b99a7f..d1a90f1324c2c 100644
--- a/flang/lib/Optimizer/Analysis/ArraySectionAnalyzer.cpp
+++ b/flang/lib/Optimizer/Analysis/ArraySectionAnalyzer.cpp
@@ -31,7 +31,7 @@ void ArraySectionAnalyzer::SectionDesc::normalize() {
     stride = nullptr;
   if (stride)
     if (auto val = fir::getIntIfConstant(stride))
-      if (*val == 1)
+      if (val->isOne())
         stride = nullptr;
 }
 
@@ -56,7 +56,7 @@ ArraySectionAnalyzer::getOrderedBounds(const SectionDesc &desc) {
     return {desc.lb, desc.ub};
   // Reverse the bounds, if stride is negative.
   if (auto val = fir::getIntIfConstant(stride)) {
-    if (*val >= 0)
+    if (!val->isNegative())
       return {desc.lb, desc.ub};
     else
       return {desc.ub, desc.lb};
@@ -203,7 +203,7 @@ bool ArraySectionAnalyzer::isLess(mlir::Value v1, mlir::Value v2) {
 
   auto isPositiveConstant = [](mlir::Value v) -> bool {
     if (auto val = fir::getIntIfConstant(v))
-      return *val > 0;
+      return val->isStrictlyPositive();
     return false;
   };
 
@@ -213,9 +213,12 @@ bool ArraySectionAnalyzer::isLess(mlir::Value v1, mlir::Value v2) {
     return false;
 
   // Check if they are both constants.
-  if (auto val1 = fir::getIntIfConstant(op1->getResult(0)))
-    if (auto val2 = fir::getIntIfConstant(op2->getResult(0)))
-      return *val1 < *val2;
+  std::optional<llvm::APInt> val1 = fir::getIntIfConstant(op1->getResult(0));
+  std::optional<llvm::APInt> val2 = fir::getIntIfConstant(op2->getResult(0));
+  if (val1 && val2) {
+    unsigned width = std::max(val1->getBitWidth(), val2->getBitWidth());
+    return val1->sext(width).slt(val2->sext(width));
+  }
 
   // Handle some variable cases (C > 0):
   //   v2 = v1 + C
@@ -263,7 +266,7 @@ getDesignatorIndices(hlfir::DesignateOp designate) {
       if (auto subOp =
               mlir::dyn_cast_or_null<mlir::arith::SubIOp>(v.getDefiningOp())) {
         auto cst = fir::getIntIfConstant(subOp.getRhs());
-        if (!cst || *cst != 1)
+        if (!cst || !cst->isOne())
           return false;
         if (auto dimsOp = mlir::dyn_cast_or_null<fir::BoxDimsOp>(
                 subOp.getLhs().getDefiningOp())) {
@@ -271,7 +274,7 @@ getDesignatorIndices(hlfir::DesignateOp designate) {
               dimsOp.getResult(0) != subOp.getLhs())
             return false;
           auto dimsOpDim = fir::getIntIfConstant(dimsOp.getDim());
-          return dimsOpDim && dimsOpDim == dim;
+          return dimsOpDim && *dimsOpDim == dim;
         }
       }
       return false;
diff --git a/flang/lib/Optimizer/Builder/Character.cpp b/flang/lib/Optimizer/Builder/Character.cpp
index 155bc0fbd19ce..a5e32fec05978 100644
--- a/flang/lib/Optimizer/Builder/Character.cpp
+++ b/flang/lib/Optimizer/Builder/Character.cpp
@@ -373,7 +373,8 @@ fir::factory::CharacterExprHelper::createCharacterTemp(mlir::Type type,
   auto typeLen = fir::CharacterType::unknownLen();
   // If len is a constant, reflect the length in the type.
   if (auto cstLen = getIntIfConstant(len))
-    typeLen = *cstLen;
+    if (std::optional<std::int64_t> cstLen64 = cstLen->trySExtValue())
+      typeLen = *cstLen64;
   auto *ctxt = builder.getContext();
   auto charTy = fir::CharacterType::get(ctxt, kind, typeLen);
   llvm::SmallVector<mlir::Value> lenParams;
diff --git a/flang/lib/Optimizer/Builder/FIRBuilder.cpp b/flang/lib/Optimizer/Builder/FIRBuilder.cpp
index 33360d891c3fa..59bae963ee026 100644
--- a/flang/lib/Optimizer/Builder/FIRBuilder.cpp
+++ b/flang/lib/Optimizer/Builder/FIRBuilder.cpp
@@ -1726,7 +1726,7 @@ fir::factory::getExtentFromTriplet(mlir::Value lb, mlir::Value ub,
   std::function<std::optional<std::int64_t>(mlir::Value)> getConstantValue =
       [&](mlir::Value value) -> std::optional<std::int64_t> {
     if (auto valInt = fir::getIntIfConstant(value))
-      return *valInt;
+      return valInt->trySExtValue();
     auto *definingOp = value.getDefiningOp();
     if (mlir::isa_and_nonnull<fir::ConvertOp>(definingOp)) {
       auto valOp = mlir::dyn_cast<fir::ConvertOp>(definingOp);
diff --git a/flang/lib/Optimizer/Builder/HLFIRTools.cpp b/flang/lib/Optimizer/Builder/HLFIRTools.cpp
index f95af2deb08da..f35ed4dd59e12 100644
--- a/flang/lib/Optimizer/Builder/HLFIRTools.cpp
+++ b/flang/lib/Optimizer/Builder/HLFIRTools.cpp
@@ -467,7 +467,7 @@ static mlir::Value genUBound(mlir::Location loc, fir::FirOpBuilder &builder,
                              mlir::Value lb, mlir::Value extent,
                              mlir::Value one) {
   if (auto constantLb = fir::getIntIfConstant(lb))
-    if (*constantLb == 1)
+    if (constantLb->isOne())
       return extent;
   extent = builder.createConvert(loc, one.getType(), extent);
   lb = builder.createConvert(loc, one.getType(), lb);
@@ -761,14 +761,17 @@ std::optional<std::int64_t> hlfir::getCharLengthIfConst(hlfir::Entity entity) {
     llvm::SmallVector<mlir::Value> param;
     if (getExprLengthParameters(expr, param)) {
       assert(param.size() == 1 && "characters must have one length parameters");
-      return fir::getIntIfConstant(param.pop_back_val());
+      if (std::optional<llvm::APInt> constant =
+              fir::getIntIfConstant(param.pop_back_val()))
+        return constant->trySExtValue();
     }
     return std::nullopt;
   }
 
   // entity is a var
   if (mlir::Value len = tryGettingNonDeferredCharLen(entity))
-    return fir::getIntIfConstant(len);
+    if (std::optional<llvm::APInt> constant = fir::getIntIfConstant(len))
+      return constant->trySExtValue();
   auto charType =
       mlir::cast<fir::CharacterType>(entity.getFortranElementType());
   if (charType.hasConstantLen())
@@ -905,7 +908,8 @@ static hlfir::ExprType getArrayExprType(mlir::Type elementType,
   if (auto shapeOp = shape.getDefiningOp<fir::ShapeOp>())
     for (auto extent : llvm::enumerate(shapeOp.getExtents()))
       if (auto cstExtent = fir::getIntIfConstant(extent.value()))
-        typeShape[extent.index()] = *cstExtent;
+        if (std::optional<std::int64_t> cstExtent64 = cstExtent->trySExtValue())
+          typeShape[extent.index()] = *cstExtent64;
   return hlfir::ExprType::get(elementType.getContext(), typeShape, elementType,
                               isPolymorphic);
 }
@@ -1775,7 +1779,7 @@ bool hlfir::designatePreservesContinuity(hlfir::DesignateOp op) {
         i += 2;
         mlir::Value step = subscripts[i++];
         auto constantStep = fir::getIntIfConstant(step);
-        if (!constantStep || *constantStep != 1)
+        if (!constantStep || !constantStep->isOne())
           return false;
       }
     } else {
diff --git a/flang/lib/Optimizer/Builder/IntrinsicCall.cpp b/flang/lib/Optimizer/Builder/IntrinsicCall.cpp
index 9ec64844cf6d6..6987092ea921d 100644
--- a/flang/lib/Optimizer/Builder/IntrinsicCall.cpp
+++ b/flang/lib/Optimizer/Builder/IntrinsicCall.cpp
@@ -8254,15 +8254,16 @@ IntrinsicLibrary::genSize(mlir::Type resultType,
 
   // Get the DIM argument.
   mlir::Value dim = fir::getBase(args[1]);
+  std::optional<std::int64_t> cstDim;
   if (!args[0].hasAssumedRank())
-    if (std::optional<std::int64_t> cstDim = fir::getIntIfConstant(dim)) {
-      // If both DIM and the rank are compile time constants, skip the runtime
-      // call.
-      return builder.createConvert(
-          loc, resultType,
-          fir::factory::readExtent(builder, loc, fir::BoxValue{array},
-                                   cstDim.value() - 1));
-    }
+    if (std::optional<llvm::APInt> constantDim = fir::getIntIfConstant(dim))
+      cstDim = constantDim->trySExtValue();
+  // If both DIM and the rank are compile time constants, skip the runtime call.
+  if (cstDim)
+    return builder.createConvert(loc, resultType,
+                                 fir::factory::readExtent(builder, loc,
+                                                          fir::BoxValue{array},
+                                                          cstDim.value() - 1));
   if (!fir::isa_ref_type(dim.getType()))
     return builder.createConvert(
         loc, resultType, fir::runtime::genSizeDim(builder, loc, array, dim));
@@ -8465,14 +8466,16 @@ IntrinsicLibrary::genLbound(mlir::Type resultType,
 
   // If it is a compile time constant and the rank is known, skip the runtime
   // call.
+  std::optional<std::int64_t> cstDim;
   if (!array.hasAssumedRank())
-    if (std::optional<std::int64_t> cstDim = fir::getIntIfConstant(dim)) {
-      mlir::Value one = builder.createIntegerConstant(loc, resultType, 1);
-      mlir::Value zero = builder.createIntegerConstant(loc, indexType, 0);
-      mlir::Value lb =
-          computeLBOUND(builder, loc, array, *cstDim - 1, zero, one);
-      return builder.createConvert(loc, resultType, lb);
-    }
+    if (std::optional<llvm::APInt> constantDim = fir::getIntIfConstant(dim))
+      cstDim = constantDim->trySExtValue();
+  if (cstDim) {
+    mlir::Value one = builder.createIntegerConstant(loc, resultType, 1);
+    mlir::Value zero = builder.createIntegerConstant(loc, indexType, 0);
+    mlir::Value lb = computeLBOUND(builder, loc, array, *cstDim - 1, zero, one);
+    return builder.createConvert(loc, resultType, lb);
+  }
 
   fir::ExtendedValue box = createBoxForRuntimeBoundInquiry(loc, builder, array);
   return builder.createConvert(
diff --git a/flang/lib/Optimizer/CodeGen/CodeGen.cpp b/flang/lib/Optimizer/CodeGen/CodeGen.cpp
index 994112599dda3..0e88524126f11 100644
--- a/flang/lib/Optimizer/CodeGen/CodeGen.cpp
+++ b/flang/lib/Optimizer/CodeGen/CodeGen.cpp
@@ -111,9 +111,12 @@ static mlir::Block *createBlock(mlir::ConversionPatternRewriter &rewriter,
 /// Extract constant from a value that must be the result of one of the
 /// ConstantOp operations.
 static int64_t getConstantIntValue(mlir::Value val) {
-  if (auto constVal = fir::getIntIfConstant(val))
-    return *constVal;
-  fir::emitFatalError(val.getLoc(), "must be a constant");
+  std::optional<llvm::APInt> constVal = fir::getIntIfConstant(val);
+  if (!constVal)
+    fir::emitFatalError(val.getLoc(), "must be a constant");
+  if (std::optional<std::int64_t> constVal64 = constVal->trySExtValue())
+    return *constVal64;
+  fir::emitFatalError(val.getLoc(), "constant must fit in a 64-bit integer");
 }
 
 static unsigned getTypeDescFieldId(mlir::Type ty) {
@@ -1062,8 +1065,8 @@ struct ConvertOpConversion : public fir::FIROpConversion<fir::ConvertOp> {
 
       // Do folding for constant inputs.
       if (auto constVal = fir::getIntIfConstant(op0)) {
-        mlir::Value normVal =
-            fir::genConstantIndex(loc, toTy, rewriter, *constVal ? 1 : 0);
+        mlir::Value normVal = fir::genConstantIndex(loc, toTy, rewriter,
+                                                    constVal->isZero() ? 0 : 1);
         rewriter.replaceOp(convert, normVal);
         return mlir::success();
       }
diff --git a/flang/lib/Optimizer/Dialect/FIROps.cpp b/flang/lib/Optimizer/Dialect/FIROps.cpp
index b9968897ade6d..798ab130c1d30 100644
--- a/flang/lib/Optimizer/Dialect/FIROps.cpp
+++ b/flang/lib/Optimizer/Dialect/FIROps.cpp
@@ -776,7 +776,7 @@ struct SimplifyArrayCoorOp : public mlir::OpRewritePattern<fir::ArrayCoorOp> {
           if (!lowerBounds.empty()) {
             mlir::Value lb = lowerBounds[i];
             auto constLb = fir::getIntIfConstant(lb);
-            if (!(constLb && *constLb == 1)) {
+            if (!(constLb && constLb->isOne())) {
               mlir::Location loc = op.getLoc();
               mlir::Value extLb =
                   fir::ConvertOp::create(rewriter, loc, idxTy, lb);
@@ -1630,7 +1630,9 @@ struct SimplifyBoxDimsFromCreateBox
     if (!createBox)
       return mlir::failure();
 
-    std::optional<std::int64_t> dim = fir::getIntIfConstant(op.getDim());
+    std::optional<llvm::APInt> constantDim = fir::getIntIfConstant(op.getDim());
+    std::optional<std::int64_t> dim =
+        constantDim ? constantDim->trySExtValue() : std::nullopt;
     if (!dim || *dim < 0 || *dim >= createBox.getRank())
       return mlir::failure();
 
@@ -2095,7 +2097,7 @@ mlir::OpFoldResult fir::ConvertOp::fold(FoldAdaptor adaptor) {
       matchPattern(getValue(), mlir::m_Op<fir::BitcastOp>())) {
     auto bitcast = mlir::cast<fir::BitcastOp>(getValue().getDefiningOp());
     if (auto cst = fir::getIntIfConstant(bitcast.getValue()))
-      return mlir::IntegerAttr::get(getType(), cst != 0 ? 1 : 0);
+      return mlir::IntegerAttr::get(getType(), cst->isZero() ? 0 : 1);
   }
   return {};
 }
@@ -2110,7 +2112,7 @@ static std::optional<bool> getLogicalConstant(mlir::Value value) {
   if (auto convertOp = value.getDefiningOp<fir::ConvertOp>())
     maybeConvertInput = convertOp.getValue();
   if (auto cst = fir::getIntIfConstant(maybeConvertInput))
-    return *cst != 0;
+    return !cst->isZero();
   return std::nullopt;
 }
 
@@ -2751,7 +2753,7 @@ static bool isBoxLb(mlir::Value box, std::int64_t dim, mlir::Value lb,
         return *dimOperand == dim;
   } else if (!mayHaveNonDefaultLowerBounds) {
     if (auto constantLb = fir::getIntIfConstant(lb))
-      return *constantLb == 1;
+      return constantLb->isOne();
   }
   return false;
 }
@@ -2768,7 +2770,7 @@ static bool isBoxUb(mlir::Value box, std::int64_t dim, mlir::Value ub,
                     bool mayHaveNonDefaultLowerBounds = true) {
   if (auto sub1 = ub.getDefiningOp<mlir::arith::SubIOp>()) {
     auto one = fir::getIntIfConstant(sub1.getOperand(1));
-    if (!one || *one != 1)
+    if (!one || !one->isOne())
       return false;
     if (auto add = sub1.getOperand(0).getDefiningOp<mlir::arith::AddIOp>())
       if ((isBoxLb(box, dim, add.getOperand(0)) &&
@@ -2831,7 +2833,7 @@ static bool isContiguousArraySlice(fir::SliceOp sliceOp, bool checkWhole = true,
             return false;
         }
         auto constantStep = fir::getIntIfConstant(triples[i + 2]);
-        if (!constantStep || *constantStep != 1)
+        if (!constantStep || !constantStep->isOne())
           return false;
       }
     }
@@ -6121,14 +6123,14 @@ bool fir::anyFuncArgsHaveAttr(mlir::func::FuncOp func, llvm::StringRef attr) {
   return false;
 }
 
-std::optional<std::int64_t> fir::getIntIfConstant(mlir::Value value) {
+std::optional<llvm::APInt> fir::getIntIfConstant(mlir::Value value) {
   if (auto *definingOp = value.getDefiningOp()) {
     if (auto cst = mlir::dyn_cast<mlir::arith::ConstantOp>(definingOp))
       if (auto intAttr = mlir::dyn_cast<mlir::IntegerAttr>(cst.getValue()))
-        return intAttr.getInt();
+        return intAttr.getValue();
     if (auto llConstOp = mlir::dyn_cast<mlir::LLVM::ConstantOp>(definingOp))
       if (auto attr = mlir::dyn_cast<mlir::IntegerAttr>(llConstOp.getValue()))
-        return attr.getValue().getSExtValue();
+        return attr.getValue();
   }
   return {};
 }
diff --git a/flang/lib/Optimizer/HLFIR/IR/HLFIROps.cpp b/flang/lib/Optimizer/HLFIR/IR/HLFIROps.cpp
index 9de2d718a9c3a..df2811f70abf2 100644
--- a/flang/lib/Optimizer/HLFIR/IR/HLFIROps.cpp
+++ b/flang/lib/Optimizer/HLFIR/IR/HLFIROps.cpp
@@ -1197,7 +1197,8 @@ void hlfir::SetLengthOp::build(mlir::OpBuilder &builder,
                                mlir::Value len) {
   fir::CharacterType::LenType resultTypeLen = fir::CharacterType::unknownLen();
   if (auto cstLen = fir::getIntIfConstant(len))
-    resultTypeLen = *cstLen;
+    if (std::optional<std::int64_t> cstLen64 = cstLen->trySExtValue())
+      resultTypeLen = *cstLen64;
   unsigned kind = getCharacterKind(string.getType());
   auto resultType = hlfir::ExprType::get(
       builder.getContext(), hlfir::ExprType::Shape{},
@@ -1568,8 +1569,15 @@ static llvm::LogicalResult verifyArrayShift(Op op) {
   int64_t dimVal = -1;
   if (!op.getDim())
     dimVal = 1;
-  else if (auto dim = fir::getIntIfConstant(op.getDim()))
-    dimVal = *dim;
+  else if (std::optional<llvm::APInt> dim =
+               fir::getIntIfConstant(op.getDim())) {
+    if (std::optional<std::int64_t> dim64 = dim->trySExtValue())
+      dimVal = *dim64;
+    else if (useStrictIntrinsicVerifier)
+      return op.emitOpError(dim->isNegative()
+                                ? "DIM must be >= 1"
+                                : "DIM must be <= input array's rank");
+  }
 
   // The DIM argument may be statically in...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/211233


More information about the flang-commits mailing list