Use %ull here.
[llvm/stm8.git] / lib / Target / X86 / README-X86-64.txt
blobe21d69a7bcbf15e6b2e401076e63cefceb051815
1 //===- README_X86_64.txt - Notes for X86-64 code gen ----------------------===//
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.
8 //===---------------------------------------------------------------------===//
10 Are we better off using branches instead of cmove to implement FP to
11 unsigned i64?
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
25 instead of
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
39 Seems like the jb branch has high likelyhood of being taken. It would have
40 saved a few instructions.
42 //===---------------------------------------------------------------------===//
44 It's not possible to reference AH, BH, CH, and DH registers in an instruction
45 requiring REX prefix. However, divb and mulb both produce results in AH. If isel
46 emits a CopyFromReg which gets turned into a movb and that can be allocated a
47 r8b - r15b.
49 To get around this, isel emits a CopyFromReg from AX and then right shift it
50 down by 8 and truncate it. It's not pretty but it works. We need some register
51 allocation magic to make the hack go away (e.g. putting additional constraints
52 on the result of the movb).
54 //===---------------------------------------------------------------------===//
56 The x86-64 ABI for hidden-argument struct returns requires that the
57 incoming value of %rdi be copied into %rax by the callee upon return.
59 The idea is that it saves callers from having to remember this value,
60 which would often require a callee-saved register. Callees usually
61 need to keep this value live for most of their body anyway, so it
62 doesn't add a significant burden on them.
64 We currently implement this in codegen, however this is suboptimal
65 because it means that it would be quite awkward to implement the
66 optimization for callers.
68 A better implementation would be to relax the LLVM IR rules for sret
69 arguments to allow a function with an sret argument to have a non-void
70 return type, and to have the front-end to set up the sret argument value
71 as the return value of the function. The front-end could more easily
72 emit uses of the returned struct value to be in terms of the function's
73 lowered return value, and it would free non-C frontends from a
74 complication only required by a C-based ABI.
76 //===---------------------------------------------------------------------===//
78 We get a redundant zero extension for code like this:
80 int mask[1000];
81 int foo(unsigned x) {
82  if (x < 10)
83    x = x * 45;
84  else
85    x = x * 78;
86  return mask[x];
89 _foo:
90 LBB1_0: ## entry
91         cmpl    $9, %edi
92         jbe     LBB1_3  ## bb
93 LBB1_1: ## bb1
94         imull   $78, %edi, %eax
95 LBB1_2: ## bb2
96         movl    %eax, %eax                    <----
97         movq    _mask@GOTPCREL(%rip), %rcx
98         movl    (%rcx,%rax,4), %eax
99         ret
100 LBB1_3: ## bb
101         imull   $45, %edi, %eax
102         jmp     LBB1_2  ## bb2
103   
104 Before regalloc, we have:
106         %reg1025<def> = IMUL32rri8 %reg1024, 45, %EFLAGS<imp-def>
107         JMP mbb<bb2,0x203afb0>
108     Successors according to CFG: 0x203afb0 (#3)
110 bb1: 0x203af60, LLVM BB @0x1e02310, ID#2:
111     Predecessors according to CFG: 0x203aec0 (#0)
112         %reg1026<def> = IMUL32rri8 %reg1024, 78, %EFLAGS<imp-def>
113     Successors according to CFG: 0x203afb0 (#3)
115 bb2: 0x203afb0, LLVM BB @0x1e02340, ID#3:
116     Predecessors according to CFG: 0x203af10 (#1) 0x203af60 (#2)
117         %reg1027<def> = PHI %reg1025, mbb<bb,0x203af10>,
118                             %reg1026, mbb<bb1,0x203af60>
119         %reg1029<def> = MOVZX64rr32 %reg1027
121 so we'd have to know that IMUL32rri8 leaves the high word zero extended and to
122 be able to recognize the zero extend.  This could also presumably be implemented
123 if we have whole-function selectiondags.
125 //===---------------------------------------------------------------------===//
127 Take the following C code
128 (from http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43640):
130 struct u1
132         float x;
133         float y;
136 float foo(struct u1 u)
138         return u.x + u.y;
141 Optimizes to the following IR:
142 define float @foo(double %u.0) nounwind readnone {
143 entry:
144   %tmp8 = bitcast double %u.0 to i64              ; <i64> [#uses=2]
145   %tmp6 = trunc i64 %tmp8 to i32                  ; <i32> [#uses=1]
146   %tmp7 = bitcast i32 %tmp6 to float              ; <float> [#uses=1]
147   %tmp2 = lshr i64 %tmp8, 32                      ; <i64> [#uses=1]
148   %tmp3 = trunc i64 %tmp2 to i32                  ; <i32> [#uses=1]
149   %tmp4 = bitcast i32 %tmp3 to float              ; <float> [#uses=1]
150   %0 = fadd float %tmp7, %tmp4                    ; <float> [#uses=1]
151   ret float %0
154 And current llvm-gcc/clang output:
155         movd    %xmm0, %rax
156         movd    %eax, %xmm1
157         shrq    $32, %rax
158         movd    %eax, %xmm0
159         addss   %xmm1, %xmm0
160         ret
162 We really shouldn't move the floats to RAX, only to immediately move them
163 straight back to the XMM registers.
165 There really isn't any good way to handle this purely in IR optimizers; it
166 could possibly be handled by changing the output of the fronted, though.  It
167 would also be feasible to add a x86-specific DAGCombine to optimize the
168 bitcast+trunc+(lshr+)bitcast combination.
170 //===---------------------------------------------------------------------===//
172 Take the following code
173 (from http://gcc.gnu.org/bugzilla/show_bug.cgi?id=34653):
174 extern unsigned long table[];
175 unsigned long foo(unsigned char *p) {
176   unsigned long tag = *p;
177   return table[tag >> 4] + table[tag & 0xf];
180 Current code generated:
181         movzbl  (%rdi), %eax
182         movq    %rax, %rcx
183         andq    $240, %rcx
184         shrq    %rcx
185         andq    $15, %rax
186         movq    table(,%rax,8), %rax
187         addq    table(%rcx), %rax
188         ret
190 Issues:
191 1. First movq should be movl; saves a byte.
192 2. Both andq's should be andl; saves another two bytes.  I think this was
193    implemented at one point, but subsequently regressed.
194 3. shrq should be shrl; saves another byte.
195 4. The first andq can be completely eliminated by using a slightly more
196    expensive addressing mode.
198 //===---------------------------------------------------------------------===//
200 Consider the following (contrived testcase, but contains common factors):
202 #include <stdarg.h>
203 int test(int x, ...) {
204   int sum, i;
205   va_list l;
206   va_start(l, x);
207   for (i = 0; i < x; i++)
208     sum += va_arg(l, int);
209   va_end(l);
210   return sum;
213 Testcase given in C because fixing it will likely involve changing the IR
214 generated for it.  The primary issue with the result is that it doesn't do any
215 of the optimizations which are possible if we know the address of a va_list
216 in the current function is never taken:
217 1. We shouldn't spill the XMM registers because we only call va_arg with "int".
218 2. It would be nice if we could scalarrepl the va_list.
219 3. Probably overkill, but it'd be cool if we could peel off the first five
220 iterations of the loop.
222 Other optimizations involving functions which use va_arg on floats which don't
223 have the address of a va_list taken:
224 1. Conversely to the above, we shouldn't spill general registers if we only
225    call va_arg on "double".
226 2. If we know nothing more than 64 bits wide is read from the XMM registers,
227    we can change the spilling code to reduce the amount of stack used by half.
229 //===---------------------------------------------------------------------===//