another xform that is target-independent (should be done in instcombine).
authorChris Lattner <sabre@nondot.org>
Tue, 16 Jun 2009 06:15:56 +0000 (06:15 +0000)
committerChris Lattner <sabre@nondot.org>
Tue, 16 Jun 2009 06:15:56 +0000 (06:15 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@73472 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/X86/README.txt

index 767771f082a6d59955248b5e7eb344ccfb88691b..4464878ce2173c49c827b5a04cb9314243d461b3 100644 (file)
@@ -1895,20 +1895,40 @@ Ideal output:
 
 Testcase:
 int x(int a) { return (a & 0x80) ? 0x100 : 0; }
+int y(int a) { return (a & 0x80) *2; }
 
-Current output:
+Current:
        testl   $128, 4(%esp)
        setne   %al
        movzbl  %al, %eax
        shll    $8, %eax
        ret
 
-Ideal output:
+Better:
        movl    4(%esp), %eax
        addl    %eax, %eax
        andl    $256, %eax
        ret
 
-We generally want to fold shifted tests of a single bit into a shift+and on x86.
+This is another general instcombine transformation that is profitable on all
+targets.  In LLVM IR, these functions look like this:
+
+define i32 @x(i32 %a) nounwind readnone {
+entry:
+       %0 = and i32 %a, 128
+       %1 = icmp eq i32 %0, 0
+       %iftmp.0.0 = select i1 %1, i32 0, i32 256
+       ret i32 %iftmp.0.0
+}
+
+define i32 @y(i32 %a) nounwind readnone {
+entry:
+       %0 = shl i32 %a, 1
+       %1 = and i32 %0, 256
+       ret i32 %1
+}
+
+Replacing an icmp+select with a shift should always be considered profitable in
+instcombine.
 
 //===---------------------------------------------------------------------===//