Skip to content

Commit e944411

Browse files
committed
[rebase] workaround LLVM dialect array constant issue with dense attributes
StringLitOp use to be translated to things like: llvm.func @character_literal2() -> !llvm.array<2 x i16> { %0 = llvm.mlir.constant(dense<[234, 456]> : vector<2xi16>) : !llvm.array<2 x i16> llvm.return %0 : !llvm.array<2 x i16> } Now yields error: Function return type does not match operand type of return inst! ret <2 x i16> <i16 234, i16 456>, !dbg !7 [2 x i16]error: could not emit LLVM-IR Yet, using dense attr looks the right things to do given mlir tests like https://github.com/llvm/llvm-project/blob/e356027016c6365b3d8924f54c33e2c63d931492/mlir/test/Target/LLVMIR/llvmir.mlir#L31 So there might be an MLIR regression here. In the short-term, use a chain of insert_value as a fallback.
1 parent c49360d commit e944411

File tree

1 file changed

+20
-11
lines changed

1 file changed

+20
-11
lines changed

flang/lib/Optimizer/CodeGen/CodeGen.cpp

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -701,21 +701,30 @@ struct StringLitOpConversion : public FIROpConversion<fir::StringLitOp> {
701701
if (attr.isa<mlir::StringAttr>()) {
702702
rewriter.replaceOpWithNewOp<mlir::LLVM::ConstantOp>(constop, ty, attr);
703703
} else {
704-
// convert the array attr to a dense elements attr
705-
// LLVMIR dialect knows how to lower the latter to LLVM IR
704+
// FIXME: As of llvm head 85bf221f204eafc1142a064f1650ffa9d9e03dad, using
705+
// a dense elements attr causes llvm ir verification error:
706+
// %0 = llvm.mlir.constant(dense<[234, 456]> : vector<2xi16>) : !llvm.array<2 x i16>
707+
// creates a vector type constant instead of an array, later
708+
// conflicting with its usage. It is likely an MLIR bug that should
709+
// be investigated. In the meantime, do a dumb chain of inserts.
706710
auto arr = attr.cast<mlir::ArrayAttr>();
707-
auto size = constop.getSize().cast<mlir::IntegerAttr>().getInt();
708711
auto charTy = constop.getType().cast<fir::CharacterType>();
709712
auto bits = lowerTy().characterBitsize(charTy);
710713
auto intTy = rewriter.getIntegerType(bits);
711-
auto det = mlir::VectorType::get({size}, intTy);
712-
// convert each character to a precise bitsize
713-
SmallVector<mlir::Attribute, 64> vec;
714-
for (auto a : arr.getValue())
715-
vec.push_back(mlir::IntegerAttr::get(
716-
intTy, a.cast<mlir::IntegerAttr>().getValue().sextOrTrunc(bits)));
717-
auto dea = mlir::DenseElementsAttr::get(det, vec);
718-
rewriter.replaceOpWithNewOp<mlir::LLVM::ConstantOp>(constop, ty, dea);
714+
auto loc = constop.getLoc();
715+
716+
mlir::Value cst = rewriter.create<mlir::LLVM::UndefOp>(loc, ty);
717+
for (auto a : llvm::enumerate(arr.getValue())) {
718+
// convert each character to a precise bitsize
719+
auto elemAttr =
720+
mlir::IntegerAttr::get(
721+
intTy, a.value().cast<mlir::IntegerAttr>().getValue().sextOrTrunc(bits));
722+
auto elemCst = rewriter.create<mlir::LLVM::ConstantOp>(loc, intTy, elemAttr);
723+
auto index = mlir::ArrayAttr::get(constop.getContext(), rewriter.getI32IntegerAttr(a.index()));
724+
cst = rewriter.create<mlir::LLVM::InsertValueOp>(
725+
loc, ty, cst, elemCst, index);
726+
}
727+
rewriter.replaceOp(constop, cst);
719728
}
720729
return success();
721730
}

0 commit comments

Comments
 (0)