xref: /llvm-project/llvm/test/Transforms/LowerTypeTests/cfi-direct-call1.ll (revision 63dc31b68b78bc0e5deef21b98cab72de997c471)
1; RUN: opt -passes=lowertypetests -S %s | FileCheck --check-prefix=FULL %s
2; RUN: opt -passes=lowertypetests -lowertypetests-summary-action=import -lowertypetests-read-summary=%p/Inputs/cfi-direct-call1.yaml -S %s | FileCheck --check-prefix=THIN %s
3
4target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
5target triple = "x86_64-unknown-linux"
6
7define hidden i32 @local_func1() !type !3 !type !4 {
8  ret i32 11
9}
10
11define hidden i32 @local_func2() !type !3 !type !4 {
12  ret i32 22
13}
14
15define hidden i32 @local_func3(i32 %i) local_unnamed_addr !type !5 !type !6 {
16entry:
17  %add = add nsw i32 %i, 44
18  ret i32 %add
19}
20
21declare !type !3 !type !4 extern_weak i32 @extern_weak()
22declare !type !3 !type !4 i32 @extern_decl()
23declare i1 @llvm.type.test(ptr, metadata)
24
25define hidden i32 @main(i32 %argc) {
26entry:
27  %cmp.i = icmp sgt i32 %argc, 1
28  %fptr1 = select i1 %cmp.i, ptr @local_func1, ptr @local_func2
29  %fptr2 = select i1 %cmp.i, ptr @extern_weak, ptr @extern_decl
30  %0 = tail call i1 @llvm.type.test(ptr nonnull %fptr1, metadata !"_ZTSFivE")
31
32  %call2 = tail call i32 %fptr1()
33  %1 = tail call i1 @llvm.type.test(ptr %fptr2, metadata !"_ZTSFivE")
34
35  %call4 = tail call i32 %fptr2()
36  %call5 = tail call i32 @extern_decl()
37  %call7 = tail call i32 @extern_weak()
38  %call6 = tail call i32 @local_func1()
39  %call8 = tail call i32 @local_func3(i32 4)
40  ret i32 12
41}
42
43!3 = !{i64 0, !"_ZTSFivE"}
44!4 = !{i64 0, !"_ZTSFivE.generalized"}
45!5 = !{i64 0, !"_ZTSFiiE"}
46!6 = !{i64 0, !"_ZTSFiiE.generalized"}
47
48; Make sure local_func1 and local_func2 have been renamed to <name>.cfi
49; FULL: define hidden i32 @local_func1.cfi()
50; FULL: define hidden i32 @local_func2.cfi()
51
52; There are no indirect calls of local_func3 type, it should not be renamed
53; FULL: define hidden i32 @local_func3(i32 %i)
54
55; Indirect references to local_func1 and local_func2 must to through jump table
56; FULL: %fptr1 = select i1 %cmp.i, ptr @local_func1, ptr @local_func2
57
58; Indirect references to extern_weak and extern_decl must go through jump table
59; FULL: [[CMP:%.*]] = icmp ne ptr @extern_weak, null
60; FULL: [[SEL:%.*]] = select i1 [[CMP]], ptr getelementptr inbounds ([4 x [8 x i8]], ptr @.cfi.jumptable, i64 0, i64 2), ptr null
61; FULL: %fptr2 = select i1 %cmp.i, ptr [[SEL]], ptr getelementptr inbounds ([4 x [8 x i8]], ptr @.cfi.jumptable, i64 0, i64 3)
62
63; Direct calls to extern_weak and extern_decl should go to original names
64; FULL: %call5 = tail call i32 @extern_decl()
65; FULL: %call7 = tail call i32 @extern_weak()
66
67; Direct call to local_func1 should to the renamed version
68; FULL: %call6 = tail call i32 @local_func1.cfi()
69
70; local_func3 hasn't been renamed, direct call should go to the original name
71; FULL: %call8 = tail call i32 @local_func3(i32 4)
72
73; Check which jump table entries are created
74; FULL: define private void @.cfi.jumptable(){{.*}}
75; FULL-NEXT: entry:
76; FULL-NEXT: call void asm{{.*}}local_func1.cfi{{.*}}local_func2.cfi{{.*}}extern_weak{{.*}}extern_decl
77
78; Make sure all local functions have been renamed to <name>.cfi
79; THIN: define hidden i32 @local_func1.cfi()
80; THIN: define hidden i32 @local_func2.cfi()
81; THIN: define hidden i32 @local_func3.cfi(i32 %i){{.*}}
82
83; Indirect references to local_func1 and local_func2 must to through jump table
84; THIN: %fptr1 = select i1 %cmp.i, ptr @local_func1, ptr @local_func2
85
86; Indirect references to extern_weak and extern_decl must go through jump table
87; THIN: [[CMP:%.*]] = icmp ne ptr @extern_weak, null
88; THIN: [[SEL:%.*]] = select i1 [[CMP]], ptr @extern_weak.cfi_jt, ptr null
89; THIN: %fptr2 = select i1 %cmp.i, ptr [[SEL]], ptr @extern_decl.cfi_jt
90
91; Direct calls to extern_weak and extern_decl should go to original names
92; THIN: %call5 = tail call i32 @extern_decl()
93; THIN: %call7 = tail call i32 @extern_weak()
94
95; Direct call to local_func1 should to the renamed version
96; THIN: %call6 = tail call i32 @local_func1.cfi()
97; THIN: %call8 = tail call i32 @local_func3.cfi(i32 4)
98
99