Skip to content

Commit 62dd488

Browse files
committed
Add llvm-tli-checker
A new tool that compares TargetLibraryInfo's opinion of the availability of library function calls against the functions actually exported by a specified set of libraries. Can be helpful in verifying the correctness of TLI for a given target, and avoid mishaps such as had to be addressed in D107509 and 94b4598. The tool currently supports ELF object files only, although it's unlikely to be hard to add support for other formats. Differential Revision: https://reviews.llvm.org/D111358
1 parent 2494e9c commit 62dd488

File tree

6 files changed

+773
-0
lines changed

6 files changed

+773
-0
lines changed

llvm/docs/CommandGuide/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,3 +82,4 @@ Developer Tools
8282
llvm-locstats
8383
llvm-pdbutil
8484
llvm-profgen
85+
llvm-tli-checker
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
llvm-tli-checker - TargetLibraryInfo vs library checker
2+
=======================================================
3+
4+
.. program:: llvm-tli-checker
5+
6+
SYNOPSIS
7+
--------
8+
9+
:program:`llvm-tli-checker` [*options*] [*library-file...*]
10+
11+
DESCRIPTION
12+
-----------
13+
14+
:program:`llvm-tli-checker` compares TargetLibraryInfo's opinion of the
15+
availability of library functions against the set of functions exported
16+
by the specified library files, reporting any disagreements between TLI's
17+
opinion and whether the function is actually present. This is primarily
18+
useful for vendors to ensure the TLI for their target is correct, and
19+
the compiler will not "optimize" some code sequence into a library call
20+
that is not actually available.
21+
22+
EXAMPLE
23+
-------
24+
25+
.. code-block:: console
26+
27+
$ llvm-tli-checker --triple x86_64-scei-ps4 example.so
28+
TLI knows 466 symbols, 235 available for 'x86_64-scei-ps4'
29+
30+
Looking for symbols in 'example.so'
31+
Found 235 global function symbols in 'example.so'
32+
Found a grand total of 235 library symbols
33+
<< TLI yes SDK no: '_ZdaPv' aka operator delete[](void*)
34+
>> TLI no SDK yes: '_ZdaPvj' aka operator delete[](void*, unsigned int)
35+
<< Total TLI yes SDK no: 1
36+
>> Total TLI no SDK yes: 1
37+
== Total TLI yes SDK yes: 234
38+
FAIL: LLVM TLI doesn't match SDK libraries.
39+
40+
OPTIONS
41+
-------
42+
43+
.. option:: --dump-tli
44+
45+
Print "available"/"not available" for each library function, according to
46+
TargetLibraryInfo's information for the specified triple, and exit. This
47+
option does not read any input files.
48+
49+
.. option:: --help, -h
50+
51+
Print a summary of command line options and exit.
52+
53+
.. option:: --libdir=<directory>
54+
55+
A base directory to prepend to each library file path. This is handy
56+
when there are a number of library files all in the same directory, or
57+
a list of input filenames are kept in a response file.
58+
59+
.. option:: --report=<level>
60+
61+
The amount of information to report. <level> can be summary, discrepancy,
62+
or full. A summary report gives only the count of matching and mis-matching
63+
symbols; discrepancy lists the mis-matching symbols; and full lists all
64+
symbols known to TLI, matching or mis-matching. The default is discrepancy.
65+
66+
.. option:: --separate
67+
68+
Read and report a summary for each library file separately. This can be
69+
useful to identify library files that don't contribute anything that TLI
70+
knows about. Implies --report=summary (can be overridden).
71+
72+
.. option:: --triple=<triple>
73+
74+
The triple to use for initializing TargetLibraryInfo.
75+
76+
.. option:: @<FILE>
77+
78+
Read command-line options and/or library names from response file `<FILE>`.
79+
80+
EXIT STATUS
81+
-----------
82+
83+
:program:`llvm-tli-checker` returns 0 even if there are mismatches. It returns a
84+
non-zero exit code if there is an unrecognized option, or no input files are
85+
provided.
Lines changed: 288 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,288 @@
1+
# REQUIRES: x86-registered-target
2+
#
3+
# RUN: llvm-mc --triple=x86_64-scei-ps4 --filetype=obj %s -o %t.o
4+
# RUN: ld.lld --shared %t.o -o %t.so
5+
# RUN: llvm-tli-checker --triple=x86_64-scei-ps4 %t.so | FileCheck %s
6+
#
7+
# RUN: llvm-mc --triple=x86_64-scei-ps4 --defsym WRONG=1 --filetype=obj %s -o %t2.o
8+
# RUN: ld.lld --shared %t2.o -o %t2.so
9+
# RUN: echo %t2.so > %t2.txt
10+
# RUN: llvm-tli-checker --triple x86_64-scei-ps4 @%t2.txt | \
11+
# RUN: FileCheck %s --check-prefix=WRONG_SUMMARY --check-prefix=WRONG_DETAIL \
12+
# RUN: --implicit-check-not="==" --implicit-check-not="<<" --implicit-check-not=">>"
13+
# RUN: llvm-tli-checker --triple x86_64-scei-ps4 @%t2.txt --report=summary | \
14+
# RUN: FileCheck %s --check-prefix=WRONG_SUMMARY \
15+
# RUN: --implicit-check-not="==" --implicit-check-not="<<" --implicit-check-not=">>"
16+
## --separate implies --report=summary.
17+
# RUN: llvm-tli-checker --triple x86_64-scei-ps4 @%t2.txt --separate | \
18+
# RUN: FileCheck %s --check-prefix=WRONG_SUMMARY \
19+
# RUN: --implicit-check-not="==" --implicit-check-not="<<" --implicit-check-not=">>"
20+
#
21+
# RUN: llvm-tli-checker --triple x86_64-scei-ps4 --dump-tli > %t3.txt
22+
# RUN: FileCheck %s --check-prefix=AVAIL --input-file %t3.txt
23+
# RUN: FileCheck %s --check-prefix=UNAVAIL --input-file %t3.txt
24+
#
25+
# CHECK: << Total TLI yes SDK no: 0
26+
# CHECK: >> Total TLI no SDK yes: 0
27+
# CHECK: == Total TLI yes SDK yes: 235
28+
#
29+
# WRONG_DETAIL: << TLI yes SDK no : '_ZdaPv'
30+
# WRONG_DETAIL: >> TLI no SDK yes: '_ZdaPvj'
31+
# WRONG_SUMMARY: << Total TLI yes SDK no: 1{{$}}
32+
# WRONG_SUMMARY: >> Total TLI no SDK yes: 1{{$}}
33+
# WRONG_SUMMARY: == Total TLI yes SDK yes: 234
34+
#
35+
## The -COUNT suffix doesn't care if there are too many matches, so check
36+
## the exact count first; the two directives should add up to that.
37+
# AVAIL: TLI knows 466 symbols, 235 available
38+
# AVAIL-COUNT-235: {{^}} available
39+
# UNAVAIL-COUNT-231: not available
40+
41+
.macro defname name
42+
.globl \name
43+
.type \name ,@function
44+
\name : nop
45+
.endm
46+
47+
.text
48+
# For the WRONG case, omit _ZdaPv and include _ZdaPvj.
49+
.ifdef WRONG
50+
defname _ZdaPvj
51+
.else
52+
defname _ZdaPv
53+
.endif
54+
defname _ZdaPvRKSt9nothrow_t
55+
defname _ZdaPvSt11align_val_t
56+
defname _ZdaPvSt11align_val_tRKSt9nothrow_t
57+
defname _ZdaPvm
58+
defname _ZdaPvmSt11align_val_t
59+
defname _ZdlPv
60+
defname _ZdlPvRKSt9nothrow_t
61+
defname _ZdlPvSt11align_val_t
62+
defname _ZdlPvSt11align_val_tRKSt9nothrow_t
63+
defname _ZdlPvm
64+
defname _ZdlPvmSt11align_val_t
65+
defname _Znam
66+
defname _ZnamRKSt9nothrow_t
67+
defname _ZnamSt11align_val_t
68+
defname _ZnamSt11align_val_tRKSt9nothrow_t
69+
defname _Znwm
70+
defname _ZnwmRKSt9nothrow_t
71+
defname _ZnwmSt11align_val_t
72+
defname _ZnwmSt11align_val_tRKSt9nothrow_t
73+
defname __cxa_atexit
74+
defname __cxa_guard_abort
75+
defname __cxa_guard_acquire
76+
defname __cxa_guard_release
77+
defname abs
78+
defname acos
79+
defname acosf
80+
defname acosh
81+
defname acoshf
82+
defname acoshl
83+
defname acosl
84+
defname aligned_alloc
85+
defname asin
86+
defname asinf
87+
defname asinh
88+
defname asinhf
89+
defname asinhl
90+
defname asinl
91+
defname atan
92+
defname atan2
93+
defname atan2f
94+
defname atan2l
95+
defname atanf
96+
defname atanh
97+
defname atanhf
98+
defname atanhl
99+
defname atanl
100+
defname atof
101+
defname atoi
102+
defname atol
103+
defname atoll
104+
defname calloc
105+
defname cbrt
106+
defname cbrtf
107+
defname cbrtl
108+
defname ceil
109+
defname ceilf
110+
defname ceill
111+
defname clearerr
112+
defname copysign
113+
defname copysignf
114+
defname copysignl
115+
defname cos
116+
defname cosf
117+
defname cosh
118+
defname coshf
119+
defname coshl
120+
defname cosl
121+
defname exp
122+
defname exp2
123+
defname exp2f
124+
defname exp2l
125+
defname expf
126+
defname expl
127+
defname expm1
128+
defname expm1f
129+
defname expm1l
130+
defname fabs
131+
defname fabsf
132+
defname fabsl
133+
defname fclose
134+
defname fdopen
135+
defname feof
136+
defname ferror
137+
defname fflush
138+
defname fgetc
139+
defname fgetpos
140+
defname fgets
141+
defname fileno
142+
defname floor
143+
defname floorf
144+
defname floorl
145+
defname fmax
146+
defname fmaxf
147+
defname fmaxl
148+
defname fmin
149+
defname fminf
150+
defname fminl
151+
defname fmod
152+
defname fmodf
153+
defname fmodl
154+
defname fopen
155+
defname fprintf
156+
defname fputc
157+
defname fputs
158+
defname fread
159+
defname free
160+
defname frexp
161+
defname frexpf
162+
defname frexpl
163+
defname fscanf
164+
defname fseek
165+
defname fsetpos
166+
defname ftell
167+
defname fwrite
168+
defname getc
169+
defname getchar
170+
defname gets
171+
defname isdigit
172+
defname labs
173+
defname ldexp
174+
defname ldexpf
175+
defname ldexpl
176+
defname llabs
177+
defname log
178+
defname log10
179+
defname log10f
180+
defname log10l
181+
defname log1p
182+
defname log1pf
183+
defname log1pl
184+
defname log2
185+
defname log2f
186+
defname log2l
187+
defname logb
188+
defname logbf
189+
defname logbl
190+
defname logf
191+
defname logl
192+
defname malloc
193+
defname memalign
194+
defname memchr
195+
defname memcmp
196+
defname memcpy
197+
defname memmove
198+
defname memset
199+
defname mktime
200+
defname modf
201+
defname modff
202+
defname modfl
203+
defname nearbyint
204+
defname nearbyintf
205+
defname nearbyintl
206+
defname perror
207+
defname posix_memalign
208+
defname pow
209+
defname powf
210+
defname powl
211+
defname printf
212+
defname putc
213+
defname putchar
214+
defname puts
215+
defname qsort
216+
defname realloc
217+
defname remainder
218+
defname remainderf
219+
defname remainderl
220+
defname remove
221+
defname rewind
222+
defname rint
223+
defname rintf
224+
defname rintl
225+
defname round
226+
defname roundf
227+
defname roundl
228+
defname scanf
229+
defname setbuf
230+
defname setvbuf
231+
defname sin
232+
defname sinf
233+
defname sinh
234+
defname sinhf
235+
defname sinhl
236+
defname sinl
237+
defname snprintf
238+
defname sprintf
239+
defname sqrt
240+
defname sqrtf
241+
defname sqrtl
242+
defname sscanf
243+
defname strcasecmp
244+
defname strcat
245+
defname strchr
246+
defname strcmp
247+
defname strcoll
248+
defname strcpy
249+
defname strcspn
250+
defname strdup
251+
defname strlen
252+
defname strncasecmp
253+
defname strncat
254+
defname strncmp
255+
defname strncpy
256+
defname strpbrk
257+
defname strrchr
258+
defname strspn
259+
defname strstr
260+
defname strtod
261+
defname strtof
262+
defname strtok
263+
defname strtok_r
264+
defname strtol
265+
defname strtold
266+
defname strtoll
267+
defname strtoul
268+
defname strtoull
269+
defname strxfrm
270+
defname tan
271+
defname tanf
272+
defname tanh
273+
defname tanhf
274+
defname tanhl
275+
defname tanl
276+
defname trunc
277+
defname truncf
278+
defname truncl
279+
defname ungetc
280+
defname vfprintf
281+
defname vfscanf
282+
defname vprintf
283+
defname vscanf
284+
defname vsnprintf
285+
defname vsprintf
286+
defname vsscanf
287+
defname wcslen
288+

0 commit comments

Comments
 (0)