From dc51575a5f813164e96c7c1ab41aaf33585573f6 Mon Sep 17 00:00:00 2001 From: Eli Friedman Date: Thu, 19 May 2011 22:16:13 +0000 Subject: [PATCH] Add fast-isel support for zeroext and signext ret instructions on x86. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@131689 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/X86/X86FastISel.cpp | 30 +++++++++++++++++---- test/CodeGen/X86/fast-isel-ret-ext.ll | 38 +++++++++++++++++++++++++++ 2 files changed, 63 insertions(+), 5 deletions(-) create mode 100644 test/CodeGen/X86/fast-isel-ret-ext.ll diff --git a/lib/Target/X86/X86FastISel.cpp b/lib/Target/X86/X86FastISel.cpp index a82db891761..6e96638c605 100644 --- a/lib/Target/X86/X86FastISel.cpp +++ b/lib/Target/X86/X86FastISel.cpp @@ -722,18 +722,38 @@ bool X86FastISel::X86SelectRet(const Instruction *I) { // 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; // The calling-convention tables for x87 returns don't tell // the whole story. if (VA.getLocReg() == X86::ST0 || VA.getLocReg() == X86::ST1) return false; - // Make the copy. unsigned SrcReg = Reg + VA.getValNo(); + EVT SrcVT = TLI.getValueType(RV->getType()); + EVT DstVT = VA.getValVT(); + // Special handling for extended integers. + if (SrcVT != DstVT) { + if (SrcVT != MVT::i1 && SrcVT != MVT::i8 && SrcVT != MVT::i16) + return false; + + if (!Outs[0].Flags.isZExt() && !Outs[0].Flags.isSExt()) + return false; + + assert(DstVT == MVT::i32 && "X86 should always ext to i32"); + + if (SrcVT == MVT::i1) { + if (Outs[0].Flags.isSExt()) + return false; + SrcReg = FastEmitZExtFromI1(MVT::i8, SrcReg, /*TODO: Kill=*/false); + SrcVT = MVT::i8; + } + unsigned Op = Outs[0].Flags.isZExt() ? ISD::ZERO_EXTEND : + ISD::SIGN_EXTEND; + SrcReg = FastEmit_r(SrcVT.getSimpleVT(), DstVT.getSimpleVT(), Op, + SrcReg, /*TODO: Kill=*/false); + } + + // Make the copy. unsigned DstReg = VA.getLocReg(); const TargetRegisterClass* SrcRC = MRI.getRegClass(SrcReg); // Avoid a cross-class copy. This is very unlikely. diff --git a/test/CodeGen/X86/fast-isel-ret-ext.ll b/test/CodeGen/X86/fast-isel-ret-ext.ll new file mode 100644 index 00000000000..fd768cb9b33 --- /dev/null +++ b/test/CodeGen/X86/fast-isel-ret-ext.ll @@ -0,0 +1,38 @@ +; RUN: llc < %s -O0 -fast-isel-abort -mtriple i686-apple-darwin10 | FileCheck %s +; RUN: llc < %s -O0 -fast-isel-abort -mtriple x86_64-apple-darwin10 | FileCheck %s + +define zeroext i8 @test1(i32 %y) nounwind { + %conv = trunc i32 %y to i8 + ret i8 %conv + ; CHECK: test1: + ; CHECK: movzbl {{.*}}, %eax +} + +define signext i8 @test2(i32 %y) nounwind { + %conv = trunc i32 %y to i8 + ret i8 %conv + ; CHECK: test2: + ; CHECK: movsbl {{.*}}, %eax +} + +define zeroext i16 @test3(i32 %y) nounwind { + %conv = trunc i32 %y to i16 + ret i16 %conv + ; CHECK: test3: + ; CHECK: movzwl {{.*}}, %eax +} + +define signext i16 @test4(i32 %y) nounwind { + %conv = trunc i32 %y to i16 + ret i16 %conv + ; CHECK: test4: + ; CHECK: movswl {{.*}}, %eax +} + +define zeroext i1 @test5(i32 %y) nounwind { + %conv = trunc i32 %y to i1 + ret i1 %conv + ; CHECK: test5: + ; CHECK: andb $1 + ; CHECK: movzbl {{.*}}, %eax +}