From f470cbbad204caa85275873004151b92fba24375 Mon Sep 17 00:00:00 2001 From: Chad Rosier Date: Fri, 4 Nov 2011 00:50:21 +0000 Subject: [PATCH] Add fast-isel support for returning i1, i8, and i16. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@143669 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/ARMFastISel.cpp | 25 ++++++++++++---- test/CodeGen/ARM/fast-isel-ret.ll | 48 +++++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+), 6 deletions(-) create mode 100644 test/CodeGen/ARM/fast-isel-ret.ll diff --git a/lib/Target/ARM/ARMFastISel.cpp b/lib/Target/ARM/ARMFastISel.cpp index d1f2c7fcdd2..ab5caa3d5eb 100644 --- a/lib/Target/ARM/ARMFastISel.cpp +++ b/lib/Target/ARM/ARMFastISel.cpp @@ -1751,19 +1751,32 @@ bool ARMFastISel::SelectRet(const Instruction *I) { CCValAssign &VA = ValLocs[0]; // Don't bother handling odd stuff for now. - // FIXME: Should be able to handle i1, i8, and/or i16 return types. if (VA.getLocInfo() != CCValAssign::Full) return false; // Only handle register returns for now. if (!VA.isRegLoc()) return false; - // TODO: For now, don't try to handle cases where getLocInfo() - // says Full but the types don't match. - if (TLI.getValueType(RV->getType()) != VA.getValVT()) - return false; + + unsigned SrcReg = Reg + VA.getValNo(); + EVT RVVT = TLI.getValueType(RV->getType()); + EVT DestVT = VA.getValVT(); + // Special handling for extended integers. + if (RVVT != DestVT) { + if (RVVT != MVT::i1 && RVVT != MVT::i8 && RVVT != MVT::i16) + return false; + + if (!Outs[0].Flags.isZExt() && !Outs[0].Flags.isSExt()) + return false; + + assert(DestVT == MVT::i32 && "ARM should always ext to i32"); + + bool isZExt = Outs[0].Flags.isZExt(); + unsigned ResultReg = ARMEmitIntExt(RVVT, SrcReg, DestVT, isZExt); + if (ResultReg == 0) return false; + SrcReg = ResultReg; + } // Make the copy. - unsigned SrcReg = Reg + VA.getValNo(); unsigned DstReg = VA.getLocReg(); const TargetRegisterClass* SrcRC = MRI.getRegClass(SrcReg); // Avoid a cross-class copy. This is very unlikely. diff --git a/test/CodeGen/ARM/fast-isel-ret.ll b/test/CodeGen/ARM/fast-isel-ret.ll new file mode 100644 index 00000000000..f7f4521c8dd --- /dev/null +++ b/test/CodeGen/ARM/fast-isel-ret.ll @@ -0,0 +1,48 @@ +; RUN: llc < %s -O0 -fast-isel-abort -relocation-model=dynamic-no-pic -mtriple=armv7-apple-darwin | FileCheck %s +; RUN: llc < %s -O0 -fast-isel-abort -relocation-model=dynamic-no-pic -mtriple=thumbv7-apple-darwin | FileCheck %s + +; Sign-extend of i1 currently not supported by fast-isel +;define signext i1 @ret0(i1 signext %a) nounwind uwtable ssp { +;entry: +; ret i1 %a +;} + +define zeroext i1 @ret1(i1 signext %a) nounwind uwtable ssp { +entry: +; CHECK: ret1 +; CHECK: and r0, r0, #1 +; CHECK: bx lr + ret i1 %a +} + +define signext i8 @ret2(i8 signext %a) nounwind uwtable ssp { +entry: +; CHECK: ret2 +; CHECK: sxtb r0, r0 +; CHECK: bx lr + ret i8 %a +} + +define zeroext i8 @ret3(i8 signext %a) nounwind uwtable ssp { +entry: +; CHECK: ret3 +; CHECK: uxtb r0, r0 +; CHECK: bx lr + ret i8 %a +} + +define signext i16 @ret4(i16 signext %a) nounwind uwtable ssp { +entry: +; CHECK: ret4 +; CHECK: sxth r0, r0 +; CHECK: bx lr + ret i16 %a +} + +define zeroext i16 @ret5(i16 signext %a) nounwind uwtable ssp { +entry: +; CHECK: ret5 +; CHECK: uxth r0, r0 +; CHECK: bx lr + ret i16 %a +}