summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSanjoy Das <sanjoy@playingwithpointers.com>2016-06-01 16:13:10 +0000
committerSanjoy Das <sanjoy@playingwithpointers.com>2016-06-01 16:13:10 +0000
commitc2cf6ef8e294ac96ea11f8625bf51da8339dd9a2 (patch)
tree48a6736164f596a7e0b7dcf84b5603bfbceb5a2b
parent48622090c73d19a4c534a8667425fed839135a1c (diff)
downloadbcm5719-llvm-c2cf6ef8e294ac96ea11f8625bf51da8339dd9a2.tar.gz
bcm5719-llvm-c2cf6ef8e294ac96ea11f8625bf51da8339dd9a2.zip
[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
-rw-r--r--llvm/docs/LangRef.rst27
-rw-r--r--llvm/lib/IR/Verifier.cpp2
-rw-r--r--llvm/test/Verifier/unsized-types.ll24
3 files changed, 40 insertions, 13 deletions
diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst
index 2a1c7a00049..d9de43e3e4d 100644
--- a/llvm/docs/LangRef.rst
+++ b/llvm/docs/LangRef.rst
@@ -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
@@ -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
diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
index fbf73509403..f7807d1e1b0 100644
--- a/llvm/lib/IR/Verifier.cpp
+++ b/llvm/lib/IR/Verifier.cpp
@@ -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,
@@ -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,
diff --git a/llvm/test/Verifier/unsized-types.ll b/llvm/test/Verifier/unsized-types.ll
new file mode 100644
index 00000000000..64cc36f3174
--- /dev/null
+++ b/llvm/test/Verifier/unsized-types.ll
@@ -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
+}
OpenPOWER on IntegriCloud