Enhance MemDep: When alias analysis returns a partial alias result,

return it as a clobber.  This allows GVN to do smart things.

Enhance GVN to be smart about the case when a small load is clobbered
by a larger overlapping load.  In this case, forward the value.  This
allows us to compile stuff like this:

int test(void *P) {
  int tmp = *(unsigned int*)P;
  return tmp+*((unsigned char*)P+1);
}

into:

_test:                                  ## @test
	movl	(%rdi), %ecx
	movzbl	%ch, %eax
	addl	%ecx, %eax
	ret

which has one load.  We already handled the case where the smaller
load was from a must-aliased base pointer.

llvm-svn: 130180
This commit is contained in:
Chris Lattner
2011-04-26 01:21:15 +00:00
parent 6f095d613a
commit 6f83d06ffa
4 changed files with 125 additions and 29 deletions

View File

@@ -291,16 +291,26 @@ getPointerDependencyFrom(const AliasAnalysis::Location &MemLoc, bool isLoad,
if (R == AliasAnalysis::NoAlias)
continue;
// May-alias loads don't depend on each other without a dependence.
if (isLoad && R != AliasAnalysis::MustAlias)
if (isLoad) {
// Must aliased loads are defs of each other.
if (R == AliasAnalysis::MustAlias)
return MemDepResult::getDef(Inst);
// If we have a partial alias, then return this as a clobber for the
// client to handle.
if (R == AliasAnalysis::PartialAlias)
return MemDepResult::getClobber(Inst);
// Random may-alias loads don't depend on each other without a
// dependence.
continue;
}
// Stores don't alias loads from read-only memory.
if (!isLoad && AA->pointsToConstantMemory(LoadLoc))
if (AA->pointsToConstantMemory(LoadLoc))
continue;
// Stores depend on may and must aliased loads, loads depend on must-alias
// loads.
// Stores depend on may/must aliased loads.
return MemDepResult::getDef(Inst);
}