Skip to content

Commit c2cf6ef

Browse files
committedJun 1, 2016
[IR] Disallow loading and storing unsized types
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
1 parent 4862209 commit c2cf6ef

File tree

3 files changed

+40
-13
lines changed

3 files changed

+40
-13
lines changed
 

Diff for: ‎llvm/docs/LangRef.rst

+14-13
Original file line numberDiff line numberDiff line change
@@ -6978,12 +6978,12 @@ The '``load``' instruction is used to read from memory.
69786978
Arguments:
69796979
""""""""""
69806980

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

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

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

71127113
If the ``store`` is marked as ``atomic``, it takes an extra :ref:`ordering
71137114
<ordering>` and optional ``singlethread`` argument. The ``acquire`` and

Diff for: ‎llvm/lib/IR/Verifier.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -2963,6 +2963,7 @@ void Verifier::visitLoadInst(LoadInst &LI) {
29632963
Type *ElTy = LI.getType();
29642964
Assert(LI.getAlignment() <= Value::MaximumAlignment,
29652965
"huge alignment values are unsupported", &LI);
2966+
Assert(ElTy->isSized(), "loading unsized types is not allowed", &LI);
29662967
if (LI.isAtomic()) {
29672968
Assert(LI.getOrdering() != AtomicOrdering::Release &&
29682969
LI.getOrdering() != AtomicOrdering::AcquireRelease,
@@ -2991,6 +2992,7 @@ void Verifier::visitStoreInst(StoreInst &SI) {
29912992
"Stored value type does not match pointer operand type!", &SI, ElTy);
29922993
Assert(SI.getAlignment() <= Value::MaximumAlignment,
29932994
"huge alignment values are unsupported", &SI);
2995+
Assert(ElTy->isSized(), "storing unsized types is not allowed", &SI);
29942996
if (SI.isAtomic()) {
29952997
Assert(SI.getOrdering() != AtomicOrdering::Acquire &&
29962998
SI.getOrdering() != AtomicOrdering::AcquireRelease,

Diff for: ‎llvm/test/Verifier/unsized-types.ll

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
; RUN: not opt -verify < %s 2>&1 | FileCheck %s
2+
3+
%X = type opaque
4+
5+
define void @f_0(%X* %ptr) {
6+
%t = load %X, %X* %ptr
7+
ret void
8+
; CHECK: loading unsized types is not allowed
9+
; CHECK-NEXT: %t = load %X, %X* %ptr
10+
}
11+
12+
define void @f_1(%X %val, %X* %ptr) {
13+
store %X %val, %X* %ptr
14+
ret void
15+
; CHECK: storing unsized types is not allowed
16+
; CHECK-NEXT: store %X %val, %X* %ptr
17+
}
18+
19+
define void @f_2() {
20+
%t = alloca %X
21+
ret void
22+
; CHECK: Cannot allocate unsized type
23+
; CHECK-NEXT: %t = alloca %X
24+
}

0 commit comments

Comments
 (0)