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
This commit is contained in:
Eli Friedman 2011-05-17 02:36:59 +00:00
parent b70eac42e7
commit c93943b6fe
3 changed files with 50 additions and 47 deletions

View File

@ -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<const Value *, 8> ArgVals;
SmallVector<unsigned, 8> 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<ISD::InputArg, 32> Ins;
SmallVector<EVT, 4> 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<unsigned, 4> UsedRegs;
SmallVector<CCValAssign, 16> 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<CCValAssign, 16> 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<MachineInstr *>(MIB)->setPhysRegsDeadExcept(UsedRegs, TRI);

View File

@ -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

View File

@ -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 }