218 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt -passes='cgscc(inline)' -S %s | FileCheck %s3 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 void10;11entry:12 %token = call token @llvm.experimental.convergence.anchor()13 call void @f(i32 0) [ "convergencectrl"(token %token) ]14 ret void15}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 void23;24entry:25 %token = call token @llvm.experimental.convergence.entry()26 call void @f(i32 %v) [ "convergencectrl"(token %token) ]27 ret void28}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 void36;37entry:38 call void @nonconvergent_callee()39 ret void40}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 void52;53entry:54 %token = call token @llvm.experimental.convergence.anchor()55 br i1 %cond, label %then, label %end56 57then:58 call void @convergent_callee(i32 0) [ "convergencectrl"(token %token) ]59 br label %end60 61end:62 ret void63}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 void70;71entry:72 call void @convergent_callee(i32 0)73 ret void74}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 void84;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 void91}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 void104;105entry:106 %token = call token @llvm.experimental.convergence.anchor()107 br i1 %cond, label %hdr, label %end108 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 %end113 114end:115 ret void116}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 void123;124 %token = call token @llvm.experimental.convergence.entry()125 call void %f(i32 %x) convergent [ "convergencectrl"(token %token) ]126 ret void127}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 void135;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 void140}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 void147;148 %token = call token @llvm.experimental.convergence.entry()149 call void @recurse() [ "convergencectrl"(token %token) ]150 ret void151}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 void158;159 %token = call token @llvm.experimental.convergence.entry()160 call void @recurse() [ "convergencectrl"(token %token) ]161 ret void162}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 %y173}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 void181;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 void186}187 188define i32 @token_not_first(i32 %x) convergent alwaysinline {189; CHECK-LABEL: @token_not_first(190; CHECK-NEXT: {{%.*}} = alloca ptr, align 8191; 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 8196 %token = call token @llvm.experimental.convergence.entry()197 %y = call i32 @g(i32 %x) [ "convergencectrl"(token %token) ]198 ret i32 %y199}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 void206;207 %token = call token @llvm.experimental.convergence.entry()208 %x = call i32 @token_not_first(i32 23) [ "convergencectrl"(token %token) ]209 ret void210}211 212declare void @f(i32) convergent213declare i32 @g(i32) convergent214 215declare token @llvm.experimental.convergence.entry()216declare token @llvm.experimental.convergence.anchor()217declare token @llvm.experimental.convergence.loop()218