xref: /llvm-project/llvm/test/Transforms/LowerTypeTests/function-weak.ll (revision deab451e7a7f2dff42097049274637052c87eabd)
1; RUN: opt -S -passes=lowertypetests -mtriple=i686-unknown-linux-gnu %s | FileCheck --check-prefixes=CHECK,X86 %s
2; RUN: opt -S -passes=lowertypetests -mtriple=x86_64-unknown-linux-gnu %s | FileCheck --check-prefixes=CHECK,X86 %s
3; RUN: opt -S -passes=lowertypetests -mtriple=arm-unknown-linux-gnu %s | FileCheck --check-prefixes=CHECK,ARM %s
4; RUN: opt -S -passes=lowertypetests -mtriple=aarch64-unknown-linux-gnu %s | FileCheck --check-prefixes=CHECK,ARM %s
5; RUN: opt -S -passes=lowertypetests -mtriple=riscv32-unknown-linux-gnu %s | FileCheck --check-prefixes=CHECK,RISCV %s
6; RUN: opt -S -passes=lowertypetests -mtriple=riscv64-unknown-linux-gnu %s | FileCheck --check-prefixes=CHECK,RISCV %s
7; RUN: opt -S -passes=lowertypetests -mtriple=loongarch64-unknown-linux-gnu %s | FileCheck --check-prefixes=CHECK,LOONGARCH64 %s
8
9target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
10target triple = "x86_64-unknown-linux-gnu"
11
12; CHECK: @x = global ptr null, align 8
13@x = global ptr @f, align 8
14
15; CHECK: @x2 = global ptr null, align 8
16@x2 = global ptr @f, align 8
17
18; CHECK: @x3 = internal global ptr null, align 8
19@x3 = internal constant ptr @f, align 8
20
21; f + addend
22; CHECK: @x4 = global ptr null, align 8
23@x4 = global ptr getelementptr (i8, ptr @f, i64 42), align 8
24
25; aggregate initializer
26; CHECK: @s = global { ptr, ptr, i32 } zeroinitializer, align 8
27@s = global { ptr, ptr, i32 } { ptr @f, ptr @f, i32 42 }, align 8
28
29; CHECK:  @llvm.global_ctors = appending global {{.*}}{ i32 0, ptr @__cfi_global_var_init
30
31; CHECK: declare !type !0 extern_weak void @f()
32declare !type !0 extern_weak void @f()
33
34; CHECK: define zeroext i1 @check_f()
35define zeroext i1 @check_f() {
36entry:
37; CHECK: [[CMP:%.*]] = icmp ne ptr @f, null
38; CHECK: [[SEL:%.*]] = select i1 [[CMP]], ptr @[[JT:.*]], ptr null
39; CHECK: [[PTI:%.*]] = ptrtoint ptr [[SEL]] to i1
40; CHECK: ret i1 [[PTI]]
41  ret i1 ptrtoint (ptr @f to i1)
42}
43
44; CHECK: define void @call_f() {
45define void @call_f() {
46entry:
47; CHECK: call void @f()
48  call void @f()
49  ret void
50}
51
52define void @struct() {
53; CHECK-LABEL: define void @struct() {
54; CHECK: [[CMP:%.*]] = icmp ne ptr @f, null
55; CHECK: [[SEL:%.*]] = select i1 [[CMP]], ptr @.cfi.jumptable, ptr null
56; CHECK-NEXT: [[PTI:%.*]] = ptrtoint ptr [[SEL]] to i1
57; CHECK-NEXT: [[IV:%.*]] = insertvalue { i1, i8 } poison, i1 [[PTI]], 0
58; CHECK-NEXT: [[IV2:%.*]] = insertvalue { i1, i8 } [[IV]], i8 0, 1
59; CHECK-NEXT: %x = extractvalue { i1, i8 } [[IV2]], 0
60
61entry:
62  %x = extractvalue { i1, i8 } { i1 ptrtoint (ptr @f to i1), i8 0 }, 0
63  ret void
64}
65
66define void @phi(i1 %c) {
67; CHECK-LABEL: define void @phi(i1 %c) {
68; CHECK: entry:
69; CHECK:   [[CMP:%.*]] = icmp ne ptr @f, null
70; CHECK:   [[SEL:%.*]] = select i1 [[CMP]], ptr @.cfi.jumptable, ptr null
71; CHECK:   br i1 %c, label %if, label %join
72; CHECK: if:
73; CHECK:   [[CMP2:%.*]] = icmp ne ptr @f, null
74; CHECK:   [[SEL2:%.*]] = select i1 [[CMP2]], ptr @.cfi.jumptable, ptr null
75; CHECK:   br label %join
76; CHECK: join:
77; CHECK:   %phi = phi ptr [ [[SEL2]], %if ], [ null, %entry ]
78; CHECK:   %phi2 = phi ptr [ null, %if ], [ [[SEL]], %entry ]
79
80entry:
81  br i1 %c, label %if, label %join
82
83if:
84  br label %join
85
86join:
87  %phi = phi ptr [ @f, %if ], [ null, %entry ]
88  %phi2 = phi ptr [ null, %if ], [ @f, %entry ]
89  ret void
90}
91
92define void @phi2(i1 %c, i32 %x) {
93; CHECK-LABEL: define void @phi2(i1 %c, i32 %x) {
94; CHECK: entry:
95; CHECK:   br i1 %c, label %if, label %else
96; CHECK: if:                                               ; preds = %entry
97; CHECK:   [[CMP:%.*]] = icmp ne ptr @f, null
98; CHECK:   [[SEL:%.*]] = select i1 [[CMP]], ptr @.cfi.jumptable, ptr null
99; CHECK:   switch i32 %x, label %join [
100; CHECK:     i32 0, label %join
101; CHECK:   ]
102; CHECK: else:                                             ; preds = %entry
103; CHECK:   [[CMP2:%.*]] = icmp ne ptr @f, null
104; CHECK:   [[SEL2:%.*]] = select i1 [[CMP2]], ptr @.cfi.jumptable, ptr null
105; CHECK:   switch i32 %x, label %join [
106; CHECK:     i32 0, label %join
107; CHECK:   ]
108; CHECK: join:                                             ; preds = %else, %else, %if, %if
109; CHECK:   %phi2 = phi ptr [ [[SEL]], %if ], [ [[SEL]], %if ], [ [[SEL2]], %else ], [ [[SEL2]], %else ]
110
111entry:
112  br i1 %c, label %if, label %else
113
114if:
115  switch i32 %x, label %join [
116    i32 0, label %join
117  ]
118
119else:
120  switch i32 %x, label %join [
121    i32 0, label %join
122  ]
123
124join:
125  %phi2 = phi ptr [ @f, %if ], [ @f, %if ], [ @f, %else ], [ @f, %else ]
126  ret void
127}
128
129declare i1 @llvm.type.test(ptr %ptr, metadata %bitset) nounwind readnone
130
131define i1 @foo(ptr %p) {
132  %x = call i1 @llvm.type.test(ptr %p, metadata !"typeid1")
133  ret i1 %x
134}
135
136; X86: define private void @[[JT]]() #{{.*}} align 8 {
137; ARM: define private void @[[JT]]() #{{.*}} align 4 {
138; RISCV: define private void @[[JT]]() #{{.*}} align 8 {
139; LOONGARCH64: define private void @[[JT]]() #{{.*}} align 8 {
140
141; CHECK-LABEL: define internal void @__cfi_global_var_init() section ".text.startup" {
142; CHECK-NEXT: entry:
143; CHECK-NEXT: [[CMP:%.*]] = icmp ne ptr @f, null
144; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], ptr @[[JT]], ptr null
145; CHECK-NEXT: store ptr [[SEL]], ptr @x, align 8
146; CHECK-NEXT: [[CMP2:%.*]] = icmp ne ptr @f, null
147; CHECK-NEXT: [[SEL2:%.*]] = select i1 [[CMP2]], ptr @[[JT]], ptr null
148; CHECK-NEXT: store ptr [[SEL2]], ptr @x2, align 8
149; CHECK-NEXT: [[CMP3:%.*]] = icmp ne ptr @f, null
150; CHECK-NEXT: [[SEL3:%.*]] = select i1 [[CMP3]], ptr @[[JT]], ptr null
151; CHECK-NEXT: store ptr [[SEL3]], ptr @x3, align 8
152; CHECK-NEXT: [[CMP4:%.*]] = icmp ne ptr @f, null
153; CHECK-NEXT: [[SEL4:%.*]] = select i1 [[CMP4]], ptr @[[JT]], ptr null
154; CHECK-NEXT: [[GEP:%.*]] = getelementptr i8, ptr [[SEL4]], i64 42
155; CHECK-NEXT: store ptr [[GEP]], ptr @x4, align 8
156; CHECK-NEXT: [[CMP5:%.*]] = icmp ne ptr @f, null
157; CHECK-NEXT: [[SEL5:%.*]] = select i1 [[CMP5]], ptr @[[JT]], ptr null
158; CHECK-NEXT: [[IV:%.*]] = insertvalue { ptr, ptr, i32 } poison, ptr [[SEL5]], 0
159; CHECK-NEXT: [[CMP6:%.*]] = icmp ne ptr @f, null
160; CHECK-NEXT: [[SEL6:%.*]] = select i1 [[CMP6]], ptr @[[JT]], ptr null
161; CHECK-NEXT: [[IV2:%.*]] = insertvalue { ptr, ptr, i32 } [[IV]], ptr [[SEL6]], 1
162; CHECK-NEXT: [[IV3:%.*]] = insertvalue { ptr, ptr, i32 } [[IV2]], i32 42, 2
163; CHECK-NEXT: store { ptr, ptr, i32 } [[IV3]], ptr @s, align 8
164; CHECK-NEXT: ret void
165; CHECK-NEXT: }
166
167!0 = !{i32 0, !"typeid1"}
168