[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:
parent
9d2000c24d
commit
9286c58841
19 changed files with 133 additions and 74 deletions
|
|
@ -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";
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
|
|
|
|||
|
|
@ -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];
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 {};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
Loading…
Reference in a new issue