[Flang] Return APInt from getIntIfConstant (#211233)

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
This commit is contained in:
Tom Eccles 2026-07-22 17:35:07 +01:00 committed by GitHub
parent 9d2000c24d
commit 9286c58841
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
19 changed files with 133 additions and 74 deletions

View file

@ -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";

View file

@ -2248,9 +2248,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);
}

View file

@ -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());

View file

@ -1059,8 +1059,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];

View file

@ -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;

View file

@ -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;

View file

@ -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);

View file

@ -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 {

View file

@ -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(

View file

@ -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();
}

View file

@ -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 {};
}

View file

@ -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 invalid (e.g. exceed the
// input array rank) in dead code after constant propagation,

View file

@ -614,8 +614,7 @@ static void genBufferDestruction(mlir::Location loc, fir::FirOpBuilder &builder,
/*doFinalize=*/false);
};
if (auto cstMustFree = fir::getIntIfConstant(mustFree)) {
genFreeOrFinalize(*cstMustFree != 0 ? true : false, deallocComponents,
mustFinalize);
genFreeOrFinalize(!cstMustFree->isZero(), deallocComponents, mustFinalize);
return;
}

View file

@ -1120,7 +1120,9 @@ computeLoopNestIterationNumber(mlir::Location loc, fir::FirOpBuilder &builder,
static std::optional<int64_t> unwrapConstantInt(mlir::Value value) {
while (auto convert = value.getDefiningOp<fir::ConvertOp>())
value = convert.getValue();
return fir::getIntIfConstant(value);
if (std::optional<llvm::APInt> constant = fir::getIntIfConstant(value))
return constant->trySExtValue();
return std::nullopt;
}
/// Compute the extents and lower bounds of \p loopNest, in the same order as

View file

@ -311,7 +311,10 @@ protected:
auto constDim = fir::getIntIfConstant(getDim());
if (!constDim)
return rewriter.notifyMatchFailure(op, "Nonconstant DIM");
dimVal = *constDim;
std::optional<std::int64_t> constDim64 = constDim->trySExtValue();
if (!constDim64)
return rewriter.notifyMatchFailure(op, "DIM does not fit in int64_t");
dimVal = *constDim64;
if ((dimVal <= 0 || dimVal > getSourceRank()))
return rewriter.notifyMatchFailure(op,
@ -1435,7 +1438,11 @@ public:
if (!constDim)
return rewriter.notifyMatchFailure(
op, "Nonconstant DIM for CSHIFT/EOSHIFT");
dimVal = *constDim;
std::optional<std::int64_t> constDim64 = constDim->trySExtValue();
if (!constDim64)
return rewriter.notifyMatchFailure(
op, "DIM does not fit in int64_t for CSHIFT/EOSHIFT");
dimVal = *constDim64;
}
if (dimVal <= 0 || dimVal > arrayRank)
@ -2505,7 +2512,7 @@ public:
std::optional<bool> isBack;
if (back) {
if (auto backCst = fir::getIntIfConstant(back))
isBack = *backCst != 0;
isBack = !backCst->isZero();
} else {
isBack = false;
}

View file

@ -628,9 +628,10 @@ genDesignateWithTriplets(fir::FirOpBuilder &builder, mlir::Location loc,
fir::SequenceType::Shape resultTypeShape;
bool shapeIsConstant = true;
for (mlir::Value extent : extents) {
if (std::optional<std::int64_t> cst_extent =
fir::getIntIfConstant(extent)) {
resultTypeShape.push_back(*cst_extent);
std::optional<llvm::APInt> cstExtent = fir::getIntIfConstant(extent);
if (std::optional<std::int64_t> cstExtent64 =
cstExtent ? cstExtent->trySExtValue() : std::nullopt) {
resultTypeShape.push_back(*cstExtent64);
} else {
resultTypeShape.push_back(fir::SequenceType::getUnknownExtent());
shapeIsConstant = false;

View file

@ -378,10 +378,14 @@ getRecipeBounds(fir::FirOpBuilder &builder, mlir::Location loc,
assert(
dataBound.getLowerbound() && dataBound.getUpperbound() &&
"expect acc bounds for Fortran to always have lower and upper bounds");
std::optional<std::int64_t> lb =
fir::getIntIfConstant(dataBound.getLowerbound());
std::optional<std::int64_t> ub =
fir::getIntIfConstant(dataBound.getUpperbound());
std::optional<std::int64_t> lb;
if (std::optional<llvm::APInt> constant =
fir::getIntIfConstant(dataBound.getLowerbound()))
lb = constant->trySExtValue();
std::optional<std::int64_t> ub;
if (std::optional<llvm::APInt> constant =
fir::getIntIfConstant(dataBound.getUpperbound()))
ub = constant->trySExtValue();
assert(lb.has_value() && ub.has_value() &&
"must get constant bounds when there are no bound block arguments");
bounds.push_back(builder.createIntegerConstant(loc, idxTy, *lb));

View file

@ -224,8 +224,11 @@ mlir::LLVM::DITypeAttr DebugTypeGenerator::convertBoxedSequenceType(
mlir::Attribute lowerAttr = nullptr;
// If declaration has a lower bound, use it.
if (declOp && declOp.getShift().size() > index) {
if (std::optional<std::int64_t> optint =
getIntIfConstant(declOp.getShift()[index]))
std::optional<llvm::APInt> constant =
getIntIfConstant(declOp.getShift()[index]);
std::optional<std::int64_t> optint =
constant ? constant->trySExtValue() : std::nullopt;
if (optint)
lowerAttr = mlir::IntegerAttr::get(intTy, llvm::APInt(64, *optint));
else
lowerAttr = generateArtificialVariable(
@ -545,8 +548,11 @@ mlir::LLVM::DITypeAttr DebugTypeGenerator::convertSequenceType(
// bound. As an optimization, we don't create a lower bound when shift is a
// constant 1 as that is the default.
if (declOp && declOp.getShift().size() > index) {
if (std::optional<std::int64_t> optint =
getIntIfConstant(declOp.getShift()[index])) {
std::optional<llvm::APInt> constant =
getIntIfConstant(declOp.getShift()[index]);
std::optional<std::int64_t> optint =
constant ? constant->trySExtValue() : std::nullopt;
if (optint) {
if (*optint != 1)
lowerAttr = mlir::IntegerAttr::get(intTy, llvm::APInt(64, *optint));
} else

View file

@ -201,7 +201,10 @@ private:
auto fields = sliceOp.getFields();
if (fields.empty())
return std::nullopt;
return fir::getIntIfConstant(fields.front());
if (std::optional<llvm::APInt> constant =
fir::getIntIfConstant(fields.front()))
return constant->trySExtValue();
return std::nullopt;
}
unsigned getRankFromEmbox(fir::EmboxOp embox) const {