ISel: Fix FastISel of swifterror values

The code assumed that we process instructions in basic block order.  FastISel
processes instructions in reverse basic block order. We need to pre-assign
virtual registers before selecting otherwise we get def-use relationships wrong.

This only affects code with swifterror registers.

rdar://32659327

llvm-svn: 305484
diff --git a/llvm/test/CodeGen/AArch64/swifterror.ll b/llvm/test/CodeGen/AArch64/swifterror.ll
index 69bf351..bc28f47 100644
--- a/llvm/test/CodeGen/AArch64/swifterror.ll
+++ b/llvm/test/CodeGen/AArch64/swifterror.ll
@@ -597,3 +597,30 @@
   tail call void @acallee(i8* null)
   ret void
 }
+
+declare swiftcc void @foo2(%swift_error** swifterror)
+
+; Make sure we properly assign registers during fast-isel.
+; CHECK-O0-LABEL: testAssign
+; CHECK-O0: mov     [[TMP:x.*]], xzr
+; CHECK-O0: mov     x21, [[TMP]]
+; CHECK-O0: bl      _foo2
+; CHECK-O0: str     x21, [s[[STK:.*]]]
+; CHECK-O0: ldr     x0, [s[[STK]]]
+
+; CHECK-APPLE-LABEL: testAssign
+; CHECK-APPLE: mov      x21, xzr
+; CHECK-APPLE: bl      _foo2
+; CHECK-APPLE: mov      x0, x21
+
+define swiftcc %swift_error* @testAssign(i8* %error_ref) {
+entry:
+  %error_ptr = alloca swifterror %swift_error*
+  store %swift_error* null, %swift_error** %error_ptr
+  call swiftcc void @foo2(%swift_error** swifterror %error_ptr)
+  br label %a
+
+a:
+  %error = load %swift_error*, %swift_error** %error_ptr
+  ret %swift_error* %error
+}
diff --git a/llvm/test/CodeGen/ARM/swifterror.ll b/llvm/test/CodeGen/ARM/swifterror.ll
index 7876420..3fd57c5 100644
--- a/llvm/test/CodeGen/ARM/swifterror.ll
+++ b/llvm/test/CodeGen/ARM/swifterror.ll
@@ -528,3 +528,31 @@
   tail call void @acallee(i8* null)
   ret void
 }
+
+
+declare swiftcc void @foo2(%swift_error** swifterror)
+
+; Make sure we properly assign registers during fast-isel.
+; CHECK-O0-LABEL: testAssign
+; CHECK-O0: mov     r8, #0
+; CHECK-O0: bl      _foo2
+; CHECK-O0: str     r8, [s[[STK:p.*]]]
+; CHECK-O0: ldr     r0, [s[[STK]]]
+; CHECK-O0: pop
+
+; CHECK-APPLE-LABEL: testAssign
+; CHECK-APPLE:  mov     r8, #0
+; CHECK-APPLE:  bl      _foo2
+; CHECK-APPLE:  mov     r0, r8
+
+define swiftcc %swift_error* @testAssign(i8* %error_ref) {
+entry:
+  %error_ptr = alloca swifterror %swift_error*
+  store %swift_error* null, %swift_error** %error_ptr
+  call swiftcc void @foo2(%swift_error** swifterror %error_ptr)
+  br label %a
+
+a:
+  %error = load %swift_error*, %swift_error** %error_ptr
+  ret %swift_error* %error
+}
diff --git a/llvm/test/CodeGen/X86/swifterror.ll b/llvm/test/CodeGen/X86/swifterror.ll
index 5704d19..1ecd337 100644
--- a/llvm/test/CodeGen/X86/swifterror.ll
+++ b/llvm/test/CodeGen/X86/swifterror.ll
@@ -712,3 +712,111 @@
 falseBB:
   ret void
 }
+
+
+declare swiftcc void @foo2(%swift_error** swifterror)
+
+; Make sure we properly assign registers during fast-isel.
+; CHECK-O0-LABEL: testAssign
+; CHECK-O0:        pushq   %r12
+; CHECK-O0:        xorl    [[ZERO:%[a-z0-9]+]], [[ZERO]]
+; CHECK-O0:        movl    [[ZERO]], %r12d
+; CHECK-O0:        callq   _foo2
+; CHECK-O0:        movq    %r12, [[SLOT:[-a-z0-9\(\)\%]*]]
+;
+; CHECK-O0:        movq    [[SLOT]], %rax
+; CHECK-O0:        popq    %r12
+; CHECK-O0:        retq
+
+; CHECK-APPLE-LABEL: testAssign
+; CHECK-APPLE:        pushq   %r12
+; CHECK-APPLE:        xorl    %r12d, %r12d
+; CHECK-APPLE:        callq   _foo2
+; CHECK-APPLE:        movq    %r12, %rax
+; CHECK-APPLE:        popq    %r12
+; CHECK-APPLE:        retq
+
+define swiftcc %swift_error* @testAssign(i8* %error_ref) {
+entry:
+  %error_ptr = alloca swifterror %swift_error*
+  store %swift_error* null, %swift_error** %error_ptr
+  call swiftcc void @foo2(%swift_error** swifterror %error_ptr)
+  br label %a
+
+a:
+  %error = load %swift_error*, %swift_error** %error_ptr
+  ret %swift_error* %error
+}
+
+; CHECK-O0-LABEL: testAssign2
+; CHECK-O0:        movq    %r12, {{.*}}
+; CHECK-O0:        movq    %r12, [[SLOT:[-a-z0-9\(\)\%]*]]
+; CHECK-O0:        jmp
+; CHECK-O0:        movq    [[SLOT]], %rax
+; CHECK-O0:        movq    %rax, [[SLOT2:[-a-z0-9\(\)\%]*]]
+; CHECK-O0:        movq    [[SLOT2]], %r12
+; CHECK-O0:        retq
+
+; CHECK-APPLE-LABEL: testAssign2
+; CHECK-APPLE:        movq    %r12, %rax
+; CHECK-APPLE:        retq
+define swiftcc %swift_error* @testAssign2(i8* %error_ref, %swift_error** swifterror %err) {
+entry:
+  br label %a
+
+a:
+  %error = load %swift_error*, %swift_error** %err
+  ret %swift_error* %error
+}
+
+; CHECK-O0-LABEL: testAssign3
+; CHECK-O0:        callq   _foo2
+; CHECK-O0:        movq    %r12, [[SLOT:[-a-z0-9\(\)\%]*]]
+; CHECK-O0:        movq    [[SLOT]], %rax
+; CHECK-O0:        movq    %rax, [[SLOT2:[-a-z0-9\(\)\%]*]]
+; CHECK-O0:        movq    [[SLOT2]], %r12
+; CHECK-O0:        addq    $24, %rsp
+; CHECK-O0:        retq
+
+; CHECK-APPLE-LABEL: testAssign3
+; CHECK-APPLE:         callq   _foo2
+; CHECK-APPLE:         movq    %r12, %rax
+; CHECK-APPLE:         retq
+
+define swiftcc %swift_error* @testAssign3(i8* %error_ref, %swift_error** swifterror %err) {
+entry:
+  call swiftcc void @foo2(%swift_error** swifterror %err)
+  br label %a
+
+a:
+  %error = load %swift_error*, %swift_error** %err
+  ret %swift_error* %error
+}
+
+
+; CHECK-O0-LABEL: testAssign4
+; CHECK-O0:        callq   _foo2
+; CHECK-O0:        xorl    %ecx, %ecx
+; CHECK-O0:        movl    %ecx, %eax
+; CHECK-O0:        movq    %rax, [[SLOT:[-a-z0-9\(\)\%]*]]
+; CHECK-O0:        movq    [[SLOT]], %rax
+; CHECK-O0:        movq    %rax, [[SLOT2:[-a-z0-9\(\)\%]*]]
+; CHECK-O0:        movq    [[SLOT2]], %r12
+; CHECK-O0:        retq
+
+; CHECK-APPLE-LABEL: testAssign4
+; CHECK-APPLE:        callq   _foo2
+; CHECK-APPLE:        xorl    %eax, %eax
+; CHECK-APPLE:        xorl    %r12d, %r12d
+; CHECK-APPLE:        retq
+
+define swiftcc %swift_error* @testAssign4(i8* %error_ref, %swift_error** swifterror %err) {
+entry:
+  call swiftcc void @foo2(%swift_error** swifterror %err)
+  store %swift_error* null, %swift_error** %err
+  br label %a
+
+a:
+  %error = load %swift_error*, %swift_error** %err
+  ret %swift_error* %error
+}