aboutsummaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/NaCl/PNaClABI/abi-debug-info.ll37
-rw-r--r--test/NaCl/PNaClABI/abi-metadata.ll11
-rw-r--r--test/NaCl/PNaClABI/abi-small-arguments.ll17
-rw-r--r--test/NaCl/PNaClABI/abi-stripped-pointers.ll131
-rw-r--r--test/NaCl/PNaClABI/abi-switch.ll31
-rw-r--r--test/NaCl/PNaClABI/abi-varargs.ll2
-rw-r--r--test/NaCl/PNaClABI/instructions.ll61
-rw-r--r--test/NaCl/PNaClABI/types-function.ll13
-rw-r--r--test/NaCl/PNaClABI/types.ll56
-rw-r--r--test/Transforms/NaCl/replace-ptrs-with-ints.ll8
10 files changed, 292 insertions, 75 deletions
diff --git a/test/NaCl/PNaClABI/abi-debug-info.ll b/test/NaCl/PNaClABI/abi-debug-info.ll
new file mode 100644
index 0000000000..95efa0ced7
--- /dev/null
+++ b/test/NaCl/PNaClABI/abi-debug-info.ll
@@ -0,0 +1,37 @@
+; RUN: pnacl-abicheck -pnaclabi-allow-dev-intrinsics=0 < %s | FileCheck %s
+; RUN: pnacl-abicheck -pnaclabi-allow-dev-intrinsics=0 \
+; RUN: -pnaclabi-allow-debug-metadata < %s | FileCheck %s --check-prefix=DBG
+; RUN: pnacl-abicheck -pnaclabi-allow-dev-intrinsics=1 < %s | \
+; RUN: FileCheck %s --check-prefix=DBG
+
+
+; DBG-NOT: disallowed
+
+
+declare void @llvm.dbg.declare(metadata, metadata)
+declare void @llvm.dbg.value(metadata, i64, metadata)
+
+; CHECK: Function llvm.dbg.declare is a disallowed LLVM intrinsic
+; CHECK: Function llvm.dbg.value is a disallowed LLVM intrinsic
+
+
+define void @debug_declare(i32 %val) {
+ ; We normally expect llvm.dbg.declare to be used on an alloca.
+ %var = alloca [4 x i8]
+ tail call void @llvm.dbg.declare(metadata !{[4 x i8]* %var}, metadata !{})
+ tail call void @llvm.dbg.declare(metadata !{i32 %val}, metadata !{})
+ ret void
+}
+
+define void @debug_value(i32 %ptr_as_int, i32 %val) {
+ %ptr = inttoptr i32 %ptr_as_int to i8*
+ tail call void @llvm.dbg.value(metadata !{i8* %ptr}, i64 2, metadata !{})
+ tail call void @llvm.dbg.value(metadata !{i32 %val}, i64 1, metadata !{})
+ ret void
+}
+
+; FileCheck gives an error if its input file is empty, so ensure that
+; the output of pnacl-abicheck is non-empty by generating at least one
+; error.
+declare void @bad_func(ppc_fp128 %bad_arg)
+; DBG: Function bad_func has disallowed type: void (ppc_fp128)
diff --git a/test/NaCl/PNaClABI/abi-metadata.ll b/test/NaCl/PNaClABI/abi-metadata.ll
index 4734c25973..751a3d3673 100644
--- a/test/NaCl/PNaClABI/abi-metadata.ll
+++ b/test/NaCl/PNaClABI/abi-metadata.ll
@@ -2,12 +2,13 @@
; RUN: pnacl-abicheck -pnaclabi-allow-debug-metadata < %s | FileCheck %s --check-prefix=DEBUG
-; If the metadata is allowed we want to check for types.
-; We have a hacky way to test this. The -allow-debug-metadata whitelists debug
-; metadata. That allows us to check types within debug metadata, even though
-; debug metadata normally does not have illegal types.
+; Metadata is not part of the PNaCl's stable ABI, so normally the ABI
+; checker rejects metadata entirely. However, for debugging support,
+; pre-finalized pexes may contain metadata. When checking a
+; pre-finalized pexe, the ABI checker does not check the types in the
+; metadata.
+
; DEBUG-NOT: Named metadata node llvm.dbg.cu is disallowed
-; DEBUG: Named metadata node llvm.dbg.cu refers to disallowed type: half
; CHECK: Named metadata node llvm.dbg.cu is disallowed
!llvm.dbg.cu = !{!0}
!0 = metadata !{ half 0.0}
diff --git a/test/NaCl/PNaClABI/abi-small-arguments.ll b/test/NaCl/PNaClABI/abi-small-arguments.ll
index 890b84c42a..ce698e7d47 100644
--- a/test/NaCl/PNaClABI/abi-small-arguments.ll
+++ b/test/NaCl/PNaClABI/abi-small-arguments.ll
@@ -21,25 +21,32 @@ define i8 @return_i8() {
; CHECK: Function return_i8 has disallowed type:
-; Direct calls currently do not produce errors because the functions
-; are deemed to have already been flagged.
-; CHECK-NOT: disallowed
define void @bad_direct_calls() {
call void @arg_i1(i1 0)
+; CHECK: bad function callee operand: call void @arg_i1
+
call void @arg_i16(i32 0, i16 0)
+; CHECK-NEXT: bad function callee operand: call void @arg_i16
+
%result1 = call i1 @return_i1()
+; CHECK-NEXT: bad function callee operand: {{.*}} call i1 @return_i1
+
%result2 = call i8 @return_i8()
+; CHECK-NEXT: bad function callee operand: {{.*}} call i8 @return_i8
+
ret void
}
define void @bad_indirect_calls(i32 %ptr) {
%func1 = inttoptr i32 %ptr to void (i8)*
+; CHECK: bad result type: %func1
call void %func1(i8 0)
-; CHECK: Function bad_indirect_calls has instruction with disallowed type: void (i8)*
+; CHECK: bad function callee operand: {{.*}} %func1
%func2 = inttoptr i32 %ptr to i16 ()*
+; CHECK: bad result type: %func2
%result3 = call i16 %func2()
-; CHECK: Function bad_indirect_calls has instruction with disallowed type: i16 ()*
+; CHECK: bad function callee operand: {{.*}} %func2
ret void
}
diff --git a/test/NaCl/PNaClABI/abi-stripped-pointers.ll b/test/NaCl/PNaClABI/abi-stripped-pointers.ll
new file mode 100644
index 0000000000..c994b7d009
--- /dev/null
+++ b/test/NaCl/PNaClABI/abi-stripped-pointers.ll
@@ -0,0 +1,131 @@
+; RUN: pnacl-abicheck < %s | FileCheck %s
+
+; This test checks that the PNaCl ABI verifier enforces the normal
+; form introduced by the ReplacePtrsWithInts pass.
+
+
+@var = global [4 x i8] c"xxxx"
+@ptr = global i32 ptrtoint ([4 x i8]* @var to i32)
+
+declare i8* @llvm.nacl.read.tp()
+
+
+define void @pointer_arg(i8* %arg) {
+ ret void
+}
+; CHECK: Function pointer_arg has disallowed type
+
+define i8* @pointer_return() {
+ unreachable
+}
+; CHECK-NEXT: Function pointer_return has disallowed type
+
+define void @func() {
+ ret void
+}
+
+define void @func_with_arg(i32 %arg) {
+ ret void
+}
+
+
+define void @allowed_cases(i32 %arg) {
+ inttoptr i32 123 to i8*
+
+ ptrtoint [4 x i8]* @var to i32
+
+ %alloc = alloca [1 x i8]
+ ptrtoint [1 x i8]* %alloc to i32
+
+ ; These instructions may use a NormalizedPtr, which may be a global.
+ load i32* @ptr
+ store i32 123, i32* @ptr
+ cmpxchg i32* @ptr, i32 1, i32 2 seq_cst
+ atomicrmw add i32* @ptr, i32 3 seq_cst
+
+ ; A NormalizedPtr may be a bitcast.
+ %ptr_bitcast = bitcast [4 x i8]* @var to i32*
+ load i32* %ptr_bitcast
+
+ ; A NormalizedPtr may be an inttoptr.
+ %ptr_from_int = inttoptr i32 123 to i32*
+ load i32* %ptr_from_int
+
+ ; Check direct and indirect function calls.
+ %func_as_int = ptrtoint void ()* @func to i32
+ %func_ptr = inttoptr i32 %func_as_int to void ()*
+ call void %func_ptr()
+ call void @func()
+ call void @func_with_arg(i32 123)
+
+ ; Intrinsic calls may return pointers.
+ %thread_ptr = call i8* @llvm.nacl.read.tp()
+ ptrtoint i8* %thread_ptr to i32
+
+ ; Bitcasts between non-pointers are not restricted
+ bitcast i64 0 to double
+ bitcast i32 0 to float
+
+ ; ConstantInts and Arguments are allowed as operands.
+ add i32 %arg, 123
+
+ ret void
+}
+; CHECK-NOT: disallowed
+
+
+define void @bad_cases() {
+entry:
+ ptrtoint [4 x i8]* @var to i16
+; CHECK: Function bad_cases disallowed: non-i32 ptrtoint
+
+ inttoptr i16 123 to i8*
+; CHECK-NEXT: non-i32 inttoptr
+
+ %a = alloca i32
+; CHECK-NEXT: non-i8-array alloca
+
+ store i32 0, i32* null
+; CHECK-NEXT: bad pointer
+
+ store i32 0, i32* undef
+; CHECK-NEXT: bad pointer
+
+ %bc = bitcast i32* @ptr to i31*
+; CHECK-NEXT: bad result type
+ store i31 0, i31* %bc
+; CHECK-NEXT: bad pointer
+
+ ; Only one level of bitcasts is allowed.
+ %b = bitcast i32* %a to i8*
+ %c = bitcast i8* %b to i16*
+; CHECK-NEXT: operand not InherentPtr
+
+ br label %block
+block:
+ %phi1 = phi i8* [ undef, %entry ]
+; CHECK-NEXT: bad operand: %phi1
+ %phi2 = phi i32* [ undef, %entry ]
+; CHECK-NEXT: bad operand: %phi2
+
+ icmp eq i32* @ptr, @ptr
+; CHECK-NEXT: bad operand: {{.*}} icmp
+ icmp eq void ()* @func, @func
+; CHECK-NEXT: bad operand: {{.*}} icmp
+ icmp eq i31 0, 0
+; CHECK-NEXT: bad operand: {{.*}} icmp
+
+ call void null()
+; CHECK-NEXT: bad function callee operand
+
+ call void @func_with_arg(i32 ptrtoint (i32* @ptr to i32))
+; CHECK-NEXT: bad operand
+
+ ; Taking the address of an intrinsic is not allowed.
+ ptrtoint i8* ()* @llvm.nacl.read.tp to i32
+; CHECK-NEXT: operand not InherentPtr
+
+ ret void
+}
+
+; CHECK-NOT: disallowed
diff --git a/test/NaCl/PNaClABI/abi-switch.ll b/test/NaCl/PNaClABI/abi-switch.ll
new file mode 100644
index 0000000000..a3b5e631fc
--- /dev/null
+++ b/test/NaCl/PNaClABI/abi-switch.ll
@@ -0,0 +1,31 @@
+; RUN: pnacl-abicheck < %s | FileCheck %s
+
+@var = global [4 x i8] c"xxxx"
+
+
+; CHECK-NOT: disallowed
+
+define void @bad_cases() {
+ ; ConstantExprs should be rejected here.
+ switch i32 ptrtoint ([4 x i8]* @var to i32), label %next [i32 0, label %next]
+; CHECK: disallowed: bad switch condition
+next:
+
+ ; Bad integer type.
+ switch i32 0, label %next [i99 0, label %next]
+; CHECK: bad switch case
+
+ ; Bad integer type.
+ switch i32 0, label %next [i32 0, label %next
+ i99 1, label %next]
+; CHECK: bad switch case
+
+ ; Note that the reader only allows ConstantInts in the label list.
+ ; We don't need to check the following, because the reader rejects
+ ; it:
+ ; switch i32 0, label %next [i32 ptrtoint (i32* @ptr to i32), label %next]
+
+ ret void
+}
+
+; CHECK-NOT: disallowed
diff --git a/test/NaCl/PNaClABI/abi-varargs.ll b/test/NaCl/PNaClABI/abi-varargs.ll
index 6eda0b9b53..dac94e00e0 100644
--- a/test/NaCl/PNaClABI/abi-varargs.ll
+++ b/test/NaCl/PNaClABI/abi-varargs.ll
@@ -10,4 +10,4 @@ define void @call_varargs_func(i32 %ptr) {
call void (i32, ...)* %ptr2(i32 123)
ret void
}
-; CHECK: Function call_varargs_func has instruction with disallowed type: void (i32, ...)*
+; CHECK: Function call_varargs_func disallowed: bad function callee operand: call void (i32, ...)*
diff --git a/test/NaCl/PNaClABI/instructions.ll b/test/NaCl/PNaClABI/instructions.ll
index 0076c3d07c..57d1ec856b 100644
--- a/test/NaCl/PNaClABI/instructions.ll
+++ b/test/NaCl/PNaClABI/instructions.ll
@@ -1,6 +1,5 @@
; RUN: pnacl-abicheck < %s | FileCheck %s
; Test instruction opcodes allowed by PNaCl ABI
-; No testing yet of operands, types, attributes, etc
target datalayout = "e-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-p:32:32:32-v128:32:32"
target triple = "le32-unknown-nacl"
@@ -15,7 +14,7 @@ next:
next2:
unreachable
; CHECK-NOT: disallowed
-; CHECK: Function terminators has disallowed instruction: indirectbr
+; CHECK: Function terminators disallowed: bad instruction opcode: indirectbr
indirectbr i8* undef, [label %next, label %next2]
}
@@ -44,37 +43,43 @@ define void @binops() {
define void @vectors() {
; CHECK-NOT: disallowed
-; CHECK: Function vectors has disallowed instruction: extractelement
+
+; CHECK: disallowed: bad instruction opcode: {{.*}} extractelement
%a1 = extractelement <2 x i32> <i32 0, i32 0>, i32 0
-; CHECK: Function vectors has disallowed instruction: shufflevector
+
+; CHECK: disallowed: bad instruction opcode: {{.*}} shufflevector
%a2 = shufflevector <2 x i32> undef, <2 x i32> undef, <2 x i32> undef
-; CHECK: Function vectors has disallowed instruction: insertelement
-; CHECK: Function vectors has instruction with disallowed type
-; CHECK: Function vectors has instruction operand with disallowed type
+
+; CHECK: disallowed: bad instruction opcode: {{.*}} insertelement
%a3 = insertelement <2 x i32> undef, i32 1, i32 0
+
ret void
}
define void @aggregates() {
+; CHECK-NOT: disallowed
+
; Aggregate operations
%a1 = extractvalue { i32, i32 } { i32 0, i32 0 }, 0
-; CHECK-NOT: disallowed
-; CHECK: Function aggregates has disallowed instruction: extractvalue
+; CHECK: disallowed: bad instruction opcode: {{.*}} extractvalue
+
%a2 = insertvalue {i32, float} undef, i32 1, 0
-; CHECK-NEXT: Function aggregates has disallowed instruction: insertvalue
+; CHECK-NEXT: disallowed: bad instruction opcode: {{.*}} insertvalue
+
ret void
}
define void @memory() {
; Memory operations
- %a1 = alloca i32
- %a2 = load i32* undef
- store i32 undef, i32* undef
+ %a1 = alloca [4 x i8]
+ %ptr = inttoptr i32 0 to i32*
+ %a2 = load i32* %ptr
+ store i32 undef, i32* %ptr
fence acq_rel
- %a3 = cmpxchg i32* undef, i32 undef, i32 undef acq_rel
- %a4 = atomicrmw add i32* undef, i32 1 acquire
+ %a3 = cmpxchg i32* %ptr, i32 undef, i32 undef acq_rel
+ %a4 = atomicrmw add i32* %ptr, i32 1 acquire
; CHECK-NOT: disallowed
-; CHECK: Function memory has disallowed instruction: getelementptr
+; CHECK: disallowed: bad instruction opcode: {{.*}} getelementptr
%a5 = getelementptr { i32, i32}* undef
ret void
}
@@ -90,9 +95,6 @@ define void @conversion() {
%a7 = fptosi double undef to i64
%a8 = uitofp i64 undef to double
%a9 = sitofp i64 undef to double
- %a10 = ptrtoint i8* undef to i32
- %a11 = inttoptr i32 undef to i8*
- %a12 = bitcast i8* undef to i32*
ret void
}
@@ -117,40 +119,41 @@ declare void @personality_func()
define void @invoke_func() {
invoke void @external_func() to label %ok unwind label %onerror
; CHECK-NOT: disallowed
-; CHECK: Function invoke_func has disallowed instruction: invoke
+; CHECK: disallowed: bad instruction opcode: invoke
ok:
ret void
onerror:
%lp = landingpad i32
personality i8* bitcast (void ()* @personality_func to i8*)
catch i32* null
-; CHECK-NEXT: Function invoke_func has disallowed instruction: landingpad
-; CHECK-NEXT: Function invoke_func contains disallowed ConstantExpr
+; CHECK: disallowed: bad instruction opcode: {{.*}} landingpad
resume i32 %lp
-; CHECK-NEXT: Function invoke_func has disallowed instruction: resume
+; CHECK: disallowed: bad instruction opcode: resume
}
-define i32 @va_arg(i8* %va_list) {
+define i32 @va_arg(i32 %va_list_as_int) {
+ %va_list = inttoptr i32 %va_list_as_int to i8*
%val = va_arg i8* %va_list, i32
ret i32 %val
}
; CHECK-NOT: disallowed
-; CHECK: Function va_arg has disallowed instruction: va_arg
+; CHECK: disallowed: bad instruction opcode: {{.*}} va_arg
@global_var = global [4 x i8] zeroinitializer
-define i8* @constantexpr() {
- ret i8* getelementptr ([4 x i8]* @global_var, i32 1, i32 0)
+define void @constantexpr() {
+ ptrtoint i8* getelementptr ([4 x i8]* @global_var, i32 1, i32 0) to i32
+ ret void
}
; CHECK-NOT: disallowed
-; CHECK: Function constantexpr contains disallowed ConstantExpr
+; CHECK: disallowed: operand not InherentPtr: %1 = ptrtoint i8* getelementptr
define void @inline_asm() {
call void asm "foo", ""()
ret void
}
; CHECK-NOT: disallowed
-; CHECK: Function inline_asm contains disallowed inline assembly
+; CHECK: disallowed: inline assembly: call void asm "foo", ""()
; CHECK-NOT: disallowed
; If another check is added, there should be a check-not in between each check
diff --git a/test/NaCl/PNaClABI/types-function.ll b/test/NaCl/PNaClABI/types-function.ll
index 32004d39ad..1482c727f0 100644
--- a/test/NaCl/PNaClABI/types-function.ll
+++ b/test/NaCl/PNaClABI/types-function.ll
@@ -4,22 +4,27 @@
; stashed in various places in function bodies are caught.
@a2 = private global i17 zeroinitializer
+
+; CHECK: Function func has disallowed type: void (i15)
declare void @func(i15 %arg)
!llvm.foo = !{!0}
!0 = metadata !{ half 0.0}
define void @types() {
-; CHECK: Function types has instruction with disallowed type: half
+; CHECK: bad result type: {{.*}} fptrunc
%h1 = fptrunc double undef to half
-; CHECK: Function types has instruction operand with disallowed type: half
+
+; CHECK: bad operand: {{.*}} bitcast half
%h2 = bitcast half 0.0 to i16
+
; see below...
%h3 = fadd double 0.0, fpext (half 0.0 to double)
-; CHECK: Function types has instruction operand with disallowed type: i17*
+; CHECK: bad pointer: store
store i32 0, i32* bitcast (i17* @a2 to i32*), align 4
-; CHECK: Function types has instruction operand with disallowed type: i15
+
+; CHECK: bad function callee operand: call void @func(i15 1)
call void @func(i15 1)
; CHECK: Function types has disallowed instruction metadata: !foo
diff --git a/test/NaCl/PNaClABI/types.ll b/test/NaCl/PNaClABI/types.ll
index 7587609d11..b1527ec111 100644
--- a/test/NaCl/PNaClABI/types.ll
+++ b/test/NaCl/PNaClABI/types.ll
@@ -34,66 +34,59 @@ block:
; Disallowed integer types
phi i4 [ undef, %entry ]
-; CHECK: Function func has instruction with disallowed type: i4
+; CHECK: Function func disallowed: bad operand: {{.*}} i4
phi i33 [ undef, %entry ]
-; CHECK: instruction with disallowed type: i33
+; CHECK-NEXT: disallowed: bad operand: {{.*}} i33
phi i128 [ undef, %entry ]
-; CHECK: instruction with disallowed type: i128
+; CHECK-NEXT: disallowed: bad operand: {{.*}} i128
; Disallowed floating point types
phi half [ undef, %entry ]
-; CHECK: instruction with disallowed type: half
+; CHECK-NEXT: disallowed: bad operand: {{.*}} half
phi x86_fp80 [ undef, %entry ]
-; CHECK: instruction with disallowed type: x86_fp80
+; CHECK-NEXT: disallowed: bad operand: {{.*}} x86_fp80
phi fp128 [ undef, %entry ]
-; CHECK: instruction with disallowed type: fp128
+; CHECK-NEXT: disallowed: bad operand: {{.*}} fp128
phi ppc_fp128 [ undef, %entry ]
-; CHECK: instruction with disallowed type: ppc_fp128
+; CHECK-NEXT: disallowed: bad operand: {{.*}} ppc_fp128
phi x86_mmx [ undef, %entry ]
-; CHECK: instruction with disallowed type: x86_mmx
-; CHECK: instruction operand with disallowed type: x86_mmx
+; CHECK-NEXT: disallowed: bad operand: {{.*}} x86_mmx
- ; Derived types
+ ; Derived types are disallowed too
- ; TODO(mseaborn): These are currently allowed but should be disallowed.
phi i32* [ undef, %entry ]
+; CHECK-NEXT: disallowed: bad operand: {{.*}} i32*
+
phi [1 x i32] [ undef, %entry ]
+; CHECK-NEXT: disallowed: bad operand: {{.*}} [1 x i32]
+
phi { i32, float } [ undef, %entry ]
+; CHECK-NEXT: disallowed: bad operand: {{.*}} { i32, float }
+
phi void (i32)* [ undef, %entry ]
- phi <{ i8, i32 }> [ undef, %entry ]
- phi { i32, { i32, double }, float } [ undef, %entry ]
-; CHECK-NOT: disallowed
+; CHECK-NEXT: disallowed: bad operand: {{.*}} void (i32)*
- ; Derived types containing disallowed types
- phi half* [ undef, %entry ]
-; CHECK: instruction with disallowed type: half*
- phi [2 x i33] [ undef, %entry ]
-; CHECK: instruction with disallowed type: [2 x i33]
- phi { half, i32 } [ undef, %entry ]
-; CHECK: instruction with disallowed type: { half, i32 }
- phi { float, i33 } [ undef, %entry ]
-; CHECK: instruction with disallowed type: { float, i33 }
- phi { i32, { i32, half }, float } [ undef, %entry ]
-; CHECK: instruction with disallowed type: { i32, { i32, half }, float }
+ phi <{ i8, i32 }> [ undef, %entry ]
+; CHECK-NEXT: disallowed: bad operand: {{.*}} <{ i8, i32 }>
; Vector types are disallowed
phi <2 x i32> [ undef, %entry ]
-; CHECK: instruction with disallowed type: <2 x i32>
+; CHECK-NEXT: disallowed: bad operand: {{.*}} <2 x i32>
ret void
}
-; named types. with the current implementation, bogus named types are legal
+; Named types. With the current implementation, named types are legal
; until they are actually attempted to be used. Might want to fix that.
%struct.s1 = type { half, float}
%struct.s2 = type { i32, i32}
@@ -104,11 +97,10 @@ entry:
block:
phi %struct.s1 [ undef, %entry ]
-; CHECK: instruction with disallowed type: %struct.s1 = type { half, float }
-; CHECK: instruction operand with disallowed type: %struct.s1 = type { half, float }
+; CHECK: disallowed: bad operand: {{.*}} %struct.s1
phi %struct.s2 [ undef, %entry ]
-; CHECK-NOT: disallowed
+; CHECK-NEXT: disallowed: bad operand: {{.*}} %struct.s2
ret void
}
@@ -129,8 +121,10 @@ entry:
block:
phi %struct.snake [ undef, %entry ]
+; CHECK: disallowed: bad operand: {{.*}} %struct.snake
+
phi %struct.linked [ undef, %entry ]
-; CHECK-NOT: disallowed
+; CHECK-NEXT: disallowed: bad operand: {{.*}} %struct.linked
ret void
}
diff --git a/test/Transforms/NaCl/replace-ptrs-with-ints.ll b/test/Transforms/NaCl/replace-ptrs-with-ints.ll
index 5a8f58dbaf..823697d738 100644
--- a/test/Transforms/NaCl/replace-ptrs-with-ints.ll
+++ b/test/Transforms/NaCl/replace-ptrs-with-ints.ll
@@ -202,6 +202,14 @@ define i16* @constant_pointer_null_load() {
; CHECK-NEXT: %.asptr = inttoptr i32 0 to i32*
; CHECK-NEXT: %val = load i32* %.asptr
+define i16* @constant_pointer_undef_load() {
+ %val = load i16** undef
+ ret i16* %val
+}
+; CHECK: define i32 @constant_pointer_undef_load() {
+; CHECK-NEXT: %.asptr = inttoptr i32 undef to i32*
+; CHECK-NEXT: %val = load i32* %.asptr
+
define i8 @load(i8* %ptr) {
%x = load i8* %ptr