~ubuntu-branches/ubuntu/wily/clamav/wily-proposed

« back to all changes in this revision

Viewing changes to libclamav/c++/llvm/lib/Target/X86/README-X86-64.txt

  • Committer: Package Import Robot
  • Author(s): Scott Kitterman, Sebastian Andrzej Siewior, Andreas Cadhalpun, Scott Kitterman, Javier Fernández-Sanguino
  • Date: 2015-01-28 00:25:13 UTC
  • mfrom: (0.48.14 sid)
  • Revision ID: package-import@ubuntu.com-20150128002513-lil2oi74cooy4lzr
Tags: 0.98.6+dfsg-1
[ Sebastian Andrzej Siewior ]
* update "fix-ssize_t-size_t-off_t-printf-modifier", include of misc.h was
  missing but was pulled in via the systemd patch.
* Don't leak return codes from libmspack to clamav API. (Closes: #774686).

[ Andreas Cadhalpun ]
* Add patch to avoid emitting incremental progress messages when not
  outputting to a terminal. (Closes: #767350)
* Update lintian-overrides for unused-file-paragraph-in-dep5-copyright.
* clamav-base.postinst: always chown /var/log/clamav and /var/lib/clamav
  to clamav:clamav, not only on fresh installations. (Closes: #775400)
* Adapt the clamav-daemon and clamav-freshclam logrotate scripts,
  so that they correctly work under systemd.
* Move the PidFile variable from the clamd/freshclam configuration files
  to the init scripts. This makes the init scripts more robust against
  misconfiguration and avoids error messages with systemd. (Closes: #767353)
* debian/copyright: drop files from Files-Excluded only present in github
  tarballs
* Drop Workaround-a-bug-in-libc-on-Hurd.patch, because hurd got fixed.
  (see #752237)
* debian/rules: Remove useless --with-system-tommath --without-included-ltdl
  configure options.

[ Scott Kitterman ]
* Stop stripping llvm when repacking the tarball as the system llvm on some
  releases is too old to use
* New upstream bugfix release
  - Library shared object revisions.
  - Includes a patch from Sebastian Andrzej Siewior making ClamAV pid files
    compatible with systemd.
  - Fix a heap out of bounds condition with crafted Yoda's crypter files.
    This issue was discovered by Felix Groebert of the Google Security Team.
  - Fix a heap out of bounds condition with crafted mew packer files. This
    issue was discovered by Felix Groebert of the Google Security Team.
  - Fix a heap out of bounds condition with crafted upx packer files. This
    issue was discovered by Kevin Szkudlapski of Quarkslab.
  - Fix a heap out of bounds condition with crafted upack packer files. This
    issue was discovered by Sebastian Andrzej Siewior. CVE-2014-9328.
  - Compensate a crash due to incorrect compiler optimization when handling
    crafted petite packer files. This issue was discovered by Sebastian
    Andrzej Siewior.
* Update lintian override for embedded zlib to match new so version

[ Javier Fernández-Sanguino ]
* Updated Spanish Debconf template translation (Closes: #773563)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
//===- README_X86_64.txt - Notes for X86-64 code gen ----------------------===//
 
2
 
 
3
AMD64 Optimization Manual 8.2 has some nice information about optimizing integer
 
4
multiplication by a constant. How much of it applies to Intel's X86-64
 
5
implementation? There are definite trade-offs to consider: latency vs. register
 
6
pressure vs. code size.
 
7
 
 
8
//===---------------------------------------------------------------------===//
 
9
 
 
10
Are we better off using branches instead of cmove to implement FP to
 
11
unsigned i64?
 
12
 
 
13
_conv:
 
14
        ucomiss LC0(%rip), %xmm0
 
15
        cvttss2siq      %xmm0, %rdx
 
16
        jb      L3
 
17
        subss   LC0(%rip), %xmm0
 
18
        movabsq $-9223372036854775808, %rax
 
19
        cvttss2siq      %xmm0, %rdx
 
20
        xorq    %rax, %rdx
 
21
L3:
 
22
        movq    %rdx, %rax
 
23
        ret
 
24
 
 
25
instead of
 
26
 
 
27
_conv:
 
28
        movss LCPI1_0(%rip), %xmm1
 
29
        cvttss2siq %xmm0, %rcx
 
30
        movaps %xmm0, %xmm2
 
31
        subss %xmm1, %xmm2
 
32
        cvttss2siq %xmm2, %rax
 
33
        movabsq $-9223372036854775808, %rdx
 
34
        xorq %rdx, %rax
 
35
        ucomiss %xmm1, %xmm0
 
36
        cmovb %rcx, %rax
 
37
        ret
 
38
 
 
39
Seems like the jb branch has high likelyhood of being taken. It would have
 
40
saved a few instructions.
 
41
 
 
42
//===---------------------------------------------------------------------===//
 
43
 
 
44
Poor codegen:
 
45
 
 
46
int X[2];
 
47
int b;
 
48
void test(void) {
 
49
  memset(X, b, 2*sizeof(X[0]));
 
50
}
 
51
 
 
52
llc:
 
53
        movq _b@GOTPCREL(%rip), %rax
 
54
        movzbq (%rax), %rax
 
55
        movq %rax, %rcx
 
56
        shlq $8, %rcx
 
57
        orq %rax, %rcx
 
58
        movq %rcx, %rax
 
59
        shlq $16, %rax
 
60
        orq %rcx, %rax
 
61
        movq %rax, %rcx
 
62
        shlq $32, %rcx
 
63
        movq _X@GOTPCREL(%rip), %rdx
 
64
        orq %rax, %rcx
 
65
        movq %rcx, (%rdx)
 
66
        ret
 
67
 
 
68
gcc:
 
69
        movq    _b@GOTPCREL(%rip), %rax
 
70
        movabsq $72340172838076673, %rdx
 
71
        movzbq  (%rax), %rax
 
72
        imulq   %rdx, %rax
 
73
        movq    _X@GOTPCREL(%rip), %rdx
 
74
        movq    %rax, (%rdx)
 
75
        ret
 
76
 
 
77
And the codegen is even worse for the following
 
78
(from http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33103):
 
79
  void fill1(char *s, int a)
 
80
  {
 
81
    __builtin_memset(s, a, 15);
 
82
  }
 
83
 
 
84
For this version, we duplicate the computation of the constant to store.
 
85
 
 
86
//===---------------------------------------------------------------------===//
 
87
 
 
88
It's not possible to reference AH, BH, CH, and DH registers in an instruction
 
89
requiring REX prefix. However, divb and mulb both produce results in AH. If isel
 
90
emits a CopyFromReg which gets turned into a movb and that can be allocated a
 
91
r8b - r15b.
 
92
 
 
93
To get around this, isel emits a CopyFromReg from AX and then right shift it
 
94
down by 8 and truncate it. It's not pretty but it works. We need some register
 
95
allocation magic to make the hack go away (e.g. putting additional constraints
 
96
on the result of the movb).
 
97
 
 
98
//===---------------------------------------------------------------------===//
 
99
 
 
100
The x86-64 ABI for hidden-argument struct returns requires that the
 
101
incoming value of %rdi be copied into %rax by the callee upon return.
 
102
 
 
103
The idea is that it saves callers from having to remember this value,
 
104
which would often require a callee-saved register. Callees usually
 
105
need to keep this value live for most of their body anyway, so it
 
106
doesn't add a significant burden on them.
 
107
 
 
108
We currently implement this in codegen, however this is suboptimal
 
109
because it means that it would be quite awkward to implement the
 
110
optimization for callers.
 
111
 
 
112
A better implementation would be to relax the LLVM IR rules for sret
 
113
arguments to allow a function with an sret argument to have a non-void
 
114
return type, and to have the front-end to set up the sret argument value
 
115
as the return value of the function. The front-end could more easily
 
116
emit uses of the returned struct value to be in terms of the function's
 
117
lowered return value, and it would free non-C frontends from a
 
118
complication only required by a C-based ABI.
 
119
 
 
120
//===---------------------------------------------------------------------===//
 
121
 
 
122
We get a redundant zero extension for code like this:
 
123
 
 
124
int mask[1000];
 
125
int foo(unsigned x) {
 
126
 if (x < 10)
 
127
   x = x * 45;
 
128
 else
 
129
   x = x * 78;
 
130
 return mask[x];
 
131
}
 
132
 
 
133
_foo:
 
134
LBB1_0: ## entry
 
135
        cmpl    $9, %edi
 
136
        jbe     LBB1_3  ## bb
 
137
LBB1_1: ## bb1
 
138
        imull   $78, %edi, %eax
 
139
LBB1_2: ## bb2
 
140
        movl    %eax, %eax                    <----
 
141
        movq    _mask@GOTPCREL(%rip), %rcx
 
142
        movl    (%rcx,%rax,4), %eax
 
143
        ret
 
144
LBB1_3: ## bb
 
145
        imull   $45, %edi, %eax
 
146
        jmp     LBB1_2  ## bb2
 
147
  
 
148
Before regalloc, we have:
 
149
 
 
150
        %reg1025<def> = IMUL32rri8 %reg1024, 45, %EFLAGS<imp-def>
 
151
        JMP mbb<bb2,0x203afb0>
 
152
    Successors according to CFG: 0x203afb0 (#3)
 
153
 
 
154
bb1: 0x203af60, LLVM BB @0x1e02310, ID#2:
 
155
    Predecessors according to CFG: 0x203aec0 (#0)
 
156
        %reg1026<def> = IMUL32rri8 %reg1024, 78, %EFLAGS<imp-def>
 
157
    Successors according to CFG: 0x203afb0 (#3)
 
158
 
 
159
bb2: 0x203afb0, LLVM BB @0x1e02340, ID#3:
 
160
    Predecessors according to CFG: 0x203af10 (#1) 0x203af60 (#2)
 
161
        %reg1027<def> = PHI %reg1025, mbb<bb,0x203af10>,
 
162
                            %reg1026, mbb<bb1,0x203af60>
 
163
        %reg1029<def> = MOVZX64rr32 %reg1027
 
164
 
 
165
so we'd have to know that IMUL32rri8 leaves the high word zero extended and to
 
166
be able to recognize the zero extend.  This could also presumably be implemented
 
167
if we have whole-function selectiondags.
 
168
 
 
169
//===---------------------------------------------------------------------===//
 
170
 
 
171
Take the following C code
 
172
(from http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43640):
 
173
 
 
174
struct u1
 
175
{
 
176
        float x;
 
177
        float y;
 
178
};
 
179
 
 
180
float foo(struct u1 u)
 
181
{
 
182
        return u.x + u.y;
 
183
}
 
184
 
 
185
Optimizes to the following IR:
 
186
define float @foo(double %u.0) nounwind readnone {
 
187
entry:
 
188
  %tmp8 = bitcast double %u.0 to i64              ; <i64> [#uses=2]
 
189
  %tmp6 = trunc i64 %tmp8 to i32                  ; <i32> [#uses=1]
 
190
  %tmp7 = bitcast i32 %tmp6 to float              ; <float> [#uses=1]
 
191
  %tmp2 = lshr i64 %tmp8, 32                      ; <i64> [#uses=1]
 
192
  %tmp3 = trunc i64 %tmp2 to i32                  ; <i32> [#uses=1]
 
193
  %tmp4 = bitcast i32 %tmp3 to float              ; <float> [#uses=1]
 
194
  %0 = fadd float %tmp7, %tmp4                    ; <float> [#uses=1]
 
195
  ret float %0
 
196
}
 
197
 
 
198
And current llvm-gcc/clang output:
 
199
        movd    %xmm0, %rax
 
200
        movd    %eax, %xmm1
 
201
        shrq    $32, %rax
 
202
        movd    %eax, %xmm0
 
203
        addss   %xmm1, %xmm0
 
204
        ret
 
205
 
 
206
We really shouldn't move the floats to RAX, only to immediately move them
 
207
straight back to the XMM registers.
 
208
 
 
209
There really isn't any good way to handle this purely in IR optimizers; it
 
210
could possibly be handled by changing the output of the fronted, though.  It
 
211
would also be feasible to add a x86-specific DAGCombine to optimize the
 
212
bitcast+trunc+(lshr+)bitcast combination.
 
213
 
 
214
//===---------------------------------------------------------------------===//
 
215
 
 
216
Take the following code
 
217
(from http://gcc.gnu.org/bugzilla/show_bug.cgi?id=34653):
 
218
extern unsigned long table[];
 
219
unsigned long foo(unsigned char *p) {
 
220
  unsigned long tag = *p;
 
221
  return table[tag >> 4] + table[tag & 0xf];
 
222
}
 
223
 
 
224
Current code generated:
 
225
        movzbl  (%rdi), %eax
 
226
        movq    %rax, %rcx
 
227
        andq    $240, %rcx
 
228
        shrq    %rcx
 
229
        andq    $15, %rax
 
230
        movq    table(,%rax,8), %rax
 
231
        addq    table(%rcx), %rax
 
232
        ret
 
233
 
 
234
Issues:
 
235
1. First movq should be movl; saves a byte.
 
236
2. Both andq's should be andl; saves another two bytes.  I think this was
 
237
   implemented at one point, but subsequently regressed.
 
238
3. shrq should be shrl; saves another byte.
 
239
4. The first andq can be completely eliminated by using a slightly more
 
240
   expensive addressing mode.
 
241
 
 
242
//===---------------------------------------------------------------------===//
 
243
 
 
244
Consider the following (contrived testcase, but contains common factors):
 
245
 
 
246
#include <stdarg.h>
 
247
int test(int x, ...) {
 
248
  int sum, i;
 
249
  va_list l;
 
250
  va_start(l, x);
 
251
  for (i = 0; i < x; i++)
 
252
    sum += va_arg(l, int);
 
253
  va_end(l);
 
254
  return sum;
 
255
}
 
256
 
 
257
Testcase given in C because fixing it will likely involve changing the IR
 
258
generated for it.  The primary issue with the result is that it doesn't do any
 
259
of the optimizations which are possible if we know the address of a va_list
 
260
in the current function is never taken:
 
261
1. We shouldn't spill the XMM registers because we only call va_arg with "int".
 
262
2. It would be nice if we could scalarrepl the va_list.
 
263
3. Probably overkill, but it'd be cool if we could peel off the first five
 
264
iterations of the loop.
 
265
 
 
266
Other optimizations involving functions which use va_arg on floats which don't
 
267
have the address of a va_list taken:
 
268
1. Conversely to the above, we shouldn't spill general registers if we only
 
269
   call va_arg on "double".
 
270
2. If we know nothing more than 64 bits wide is read from the XMM registers,
 
271
   we can change the spilling code to reduce the amount of stack used by half.
 
272
 
 
273
//===---------------------------------------------------------------------===//