From 2a2e9d54e95f01eaa5626dcdf57950e9e6f95f2c Mon Sep 17 00:00:00 2001 From: Chad Rosier Date: Fri, 11 May 2012 18:51:55 +0000 Subject: [PATCH] [fast-isel] Cleaner fix for when we're unable to handle a non-double multi-reg retval. Hoists check before emitting the call to avoid unnecessary work. rdar://11430407 PR12796 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@156628 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/ARMFastISel.cpp | 25 ++++++++++++++++--- .../ARM/fast-isel-call-multi-reg-return.ll | 17 +++++++++++++ 2 files changed, 38 insertions(+), 4 deletions(-) create mode 100644 test/CodeGen/ARM/fast-isel-call-multi-reg-return.ll diff --git a/lib/Target/ARM/ARMFastISel.cpp b/lib/Target/ARM/ARMFastISel.cpp index f49a5d3f83c..02bb5f41fea 100644 --- a/lib/Target/ARM/ARMFastISel.cpp +++ b/lib/Target/ARM/ARMFastISel.cpp @@ -2014,7 +2014,8 @@ bool ARMFastISel::FinishCall(MVT RetVT, SmallVectorImpl &UsedRegs, // Finally update the result. UpdateValueMap(I, ResultReg); - } else if (RVLocs.size() == 1) { + } else { + assert(RVLocs.size() == 1 &&"Can't handle non-double multi-reg retvals!"); EVT CopyVT = RVLocs[0].getValVT(); // Special handling for extended integers. @@ -2030,9 +2031,6 @@ bool ARMFastISel::FinishCall(MVT RetVT, SmallVectorImpl &UsedRegs, // Finally update the result. UpdateValueMap(I, ResultReg); - } else { - // Can't handle non-double multi-reg retvals. - return false; } } @@ -2144,6 +2142,15 @@ bool ARMFastISel::ARMEmitLibcall(const Instruction *I, RTLIB::Libcall Call) { // TODO: For now if we have long calls specified we don't handle the call. if (EnableARMLongCalls) return false; + // Can't handle non-double multi-reg retvals. + if (RetVT != MVT::isVoid && RetVT != MVT::i32) { + SmallVector RVLocs; + CCState CCInfo(CC, false, *FuncInfo.MF, TM, RVLocs, *Context); + CCInfo.AnalyzeCallResult(RetVT, CCAssignFnForCall(CC, true)); + if (RVLocs.size() >= 2 && RetVT != MVT::f64) + return false; + } + // Set up the argument vectors. SmallVector Args; SmallVector ArgRegs; @@ -2247,6 +2254,16 @@ bool ARMFastISel::SelectCall(const Instruction *I, // TODO: For now if we have long calls specified we don't handle the call. if (EnableARMLongCalls) return false; + // Can't handle non-double multi-reg retvals. + if (RetVT != MVT::isVoid && RetVT != MVT::i1 && RetVT != MVT::i8 && + RetVT != MVT::i16 && RetVT != MVT::i32) { + SmallVector RVLocs; + CCState CCInfo(CC, false, *FuncInfo.MF, TM, RVLocs, *Context); + CCInfo.AnalyzeCallResult(RetVT, CCAssignFnForCall(CC, true)); + if (RVLocs.size() >= 2 && RetVT != MVT::f64) + return false; + } + // Set up the argument vectors. SmallVector Args; SmallVector ArgRegs; diff --git a/test/CodeGen/ARM/fast-isel-call-multi-reg-return.ll b/test/CodeGen/ARM/fast-isel-call-multi-reg-return.ll new file mode 100644 index 00000000000..14721a4d802 --- /dev/null +++ b/test/CodeGen/ARM/fast-isel-call-multi-reg-return.ll @@ -0,0 +1,17 @@ +; RUN: llc < %s -O0 -relocation-model=dynamic-no-pic -mtriple=armv7-apple-ios | FileCheck %s --check-prefix=ARM +; RUN: llc < %s -O0 -relocation-model=dynamic-no-pic -mtriple=thumbv7-apple-ios | FileCheck %s --check-prefix=THUMB + +; Fast-isel can't handle non-double multi-reg retvals. +; This test just check to make sure we don't hit the assert in FinishCall. +define <16 x i8> @foo() nounwind ssp { +entry: + ret <16 x i8> zeroinitializer +} + +define void @t1() nounwind ssp { +entry: +; ARM: @t1 +; THUMB: @t1 + %call = call <16 x i8> @foo() + ret void +} -- 2.34.1