Index: include/llvm/CodeGen/FastISel.h =================================================================== --- include/llvm/CodeGen/FastISel.h +++ include/llvm/CodeGen/FastISel.h @@ -231,6 +231,11 @@ /// be appended, and clear the local CSE map. void startNewBlock(); + /// \brief Clear the local CSE map without changing the current block. + void wrapUpBlock() { + flushLocalValueMap(); + } + /// \brief Return current debug location information. DebugLoc getCurDebugLoc() const { return DbgLoc; } Index: lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp =================================================================== --- lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -1337,7 +1337,7 @@ break; } - FastIS->recomputeInsertPt(); + FastIS->wrapUpBlock(); } else { // Lower any arguments needed in this block if this is the entry block. if (LLVMBB == &Fn.getEntryBlock()) { Index: test/CodeGen/Mips/emergency-spill-slot-near-fp.ll =================================================================== --- test/CodeGen/Mips/emergency-spill-slot-near-fp.ll +++ test/CodeGen/Mips/emergency-spill-slot-near-fp.ll @@ -28,7 +28,7 @@ %3 = load <16 x i8>, <16 x i8>* %v1, align 16 %mul = mul <16 x i8> %2, %3 store <16 x i8> %mul, <16 x i8>* %result, align 16 - ret i32 0 + ret i32 %argc } attributes #0 = { noinline "no-frame-pointer-elim"="true" } Index: test/CodeGen/X86/fast-isel-flush.ll =================================================================== --- test/CodeGen/X86/fast-isel-flush.ll +++ test/CodeGen/X86/fast-isel-flush.ll @@ -0,0 +1,57 @@ +; REQUIRES: asserts +; RUN: not llc -mtriple=x86_64-unknown-unknown -mattr=+avx -O0 -fast-isel-abort=1 %s -o - 2>&1 | FileCheck -check-prefix=ABORT %s +; RUN: llc -mtriple=x86_64-unknown-unknown -mattr=+avx -O0 %s -o - | FileCheck %s +; +; Verify that local value instructions are not pushed all the way to the top of +; the basic block (past call instructions) when FastISel hands off code generation to +; SelectionDAGISel. +; +; FastISel does not handle the store { i64, i64 } instruction before the return and +; quits. The first RUN line ensures that this is the case, so the actual test is +; valid. +; +; struct X +; { +; int F(); +; }; +; +; void foo(); +; +; int main() +; { +; foo(); +; int (X::*mp)() = &X::F; +; return 0; +; } +; +; ModuleID = 'test.cpp' + +%struct.X = type { i8 } + +; Function Attrs: norecurse uwtable +define i32 @main() { +entry: + %retval = alloca i32, align 4 + %mp = alloca { i64, i64 }, align 8 + store i32 0, i32* %retval, align 4 + call void @foo() + store { i64, i64 } { i64 ptrtoint (i32 (%struct.X*)* @_ZN1X1FEv to i64), i64 0 }, { i64, i64 }* %mp, align 8 + ret i32 0 +} + +declare void @foo() + +declare i32 @_ZN1X1FEv(%struct.X*) + +!llvm.ident = !{!0} + +!0 = !{!"clang version 3.8.0 (trunk 257544)"} + +; CHECK-LABEL: main +; CHECK-NOT: xorl{{[ \t]+}}[[REGISTER:%[a-z]+]], [[REGISTER]] +; CHECK: callq{{[ \t]+}}foo +; CHECK: xorl{{[ \t]+}}[[REGISTER:%[a-z]+]], [[REGISTER]] +; CHECK: retq + +; Verify FastISel bails out on a store i64 instruction. +; ABORT: miss:{{.*}}store { i64, i64 } Index: test/DebugInfo/X86/vla.ll =================================================================== --- test/DebugInfo/X86/vla.ll +++ test/DebugInfo/X86/vla.ll @@ -1,7 +1,7 @@ ; RUN: llc -O0 -mtriple=x86_64-apple-darwin -filetype=asm %s -o - | FileCheck %s ; Ensure that we generate an indirect location for the variable length array a. -; CHECK: ##DEBUG_VALUE: vla:a <- [%RDX+0] -; CHECK: DW_OP_breg1 +; CHECK: ##DEBUG_VALUE: vla:a <- [%{{RAX|RDX|RCX|RBX|RSI|RDI}}+0] +; CHECK: DW_OP_breg{{[0-5]}} ; rdar://problem/13658587 ; ; generated from: