aboutsummaryrefslogtreecommitdiffstats
path: root/test/Verifier
diff options
context:
space:
mode:
authorStephen Hines <srhines@google.com>2015-03-23 12:10:34 -0700
committerStephen Hines <srhines@google.com>2015-03-23 12:10:34 -0700
commitebe69fe11e48d322045d5949c83283927a0d790b (patch)
treec92f1907a6b8006628a4b01615f38264d29834ea /test/Verifier
parentb7d2e72b02a4cb8034f32f8247a2558d2434e121 (diff)
downloadexternal_llvm-ebe69fe11e48d322045d5949c83283927a0d790b.zip
external_llvm-ebe69fe11e48d322045d5949c83283927a0d790b.tar.gz
external_llvm-ebe69fe11e48d322045d5949c83283927a0d790b.tar.bz2
Update aosp/master LLVM for rebase to r230699.
Change-Id: I2b5be30509658cb8266be782de0ab24f9099f9b9
Diffstat (limited to 'test/Verifier')
-rw-r--r--test/Verifier/2008-03-01-AllocaSized.ll2
-rw-r--r--test/Verifier/comdat.ll2
-rw-r--r--test/Verifier/comdat2.ll2
-rw-r--r--test/Verifier/comdat3.ll5
-rw-r--r--test/Verifier/fpmath.ll14
-rw-r--r--test/Verifier/frameallocate.ll48
-rw-r--r--test/Verifier/ident-meta1.ll6
-rw-r--r--test/Verifier/ident-meta2.ll8
-rw-r--r--test/Verifier/ident-meta3.ll4
-rw-r--r--test/Verifier/ident-meta4.ll9
-rw-r--r--test/Verifier/module-flags-1.ll47
-rw-r--r--test/Verifier/module-flags-2.ll6
-rw-r--r--test/Verifier/module-flags-3.ll6
-rw-r--r--test/Verifier/range-1.ll38
-rw-r--r--test/Verifier/range-2.ll10
-rw-r--r--test/Verifier/statepoint.ll83
16 files changed, 221 insertions, 69 deletions
diff --git a/test/Verifier/2008-03-01-AllocaSized.ll b/test/Verifier/2008-03-01-AllocaSized.ll
index fc12a96..7478334 100644
--- a/test/Verifier/2008-03-01-AllocaSized.ll
+++ b/test/Verifier/2008-03-01-AllocaSized.ll
@@ -1,5 +1,5 @@
; RUN: not llvm-as %s -o /dev/null 2>&1 | FileCheck %s
-; CHECK: Cannot allocate unsized type
+; CHECK: invalid type for alloca
; PR2113
define void @test() {
diff --git a/test/Verifier/comdat.ll b/test/Verifier/comdat.ll
index ca47429..dcf67d8 100644
--- a/test/Verifier/comdat.ll
+++ b/test/Verifier/comdat.ll
@@ -1,5 +1,5 @@
; RUN: not llvm-as %s -o /dev/null 2>&1 | FileCheck %s
$v = comdat any
-@v = common global i32 0, comdat $v
+@v = common global i32 0, comdat($v)
; CHECK: 'common' global may not be in a Comdat!
diff --git a/test/Verifier/comdat2.ll b/test/Verifier/comdat2.ll
index d78030c..9d892b9 100644
--- a/test/Verifier/comdat2.ll
+++ b/test/Verifier/comdat2.ll
@@ -1,5 +1,5 @@
; RUN: not llvm-as %s -o /dev/null 2>&1 | FileCheck %s
$v = comdat any
-@v = private global i32 0, comdat $v
+@v = private global i32 0, comdat($v)
; CHECK: comdat global value has private linkage
diff --git a/test/Verifier/comdat3.ll b/test/Verifier/comdat3.ll
new file mode 100644
index 0000000..28df930
--- /dev/null
+++ b/test/Verifier/comdat3.ll
@@ -0,0 +1,5 @@
+; This used to be invalid, but now it's valid. Ensure the verifier
+; doesn't reject it.
+; RUN: llvm-as %s -o /dev/null
+
+$v = comdat largest
diff --git a/test/Verifier/fpmath.ll b/test/Verifier/fpmath.ll
index 7002c5c..2689b69 100644
--- a/test/Verifier/fpmath.ll
+++ b/test/Verifier/fpmath.ll
@@ -22,10 +22,10 @@ define void @fpmath1(i32 %i, float %f, <2 x float> %g) {
ret void
}
-!0 = metadata !{ float 1.0 }
-!1 = metadata !{ }
-!2 = metadata !{ float 1.0, float 1.0 }
-!3 = metadata !{ i32 1 }
-!4 = metadata !{ float -1.0 }
-!5 = metadata !{ float 0.0 }
-!6 = metadata !{ float 0x7FFFFFFF00000000 }
+!0 = !{ float 1.0 }
+!1 = !{ }
+!2 = !{ float 1.0, float 1.0 }
+!3 = !{ i32 1 }
+!4 = !{ float -1.0 }
+!5 = !{ float 0.0 }
+!6 = !{ float 0x7FFFFFFF00000000 }
diff --git a/test/Verifier/frameallocate.ll b/test/Verifier/frameallocate.ll
new file mode 100644
index 0000000..e3018db
--- /dev/null
+++ b/test/Verifier/frameallocate.ll
@@ -0,0 +1,48 @@
+; RUN: not llvm-as %s -o /dev/null 2>&1 | FileCheck %s
+
+declare i8* @llvm.frameallocate(i32)
+declare i8* @llvm.framerecover(i8*, i8*)
+
+define internal void @f() {
+ call i8* @llvm.frameallocate(i32 4)
+ call i8* @llvm.frameallocate(i32 4)
+ ret void
+}
+; CHECK: multiple calls to llvm.frameallocate in one function
+
+define internal void @f_a(i32 %n) {
+ call i8* @llvm.frameallocate(i32 %n)
+ ret void
+}
+; CHECK: llvm.frameallocate argument must be constant integer size
+
+define internal void @g() {
+entry:
+ br label %not_entry
+not_entry:
+ call i8* @llvm.frameallocate(i32 4)
+ ret void
+}
+; CHECK: llvm.frameallocate used outside of entry block
+
+define internal void @h() {
+ call i8* @llvm.framerecover(i8* null, i8* null)
+ ret void
+}
+; CHECK: llvm.framerecover first argument must be function defined in this module
+
+@global = constant i8 0
+
+declare void @declaration()
+
+define internal void @i() {
+ call i8* @llvm.framerecover(i8* @global, i8* null)
+ ret void
+}
+; CHECK: llvm.framerecover first argument must be function defined in this module
+
+define internal void @j() {
+ call i8* @llvm.framerecover(i8* bitcast(void()* @declaration to i8*), i8* null)
+ ret void
+}
+; CHECK: llvm.framerecover first argument must be function defined in this module
diff --git a/test/Verifier/ident-meta1.ll b/test/Verifier/ident-meta1.ll
index fb247a8..3202fbd 100644
--- a/test/Verifier/ident-meta1.ll
+++ b/test/Verifier/ident-meta1.ll
@@ -4,9 +4,9 @@
; Each metadata entry can have only one string.
!llvm.ident = !{!0, !1}
-!0 = metadata !{metadata !"version string"}
-!1 = metadata !{metadata !"string1", metadata !"string2"}
+!0 = !{!"version string"}
+!1 = !{!"string1", !"string2"}
; CHECK: assembly parsed, but does not verify as correct!
; CHECK-NEXT: incorrect number of operands in llvm.ident metadata
-; CHECK-NEXT: metadata !1
+; CHECK-NEXT: !1
diff --git a/test/Verifier/ident-meta2.ll b/test/Verifier/ident-meta2.ll
index e86f18a..1c11e1b 100644
--- a/test/Verifier/ident-meta2.ll
+++ b/test/Verifier/ident-meta2.ll
@@ -4,10 +4,10 @@
; Each metadata entry can contain one string only.
!llvm.ident = !{!0, !1, !2, !3}
-!0 = metadata !{metadata !"str1"}
-!1 = metadata !{metadata !"str2"}
-!2 = metadata !{metadata !"str3"}
-!3 = metadata !{i32 1}
+!0 = !{!"str1"}
+!1 = !{!"str2"}
+!2 = !{!"str3"}
+!3 = !{i32 1}
; CHECK: assembly parsed, but does not verify as correct!
; CHECK-NEXT: invalid value for llvm.ident metadata entry operand(the operand should be a string)
; CHECK-NEXT: i32 1
diff --git a/test/Verifier/ident-meta3.ll b/test/Verifier/ident-meta3.ll
index a847b46..91e1cfe 100644
--- a/test/Verifier/ident-meta3.ll
+++ b/test/Verifier/ident-meta3.ll
@@ -4,7 +4,7 @@
; Each metadata entry can contain one string only.
!llvm.ident = !{!0}
-!0 = metadata !{metadata !{metadata !"nested metadata"}}
+!0 = !{!{!"nested metadata"}}
; CHECK: assembly parsed, but does not verify as correct!
; CHECK-NEXT: invalid value for llvm.ident metadata entry operand(the operand should be a string)
-; CHECK-NEXT: metadata !1
+; CHECK-NEXT: !1
diff --git a/test/Verifier/ident-meta4.ll b/test/Verifier/ident-meta4.ll
new file mode 100644
index 0000000..f44dbd5
--- /dev/null
+++ b/test/Verifier/ident-meta4.ll
@@ -0,0 +1,9 @@
+; RUN: not llvm-as < %s -o /dev/null 2>&1 | FileCheck %s
+; Verify that llvm.ident is properly structured.
+; llvm.ident takes a list of metadata entries.
+; Each metadata entry can contain one string only.
+
+!llvm.ident = !{!0}
+!0 = !{null}
+; CHECK: assembly parsed, but does not verify as correct!
+; CHECK-NEXT: invalid value for llvm.ident metadata entry operand(the operand should be a string)
diff --git a/test/Verifier/module-flags-1.ll b/test/Verifier/module-flags-1.ll
index e5feaf3..36bcb33 100644
--- a/test/Verifier/module-flags-1.ll
+++ b/test/Verifier/module-flags-1.ll
@@ -3,57 +3,54 @@
; Check that module flags are structurally correct.
;
; CHECK: incorrect number of operands in module flag
-; CHECK: metadata !0
-!0 = metadata !{ i32 1 }
+; CHECK: !0
+!0 = !{i32 1}
; CHECK: invalid behavior operand in module flag (expected constant integer)
-; CHECK: metadata !"foo"
-!1 = metadata !{ metadata !"foo", metadata !"foo", i32 42 }
+; CHECK: !"foo"
+!1 = !{!"foo", !"foo", i32 42}
; CHECK: invalid behavior operand in module flag (unexpected constant)
; CHECK: i32 999
-!2 = metadata !{ i32 999, metadata !"foo", i32 43 }
+!2 = !{i32 999, !"foo", i32 43}
; CHECK: invalid ID operand in module flag (expected metadata string)
; CHECK: i32 1
-!3 = metadata !{ i32 1, i32 1, i32 44 }
+!3 = !{i32 1, i32 1, i32 44}
; CHECK: invalid value for 'require' module flag (expected metadata pair)
; CHECK: i32 45
-!4 = metadata !{ i32 3, metadata !"bla", i32 45 }
+!4 = !{i32 3, !"bla", i32 45}
; CHECK: invalid value for 'require' module flag (expected metadata pair)
-; CHECK: metadata !
-!5 = metadata !{ i32 3, metadata !"bla", metadata !{ i32 46 } }
+; CHECK: !
+!5 = !{i32 3, !"bla", !{i32 46}}
; CHECK: invalid value for 'require' module flag (first value operand should be a string)
; CHECK: i32 47
-!6 = metadata !{ i32 3, metadata !"bla", metadata !{ i32 47, i32 48 } }
+!6 = !{i32 3, !"bla", !{i32 47, i32 48}}
; Check that module flags only have unique IDs.
;
; CHECK: module flag identifiers must be unique (or of 'require' type)
-!7 = metadata !{ i32 1, metadata !"foo", i32 49 }
-!8 = metadata !{ i32 2, metadata !"foo", i32 50 }
+!7 = !{i32 1, !"foo", i32 49}
+!8 = !{i32 2, !"foo", i32 50}
; CHECK-NOT: module flag identifiers must be unique
-!9 = metadata !{ i32 2, metadata !"bar", i32 51 }
-!10 = metadata !{ i32 3, metadata !"bar", metadata !{ metadata !"bar", i32 51 } }
+!9 = !{i32 2, !"bar", i32 51}
+!10 = !{i32 3, !"bar", !{!"bar", i32 51}}
; Check that any 'append'-type module flags are valid.
; CHECK: invalid value for 'append'-type module flag (expected a metadata node)
-!16 = metadata !{ i32 5, metadata !"flag-2", i32 56 }
+!16 = !{i32 5, !"flag-2", i32 56}
; CHECK: invalid value for 'append'-type module flag (expected a metadata node)
-!17 = metadata !{ i32 5, metadata !"flag-3", i32 57 }
+!17 = !{i32 5, !"flag-3", i32 57}
; CHECK-NOT: invalid value for 'append'-type module flag (expected a metadata node)
-!18 = metadata !{ i32 5, metadata !"flag-4", metadata !{ i32 57 } }
+!18 = !{i32 5, !"flag-4", !{i32 57}}
; Check that any 'require' module flags are valid.
; CHECK: invalid requirement on flag, flag is not present in module
-!11 = metadata !{ i32 3, metadata !"bar",
- metadata !{ metadata !"no-such-flag", i32 52 } }
+!11 = !{i32 3, !"bar", !{!"no-such-flag", i32 52}}
; CHECK: invalid requirement on flag, flag does not have the required value
-!12 = metadata !{ i32 1, metadata !"flag-0", i32 53 }
-!13 = metadata !{ i32 3, metadata !"bar",
- metadata !{ metadata !"flag-0", i32 54 } }
+!12 = !{i32 1, !"flag-0", i32 53}
+!13 = !{i32 3, !"bar", !{!"flag-0", i32 54}}
; CHECK-NOT: invalid requirement on flag, flag is not present in module
; CHECK-NOT: invalid requirement on flag, flag does not have the required value
-!14 = metadata !{ i32 1, metadata !"flag-1", i32 55 }
-!15 = metadata !{ i32 3, metadata !"bar",
- metadata !{ metadata !"flag-1", i32 55 } }
+!14 = !{i32 1, !"flag-1", i32 55}
+!15 = !{i32 3, !"bar", !{!"flag-1", i32 55}}
!llvm.module.flags = !{
!0, !1, !2, !3, !4, !5, !6, !7, !8, !9, !10, !11, !12, !13, !14, !15,
diff --git a/test/Verifier/module-flags-2.ll b/test/Verifier/module-flags-2.ll
new file mode 100644
index 0000000..8582162
--- /dev/null
+++ b/test/Verifier/module-flags-2.ll
@@ -0,0 +1,6 @@
+; RUN: not llvm-as < %s -o /dev/null 2>&1 | FileCheck %s
+
+!llvm.module.flags = !{!0}
+!0 = !{null, null, null}
+
+; CHECK: invalid behavior operand in module flag (expected constant integer)
diff --git a/test/Verifier/module-flags-3.ll b/test/Verifier/module-flags-3.ll
new file mode 100644
index 0000000..64ab57e
--- /dev/null
+++ b/test/Verifier/module-flags-3.ll
@@ -0,0 +1,6 @@
+; RUN: not llvm-as < %s -o /dev/null 2>&1 | FileCheck %s
+
+!llvm.module.flags = !{!0}
+!0 = !{i32 1, null, null}
+
+; CHECK: invalid ID operand in module flag (expected metadata string)
diff --git a/test/Verifier/range-1.ll b/test/Verifier/range-1.ll
index 0b20ca2..fda65cb 100644
--- a/test/Verifier/range-1.ll
+++ b/test/Verifier/range-1.ll
@@ -5,7 +5,7 @@ entry:
store i8 0, i8* %x, align 1, !range !0
ret void
}
-!0 = metadata !{i8 0, i8 1}
+!0 = !{i8 0, i8 1}
; CHECK: Ranges are only for loads, calls and invokes!
; CHECK-NEXT: store i8 0, i8* %x, align 1, !range !0
@@ -14,16 +14,15 @@ entry:
%y = load i8* %x, align 1, !range !1
ret i8 %y
}
-!1 = metadata !{}
+!1 = !{}
; CHECK: It should have at least one range!
-; CHECK-NEXT: metadata
define i8 @f3(i8* %x) {
entry:
%y = load i8* %x, align 1, !range !2
ret i8 %y
}
-!2 = metadata !{i8 0}
+!2 = !{i8 0}
; CHECK: Unfinished range!
define i8 @f4(i8* %x) {
@@ -31,7 +30,7 @@ entry:
%y = load i8* %x, align 1, !range !3
ret i8 %y
}
-!3 = metadata !{double 0.0, i8 0}
+!3 = !{double 0.0, i8 0}
; CHECK: The lower limit must be an integer!
define i8 @f5(i8* %x) {
@@ -39,7 +38,7 @@ entry:
%y = load i8* %x, align 1, !range !4
ret i8 %y
}
-!4 = metadata !{i8 0, double 0.0}
+!4 = !{i8 0, double 0.0}
; CHECK: The upper limit must be an integer!
define i8 @f6(i8* %x) {
@@ -47,7 +46,7 @@ entry:
%y = load i8* %x, align 1, !range !5
ret i8 %y
}
-!5 = metadata !{i32 0, i8 0}
+!5 = !{i32 0, i8 0}
; CHECK: Range types must match instruction type!
; CHECK: %y = load
@@ -56,7 +55,7 @@ entry:
%y = load i8* %x, align 1, !range !6
ret i8 %y
}
-!6 = metadata !{i8 0, i32 0}
+!6 = !{i8 0, i32 0}
; CHECK: Range types must match instruction type!
; CHECK: %y = load
@@ -65,7 +64,7 @@ entry:
%y = load i8* %x, align 1, !range !7
ret i8 %y
}
-!7 = metadata !{i32 0, i32 0}
+!7 = !{i32 0, i32 0}
; CHECK: Range types must match instruction type!
; CHECK: %y = load
@@ -74,7 +73,7 @@ entry:
%y = load i8* %x, align 1, !range !8
ret i8 %y
}
-!8 = metadata !{i8 0, i8 0}
+!8 = !{i8 0, i8 0}
; CHECK: Range must not be empty!
define i8 @f10(i8* %x) {
@@ -82,7 +81,7 @@ entry:
%y = load i8* %x, align 1, !range !9
ret i8 %y
}
-!9 = metadata !{i8 0, i8 2, i8 1, i8 3}
+!9 = !{i8 0, i8 2, i8 1, i8 3}
; CHECK: Intervals are overlapping
define i8 @f11(i8* %x) {
@@ -90,7 +89,7 @@ entry:
%y = load i8* %x, align 1, !range !10
ret i8 %y
}
-!10 = metadata !{i8 0, i8 2, i8 2, i8 3}
+!10 = !{i8 0, i8 2, i8 2, i8 3}
; CHECK: Intervals are contiguous
define i8 @f12(i8* %x) {
@@ -98,7 +97,7 @@ entry:
%y = load i8* %x, align 1, !range !11
ret i8 %y
}
-!11 = metadata !{i8 1, i8 2, i8 -1, i8 0}
+!11 = !{i8 1, i8 2, i8 -1, i8 0}
; CHECK: Intervals are not in order
define i8 @f13(i8* %x) {
@@ -106,7 +105,7 @@ entry:
%y = load i8* %x, align 1, !range !12
ret i8 %y
}
-!12 = metadata !{i8 1, i8 3, i8 5, i8 1}
+!12 = !{i8 1, i8 3, i8 5, i8 1}
; CHECK: Intervals are contiguous
define i8 @f14(i8* %x) {
@@ -114,7 +113,7 @@ entry:
%y = load i8* %x, align 1, !range !13
ret i8 %y
}
-!13 = metadata !{i8 1, i8 3, i8 5, i8 2}
+!13 = !{i8 1, i8 3, i8 5, i8 2}
; CHECK: Intervals are overlapping
define i8 @f15(i8* %x) {
@@ -122,7 +121,7 @@ entry:
%y = load i8* %x, align 1, !range !14
ret i8 %y
}
-!14 = metadata !{i8 10, i8 1, i8 12, i8 13}
+!14 = !{i8 10, i8 1, i8 12, i8 13}
; CHECK: Intervals are overlapping
define i8 @f16(i8* %x) {
@@ -130,7 +129,7 @@ entry:
%y = load i8* %x, align 1, !range !16
ret i8 %y
}
-!16 = metadata !{i8 1, i8 3, i8 4, i8 5, i8 6, i8 2}
+!16 = !{i8 1, i8 3, i8 4, i8 5, i8 6, i8 2}
; CHECK: Intervals are overlapping
define i8 @f17(i8* %x) {
@@ -138,7 +137,7 @@ entry:
%y = load i8* %x, align 1, !range !17
ret i8 %y
}
-!17 = metadata !{i8 1, i8 3, i8 4, i8 5, i8 6, i8 1}
+!17 = !{i8 1, i8 3, i8 4, i8 5, i8 6, i8 1}
; CHECK: Intervals are contiguous
define i8 @f18() {
@@ -146,6 +145,5 @@ entry:
%y = call i8 undef(), !range !18
ret i8 %y
}
-!18 = metadata !{}
+!18 = !{}
; CHECK: It should have at least one range!
-; CHECK-NEXT: metadata
diff --git a/test/Verifier/range-2.ll b/test/Verifier/range-2.ll
index 1d2e057..f8891c8 100644
--- a/test/Verifier/range-2.ll
+++ b/test/Verifier/range-2.ll
@@ -5,35 +5,35 @@ entry:
%y = load i8* %x, align 1, !range !0
ret i8 %y
}
-!0 = metadata !{i8 0, i8 1}
+!0 = !{i8 0, i8 1}
define i8 @f2(i8* %x) {
entry:
%y = load i8* %x, align 1, !range !1
ret i8 %y
}
-!1 = metadata !{i8 255, i8 1}
+!1 = !{i8 255, i8 1}
define i8 @f3(i8* %x) {
entry:
%y = load i8* %x, align 1, !range !2
ret i8 %y
}
-!2 = metadata !{i8 1, i8 3, i8 5, i8 42}
+!2 = !{i8 1, i8 3, i8 5, i8 42}
define i8 @f4(i8* %x) {
entry:
%y = load i8* %x, align 1, !range !3
ret i8 %y
}
-!3 = metadata !{i8 -1, i8 0, i8 1, i8 2}
+!3 = !{i8 -1, i8 0, i8 1, i8 2}
define i8 @f5(i8* %x) {
entry:
%y = load i8* %x, align 1, !range !4
ret i8 %y
}
-!4 = metadata !{i8 -1, i8 0, i8 1, i8 -2}
+!4 = !{i8 -1, i8 0, i8 1, i8 -2}
; We can annotate the range of the return value of a CALL.
define void @call_all(i8* %x) {
diff --git a/test/Verifier/statepoint.ll b/test/Verifier/statepoint.ll
new file mode 100644
index 0000000..9342309
--- /dev/null
+++ b/test/Verifier/statepoint.ll
@@ -0,0 +1,83 @@
+; RUN: opt -S %s -verify | FileCheck %s
+
+declare void @use(...)
+declare i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(i32, i32, i32)
+declare i64 addrspace(1)* @llvm.experimental.gc.relocate.p1i64(i32, i32, i32)
+declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()*, i32, i32, ...)
+declare i32 @"personality_function"()
+
+;; Basic usage
+define i64 addrspace(1)* @test1(i8 addrspace(1)* %arg) gc "statepoint-example" {
+entry:
+ %cast = bitcast i8 addrspace(1)* %arg to i64 addrspace(1)*
+ %safepoint_token = call i32 (void ()*, i32, i32, ...)* @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* undef, i32 0, i32 0, i32 5, i32 0, i32 0, i32 0, i32 10, i32 0, i8 addrspace(1)* %arg, i64 addrspace(1)* %cast, i8 addrspace(1)* %arg, i8 addrspace(1)* %arg)
+ %reloc = call i64 addrspace(1)* @llvm.experimental.gc.relocate.p1i64(i32 %safepoint_token, i32 9, i32 10)
+ ;; It is perfectly legal to relocate the same value multiple times...
+ %reloc2 = call i64 addrspace(1)* @llvm.experimental.gc.relocate.p1i64(i32 %safepoint_token, i32 9, i32 10)
+ %reloc3 = call i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(i32 %safepoint_token, i32 10, i32 9)
+ ret i64 addrspace(1)* %reloc
+; CHECK-LABEL: test1
+; CHECK: statepoint
+; CHECK: gc.relocate
+; CHECK: gc.relocate
+; CHECK: gc.relocate
+; CHECK: ret i64 addrspace(1)* %reloc
+}
+
+; This test catches two cases where the verifier was too strict:
+; 1) A base doesn't need to be relocated if it's never used again
+; 2) A value can be replaced by one which is known equal. This
+; means a potentially derived pointer can be known base and that
+; we can't check that derived pointer are never bases.
+define void @test2(i8 addrspace(1)* %arg, i64 addrspace(1)* %arg2) gc "statepoint-example" {
+entry:
+ %cast = bitcast i8 addrspace(1)* %arg to i64 addrspace(1)*
+ %c = icmp eq i64 addrspace(1)* %cast, %arg2
+ br i1 %c, label %equal, label %notequal
+
+notequal:
+ ret void
+
+equal:
+ %safepoint_token = call i32 (void ()*, i32, i32, ...)* @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* undef, i32 0, i32 0, i32 5, i32 0, i32 0, i32 0, i32 10, i32 0, i8 addrspace(1)* %arg, i64 addrspace(1)* %cast, i8 addrspace(1)* %arg, i8 addrspace(1)* %arg)
+ %reloc = call i64 addrspace(1)* @llvm.experimental.gc.relocate.p1i64(i32 %safepoint_token, i32 9, i32 10)
+ call void undef(i64 addrspace(1)* %reloc)
+ ret void
+; CHECK-LABEL: test2
+; CHECK-LABEL: equal
+; CHECK: statepoint
+; CHECK-NEXT: %reloc = call
+; CHECK-NEXT: call
+; CHECK-NEXT: ret voi
+}
+
+; Basic test for invoke statepoints
+define i8 addrspace(1)* @test3(i8 addrspace(1)* %obj, i8 addrspace(1)* %obj1) gc "statepoint-example" {
+; CHECK-LABEL: test3
+entry:
+ ; CHECK-LABEL: entry
+ ; CHECK: statepoint
+ %0 = invoke i32 (void ()*, i32, i32, ...)* @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* undef, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0, i8 addrspace(1)* %obj, i8 addrspace(1)* %obj1)
+ to label %normal_dest unwind label %exceptional_return
+
+normal_dest:
+ ; CHECK-LABEL: normal_dest:
+ ; CHECK: gc.relocate
+ ; CHECK: gc.relocate
+ ; CHECK: ret
+ %obj.relocated = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(i32 %0, i32 9, i32 9)
+ %obj1.relocated = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(i32 %0, i32 10, i32 10)
+ ret i8 addrspace(1)* %obj.relocated
+
+exceptional_return:
+ ; CHECK-LABEL: exceptional_return
+ ; CHECK: gc.relocate
+ ; CHECK: gc.relocate
+ %landing_pad = landingpad { i8*, i32 } personality i32 ()* @"personality_function"
+ cleanup
+ %relocate_token = extractvalue { i8*, i32 } %landing_pad, 1
+ %obj.relocated1 = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(i32 %relocate_token, i32 9, i32 9)
+ %obj1.relocated1 = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(i32 %relocate_token, i32 10, i32 10)
+ ret i8 addrspace(1)* %obj1.relocated1
+}
+