From c93943b6fef4d84a9934cf23f8b14d3a8952f26f Mon Sep 17 00:00:00 2001 From: Eli Friedman Date: Tue, 17 May 2011 02:36:59 +0000 Subject: [PATCH] Back out r131444 and r131438; they're breaking nightly tests. I'll look into it more tomorrow. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@131451 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/X86/X86FastISel.cpp | 91 ++++++++++++++------------- test/CodeGen/X86/fast-isel-call.ll | 4 +- test/CodeGen/X86/fast-isel-extract.ll | 2 +- 3 files changed, 50 insertions(+), 47 deletions(-) diff --git a/lib/Target/X86/X86FastISel.cpp b/lib/Target/X86/X86FastISel.cpp index e817f233660..ebdc8f8898f 100644 --- a/lib/Target/X86/X86FastISel.cpp +++ b/lib/Target/X86/X86FastISel.cpp @@ -1414,6 +1414,14 @@ bool X86FastISel::X86SelectCall(const Instruction *I) { if (Subtarget->IsCalleePop(isVarArg, CC)) return false; + // Handle *simple* calls for now. + const Type *RetTy = CS.getType(); + MVT RetVT; + if (RetTy->isVoidTy()) + RetVT = MVT::isVoid; + else if (!isTypeLegal(RetTy, RetVT, true)) + return false; + // Materialize callee address in a register. FIXME: GV address can be // handled with a CALLpcrel32 instead. X86AddressMode CalleeAM; @@ -1428,6 +1436,13 @@ bool X86FastISel::X86SelectCall(const Instruction *I) { } else return false; + // Allow calls which produce i1 results. + bool AndToI1 = false; + if (RetVT == MVT::i1) { + RetVT = MVT::i8; + AndToI1 = true; + } + // Deal with call operands first. SmallVector ArgVals; SmallVector Args; @@ -1682,72 +1697,62 @@ bool X86FastISel::X86SelectCall(const Instruction *I) { BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(AdjStackUp)) .addImm(NumBytes).addImm(NumBytesCallee); - // Build info for return calling conv lowering code. - // FIXME: This is practically a copy-paste from TargetLowering::LowerCallTo. - SmallVector Ins; - SmallVector RetTys; - ComputeValueVTs(TLI, I->getType(), RetTys); - for (unsigned i = 0, e = RetTys.size(); i != e; ++i) { - EVT VT = RetTys[i]; - EVT RegisterVT = TLI.getRegisterType(I->getParent()->getContext(), VT); - unsigned NumRegs = TLI.getNumRegisters(I->getParent()->getContext(), VT); - for (unsigned j = 0; j != NumRegs; ++j) { - ISD::InputArg MyFlags; - MyFlags.VT = RegisterVT.getSimpleVT(); - MyFlags.Used = !CS.getInstruction()->use_empty(); - if (CS.paramHasAttr(0, Attribute::SExt)) - MyFlags.Flags.setSExt(); - if (CS.paramHasAttr(0, Attribute::ZExt)) - MyFlags.Flags.setZExt(); - if (CS.paramHasAttr(0, Attribute::InReg)) - MyFlags.Flags.setInReg(); - Ins.push_back(MyFlags); - } - } - - // Now handle call return values. + // Now handle call return value (if any). SmallVector UsedRegs; - SmallVector RVLocs; - CCState CCRetInfo(CC, false, TM, RVLocs, I->getParent()->getContext()); - unsigned ResultReg = FuncInfo.CreateRegs(I->getType()); - CCRetInfo.AnalyzeCallResult(Ins, RetCC_X86); - for (unsigned i = 0; i != RVLocs.size(); ++i) { - EVT CopyVT = RVLocs[i].getValVT(); - unsigned CopyReg = ResultReg + i; + if (RetVT != MVT::isVoid) { + SmallVector RVLocs; + CCState CCInfo(CC, false, TM, RVLocs, I->getParent()->getContext()); + CCInfo.AnalyzeCallResult(RetVT, RetCC_X86); + + // Copy all of the result registers out of their specified physreg. + assert(RVLocs.size() == 1 && "Can't handle multi-value calls!"); + EVT CopyVT = RVLocs[0].getValVT(); + TargetRegisterClass* DstRC = TLI.getRegClassFor(CopyVT); // If this is a call to a function that returns an fp value on the x87 fp // stack, but where we prefer to use the value in xmm registers, copy it // out as F80 and use a truncate to move it from fp stack reg to xmm reg. - if ((RVLocs[i].getLocReg() == X86::ST0 || - RVLocs[i].getLocReg() == X86::ST1) && + if ((RVLocs[0].getLocReg() == X86::ST0 || + RVLocs[0].getLocReg() == X86::ST1) && isScalarFPTypeInSSEReg(RVLocs[0].getValVT())) { CopyVT = MVT::f80; - CopyReg = createResultReg(X86::RFP80RegisterClass); + DstRC = X86::RFP80RegisterClass; } + unsigned ResultReg = createResultReg(DstRC); BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(TargetOpcode::COPY), - ResultReg+i).addReg(RVLocs[i].getLocReg()); - UsedRegs.push_back(RVLocs[i].getLocReg()); + ResultReg).addReg(RVLocs[0].getLocReg()); + UsedRegs.push_back(RVLocs[0].getLocReg()); - if (CopyVT != RVLocs[i].getValVT()) { + if (CopyVT != RVLocs[0].getValVT()) { // Round the F80 the right size, which also moves to the appropriate xmm // register. This is accomplished by storing the F80 value in memory and // then loading it back. Ewww... - EVT ResVT = RVLocs[i].getValVT(); + EVT ResVT = RVLocs[0].getValVT(); unsigned Opc = ResVT == MVT::f32 ? X86::ST_Fp80m32 : X86::ST_Fp80m64; unsigned MemSize = ResVT.getSizeInBits()/8; int FI = MFI.CreateStackObject(MemSize, MemSize, false); addFrameReference(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(Opc)), FI) - .addReg(CopyReg); + .addReg(ResultReg); + DstRC = ResVT == MVT::f32 + ? X86::FR32RegisterClass : X86::FR64RegisterClass; Opc = ResVT == MVT::f32 ? X86::MOVSSrm : X86::MOVSDrm; + ResultReg = createResultReg(DstRC); addFrameReference(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, - TII.get(Opc), ResultReg + i), FI); + TII.get(Opc), ResultReg), FI); } - } - if (RVLocs.size()) - UpdateValueMap(I, ResultReg, RVLocs.size()); + if (AndToI1) { + // Mask out all but lowest bit for some call which produces an i1. + unsigned AndResult = createResultReg(X86::GR8RegisterClass); + BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, + TII.get(X86::AND8ri), AndResult).addReg(ResultReg).addImm(1); + ResultReg = AndResult; + } + + UpdateValueMap(I, ResultReg); + } // Set all unused physreg defs as dead. static_cast(MIB)->setPhysRegsDeadExcept(UsedRegs, TRI); diff --git a/test/CodeGen/X86/fast-isel-call.ll b/test/CodeGen/X86/fast-isel-call.ll index f5fcf1ea1b0..5fcdbbbe53b 100644 --- a/test/CodeGen/X86/fast-isel-call.ll +++ b/test/CodeGen/X86/fast-isel-call.ll @@ -1,4 +1,4 @@ -; RUN: llc < %s -fast-isel -march=x86 | FileCheck %s +; RUN: llc < %s -fast-isel -march=x86 | grep and define i32 @t() nounwind { tak: @@ -8,8 +8,6 @@ BB1: ret i32 1 BB2: ret i32 0 -; CHECK: calll -; CHECK-NEXT: testb $1 } declare i1 @foo() zeroext nounwind diff --git a/test/CodeGen/X86/fast-isel-extract.ll b/test/CodeGen/X86/fast-isel-extract.ll index f63396e40ca..e51c4179dd8 100644 --- a/test/CodeGen/X86/fast-isel-extract.ll +++ b/test/CodeGen/X86/fast-isel-extract.ll @@ -1,4 +1,4 @@ -; RUN: llc < %s -mtriple x86_64-apple-darwin11 -O0 -fast-isel-abort | FileCheck %s +; RUN: llc < %s -mtriple x86_64-apple-darwin11 -O0 | FileCheck %s %struct.x = type { i64, i64 } %addovf = type { i32, i1 }