From 011369bb7f212748831a026dae045b975e07124c Mon Sep 17 00:00:00 2001 From: Chad Rosier Date: Sat, 5 Nov 2011 20:16:15 +0000 Subject: [PATCH] Add support for passing i1, i8, and i16 call parameters. Also, be sure to zero-extend the constant integer encoding. Test case provides testing for both call parameters and materialization of i1, i8, and i16 types. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@143821 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/ARMFastISel.cpp | 44 +++++++++---------------- test/CodeGen/ARM/fast-isel-call.ll | 67 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 83 insertions(+), 28 deletions(-) create mode 100644 test/CodeGen/ARM/fast-isel-call.ll diff --git a/lib/Target/ARM/ARMFastISel.cpp b/lib/Target/ARM/ARMFastISel.cpp index 517f73f4e13..c98156e8869 100644 --- a/lib/Target/ARM/ARMFastISel.cpp +++ b/lib/Target/ARM/ARMFastISel.cpp @@ -557,7 +557,7 @@ unsigned ARMFastISel::ARMMaterializeInt(const Constant *C, EVT VT) { unsigned ImmReg = createResultReg(TLI.getRegClassFor(SrcVT)); AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(Opc), ImmReg) - .addImm(CI->getSExtValue())); + .addImm(CI->getZExtValue())); return ImmReg; } @@ -1599,33 +1599,21 @@ bool ARMFastISel::ProcessCallArgs(SmallVectorImpl &Args, switch (VA.getLocInfo()) { case CCValAssign::Full: break; case CCValAssign::SExt: { - bool Emitted = FastEmitExtend(ISD::SIGN_EXTEND, VA.getLocVT(), - Arg, ArgVT, Arg); - assert(Emitted && "Failed to emit a sext!"); (void)Emitted; - Emitted = true; - ArgVT = VA.getLocVT(); + EVT DestVT = VA.getLocVT(); + unsigned ResultReg = ARMEmitIntExt(ArgVT, Arg, DestVT, + /*isZExt*/false); + assert (ResultReg != 0 && "Failed to emit a sext"); + Arg = ResultReg; break; } + case CCValAssign::AExt: + // Intentional fall-through. Handle AExt and ZExt. case CCValAssign::ZExt: { - bool Emitted = FastEmitExtend(ISD::ZERO_EXTEND, VA.getLocVT(), - Arg, ArgVT, Arg); - assert(Emitted && "Failed to emit a zext!"); (void)Emitted; - Emitted = true; - ArgVT = VA.getLocVT(); - break; - } - case CCValAssign::AExt: { - bool Emitted = FastEmitExtend(ISD::ANY_EXTEND, VA.getLocVT(), - Arg, ArgVT, Arg); - if (!Emitted) - Emitted = FastEmitExtend(ISD::ZERO_EXTEND, VA.getLocVT(), - Arg, ArgVT, Arg); - if (!Emitted) - Emitted = FastEmitExtend(ISD::SIGN_EXTEND, VA.getLocVT(), - Arg, ArgVT, Arg); - - assert(Emitted && "Failed to emit a aext!"); (void)Emitted; - ArgVT = VA.getLocVT(); + EVT DestVT = VA.getLocVT(); + unsigned ResultReg = ARMEmitIntExt(ArgVT, Arg, DestVT, + /*isZExt*/true); + assert (ResultReg != 0 && "Failed to emit a sext"); + Arg = ResultReg; break; } case CCValAssign::BCvt: { @@ -1643,7 +1631,7 @@ bool ARMFastISel::ProcessCallArgs(SmallVectorImpl &Args, if (VA.isRegLoc() && !VA.needsCustom()) { BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(TargetOpcode::COPY), VA.getLocReg()) - .addReg(Arg); + .addReg(Arg); RegArgs.push_back(VA.getLocReg()); } else if (VA.needsCustom()) { // TODO: We need custom lowering for vector (v2f64) args. @@ -1962,8 +1950,8 @@ bool ARMFastISel::SelectCall(const Instruction *I) { Type *ArgTy = (*i)->getType(); MVT ArgVT; - // FIXME: Should be able to handle i1, i8, and/or i16 parameters. - if (!isTypeLegal(ArgTy, ArgVT)) + if (!isTypeLegal(ArgTy, ArgVT) && ArgVT != MVT::i16 && ArgVT != MVT::i8 && + ArgVT != MVT::i1) return false; unsigned OriginalAlignment = TD.getABITypeAlignment(ArgTy); Flags.setOrigAlign(OriginalAlignment); diff --git a/test/CodeGen/ARM/fast-isel-call.ll b/test/CodeGen/ARM/fast-isel-call.ll new file mode 100644 index 00000000000..20046a32f99 --- /dev/null +++ b/test/CodeGen/ARM/fast-isel-call.ll @@ -0,0 +1,67 @@ +; RUN: llc < %s -O0 -fast-isel-abort -relocation-model=dynamic-no-pic -mtriple=armv7-apple-darwin | FileCheck %s --check-prefix=ARM +; RUN: llc < %s -O0 -fast-isel-abort -relocation-model=dynamic-no-pic -mtriple=thumbv7-apple-darwin | FileCheck %s --check-prefix=THUMB + +define i32 @t0(i1 zeroext %a) nounwind { + %1 = zext i1 %a to i32 + ret i32 %1 +} + +define i32 @t1(i8 signext %a) nounwind { + %1 = sext i8 %a to i32 + ret i32 %1 +} + +define i32 @t2(i8 zeroext %a) nounwind { + %1 = zext i8 %a to i32 + ret i32 %1 +} + +define i32 @t3(i16 signext %a) nounwind { + %1 = sext i16 %a to i32 + ret i32 %1 +} + +define i32 @t4(i16 zeroext %a) nounwind { + %1 = zext i16 %a to i32 + ret i32 %1 +} + +define void @foo(i8 %a, i16 %b) nounwind { +; ARM: foo +; THUMB: foo +;; Materialize i1 1 +; ARM: movw r2, #1 +;; zero-ext +; ARM: and r2, r2, #1 +; THUMB: and r2, r2, #1 + %1 = call i32 @t0(i1 zeroext 1) +; ARM: sxtb r2, r1 +; ARM: mov r0, r2 +; THUMB: sxtb r2, r1 +; THUMB: mov r0, r2 + %2 = call i32 @t1(i8 signext %a) +; ARM: uxtb r2, r1 +; ARM: mov r0, r2 +; THUMB: uxtb r2, r1 +; THUMB: mov r0, r2 + %3 = call i32 @t2(i8 zeroext %a) +; ARM: sxth r2, r1 +; ARM: mov r0, r2 +; THUMB: sxth r2, r1 +; THUMB: mov r0, r2 + %4 = call i32 @t3(i16 signext %b) +; ARM: uxth r2, r1 +; ARM: mov r0, r2 +; THUMB: uxth r2, r1 +; THUMB: mov r0, r2 + %5 = call i32 @t4(i16 zeroext %b) + +;; A few test to check materialization +;; Note: i1 1 was materialized with t1 call +; ARM: movw r1, #255 +%6 = call i32 @t2(i8 zeroext 255) +; ARM: movw r1, #65535 +; THUMB: movw r1, #65535 +%7 = call i32 @t4(i16 zeroext 65535) + ret void +} -- 2.11.0