From 0eff39f2e25e9d8dd52b1eb7fa4e7cc6cc77875f Mon Sep 17 00:00:00 2001 From: Chad Rosier Date: Tue, 8 Nov 2011 00:03:32 +0000 Subject: [PATCH] Enable support for returning i1, i8, and i16. Nothing special todo as it's the callee's responsibility to sign or zero-extend the return value. The additional test case just checks to make sure the calls are selected (i.e., -fast-isel-abort doesn't assert). git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@144047 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/ARMCallingConv.td | 2 ++ lib/Target/ARM/ARMFastISel.cpp | 8 +++++++- test/CodeGen/ARM/fast-isel-call.ll | 15 +++++++++++++++ 3 files changed, 24 insertions(+), 1 deletion(-) diff --git a/lib/Target/ARM/ARMCallingConv.td b/lib/Target/ARM/ARMCallingConv.td index a482a200aaa..c22a08eec72 100644 --- a/lib/Target/ARM/ARMCallingConv.td +++ b/lib/Target/ARM/ARMCallingConv.td @@ -43,6 +43,7 @@ def CC_ARM_APCS : CallingConv<[ ]>; def RetCC_ARM_APCS : CallingConv<[ + CCIfType<[i1, i8, i16], CCPromoteToType>, CCIfType<[f32], CCBitConvertToType>, // Handle all vector types as either f64 or v2f64. @@ -106,6 +107,7 @@ def CC_ARM_AAPCS_Common : CallingConv<[ ]>; def RetCC_ARM_AAPCS_Common : CallingConv<[ + CCIfType<[i1, i8, i16], CCPromoteToType>, CCIfType<[i32], CCAssignToReg<[R0, R1, R2, R3]>>, CCIfType<[i64], CCAssignToRegWithShadow<[R0, R2], [R1, R3]>> ]>; diff --git a/lib/Target/ARM/ARMFastISel.cpp b/lib/Target/ARM/ARMFastISel.cpp index c98156e8869..8acdd91a19e 100644 --- a/lib/Target/ARM/ARMFastISel.cpp +++ b/lib/Target/ARM/ARMFastISel.cpp @@ -1697,6 +1697,11 @@ bool ARMFastISel::FinishCall(MVT RetVT, SmallVectorImpl &UsedRegs, } else { assert(RVLocs.size() == 1 &&"Can't handle non-double multi-reg retvals!"); EVT CopyVT = RVLocs[0].getValVT(); + + // Special handling for extended integers. + if (RetVT == MVT::i1 || RetVT == MVT::i8 || RetVT == MVT::i16) + CopyVT = MVT::i32; + TargetRegisterClass* DstRC = TLI.getRegClassFor(CopyVT); unsigned ResultReg = createResultReg(DstRC); @@ -1913,7 +1918,8 @@ bool ARMFastISel::SelectCall(const Instruction *I) { MVT RetVT; if (RetTy->isVoidTy()) RetVT = MVT::isVoid; - else if (!isTypeLegal(RetTy, RetVT)) + else if (!isTypeLegal(RetTy, RetVT) && RetVT != MVT::i16 && + RetVT != MVT::i8 && RetVT != MVT::i1) return false; // TODO: For now if we have long calls specified we don't handle the call. diff --git a/test/CodeGen/ARM/fast-isel-call.ll b/test/CodeGen/ARM/fast-isel-call.ll index 20046a32f99..00346bf404c 100644 --- a/test/CodeGen/ARM/fast-isel-call.ll +++ b/test/CodeGen/ARM/fast-isel-call.ll @@ -65,3 +65,18 @@ define void @foo(i8 %a, i16 %b) nounwind { %7 = call i32 @t4(i16 zeroext 65535) ret void } + +define void @foo2() nounwind { + %1 = call signext i16 @t5() + %2 = call zeroext i16 @t6() + %3 = call signext i8 @t7() + %4 = call zeroext i8 @t8() + %5 = call zeroext i1 @t9() + ret void +} + +declare signext i16 @t5(); +declare zeroext i16 @t6(); +declare signext i8 @t7(); +declare zeroext i8 @t8(); +declare zeroext i1 @t9(); -- 2.34.1