1; RUN: llvm-as %s -o %t.bc 2; RUN: llvm-link %t.bc -S | FileCheck %s 3 4declare void @f(ptr) 5 6; Test that a blockaddress in @y referring to %label in @x can be moved when @y 7; appears after @x. 8define void @x() { 9 br label %label 10 11label: 12 call void @y() 13 ret void 14} 15 16define void @y() { 17; CHECK: define void @y() { 18; CHECK-NEXT: call void @f(ptr blockaddress(@x, %label)) 19 call void @f(ptr blockaddress(@x, %label)) 20 ret void 21} 22 23; Test that a blockaddress in @a referring to %label in @b can be moved when @a 24; appears before @b. 25define void @a() { 26; CHECK: define void @a() { 27; CHECK-NEXT: call void @f(ptr blockaddress(@b, %label)) 28 call void @f(ptr blockaddress(@b, %label)) 29 ret void 30} 31 32define void @b() { 33 br label %label 34 35label: 36 call void @a() 37 ret void 38} 39 40; Test that @c and @d can both have blockaddress Constants that refer to one 41; another. 42 43define void @c() { 44; CHECK: define void @c() { 45; CHECK-NEXT: br label %label 46; CHECK-EMPTY: 47; CHECK-NEXT: label: 48; CHECK-NEXT: call void @f(ptr blockaddress(@d, %label)) 49 br label %label 50 51label: 52 call void @f(ptr blockaddress(@d, %label)) 53 ret void 54} 55 56define void @d() { 57; CHECK: define void @d() { 58; CHECK-NEXT: br label %label 59; CHECK-EMPTY: 60; CHECK-NEXT: label: 61; CHECK-NEXT: call void @f(ptr blockaddress(@c, %label)) 62 br label %label 63 64label: 65 call void @f(ptr blockaddress(@c, %label)) 66 ret void 67} 68 69; Test that Functions added to IRLinker's Worklist member lazily (linkonce_odr) 70; aren't susceptible to the the same issues as @x/@y above. 71define void @parsed() { 72 br label %label 73 74label: 75 ret void 76} 77 78define linkonce_odr void @lazy() { 79; CHECK: define linkonce_odr void @lazy() { 80; CHECK-NEXT: br label %label 81; CHECK-EMPTY: 82; CHECK-NEXT: label: 83; CHECK-NEXT: call void @f(ptr blockaddress(@parsed, %label)) 84 br label %label 85 86label: 87 call void @f(ptr blockaddress(@parsed, %label)) 88 ret void 89} 90 91define void @parsed2() { 92 call void @lazy() 93 ret void 94} 95 96; Same test as @lazy, just with one more level of lazy parsed functions. 97define void @parsed3() { 98 br label %label 99 100label: 101 ret void 102} 103 104define linkonce_odr void @lazy1() { 105; CHECK: define linkonce_odr void @lazy1() { 106; CHECK-NEXT: br label %label 107; CHECK-EMPTY: 108; CHECK-NEXT: label: 109; CHECK-NEXT: call void @f(ptr blockaddress(@parsed3, %label)) 110 br label %label 111 112label: 113 call void @f(ptr blockaddress(@parsed3, %label)) 114 ret void 115} 116 117define linkonce_odr void @lazy2() { 118 call void @lazy1() 119 ret void 120} 121 122define void @parsed4() { 123 call void @lazy2() 124 ret void 125} 126