mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-13 04:30:23 +00:00
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
This commit is contained in:
parent
d23fffeb16
commit
b42e20be77
@ -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.
|
||||
|
||||
//===---------------------------------------------------------------------===//
|
||||
|
Loading…
Reference in New Issue
Block a user