"Allow LICM to sink or lift loads from constant memory. Also add a test

case for this.

This allows instructions like loads from global variables declared to
be constant to be moved out of loops."

Patch by Stefanus Du Toit!

llvm-svn: 53945
This commit is contained in:
Chris Lattner 2008-07-23 05:06:28 +00:00
parent 94281a5c22
commit 8eb899ecbc
2 changed files with 28 additions and 0 deletions

View File

@ -370,6 +370,11 @@ bool LICM::canSinkOrHoistInst(Instruction &I) {
if (LI->isVolatile())
return false; // Don't hoist volatile loads!
// Loads from constant memory are always safe to move, even if they end up
// in the same alias set as something that ends up being modified.
if (AA->pointsToConstantMemory(LI->getOperand(0)))
return true;
// Don't hoist loads which have may-aliased stores in loop.
unsigned Size = 0;
if (LI->getType()->isSized())

View File

@ -0,0 +1,23 @@
; RUN: llvm-as < %s | opt -licm | llvm-dis | grep -A 1 entry | grep load.*@a
@a = external constant float*
define void @test(i32 %count) {
entry:
br label %forcond
forcond:
%i.0 = phi i32 [ 0, %entry ], [ %inc, %forbody ]
%cmp = icmp ult i32 %i.0, %count
br i1 %cmp, label %forbody, label %afterfor
forbody:
%tmp3 = load float** @a
%arrayidx = getelementptr float* %tmp3, i32 %i.0
%tmp7 = uitofp i32 %i.0 to float
store float %tmp7, float* %arrayidx
%inc = add i32 %i.0, 1
br label %forcond
afterfor:
ret void
}