summaryrefslogtreecommitdiffstats
path: root/llvm
diff options
context:
space:
mode:
authorJakob Stoklund Olesen <stoklund@2pi.dk>2009-08-15 18:16:58 +0000
committerJakob Stoklund Olesen <stoklund@2pi.dk>2009-08-15 18:16:58 +0000
commitffa73acfec6b8ce9f437efc1f02802bbb60a6d6b (patch)
tree5640a18acb5d42f2da4eed777c24fb003c703ea8 /llvm
parent10f10ced3f78772c3e95e2cea316344ef13ab199 (diff)
downloadbcm5719-llvm-ffa73acfec6b8ce9f437efc1f02802bbb60a6d6b.tar.gz
bcm5719-llvm-ffa73acfec6b8ce9f437efc1f02802bbb60a6d6b.zip
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
Diffstat (limited to 'llvm')
-rw-r--r--llvm/lib/CodeGen/RegisterScavenging.cpp2
-rw-r--r--llvm/test/CodeGen/ARM/2009-08-15-RegScavenger-EarlyClobber.ll42
2 files changed, 43 insertions, 1 deletions
diff --git a/llvm/lib/CodeGen/RegisterScavenging.cpp b/llvm/lib/CodeGen/RegisterScavenging.cpp
index 323d3db39a3..a82562838ec 100644
--- a/llvm/lib/CodeGen/RegisterScavenging.cpp
+++ b/llvm/lib/CodeGen/RegisterScavenging.cpp
@@ -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());
diff --git a/llvm/test/CodeGen/ARM/2009-08-15-RegScavenger-EarlyClobber.ll b/llvm/test/CodeGen/ARM/2009-08-15-RegScavenger-EarlyClobber.ll
new file mode 100644
index 00000000000..15fa145c5d9
--- /dev/null
+++ b/llvm/test/CodeGen/ARM/2009-08-15-RegScavenger-EarlyClobber.ll
@@ -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
+}
OpenPOWER on IntegriCloud