[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