Add patterns for selecting TBM instructions from logical operations. Patch from Yunzh...
[oota-llvm.git] / lib / Target / X86 / README-X86-64.txt
index 86b16ec40631576117495ebdece1075545b26487..bcfdf0bc56b28ca4853244aa3669c96c8c968e09 100644 (file)
@@ -36,46 +36,11 @@ _conv:
        cmovb %rcx, %rax
        ret
 
-Seems like the jb branch has high likelyhood of being taken. It would have
+Seems like the jb branch has high likelihood of being taken. It would have
 saved a few instructions.
 
 //===---------------------------------------------------------------------===//
 
-Poor codegen:
-
-int X[2];
-int b;
-void test(void) {
-  memset(X, b, 2*sizeof(X[0]));
-}
-
-llc:
-       movq _b@GOTPCREL(%rip), %rax
-       movzbq (%rax), %rax
-       movq %rax, %rcx
-       shlq $8, %rcx
-       orq %rax, %rcx
-       movq %rcx, %rax
-       shlq $16, %rax
-       orq %rcx, %rax
-       movq %rax, %rcx
-       shlq $32, %rcx
-       movq _X@GOTPCREL(%rip), %rdx
-       orq %rax, %rcx
-       movq %rcx, (%rdx)
-       ret
-
-gcc:
-       movq    _b@GOTPCREL(%rip), %rax
-       movabsq $72340172838076673, %rdx
-       movzbq  (%rax), %rax
-       imulq   %rdx, %rax
-       movq    _X@GOTPCREL(%rip), %rdx
-       movq    %rax, (%rdx)
-       ret
-
-//===---------------------------------------------------------------------===//
-
 It's not possible to reference AH, BH, CH, and DH registers in an instruction
 requiring REX prefix. However, divb and mulb both produce results in AH. If isel
 emits a CopyFromReg which gets turned into a movb and that can be allocated a
@@ -158,3 +123,62 @@ be able to recognize the zero extend.  This could also presumably be implemented
 if we have whole-function selectiondags.
 
 //===---------------------------------------------------------------------===//
+
+Take the following code
+(from http://gcc.gnu.org/bugzilla/show_bug.cgi?id=34653):
+extern unsigned long table[];
+unsigned long foo(unsigned char *p) {
+  unsigned long tag = *p;
+  return table[tag >> 4] + table[tag & 0xf];
+}
+
+Current code generated:
+       movzbl  (%rdi), %eax
+       movq    %rax, %rcx
+       andq    $240, %rcx
+       shrq    %rcx
+       andq    $15, %rax
+       movq    table(,%rax,8), %rax
+       addq    table(%rcx), %rax
+       ret
+
+Issues:
+1. First movq should be movl; saves a byte.
+2. Both andq's should be andl; saves another two bytes.  I think this was
+   implemented at one point, but subsequently regressed.
+3. shrq should be shrl; saves another byte.
+4. The first andq can be completely eliminated by using a slightly more
+   expensive addressing mode.
+
+//===---------------------------------------------------------------------===//
+
+Consider the following (contrived testcase, but contains common factors):
+
+#include <stdarg.h>
+int test(int x, ...) {
+  int sum, i;
+  va_list l;
+  va_start(l, x);
+  for (i = 0; i < x; i++)
+    sum += va_arg(l, int);
+  va_end(l);
+  return sum;
+}
+
+Testcase given in C because fixing it will likely involve changing the IR
+generated for it.  The primary issue with the result is that it doesn't do any
+of the optimizations which are possible if we know the address of a va_list
+in the current function is never taken:
+1. We shouldn't spill the XMM registers because we only call va_arg with "int".
+2. It would be nice if we could scalarrepl the va_list.
+3. Probably overkill, but it'd be cool if we could peel off the first five
+iterations of the loop.
+
+Other optimizations involving functions which use va_arg on floats which don't
+have the address of a va_list taken:
+1. Conversely to the above, we shouldn't spill general registers if we only
+   call va_arg on "double".
+2. If we know nothing more than 64 bits wide is read from the XMM registers,
+   we can change the spilling code to reduce the amount of stack used by half.
+
+//===---------------------------------------------------------------------===//