Unverified Commit 9fe04e0c authored by Nathan Gauër's avatar Nathan Gauër Committed by GitHub
Browse files

[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.
parent dc79e2a9
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -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
===============================
+10 −0
Original line number Diff line number Diff line
@@ -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);
+30 −0
Original line number Diff line number Diff line
; 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}
+18 −0
Original line number Diff line number Diff line
; 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}
+18 −0
Original line number Diff line number Diff line
; 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}