[llvm] 9fe04e0 - [IR] Add require-logical-module module flag (#193502)
via llvm-commits
llvm-commits at lists.llvm.org
Mon May 4 02:37:02 PDT 2026
Author: Nathan Gauër
Date: 2026-05-04T11:36:57+02:00
New Revision: 9fe04e0c52ca644c8c5d07589f7f5a6752557741
URL: https://github.com/llvm/llvm-project/commit/9fe04e0c52ca644c8c5d07589f7f5a6752557741
DIFF: https://github.com/llvm/llvm-project/commit/9fe04e0c52ca644c8c5d07589f7f5a6752557741.diff
LOG: [IR] Add require-logical-module module flag (#193502)
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.
Added:
llvm/test/Verifier/logical-pointer-notrequired.ll
llvm/test/Verifier/logical-pointer-required-failure.ll
llvm/test/Verifier/logical-pointer-required.ll
Modified:
llvm/docs/LangRef.rst
llvm/lib/IR/Verifier.cpp
Removed:
################################################################################
diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst
index abaa128f03db2..a1442a2a607d3 100644
--- a/llvm/docs/LangRef.rst
+++ b/llvm/docs/LangRef.rst
@@ -9253,6 +9253,16 @@ 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 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
===============================
diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
index 79d4834a7a30d..81903edfbd5f1 100644
--- a/llvm/lib/IR/Verifier.cpp
+++ b/llvm/lib/IR/Verifier.cpp
@@ -4488,6 +4488,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),
@@ -4749,6 +4754,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}
More information about the llvm-commits
mailing list