1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -passes='cgscc(inline)' -S %s | FileCheck %s 3 4define void @nonconvergent_callee() alwaysinline { 5; CHECK-LABEL: @nonconvergent_callee( 6; CHECK-NEXT: entry: 7; CHECK-NEXT: [[TOKEN:%.*]] = call token @llvm.experimental.convergence.anchor() 8; CHECK-NEXT: call void @f(i32 0) [ "convergencectrl"(token [[TOKEN]]) ] 9; CHECK-NEXT: ret void 10; 11entry: 12 %token = call token @llvm.experimental.convergence.anchor() 13 call void @f(i32 0) [ "convergencectrl"(token %token) ] 14 ret void 15} 16 17define void @convergent_callee(i32 %v) convergent alwaysinline { 18; CHECK-LABEL: @convergent_callee( 19; CHECK-NEXT: entry: 20; CHECK-NEXT: [[TOKEN:%.*]] = call token @llvm.experimental.convergence.entry() 21; CHECK-NEXT: call void @f(i32 [[V:%.*]]) [ "convergencectrl"(token [[TOKEN]]) ] 22; CHECK-NEXT: ret void 23; 24entry: 25 %token = call token @llvm.experimental.convergence.entry() 26 call void @f(i32 %v) [ "convergencectrl"(token %token) ] 27 ret void 28} 29 30define void @test_nonconvergent() { 31; CHECK-LABEL: @test_nonconvergent( 32; CHECK-NEXT: entry: 33; CHECK-NEXT: [[TOKEN_I:%.*]] = call token @llvm.experimental.convergence.anchor() 34; CHECK-NEXT: call void @f(i32 0) [ "convergencectrl"(token [[TOKEN_I]]) ] 35; CHECK-NEXT: ret void 36; 37entry: 38 call void @nonconvergent_callee() 39 ret void 40} 41 42define void @test_convergent_basic(i1 %cond) { 43; CHECK-LABEL: @test_convergent_basic( 44; CHECK-NEXT: entry: 45; CHECK-NEXT: [[TOKEN:%.*]] = call token @llvm.experimental.convergence.anchor() 46; CHECK-NEXT: br i1 [[COND:%.*]], label [[THEN:%.*]], label [[END:%.*]] 47; CHECK: then: 48; CHECK-NEXT: call void @f(i32 0) [ "convergencectrl"(token [[TOKEN]]) ] 49; CHECK-NEXT: br label [[END]] 50; CHECK: end: 51; CHECK-NEXT: ret void 52; 53entry: 54 %token = call token @llvm.experimental.convergence.anchor() 55 br i1 %cond, label %then, label %end 56 57then: 58 call void @convergent_callee(i32 0) [ "convergencectrl"(token %token) ] 59 br label %end 60 61end: 62 ret void 63} 64 65define void @test_convergent_no_token(i1 %cond) convergent { 66; CHECK-LABEL: @test_convergent_no_token( 67; CHECK-NEXT: entry: 68; CHECK-NEXT: call void @convergent_callee(i32 0) 69; CHECK-NEXT: ret void 70; 71entry: 72 call void @convergent_callee(i32 0) 73 ret void 74} 75 76define void @test_convergent_multiple() convergent { 77; CHECK-LABEL: @test_convergent_multiple( 78; CHECK-NEXT: entry: 79; CHECK-NEXT: [[TOKEN:%.*]] = call token @llvm.experimental.convergence.entry() 80; CHECK-NEXT: call void @f(i32 0) [ "convergencectrl"(token [[TOKEN]]) ] 81; CHECK-NEXT: call void @f(i32 1) [ "convergencectrl"(token [[TOKEN]]) ] 82; CHECK-NEXT: call void @f(i32 2) [ "convergencectrl"(token [[TOKEN]]) ] 83; CHECK-NEXT: ret void 84; 85entry: 86 %token = call token @llvm.experimental.convergence.entry() 87 call void @convergent_callee(i32 0) [ "convergencectrl"(token %token) ] 88 call void @convergent_callee(i32 1) [ "convergencectrl"(token %token) ] 89 call void @convergent_callee(i32 2) [ "convergencectrl"(token %token) ] 90 ret void 91} 92 93define void @test_convergent_loop(i1 %cond) { 94; CHECK-LABEL: @test_convergent_loop( 95; CHECK-NEXT: entry: 96; CHECK-NEXT: [[TOKEN:%.*]] = call token @llvm.experimental.convergence.anchor() 97; CHECK-NEXT: br i1 [[COND:%.*]], label [[HDR:%.*]], label [[END:%.*]] 98; CHECK: hdr: 99; CHECK-NEXT: [[TOK_LOOP:%.*]] = call token @llvm.experimental.convergence.loop() [ "convergencectrl"(token [[TOKEN]]) ] 100; CHECK-NEXT: call void @f(i32 0) [ "convergencectrl"(token [[TOK_LOOP]]) ] 101; CHECK-NEXT: br i1 [[COND]], label [[HDR]], label [[END]] 102; CHECK: end: 103; CHECK-NEXT: ret void 104; 105entry: 106 %token = call token @llvm.experimental.convergence.anchor() 107 br i1 %cond, label %hdr, label %end 108 109hdr: 110 %tok.loop = call token @llvm.experimental.convergence.loop() [ "convergencectrl"(token %token) ] 111 call void @convergent_callee(i32 0) [ "convergencectrl"(token %tok.loop) ] 112 br i1 %cond, label %hdr, label %end 113 114end: 115 ret void 116} 117 118define void @make_indirect_call(ptr %f, i32 %x) convergent alwaysinline { 119; CHECK-LABEL: @make_indirect_call( 120; CHECK-NEXT: [[TOKEN:%.*]] = call token @llvm.experimental.convergence.entry() 121; CHECK-NEXT: call void [[F:%.*]](i32 [[X:%.*]]) #[[ATTR2:[0-9]+]] [ "convergencectrl"(token [[TOKEN]]) ] 122; CHECK-NEXT: ret void 123; 124 %token = call token @llvm.experimental.convergence.entry() 125 call void %f(i32 %x) convergent [ "convergencectrl"(token %token) ] 126 ret void 127} 128 129define void @test_indirect_call() convergent { 130; CHECK-LABEL: @test_indirect_call( 131; CHECK-NEXT: entry: 132; CHECK-NEXT: [[TOKEN:%.*]] = call token @llvm.experimental.convergence.entry() 133; CHECK-NEXT: call void @f(i32 0) [ "convergencectrl"(token [[TOKEN]]) ] 134; CHECK-NEXT: ret void 135; 136entry: 137 %token = call token @llvm.experimental.convergence.entry() 138 call void @make_indirect_call(ptr @convergent_callee, i32 0) [ "convergencectrl"(token %token) ] 139 ret void 140} 141 142define void @recurse() convergent alwaysinline { 143; CHECK-LABEL: @recurse( 144; CHECK-NEXT: [[TOKEN:%.*]] = call token @llvm.experimental.convergence.entry() 145; CHECK-NEXT: call void @recurse() [ "convergencectrl"(token [[TOKEN]]) ] 146; CHECK-NEXT: ret void 147; 148 %token = call token @llvm.experimental.convergence.entry() 149 call void @recurse() [ "convergencectrl"(token %token) ] 150 ret void 151} 152 153define void @test_recursive_call() convergent { 154; CHECK-LABEL: @test_recursive_call( 155; CHECK-NEXT: [[TOKEN:%.*]] = call token @llvm.experimental.convergence.entry() 156; CHECK-NEXT: call void @recurse() [ "convergencectrl"(token [[TOKEN]]) ] 157; CHECK-NEXT: ret void 158; 159 %token = call token @llvm.experimental.convergence.entry() 160 call void @recurse() [ "convergencectrl"(token %token) ] 161 ret void 162} 163 164define i32 @outer_g(i32 %x) convergent alwaysinline { 165; CHECK-LABEL: @outer_g( 166; CHECK-NEXT: [[TOKEN:%.*]] = call token @llvm.experimental.convergence.entry() 167; CHECK-NEXT: [[Y:%.*]] = call i32 @g(i32 [[X:%.*]]) [ "convergencectrl"(token [[TOKEN]]) ] 168; CHECK-NEXT: ret i32 [[Y]] 169; 170 %token = call token @llvm.experimental.convergence.entry() 171 %y = call i32 @g(i32 %x) [ "convergencectrl"(token %token) ] 172 ret i32 %y 173} 174 175define void @test_two_calls() convergent { 176; CHECK-LABEL: @test_two_calls( 177; CHECK-NEXT: [[TOKEN:%.*]] = call token @llvm.experimental.convergence.entry() 178; CHECK-NEXT: [[Y_I:%.*]] = call i32 @g(i32 23) [ "convergencectrl"(token [[TOKEN]]) ] 179; CHECK-NEXT: call void @f(i32 [[Y_I]]) [ "convergencectrl"(token [[TOKEN]]) ] 180; CHECK-NEXT: ret void 181; 182 %token = call token @llvm.experimental.convergence.entry() 183 %x = call i32 @outer_g(i32 23) [ "convergencectrl"(token %token) ] 184 call void @convergent_callee(i32 %x) [ "convergencectrl"(token %token) ] 185 ret void 186} 187 188define i32 @token_not_first(i32 %x) convergent alwaysinline { 189; CHECK-LABEL: @token_not_first( 190; CHECK-NEXT: {{%.*}} = alloca ptr, align 8 191; CHECK-NEXT: [[TOKEN:%.*]] = call token @llvm.experimental.convergence.entry() 192; CHECK-NEXT: [[Y:%.*]] = call i32 @g(i32 [[X:%.*]]) [ "convergencectrl"(token [[TOKEN]]) ] 193; CHECK-NEXT: ret i32 [[Y]] 194; 195 %p = alloca ptr, align 8 196 %token = call token @llvm.experimental.convergence.entry() 197 %y = call i32 @g(i32 %x) [ "convergencectrl"(token %token) ] 198 ret i32 %y 199} 200 201define void @test_token_not_first() convergent { 202; CHECK-LABEL: @test_token_not_first( 203; CHECK-NEXT: [[TOKEN:%.*]] = call token @llvm.experimental.convergence.entry() 204; CHECK-NEXT: {{%.*}} = call i32 @g(i32 23) [ "convergencectrl"(token [[TOKEN]]) ] 205; CHECK-NEXT: ret void 206; 207 %token = call token @llvm.experimental.convergence.entry() 208 %x = call i32 @token_not_first(i32 23) [ "convergencectrl"(token %token) ] 209 ret void 210} 211 212declare void @f(i32) convergent 213declare i32 @g(i32) convergent 214 215declare token @llvm.experimental.convergence.entry() 216declare token @llvm.experimental.convergence.anchor() 217declare token @llvm.experimental.convergence.loop() 218