1; RUN: opt < %s -basicaa -functionattrs -rpo-functionattrs -S | FileCheck %s 2 3; CHECK: Function Attrs 4; CHECK-NOT: convergent 5; CHECK-NEXT: define i32 @nonleaf() 6define i32 @nonleaf() convergent { 7 %a = call i32 @leaf() 8 ret i32 %a 9} 10 11; CHECK: Function Attrs 12; CHECK-NOT: convergent 13; CHECK-NEXT: define i32 @leaf() 14define i32 @leaf() convergent { 15 ret i32 0 16} 17 18; CHECK: Function Attrs 19; CHECK-SAME: convergent 20; CHECK-NEXT: declare i32 @k() 21declare i32 @k() convergent 22 23; CHECK: Function Attrs 24; CHECK-SAME: convergent 25; CHECK-NEXT: define i32 @extern() 26define i32 @extern() convergent { 27 %a = call i32 @k() 28 ret i32 %a 29} 30 31; CHECK: Function Attrs 32; CHECK-SAME: convergent 33; CHECK-NEXT: define i32 @call_extern() 34define i32 @call_extern() convergent { 35 %a = call i32 @extern() 36 ret i32 %a 37} 38 39; CHECK: Function Attrs 40; CHECK-SAME: convergent 41; CHECK-NEXT: declare void @llvm.cuda.syncthreads() 42declare void @llvm.cuda.syncthreads() convergent 43 44; CHECK: Function Attrs 45; CHECK-SAME: convergent 46; CHECK-NEXT: define i32 @intrinsic() 47define i32 @intrinsic() convergent { 48 call void @llvm.cuda.syncthreads() 49 ret i32 0 50} 51 52@xyz = global i32 ()* null 53; CHECK: Function Attrs 54; CHECK-SAME: convergent 55; CHECK-NEXT: define i32 @functionptr() 56define i32 @functionptr() convergent { 57 %1 = load i32 ()*, i32 ()** @xyz 58 %2 = call i32 %1() 59 ret i32 %2 60} 61 62; CHECK: Function Attrs 63; CHECK-NOT: convergent 64; CHECK-NEXT: define i32 @recursive1() 65define i32 @recursive1() convergent { 66 %a = call i32 @recursive2() 67 ret i32 %a 68} 69 70; CHECK: Function Attrs 71; CHECK-NOT: convergent 72; CHECK-NEXT: define i32 @recursive2() 73define i32 @recursive2() convergent { 74 %a = call i32 @recursive1() 75 ret i32 %a 76} 77 78; CHECK: Function Attrs 79; CHECK-SAME: convergent 80; CHECK-NEXT: define i32 @noopt() 81define i32 @noopt() convergent optnone noinline { 82 %a = call i32 @noopt_friend() 83 ret i32 0 84} 85 86; A function which is mutually-recursive with a convergent, optnone function 87; shouldn't have its convergent attribute stripped. 88; CHECK: Function Attrs 89; CHECK-SAME: convergent 90; CHECK-NEXT: define i32 @noopt_friend() 91define i32 @noopt_friend() convergent { 92 %a = call i32 @noopt() 93 ret i32 0 94} 95