[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