From b42e20be77e2103c76373b4c6efa0cf8fed69025 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Tue, 16 Jun 2009 06:15:56 +0000 Subject: [PATCH] another xform that is target-independent (should be done in instcombine). git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@73472 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/X86/README.txt | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/lib/Target/X86/README.txt b/lib/Target/X86/README.txt index 767771f082a..4464878ce21 100644 --- a/lib/Target/X86/README.txt +++ b/lib/Target/X86/README.txt @@ -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. //===---------------------------------------------------------------------===//