Skip to content

Commit

Permalink
[IR] Disallow loading and storing unsized types
Browse files Browse the repository at this point in the history
Summary:
It isn't clear what is the operational meaning of loading or storing an
unsized types, since it cannot be lowered into something meaningful.
Since there does not seem to be any practical need for it either, make
such loads and stores illegal IR.

Reviewers: majnemer, chandlerc

Subscribers: mcrosier, llvm-commits

Differential Revision: http://reviews.llvm.org/D20846

llvm-svn: 271402
  • Loading branch information
sanjoy committed Jun 1, 2016
1 parent 4862209 commit c2cf6ef
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 13 deletions.
27 changes: 14 additions & 13 deletions llvm/docs/LangRef.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6978,12 +6978,12 @@ The '``load``' instruction is used to read from memory.
Arguments:
""""""""""

The argument to the ``load`` instruction specifies the memory address
from which to load. The type specified must be a :ref:`first
class <t_firstclass>` type. If the ``load`` is marked as ``volatile``,
then the optimizer is not allowed to modify the number or order of
execution of this ``load`` with other :ref:`volatile
operations <volatile>`.
The argument to the ``load`` instruction specifies the memory address from which
to load. The type specified must be a :ref:`first class <t_firstclass>` type of
known size (i.e. not containing an :ref:`opaque structural type <t_opaque>`). If
the ``load`` is marked as ``volatile``, then the optimizer is not allowed to
modify the number or order of execution of this ``load`` with other
:ref:`volatile operations <volatile>`.

If the ``load`` is marked as ``atomic``, it takes an extra :ref:`ordering
<ordering>` and optional ``singlethread`` argument. The ``release`` and
Expand Down Expand Up @@ -7101,13 +7101,14 @@ The '``store``' instruction is used to write to memory.
Arguments:
""""""""""

There are two arguments to the ``store`` instruction: a value to store
and an address at which to store it. The type of the ``<pointer>``
operand must be a pointer to the :ref:`first class <t_firstclass>` type of
the ``<value>`` operand. If the ``store`` is marked as ``volatile``,
then the optimizer is not allowed to modify the number or order of
execution of this ``store`` with other :ref:`volatile
operations <volatile>`.
There are two arguments to the ``store`` instruction: a value to store and an
address at which to store it. The type of the ``<pointer>`` operand must be a
pointer to the :ref:`first class <t_firstclass>` type of the ``<value>``
operand. If the ``store`` is marked as ``volatile``, then the optimizer is not
allowed to modify the number or order of execution of this ``store`` with other
:ref:`volatile operations <volatile>`. Only values of :ref:`first class
<t_firstclass>` types of known size (i.e. not containing an :ref:`opaque
structural type <t_opaque>`) can be stored.

If the ``store`` is marked as ``atomic``, it takes an extra :ref:`ordering
<ordering>` and optional ``singlethread`` argument. The ``acquire`` and
Expand Down
2 changes: 2 additions & 0 deletions llvm/lib/IR/Verifier.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2963,6 +2963,7 @@ void Verifier::visitLoadInst(LoadInst &LI) {
Type *ElTy = LI.getType();
Assert(LI.getAlignment() <= Value::MaximumAlignment,
"huge alignment values are unsupported", &LI);
Assert(ElTy->isSized(), "loading unsized types is not allowed", &LI);
if (LI.isAtomic()) {
Assert(LI.getOrdering() != AtomicOrdering::Release &&
LI.getOrdering() != AtomicOrdering::AcquireRelease,
Expand Down Expand Up @@ -2991,6 +2992,7 @@ void Verifier::visitStoreInst(StoreInst &SI) {
"Stored value type does not match pointer operand type!", &SI, ElTy);
Assert(SI.getAlignment() <= Value::MaximumAlignment,
"huge alignment values are unsupported", &SI);
Assert(ElTy->isSized(), "storing unsized types is not allowed", &SI);
if (SI.isAtomic()) {
Assert(SI.getOrdering() != AtomicOrdering::Acquire &&
SI.getOrdering() != AtomicOrdering::AcquireRelease,
Expand Down
24 changes: 24 additions & 0 deletions llvm/test/Verifier/unsized-types.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
; RUN: not opt -verify < %s 2>&1 | FileCheck %s

%X = type opaque

define void @f_0(%X* %ptr) {
%t = load %X, %X* %ptr
ret void
; CHECK: loading unsized types is not allowed
; CHECK-NEXT: %t = load %X, %X* %ptr
}

define void @f_1(%X %val, %X* %ptr) {
store %X %val, %X* %ptr
ret void
; CHECK: storing unsized types is not allowed
; CHECK-NEXT: store %X %val, %X* %ptr
}

define void @f_2() {
%t = alloca %X
ret void
; CHECK: Cannot allocate unsized type
; CHECK-NEXT: %t = alloca %X
}

0 comments on commit c2cf6ef

Please sign in to comment.