[llvm] [IR] Add require-logical-module module flag (PR #193502)

Nathan Gauër via llvm-commits llvm-commits at lists.llvm.org
Thu Apr 30 05:52:15 PDT 2026


https://github.com/Keenuts updated https://github.com/llvm/llvm-project/pull/193502

>From af394c31209882e8c96646a29e89a083b4a7952b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Nathan=20Gau=C3=ABr?= <brioche at google.com>
Date: Wed, 22 Apr 2026 15:33:26 +0200
Subject: [PATCH 1/3] [IR] Add require-logical-module module flag

This module flag is optional and can be set to require the use
of logical alloca/gep instructions.
This flag will have 2 usages:

- tell optimization which flavor of GEP/alloca to emit
- fail loudly if a GEP/alloca is emitted in a module targeting logical.
---
 llvm/lib/IR/Verifier.cpp                      | 10 +++++++
 .../Verifier/logical-pointer-notrequired.ll   | 30 +++++++++++++++++++
 .../logical-pointer-required-failure.ll       | 18 +++++++++++
 .../test/Verifier/logical-pointer-required.ll | 18 +++++++++++
 4 files changed, 76 insertions(+)
 create mode 100644 llvm/test/Verifier/logical-pointer-notrequired.ll
 create mode 100644 llvm/test/Verifier/logical-pointer-required-failure.ll
 create mode 100644 llvm/test/Verifier/logical-pointer-required.ll

diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
index 0074ca181d2e7..d29b92a1c7d01 100644
--- a/llvm/lib/IR/Verifier.cpp
+++ b/llvm/lib/IR/Verifier.cpp
@@ -4471,6 +4471,11 @@ void Verifier::visitShuffleVectorInst(ShuffleVectorInst &SV) {
 }
 
 void Verifier::visitGetElementPtrInst(GetElementPtrInst &GEP) {
+  if (auto *MD = mdconst::extract_or_null<ConstantInt>(
+          GEP.getModule()->getModuleFlag("require-logical-pointer")))
+    Check(!MD->getZExtValue(),
+          "Non-logical getelementptr disallowed for this module.");
+
   Type *TargetTy = GEP.getPointerOperandType()->getScalarType();
 
   Check(isa<PointerType>(TargetTy),
@@ -4732,6 +4737,11 @@ void Verifier::verifySwiftErrorValue(const Value *SwiftErrorVal) {
 }
 
 void Verifier::visitAllocaInst(AllocaInst &AI) {
+  if (auto *MD = mdconst::extract_or_null<ConstantInt>(
+          AI.getModule()->getModuleFlag("require-logical-pointer")))
+    Check(!MD->getZExtValue(),
+          "Non-logical alloca disallowed for this module.");
+
   Type *Ty = AI.getAllocatedType();
   SmallPtrSet<Type*, 4> Visited;
   Check(Ty->isSized(&Visited), "Cannot allocate unsized type", &AI);
diff --git a/llvm/test/Verifier/logical-pointer-notrequired.ll b/llvm/test/Verifier/logical-pointer-notrequired.ll
new file mode 100644
index 0000000000000..0f3c4950e355c
--- /dev/null
+++ b/llvm/test/Verifier/logical-pointer-notrequired.ll
@@ -0,0 +1,30 @@
+; RUN: llvm-as -disable-output %s
+
+%S = type { i32, i32 }
+
+define void @normal_gep(ptr %src, i32 %index) {
+entry:
+  %ptr = getelementptr i8, ptr %src, i32 0
+  ret void
+}
+
+define void @structured_gep(ptr %src, i32 %index) {
+entry:
+  %ptr = call ptr (ptr, ...) @llvm.structured.gep.p0(ptr elementtype([0 x %S]) %src, i32 %index, i32 1)
+  ret void
+}
+
+define void @normal_alloca() {
+entry:
+  %tmp = alloca i32
+  ret void
+}
+
+define void @structured_alloca(ptr %src, i32 %index) {
+entry:
+  %tmp = call elementtype(i32) ptr @llvm.structured.alloca()
+  ret void
+}
+
+!llvm.module.flags = !{!0}
+!0 = !{i32 1, !"require-logical-pointer", i32 0}
diff --git a/llvm/test/Verifier/logical-pointer-required-failure.ll b/llvm/test/Verifier/logical-pointer-required-failure.ll
new file mode 100644
index 0000000000000..3552589f1fbc2
--- /dev/null
+++ b/llvm/test/Verifier/logical-pointer-required-failure.ll
@@ -0,0 +1,18 @@
+; RUN: not llvm-as -disable-output %s 2>&1 | FileCheck %s
+
+define void @gep_with_logical_required(ptr %src, i32 %index) {
+entry:
+; CHECK: Non-logical getelementptr disallowed for this module.
+  %ptr = getelementptr i8, ptr %src, i32 0
+  ret void
+}
+
+define void @alloca_with_logical_required() {
+entry:
+; CHECK: Non-logical alloca disallowed for this module.
+  %tmp = alloca i32
+  ret void
+}
+
+!llvm.module.flags = !{!0}
+!0 = !{i32 1, !"require-logical-pointer", i32 1}
diff --git a/llvm/test/Verifier/logical-pointer-required.ll b/llvm/test/Verifier/logical-pointer-required.ll
new file mode 100644
index 0000000000000..6abdecc4a8576
--- /dev/null
+++ b/llvm/test/Verifier/logical-pointer-required.ll
@@ -0,0 +1,18 @@
+; RUN: llvm-as -disable-output %s
+
+%S = type { i32, i32 }
+
+define void @structured_gep_allowed(ptr %src, i32 %index) {
+entry:
+  %ptr = call ptr (ptr, ...) @llvm.structured.gep.p0(ptr elementtype([0 x %S]) %src, i32 %index, i32 1)
+  ret void
+}
+
+define void @structured_alloca_allowed(ptr %src, i32 %index) {
+entry:
+  %tmp = call elementtype(i32) ptr @llvm.structured.alloca()
+  ret void
+}
+
+!llvm.module.flags = !{!0}
+!0 = !{i32 1, !"require-logical-pointer", i32 1}

>From 7c31705cfa10b57837496d76d9dc79c16de1f06e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Nathan=20Gau=C3=ABr?= <brioche at google.com>
Date: Thu, 30 Apr 2026 14:42:03 +0200
Subject: [PATCH 2/3] add langref

---
 llvm/docs/LangRef.rst | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst
index c73d03dcb6ad9..50964169f8438 100644
--- a/llvm/docs/LangRef.rst
+++ b/llvm/docs/LangRef.rst
@@ -9153,6 +9153,14 @@ flags metadata, using the following key-value pairs:
        * 2 --- CFG uses the "dispatch" mechanism. This calls a dispatcher
          function which both checks and then calls the target.
 
+Other Module Flags
+------------------
+
+``require-logical-pointer``
+    This flag indicates this module must only user logical pointer intrinsics
+    such as '``llvm.structured.gep``' or '``llvm.structured.alloca``'.
+    Using a normal '``getelementptr``' or '``alloca``' is illegal.
+
 Embedded Objects Names Metadata
 ===============================
 

>From af2b6039bb85c5b8b8b3f36a0a085f93f3a6b3e4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Nathan=20Gau=C3=ABr?= <brioche at google.com>
Date: Thu, 30 Apr 2026 14:50:32 +0200
Subject: [PATCH 3/3] typo + fix ref to instructions

---
 llvm/docs/LangRef.rst | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst
index 50964169f8438..b574021ee2e80 100644
--- a/llvm/docs/LangRef.rst
+++ b/llvm/docs/LangRef.rst
@@ -9157,9 +9157,11 @@ Other Module Flags
 ------------------
 
 ``require-logical-pointer``
-    This flag indicates this module must only user logical pointer intrinsics
-    such as '``llvm.structured.gep``' or '``llvm.structured.alloca``'.
-    Using a normal '``getelementptr``' or '``alloca``' is illegal.
+    This flag indicates this module must only use logical pointer intrinsics
+    such as :ref:`@llvm.structured.gep <i_structured_gep>` or
+    :ref:`@llvm.structured.alloca <i_structured_alloca>`.
+    Using a normal :ref:`getelementptr <i_getelementptr>` or
+    :ref:`alloca <i_alloca>` is illegal.
 
 Embedded Objects Names Metadata
 ===============================



More information about the llvm-commits mailing list