fix PR10605 / rdar://9930964 by adding a pretty scary missed check.

It's somewhat surprising anything works without this.  Before we would
compile the testcase into:

test:                                   # @test
	movl	$4, 8(%rdi)
	movl	8(%rdi), %eax
	orl	%esi, %eax
	cmpl	$32, %edx
	movl	%eax, -4(%rsp)          # 4-byte Spill
	je	.LBB0_2

now we produce:

test:                                   # @test
	movl	8(%rdi), %eax
	movl	$4, 8(%rdi)
	orl	%esi, %eax
	cmpl	$32, %edx
	movl	%eax, -4(%rsp)          # 4-byte Spill
	je	.LBB0_2
llvm-svn: 137303
This commit is contained in:
Chris Lattner 2011-08-11 06:26:54 +00:00
parent 6d64a738fa
commit 96710b4308
2 changed files with 32 additions and 0 deletions

View File

@ -754,6 +754,11 @@ bool SelectionDAGISel::TryToFoldFastISelLoad(const LoadInst *LI,
TheUser = TheUser->use_back();
}
// If we didn't find the fold instruction, then we failed to collapse the
// sequence.
if (TheUser != FoldInst)
return false;
// Don't try to fold volatile loads. Target has to deal with alignment
// constraints.
if (LI->isVolatile()) return false;

View File

@ -107,3 +107,30 @@ lpad: ; preds = %if.end19, %if.then1
unreachable
}
declare i8* @_ZNK18G__FastAllocString4dataEv() nounwind
; PR10605 / rdar://9930964 - Don't fold loads incorrectly. The load should
; happen before the store.
define i32 @test7({i32,i32,i32}* %tmp1, i32 %tmp71, i32 %tmp63) nounwind {
; X64: test7:
; X64: movl 8({{%rdi|%rcx}}), %eax
; X64 movl $4, 8({{%rdi|%rcx}})
%tmp29 = getelementptr inbounds {i32,i32,i32}* %tmp1, i32 0, i32 2
%tmp30 = load i32* %tmp29, align 4
%p2 = getelementptr inbounds {i32,i32,i32}* %tmp1, i32 0, i32 2
store i32 4, i32* %p2
%tmp72 = or i32 %tmp71, %tmp30
%tmp73 = icmp ne i32 %tmp63, 32
br i1 %tmp73, label %T, label %F
T:
ret i32 %tmp72
F:
ret i32 4
}