Refine EarlyClobber assert in register scavenger.

It is legal for an inline asm operand to use an earlyclobber register if the
use operand is tied to the earlyclobber operand. The issue is discussed here:

  http://gcc.gnu.org/ml/gcc/1999-04n/msg00431.html

We should perhaps let only the machine code verifier worry about these finer
details. EarlyClobber operands are not really interesting to the scavenger.

This fixes PR4528 for the third time.

llvm-svn: 79122
This commit is contained in:
Jakob Stoklund Olesen 2009-08-15 18:16:58 +00:00
parent 10f10ced3f
commit ffa73acfec
2 changed files with 43 additions and 1 deletions

View File

@ -236,7 +236,7 @@ void RegScavenger::forward() {
continue;
if (MO.isUse()) {
assert(isUsed(Reg) && "Using an undefined register!");
assert(!EarlyClobberRegs.test(Reg) &&
assert((!EarlyClobberRegs.test(Reg) || MI->isRegTiedToDefOperand(i)) &&
"Using an early clobbered register!");
} else {
assert(MO.isDef());

View File

@ -0,0 +1,42 @@
; RUN: llvm-as < %s | llc -march=arm
; PR4528
; Inline asm is allowed to contain operands "=&r", "0".
%struct.device_dma_parameters = type { i32, i32 }
%struct.iovec = type { i8*, i32 }
define arm_aapcscc i32 @generic_segment_checks(%struct.iovec* nocapture %iov, i32* nocapture %nr_segs, i32* nocapture %count, i32 %access_flags) nounwind optsize {
entry:
br label %bb8
bb: ; preds = %bb8
br i1 undef, label %bb10, label %bb2
bb2: ; preds = %bb
%asmtmp = tail call %struct.device_dma_parameters asm "adds $1, $2, $3; sbcccs $1, $1, $0; movcc $0, #0", "=&r,=&r,r,Ir,0,~{cc}"(i8* undef, i32 undef, i32 0) nounwind; <%struct.device_dma_parameters> [#uses=1]
%asmresult = extractvalue %struct.device_dma_parameters %asmtmp, 0; <i32> [#uses=1]
%0 = icmp eq i32 %asmresult, 0 ; <i1> [#uses=1]
br i1 %0, label %bb7, label %bb4
bb4: ; preds = %bb2
br i1 undef, label %bb10, label %bb9
bb7: ; preds = %bb2
%1 = add i32 %2, 1 ; <i32> [#uses=1]
br label %bb8
bb8: ; preds = %bb7, %entry
%2 = phi i32 [ 0, %entry ], [ %1, %bb7 ] ; <i32> [#uses=3]
%scevgep22 = getelementptr %struct.iovec* %iov, i32 %2, i32 0; <i8**> [#uses=0]
%3 = load i32* %nr_segs, align 4 ; <i32> [#uses=1]
%4 = icmp ult i32 %2, %3 ; <i1> [#uses=1]
br i1 %4, label %bb, label %bb9
bb9: ; preds = %bb8, %bb4
store i32 undef, i32* %count, align 4
ret i32 0
bb10: ; preds = %bb4, %bb
ret i32 0
}