[flang-commits] [flang] [flang] In AllocMemOp lowering, convert types for calling malloc on 32-bit (PR #129308)
via flang-commits
flang-commits at lists.llvm.org
Fri Feb 28 13:11:51 PST 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-flang-fir-hlfir
Author: R (ArcaneNibble)
<details>
<summary>Changes</summary>
I came across @<!-- -->georgestagg's [work on getting Flang to target WebAssembly](https://gws.phd/posts/fortran_wasm/) and attempted to clean up the hacks so that it can actually be upstreamed. This patch fixes dynamic allocations, and I am submitting it first as it is less invasive than the work needed to fix RTBuilder.
This change first ensures that the MLIR->LLVM lowering pass actually has access to the real target DataLayout, as it was previously making do with a default one. The AllocMemOp lowering then inserts a type conversion if the target has 32-bit pointers. This assumes that `size_t` is the same size as pointers.
I haven't checked whether anything else in CodeGen needs changing for cross-compiling (especially since I'm not actually familiar with Fortran), but this change should make any necessary future fixes easier.
---
Full diff: https://github.com/llvm/llvm-project/pull/129308.diff
2 Files Affected:
- (modified) flang/lib/Optimizer/CodeGen/CodeGen.cpp (+13-6)
- (modified) flang/lib/Optimizer/CodeGen/TypeConverter.cpp (+13-1)
``````````diff
diff --git a/flang/lib/Optimizer/CodeGen/CodeGen.cpp b/flang/lib/Optimizer/CodeGen/CodeGen.cpp
index aaefe675730e1..b6ce5f328b61b 100644
--- a/flang/lib/Optimizer/CodeGen/CodeGen.cpp
+++ b/flang/lib/Optimizer/CodeGen/CodeGen.cpp
@@ -982,7 +982,8 @@ struct EmboxCharOpConversion : public fir::FIROpConversion<fir::EmboxCharOp> {
template <typename ModuleOp>
static mlir::SymbolRefAttr
getMallocInModule(ModuleOp mod, fir::AllocMemOp op,
- mlir::ConversionPatternRewriter &rewriter) {
+ mlir::ConversionPatternRewriter &rewriter,
+ bool addr32) {
static constexpr char mallocName[] = "malloc";
if (auto mallocFunc =
mod.template lookupSymbol<mlir::LLVM::LLVMFuncOp>(mallocName))
@@ -992,7 +993,7 @@ getMallocInModule(ModuleOp mod, fir::AllocMemOp op,
return mlir::SymbolRefAttr::get(userMalloc);
mlir::OpBuilder moduleBuilder(mod.getBodyRegion());
- auto indexType = mlir::IntegerType::get(op.getContext(), 64);
+ auto indexType = mlir::IntegerType::get(op.getContext(), addr32 ? 32 : 64);
auto mallocDecl = moduleBuilder.create<mlir::LLVM::LLVMFuncOp>(
op.getLoc(), mallocName,
mlir::LLVM::LLVMFunctionType::get(getLlvmPtrType(op.getContext()),
@@ -1003,11 +1004,12 @@ getMallocInModule(ModuleOp mod, fir::AllocMemOp op,
/// Return the LLVMFuncOp corresponding to the standard malloc call.
static mlir::SymbolRefAttr
-getMalloc(fir::AllocMemOp op, mlir::ConversionPatternRewriter &rewriter) {
+getMalloc(fir::AllocMemOp op, mlir::ConversionPatternRewriter &rewriter,
+ bool addr32) {
if (auto mod = op->getParentOfType<mlir::gpu::GPUModuleOp>())
- return getMallocInModule(mod, op, rewriter);
+ return getMallocInModule(mod, op, rewriter, addr32);
auto mod = op->getParentOfType<mlir::ModuleOp>();
- return getMallocInModule(mod, op, rewriter);
+ return getMallocInModule(mod, op, rewriter, addr32);
}
/// Helper function for generating the LLVM IR that computes the distance
@@ -1057,6 +1059,7 @@ struct AllocMemOpConversion : public fir::FIROpConversion<fir::AllocMemOp> {
mlir::Type heapTy = heap.getType();
mlir::Location loc = heap.getLoc();
auto ity = lowerTy().indexType();
+ auto addr32 = lowerTy().getPointerBitwidth(0) == 32;
mlir::Type dataTy = fir::unwrapRefType(heapTy);
mlir::Type llvmObjectTy = convertObjectType(dataTy);
if (fir::isRecordWithTypeParameters(fir::unwrapSequenceType(dataTy)))
@@ -1067,7 +1070,11 @@ struct AllocMemOpConversion : public fir::FIROpConversion<fir::AllocMemOp> {
for (mlir::Value opnd : adaptor.getOperands())
size = rewriter.create<mlir::LLVM::MulOp>(
loc, ity, size, integerCast(loc, rewriter, ity, opnd));
- heap->setAttr("callee", getMalloc(heap, rewriter));
+ if (addr32) {
+ auto i32ty = mlir::IntegerType::get(rewriter.getContext(), 32);
+ size = integerCast(loc, rewriter, i32ty, size);
+ }
+ heap->setAttr("callee", getMalloc(heap, rewriter, addr32));
rewriter.replaceOpWithNewOp<mlir::LLVM::CallOp>(
heap, ::getLlvmPtrType(heap.getContext()), size,
addLLVMOpBundleAttrs(rewriter, heap->getAttrs(), 1));
diff --git a/flang/lib/Optimizer/CodeGen/TypeConverter.cpp b/flang/lib/Optimizer/CodeGen/TypeConverter.cpp
index 89f498433806e..c22a64bd7be7d 100644
--- a/flang/lib/Optimizer/CodeGen/TypeConverter.cpp
+++ b/flang/lib/Optimizer/CodeGen/TypeConverter.cpp
@@ -28,10 +28,22 @@
namespace fir {
+static mlir::LowerToLLVMOptions MakeLowerOptions(mlir::ModuleOp module) {
+ llvm::StringRef dataLayoutString;
+ auto dataLayoutAttr = module->template getAttrOfType<mlir::StringAttr>(
+ mlir::LLVM::LLVMDialect::getDataLayoutAttrName());
+ if (dataLayoutAttr)
+ dataLayoutString = dataLayoutAttr.getValue();
+
+ auto options = mlir::LowerToLLVMOptions(module.getContext());
+ options.dataLayout = llvm::DataLayout(dataLayoutString);
+ return options;
+}
+
LLVMTypeConverter::LLVMTypeConverter(mlir::ModuleOp module, bool applyTBAA,
bool forceUnifiedTBAATree,
const mlir::DataLayout &dl)
- : mlir::LLVMTypeConverter(module.getContext()),
+ : mlir::LLVMTypeConverter(module.getContext(), MakeLowerOptions(module)),
kindMapping(getKindMapping(module)),
specifics(CodeGenSpecifics::get(
module.getContext(), getTargetTriple(module), getKindMapping(module),
``````````
</details>
https://github.com/llvm/llvm-project/pull/129308
More information about the flang-commits
mailing list