Index: lib/Target/X86/X86FastISel.cpp |
=================================================================== |
--- lib/Target/X86/X86FastISel.cpp (revision 136701) |
+++ lib/Target/X86/X86FastISel.cpp (working copy) |
@@ -1568,10 +1568,12 @@ |
if (CS.paramHasAttr(AttrInd, Attribute::Nest)) |
Flags.setNest(); |
- // If this is an i1/i8/i16 argument, promote to i32 to avoid an extra |
- // instruction. This is safe because it is common to all fastisel supported |
- // calling conventions on x86. |
+ unsigned ArgReg; |
+ MVT ArgVT; |
if (ConstantInt *CI = dyn_cast<ConstantInt>(ArgVal)) { |
+ // If this is an i1/i8/i16 argument, promote to i32 to avoid an extra |
+ // instruction. This is safe because it is common to all fastisel |
+ // supported calling conventions on x86. |
if (CI->getBitWidth() == 1 || CI->getBitWidth() == 8 || |
CI->getBitWidth() == 16) { |
if (Flags.isSExt()) |
@@ -1579,20 +1581,24 @@ |
else |
ArgVal = ConstantExpr::getZExt(CI,Type::getInt32Ty(CI->getContext())); |
} |
- } |
- unsigned ArgReg; |
- |
+ // Emit immediate arguments for the call locally to avoid spilling. |
+ if (!isTypeLegal(ArgVal->getType(), ArgVT)) return false; |
+ uint64_t val; |
+ if (Flags.isSExt()) |
+ val = CI->getSExtValue(); |
+ else |
+ val = CI->getZExtValue(); |
+ ArgReg = FastEmit_i(ArgVT, ArgVT, ISD::Constant, val); |
// Passing bools around ends up doing a trunc to i1 and passing it. |
// Codegen this as an argument + "and 1". |
- if (ArgVal->getType()->isIntegerTy(1) && isa<TruncInst>(ArgVal) && |
+ } else if (ArgVal->getType()->isIntegerTy(1) && isa<TruncInst>(ArgVal) && |
cast<TruncInst>(ArgVal)->getParent() == I->getParent() && |
ArgVal->hasOneUse()) { |
ArgVal = cast<TruncInst>(ArgVal)->getOperand(0); |
ArgReg = getRegForValue(ArgVal); |
if (ArgReg == 0) return false; |
- MVT ArgVT; |
if (!isTypeLegal(ArgVal->getType(), ArgVT)) return false; |
ArgReg = FastEmit_ri(ArgVT, ArgVT, ISD::AND, ArgReg, |
@@ -1604,7 +1610,6 @@ |
if (ArgReg == 0) return false; |
Type *ArgTy = ArgVal->getType(); |
- MVT ArgVT; |
if (!isTypeLegal(ArgTy, ArgVT)) |
return false; |
if (ArgVT == MVT::x86mmx) |