1; RUN: not opt -verify < %s 2>&1 | FileCheck %s
2
3%0 = type opaque
4declare void @g()
5declare %0* @foo0()
6declare i8 @foo1()
7declare void @noreturn_func()
8
9; Operand bundles uses are like regular uses, and need to be dominated
10; by their defs.
11
12define void @f0(i32* %ptr) {
13; CHECK: Instruction does not dominate all uses!
14; CHECK-NEXT:  %x = add i32 42, 1
15; CHECK-NEXT:  call void @g() [ "foo"(i32 42, i64 100, i32 %x), "bar"(float 0.000000e+00, i64 100, i32 %l) ]
16
17 entry:
18  %l = load i32, i32* %ptr
19  call void @g() [ "foo"(i32 42, i64 100, i32 %x), "bar"(float 0.0, i64 100, i32 %l) ]
20  %x = add i32 42, 1
21  ret void
22}
23
24define void @f1(i32* %ptr) personality i8 3 {
25; CHECK: Instruction does not dominate all uses!
26; CHECK-NEXT:  %x = add i32 42, 1
27; CHECK-NEXT:  invoke void @g() [ "foo"(i32 42, i64 100, i32 %x), "bar"(float 0.000000e+00, i64 100, i32 %l) ]
28
29 entry:
30  %l = load i32, i32* %ptr
31  invoke void @g() [ "foo"(i32 42, i64 100, i32 %x), "bar"(float 0.0, i64 100, i32 %l) ] to label %normal unwind label %exception
32
33exception:
34  %cleanup = landingpad i8 cleanup
35  br label %normal
36
37normal:
38  %x = add i32 42, 1
39  ret void
40}
41
42define void @f_deopt(i32* %ptr) {
43; CHECK: Multiple deopt operand bundles
44; CHECK-NEXT: call void @g() [ "deopt"(i32 42, i64 100, i32 %x), "deopt"(float 0.000000e+00, i64 100, i32 %l) ]
45; CHECK-NOT: call void @g() [ "deopt"(i32 42, i64 120, i32 %x) ]
46
47 entry:
48  %l = load i32, i32* %ptr
49  call void @g() [ "deopt"(i32 42, i64 100, i32 %x), "deopt"(float 0.0, i64 100, i32 %l) ]
50  call void @g() [ "deopt"(i32 42, i64 120) ]  ;; The verifier should not complain about this one
51  %x = add i32 42, 1
52  ret void
53}
54
55define void @f_gc_transition(i32* %ptr) {
56; CHECK: Multiple gc-transition operand bundles
57; CHECK-NEXT: call void @g() [ "gc-transition"(i32 42, i64 100, i32 %x), "gc-transition"(float 0.000000e+00, i64 100, i32 %l) ]
58; CHECK-NOT: call void @g() [ "gc-transition"(i32 42, i64 120, i32 %x) ]
59
60 entry:
61  %l = load i32, i32* %ptr
62  call void @g() [ "gc-transition"(i32 42, i64 100, i32 %x), "gc-transition"(float 0.0, i64 100, i32 %l) ]
63  call void @g() [ "gc-transition"(i32 42, i64 120) ]  ;; The verifier should not complain about this one
64  %x = add i32 42, 1
65  ret void
66}
67
68define void @f_clang_arc_attachedcall() {
69; CHECK: Multiple "clang.arc.attachedcall" operand bundles
70; CHECK-NEXT: call %0* @foo0() [ "clang.arc.attachedcall"(i64 0), "clang.arc.attachedcall"(i64 0) ]
71; CHECK-NEXT: must call a function returning a pointer
72; CHECK-NEXT: call i8 @foo1() [ "clang.arc.attachedcall"(i64 0) ]
73; CHECK-NEXT: or a non-returning function
74; CHECK-NEXT: call void @g() [ "clang.arc.attachedcall"(i64 0) ]
75
76  call %0* @foo0() [ "clang.arc.attachedcall"(i64 0) ]
77  call %0* @foo0() [ "clang.arc.attachedcall"(i64 0), "clang.arc.attachedcall"(i64 0) ]
78  call i8 @foo1() [ "clang.arc.attachedcall"(i64 0) ]
79  call void @noreturn_func() #0 [ "clang.arc.attachedcall"(i64 0) ]
80  call void @g() [ "clang.arc.attachedcall"(i64 0) ]
81  ret void
82}
83
84attributes #0 = { noreturn }
85