1; RUN: opt -instcombine -S < %s | FileCheck -enable-var-scope %s
2
3declare i32 @k() convergent
4declare i32 @f()
5
6declare i64 @llvm.read_register.i64(metadata) nounwind
7
8define i32 @extern() {
9  ; Convergent attr shouldn't be removed here; k is convergent.
10  ; CHECK: call i32 @k() [[$CONVERGENT_ATTR:#[0-9]+]]
11  %a = call i32 @k() convergent
12  ret i32 %a
13}
14
15define i32 @extern_no_attr() {
16  ; Convergent attr shouldn't be added here, even though k is convergent.
17  ; CHECK: call i32 @k(){{$}}
18  %a = call i32 @k()
19  ret i32 %a
20}
21
22define i32 @no_extern() {
23  ; Convergent should be removed here, as the target is convergent.
24  ; CHECK: call i32 @f(){{$}}
25  %a = call i32 @f() convergent
26  ret i32 %a
27}
28
29define i32 @indirect_call(i32 ()* %f) {
30  ; CHECK: call i32 %f() [[$CONVERGENT_ATTR]]
31  %a = call i32 %f() convergent
32  ret i32 %a
33}
34
35; do not remove from convergent intrinsic call sites
36; CHECK-LABEL: @convergent_intrinsic_call(
37; CHECK: call i64 @llvm.read_register.i64(metadata !0) [[$CONVERGENT_ATTR]]
38define i64 @convergent_intrinsic_call() {
39  %val = call i64 @llvm.read_register.i64(metadata !0) convergent
40  ret i64 %val
41}
42
43; CHECK: [[$CONVERGENT_ATTR]] = { convergent }
44!0 = !{!"foo"}
45