[Mlir-commits] [mlir] c68a4ca - [LLVMIR] Directly lower global initializer GEP to constant expression (#226904)
llvmlistbot at llvm.org
llvmlistbot at llvm.org
Tue Sep 29 01:00:45 PDT 2026
Author: Nikita Popov
Date: 2026-09-29T10:00:36+02:00
New Revision: c68a4ca2a9202d073b569cbfbfb269f21abf7aec
URL: https://github.com/llvm/llvm-project/commit/c68a4ca2a9202d073b569cbfbfb269f21abf7aec
DIFF: https://github.com/llvm/llvm-project/commit/c68a4ca2a9202d073b569cbfbfb269f21abf7aec.diff
LOG: [LLVMIR] Directly lower global initializer GEP to constant expression (#226904)
MLIR lowers global initializers in a very unusual way, by using an
IRBuilder without insertion point, and relying on the fact that for a
well-formed initializer, all the instructions will be converted to
constant expressions and no actual instructions that require insertion
will be produced.
This causes issues for https://github.com/llvm/llvm-project/pull/226425,
which requires an insertion point for CreateGEP to determine the data
layout.
To avoid this, make convertGEPOp() directly produce a constant
expression GEP if there is no insertion point, reusing the existing code
path for inrange GEPs.
Added:
Modified:
mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp
mlir/test/Target/LLVMIR/llvmir-invalid.mlir
Removed:
################################################################################
diff --git a/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp b/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp
index 3f83a5f7f22ce..1a9dd3d260ee1 100644
--- a/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp
+++ b/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp
@@ -253,15 +253,23 @@ static LogicalResult convertGEPOp(GEPOp op, llvm::IRBuilderBase &builder,
llvm::Type *elementType = moduleTranslation.convertType(op.getElemType());
llvm::GEPNoWrapFlags nwFlags =
llvm::GEPNoWrapFlags::fromRaw(static_cast<unsigned>(op.getNoWrapFlags()));
+ ConstantRangeAttr inrangeAttr = op.getInrangeAttr();
llvm::Value *base = moduleTranslation.lookupValue(op.getBase());
llvm::Value *res;
- if (ConstantRangeAttr inrangeAttr = op.getInrangeAttr()) {
+ if (inrangeAttr || !builder.GetInsertPoint().isValid()) {
+ StringRef WhyConstExpr =
+ inrangeAttr ? "'inrange' GEP" : "global initializer GEP";
auto *baseConst = dyn_cast<llvm::Constant>(base);
if (!baseConst || !llvm::all_of(indices, [](llvm::Value *value) {
return isa<llvm::Constant>(value);
}))
- return op.emitError("'inrange' requires the base and indices to "
- "translate to LLVM constants");
+ return op.emitError(WhyConstExpr + " requires the base and indices to "
+ "translate to LLVM constants");
+
+ std::optional<llvm::ConstantRange> inrangeCR;
+ if (inrangeAttr)
+ inrangeCR = llvm::ConstantRange::getNonEmpty(inrangeAttr.getLower(),
+ inrangeAttr.getUpper());
SmallVector<llvm::Constant *> constIndices;
constIndices.reserve(indices.size());
@@ -270,12 +278,10 @@ static LogicalResult convertGEPOp(GEPOp op, llvm::IRBuilderBase &builder,
const llvm::DataLayout &dataLayout =
moduleTranslation.getLLVMModule()->getDataLayout();
res = llvm::ConstantExpr::getGetElementPtr(
- dataLayout, elementType, baseConst, constIndices, nwFlags,
- llvm::ConstantRange::getNonEmpty(inrangeAttr.getLower(),
- inrangeAttr.getUpper()));
+ dataLayout, elementType, baseConst, constIndices, nwFlags, inrangeCR);
if (!res)
- return op.emitError(
- "failed to lower 'inrange' GEP to a constant byte offset");
+ return op.emitError("failed to lower " + WhyConstExpr +
+ " to a constant byte offset");
} else {
res = builder.CreateGEP(elementType, base, indices, "", nwFlags);
}
diff --git a/mlir/test/Target/LLVMIR/llvmir-invalid.mlir b/mlir/test/Target/LLVMIR/llvmir-invalid.mlir
index c6bd08fad0585..b9ea9f6c9ace4 100644
--- a/mlir/test/Target/LLVMIR/llvmir-invalid.mlir
+++ b/mlir/test/Target/LLVMIR/llvmir-invalid.mlir
@@ -1,7 +1,7 @@
// RUN: mlir-translate -verify-diagnostics -split-input-file -mlir-to-llvmir %s
llvm.func @gep_inrange_nonconstant_base(%ptr: !llvm.ptr) -> !llvm.ptr {
- // expected-error @below{{'inrange' requires the base and indices to translate to LLVM constants}}
+ // expected-error @below{{'inrange' GEP requires the base and indices to translate to LLVM constants}}
// expected-error @below{{LLVM Translation failed for operation: llvm.getelementptr}}
%0 = llvm.getelementptr inrange <i64, -4, 4> %ptr[0] : (!llvm.ptr) -> !llvm.ptr, i8
llvm.return %0 : !llvm.ptr
@@ -13,7 +13,7 @@ llvm.mlir.global external @gep_base() : i8
llvm.func @gep_inrange_nonconstant_index(%idx: i64) -> !llvm.ptr {
%addr = llvm.mlir.addressof @gep_base : !llvm.ptr
- // expected-error @below{{'inrange' requires the base and indices to translate to LLVM constants}}
+ // expected-error @below{{'inrange' GEP requires the base and indices to translate to LLVM constants}}
// expected-error @below{{LLVM Translation failed for operation: llvm.getelementptr}}
%0 = llvm.getelementptr inrange <i64, -4, 4> %addr[%idx] : (!llvm.ptr, i64) -> !llvm.ptr, i8
llvm.return %0 : !llvm.ptr
More information about the Mlir-commits
mailing list