Skip to content
README.txt 68 KiB
Newer Older
Chris Lattner's avatar
Chris Lattner committed
Target Independent Opportunities:

//===---------------------------------------------------------------------===//

Chris Lattner's avatar
Chris Lattner committed
With the recent changes to make the implicit def/use set explicit in
machineinstrs, we should change the target descriptions for 'call' instructions
so that the .td files don't list all the call-clobbered registers as implicit
defs.  Instead, these should be added by the code generator (e.g. on the dag).

This has a number of uses:

1. PPC32/64 and X86 32/64 can avoid having multiple copies of call instructions
   for their different impdef sets.
2. Targets with multiple calling convs (e.g. x86) which have different clobber
   sets don't need copies of call instructions.
3. 'Interprocedural register allocation' can be done to reduce the clobber sets
   of calls.

//===---------------------------------------------------------------------===//

We should recognized various "overflow detection" idioms and translate them into
llvm.uadd.with.overflow and similar intrinsics.  Here is a multiply idiom:

unsigned int mul(unsigned int a,unsigned int b) {
 if ((unsigned long long)a*b>0xffffffff)
   exit(0);
  return a*b;
}

The legalization code for mul-with-overflow needs to be made more robust before
this can be implemented though.

Nate Begeman's avatar
Nate Begeman committed
//===---------------------------------------------------------------------===//
Chris Lattner's avatar
Chris Lattner committed

Get the C front-end to expand hypot(x,y) -> llvm.sqrt(x*x+y*y) when errno and
precision don't matter (ffastmath).  Misc/mandel will like this. :)  This isn't
safe in general, even on darwin.  See the libm implementation of hypot for
examples (which special case when x/y are exactly zero to get signed zeros etc
right).
Chris Lattner's avatar
Chris Lattner committed

//===---------------------------------------------------------------------===//

Chris Lattner's avatar
Chris Lattner committed
On targets with expensive 64-bit multiply, we could LSR this:

for (i = ...; ++i) {
   x = 1ULL << i;

into:
 long long tmp = 1;
 for (i = ...; ++i, tmp+=tmp)
   x = tmp;

This would be a win on ppc32, but not x86 or ppc64.

Chris Lattner's avatar
Chris Lattner committed
//===---------------------------------------------------------------------===//
Chris Lattner's avatar
Chris Lattner committed

Shrink: (setlt (loadi32 P), 0) -> (setlt (loadi8 Phi), 0)

//===---------------------------------------------------------------------===//
Chris Lattner's avatar
Chris Lattner committed

Reassociate should turn things like:

int factorial(int X) {
 return X*X*X*X*X*X*X*X;
}

into llvm.powi calls, allowing the code generator to produce balanced
multiplication trees.

First, the intrinsic needs to be extended to support integers, and second the
code generator needs to be enhanced to lower these to multiplication trees.
Chris Lattner's avatar
Chris Lattner committed

//===---------------------------------------------------------------------===//

Chris Lattner's avatar
Chris Lattner committed
Interesting? testcase for add/shift/mul reassoc:

int bar(int x, int y) {
  return x*x*x+y+x*x*x*x*x*y*y*y*y;
}
int foo(int z, int n) {
  return bar(z, n) + bar(2*z, 2*n);
}

This is blocked on not handling X*X*X -> powi(X, 3) (see note above).  The issue
is that we end up getting t = 2*X  s = t*t   and don't turn this into 4*X*X,
which is the same number of multiplies and is canonical, because the 2*X has
multiple uses.  Here's a simple example:

define i32 @test15(i32 %X1) {
  %B = mul i32 %X1, 47   ; X1*47
  %C = mul i32 %B, %B
  ret i32 %C
}


//===---------------------------------------------------------------------===//

Reassociate should handle the example in GCC PR16157:

extern int a0, a1, a2, a3, a4; extern int b0, b1, b2, b3, b4; 
void f () {  /* this can be optimized to four additions... */ 
        b4 = a4 + a3 + a2 + a1 + a0; 
        b3 = a3 + a2 + a1 + a0; 
        b2 = a2 + a1 + a0; 
        b1 = a1 + a0; 
} 

This requires reassociating to forms of expressions that are already available,
something that reassoc doesn't think about yet.
Chris Lattner's avatar
Chris Lattner committed

//===---------------------------------------------------------------------===//

This function: (derived from GCC PR19988)
double foo(double x, double y) {
  return ((x + 0.1234 * y) * (x + -0.1234 * y));
}

compiles to:
_foo:
	movapd	%xmm1, %xmm2
	mulsd	LCPI1_1(%rip), %xmm1
	mulsd	LCPI1_0(%rip), %xmm2
	addsd	%xmm0, %xmm1
	addsd	%xmm0, %xmm2
	movapd	%xmm1, %xmm0
	mulsd	%xmm2, %xmm0
	ret

Reassociate should be able to turn it into:
Chris Lattner's avatar
Chris Lattner committed

double foo(double x, double y) {
  return ((x + 0.1234 * y) * (x - 0.1234 * y));
}

Which allows the multiply by constant to be CSE'd, producing:

_foo:
	mulsd	LCPI1_0(%rip), %xmm1
	movapd	%xmm1, %xmm2
	addsd	%xmm0, %xmm2
	subsd	%xmm1, %xmm0
	mulsd	%xmm2, %xmm0
	ret

This doesn't need -ffast-math support at all.  This is particularly bad because
the llvm-gcc frontend is canonicalizing the later into the former, but clang
doesn't have this problem.

Chris Lattner's avatar
Chris Lattner committed
//===---------------------------------------------------------------------===//

Chris Lattner's avatar
Chris Lattner committed
These two functions should generate the same code on big-endian systems:

int g(int *j,int *l)  {  return memcmp(j,l,4);  }
int h(int *j, int *l) {  return *j - *l; }

this could be done in SelectionDAGISel.cpp, along with other special cases,
for 1,2,4,8 bytes.

//===---------------------------------------------------------------------===//

Chris Lattner's avatar
Chris Lattner committed
It would be nice to revert this patch:
http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20060213/031986.html

And teach the dag combiner enough to simplify the code expanded before 
legalize.  It seems plausible that this knowledge would let it simplify other
stuff too.

Chris Lattner's avatar
Chris Lattner committed
//===---------------------------------------------------------------------===//

Reid Spencer's avatar
Reid Spencer committed
For vector types, TargetData.cpp::getTypeInfo() returns alignment that is equal
to the type size. It works but can be overly conservative as the alignment of
Reid Spencer's avatar
Reid Spencer committed
specific vector types are target dependent.
Chris Lattner's avatar
Chris Lattner committed

//===---------------------------------------------------------------------===//

We should produce an unaligned load from code like this:
Chris Lattner's avatar
Chris Lattner committed

v4sf example(float *P) {
  return (v4sf){P[0], P[1], P[2], P[3] };
}

//===---------------------------------------------------------------------===//

Chris Lattner's avatar
Chris Lattner committed
Add support for conditional increments, and other related patterns.  Instead
of:

	movl 136(%esp), %eax
	cmpl $0, %eax
	je LBB16_2	#cond_next
LBB16_1:	#cond_true
	incl _foo
LBB16_2:	#cond_next

emit:
	movl	_foo, %eax
	cmpl	$1, %edi
	sbbl	$-1, %eax
	movl	%eax, _foo

Loading
Loading full blame...