Skip to content

Conversation

bcardosolopes
Copy link
Member

…fsets

Make sure LLVM bails when aliasee aren't present. Found while using mlir-translate --mlir-to-llvm. Added unittest exercises the builder using a target folder, this is the original IR triggering the issue:

@m2 = internal alias { [1 x i64] }, ptr @k0
@k0 = private constant {{ [1 x i64] }} {
  { [1 x i64] }
    {
      [1 x i64]
        [
         i64 ptrtoint (ptr getelementptr inbounds ({ [1 x i64] },
                       ptr @m2, i32 0, i32 0, i32 1) to i64)
        ]
    }
  }, align 4

…fsets

Make sure LLVM bails when aliasee aren't present. Found while using
`mlir-translate --mlir-to-llvm`.  Added unittest exercises the builder using a
target folder, this is the original IR triggering the issue:

```
@m2 = internal alias { [1 x i64] }, ptr @k0
@k0 = private constant {{ [1 x i64] }} {
  { [1 x i64] }
    {
      [1 x i64]
        [
         i64 ptrtoint (ptr getelementptr inbounds ({ [1 x i64] },
                       ptr @m2, i32 0, i32 0, i32 1) to i64)
        ]
    }
  }, align 4
```
@llvmbot
Copy link
Member

llvmbot commented Sep 17, 2025

@llvm/pr-subscribers-llvm-ir

Author: Bruno Cardoso Lopes (bcardosolopes)

Changes

…fsets

Make sure LLVM bails when aliasee aren't present. Found while using mlir-translate --mlir-to-llvm. Added unittest exercises the builder using a target folder, this is the original IR triggering the issue:

@<!-- -->m2 = internal alias { [1 x i64] }, ptr @<!-- -->k0
@<!-- -->k0 = private constant {{ [1 x i64] }} {
  { [1 x i64] }
    {
      [1 x i64]
        [
         i64 ptrtoint (ptr getelementptr inbounds ({ [1 x i64] },
                       ptr @<!-- -->m2, i32 0, i32 0, i32 1) to i64)
        ]
    }
  }, align 4

Full diff: https://github.com/llvm/llvm-project/pull/159214.diff

2 Files Affected:

  • (modified) llvm/lib/IR/Value.cpp (+1-1)
  • (modified) llvm/unittests/IR/InstructionsTest.cpp (+31)
diff --git a/llvm/lib/IR/Value.cpp b/llvm/lib/IR/Value.cpp
index 4e8f359481b81..67b80c2825fd2 100644
--- a/llvm/lib/IR/Value.cpp
+++ b/llvm/lib/IR/Value.cpp
@@ -776,7 +776,7 @@ const Value *Value::stripAndAccumulateConstantOffsets(
                Operator::getOpcode(V) == Instruction::AddrSpaceCast) {
       V = cast<Operator>(V)->getOperand(0);
     } else if (auto *GA = dyn_cast<GlobalAlias>(V)) {
-      if (!GA->isInterposable())
+      if (!GA->isInterposable() && GA->getAliasee())
         V = GA->getAliasee();
     } else if (const auto *Call = dyn_cast<CallBase>(V)) {
         if (const Value *RV = Call->getReturnedArgOperand())
diff --git a/llvm/unittests/IR/InstructionsTest.cpp b/llvm/unittests/IR/InstructionsTest.cpp
index 21d45960dce7c..8aa1783bceaaa 100644
--- a/llvm/unittests/IR/InstructionsTest.cpp
+++ b/llvm/unittests/IR/InstructionsTest.cpp
@@ -10,6 +10,7 @@
 #include "llvm-c/Core.h"
 #include "llvm/ADT/CombinationGenerator.h"
 #include "llvm/ADT/STLExtras.h"
+#include "llvm/Analysis/TargetFolder.h"
 #include "llvm/Analysis/ValueTracking.h"
 #include "llvm/Analysis/VectorUtils.h"
 #include "llvm/AsmParser/Parser.h"
@@ -874,6 +875,36 @@ TEST(InstructionsTest, GEPIndices) {
   delete GEPI;
 }
 
+TEST(InstructionsTest, PtrToIntGEPFolding) {
+  LLVMContext Context;
+  llvm::Module *M = new llvm::Module("PtrToIntGEPFolding", Context);
+  llvm::IRBuilder<llvm::TargetFolder> Builder(
+      Context, llvm::TargetFolder(M->getDataLayout()));
+
+  auto *Int64Ty = Builder.getInt64Ty();
+  auto *ArrTy = llvm::ArrayType::get(Int64Ty, 1);
+  auto *StructTy = llvm::StructType::create(Context, {ArrTy}, "anon_struct");
+
+  // Create alias @m2 to @0
+  llvm::GlobalAlias *AliasM2 = llvm::GlobalAlias::create(
+      StructTy,
+      0, // address space
+      llvm::GlobalValue::InternalLinkage, "m2", (llvm::Constant *)nullptr, M);
+
+  // Build getelementptr for ptrtoint
+  std::vector<llvm::Value *> GEPIdxs = {
+      llvm::ConstantInt::get(llvm::Type::getInt32Ty(Context), 0),
+      llvm::ConstantInt::get(llvm::Type::getInt32Ty(Context), 0),
+      llvm::ConstantInt::get(llvm::Type::getInt32Ty(Context), 1)};
+  llvm::Value *GEP = Builder.CreateGEP(StructTy, AliasM2, GEPIdxs, "",
+                                       llvm::GEPNoWrapFlags::inBounds());
+  // Make sure stripAndAccumulateConstantOffsets can properly handle
+  // GEPs with nullptr global aliasees.
+  llvm::Value *PtrToInt = Builder.CreatePtrToInt(GEP, Int64Ty);
+  EXPECT_TRUE(PtrToInt);
+  delete M;
+}
+
 TEST(InstructionsTest, ZeroIndexGEP) {
   LLVMContext Context;
   DataLayout DL;

@bcardosolopes bcardosolopes requested a review from nikic September 17, 2025 00:36
Copy link
Contributor

@nikic nikic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Per

const Constant *Aliasee = GA.getAliasee();
Check(Aliasee, "Aliasee cannot be NULL!", &GA);
this is ill-formed IR.

Generally speaking, code is not expected to handle ill-formed IR. This would need some additional justification for why we should do this. Why is MLIR generating this invalid alias and expecting it to work?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants