[IR] Make paramHasAttr to use arg indices instead of attr indices

This avoids the confusing 'CS.paramHasAttr(ArgNo + 1, Foo)' pattern.

Previously we were testing return value attributes with index 0, so I
introduced hasReturnAttr() for that use case.

llvm-svn: 300367
This commit is contained in:
Reid Kleckner 2017-04-14 20:19:02 +00:00
parent 23f28e6c75
commit fb502d2f5e
21 changed files with 116 additions and 84 deletions

View File

@ -83,12 +83,12 @@ public:
RetTy = ResultTy;
Callee = Target;
IsInReg = Call.paramHasAttr(0, Attribute::InReg);
IsInReg = Call.hasRetAttr(Attribute::InReg);
DoesNotReturn = Call.doesNotReturn();
IsVarArg = FuncTy->isVarArg();
IsReturnValueUsed = !Call.getInstruction()->use_empty();
RetSExt = Call.paramHasAttr(0, Attribute::SExt);
RetZExt = Call.paramHasAttr(0, Attribute::ZExt);
RetSExt = Call.hasRetAttr(Attribute::SExt);
RetZExt = Call.hasRetAttr(Attribute::ZExt);
CallConv = Call.getCallingConv();
Args = std::move(ArgsList);
@ -107,12 +107,12 @@ public:
Callee = Call.getCalledValue();
Symbol = Target;
IsInReg = Call.paramHasAttr(0, Attribute::InReg);
IsInReg = Call.hasRetAttr(Attribute::InReg);
DoesNotReturn = Call.doesNotReturn();
IsVarArg = FuncTy->isVarArg();
IsReturnValueUsed = !Call.getInstruction()->use_empty();
RetSExt = Call.paramHasAttr(0, Attribute::SExt);
RetZExt = Call.paramHasAttr(0, Attribute::ZExt);
RetSExt = Call.hasRetAttr(Attribute::SExt);
RetZExt = Call.hasRetAttr(Attribute::ZExt);
CallConv = Call.getCallingConv();
Args = std::move(ArgsList);

View File

@ -357,9 +357,14 @@ public:
CALLSITE_DELEGATE_GETTER(hasFnAttr(Kind));
}
/// Return true if this return value has the given attribute.
bool hasRetAttr(Attribute::AttrKind Kind) const {
CALLSITE_DELEGATE_GETTER(hasRetAttr(Kind));
}
/// Return true if the call or the callee has the given attribute.
bool paramHasAttr(unsigned i, Attribute::AttrKind Kind) const {
CALLSITE_DELEGATE_GETTER(paramHasAttr(i, Kind));
bool paramHasAttr(unsigned ArgNo, Attribute::AttrKind Kind) const {
CALLSITE_DELEGATE_GETTER(paramHasAttr(ArgNo, Kind));
}
Attribute getAttribute(unsigned i, Attribute::AttrKind Kind) const {
@ -554,24 +559,24 @@ public:
/// Determine whether this argument is passed by value.
bool isByValArgument(unsigned ArgNo) const {
return paramHasAttr(ArgNo + 1, Attribute::ByVal);
return paramHasAttr(ArgNo, Attribute::ByVal);
}
/// Determine whether this argument is passed in an alloca.
bool isInAllocaArgument(unsigned ArgNo) const {
return paramHasAttr(ArgNo + 1, Attribute::InAlloca);
return paramHasAttr(ArgNo, Attribute::InAlloca);
}
/// Determine whether this argument is passed by value or in an alloca.
bool isByValOrInAllocaArgument(unsigned ArgNo) const {
return paramHasAttr(ArgNo + 1, Attribute::ByVal) ||
paramHasAttr(ArgNo + 1, Attribute::InAlloca);
return paramHasAttr(ArgNo, Attribute::ByVal) ||
paramHasAttr(ArgNo, Attribute::InAlloca);
}
/// Determine if there are is an inalloca argument. Only the last argument can
/// have the inalloca attribute.
bool hasInAllocaArgument() const {
return paramHasAttr(arg_size(), Attribute::InAlloca);
return !arg_empty() && paramHasAttr(arg_size() - 1, Attribute::InAlloca);
}
bool doesNotAccessMemory(unsigned OpNo) const {
@ -592,7 +597,7 @@ public:
/// This may be because it has the nonnull attribute, or because at least
/// one byte is dereferenceable and the pointer is in addrspace(0).
bool isReturnNonNull() const {
if (paramHasAttr(0, Attribute::NonNull))
if (hasRetAttr(Attribute::NonNull))
return true;
else if (getDereferenceableBytes(0) > 0 &&
getType()->getPointerAddressSpace() == 0)

View File

@ -1681,8 +1681,11 @@ public:
return hasFnAttrImpl(Kind);
}
/// Determine whether the call or the callee has the given attributes.
bool paramHasAttr(unsigned i, Attribute::AttrKind Kind) const;
/// Determine whether the return value has the given attribute.
bool hasRetAttr(Attribute::AttrKind Kind) const;
/// Determine whether the argument or parameter has the given attribute.
bool paramHasAttr(unsigned ArgNo, Attribute::AttrKind Kind) const;
/// Get the attribute of a given kind at a position.
Attribute getAttribute(unsigned i, Attribute::AttrKind Kind) const {
@ -1821,7 +1824,7 @@ public:
return false;
// Be friendly and also check the callee.
return paramHasAttr(1, Attribute::StructRet);
return paramHasAttr(0, Attribute::StructRet);
}
/// Determine if any call argument is an aggregate passed by value.
@ -3767,8 +3770,11 @@ public:
return hasFnAttrImpl(Kind);
}
/// Determine whether the call or the callee has the given attributes.
bool paramHasAttr(unsigned i, Attribute::AttrKind Kind) const;
/// Determine whether the return value has the given attribute.
bool hasRetAttr(Attribute::AttrKind Kind) const;
/// Determine whether the argument or parameter has the given attribute.
bool paramHasAttr(unsigned ArgNo, Attribute::AttrKind Kind) const;
/// Get the attribute of a given kind at a position.
Attribute getAttribute(unsigned i, Attribute::AttrKind Kind) const {
@ -3902,7 +3908,7 @@ public:
return false;
// Be friendly and also check the callee.
return paramHasAttr(1, Attribute::StructRet);
return paramHasAttr(0, Attribute::StructRet);
}
/// Determine if any call argument is an aggregate passed by value.

View File

@ -186,7 +186,7 @@ public:
IsNest(false), IsByVal(false), IsInAlloca(false), IsReturned(false),
IsSwiftSelf(false), IsSwiftError(false) {}
void setAttributes(ImmutableCallSite *CS, unsigned AttrIdx);
void setAttributes(ImmutableCallSite *CS, unsigned ArgIdx);
};
typedef std::vector<ArgListEntry> ArgListTy;
@ -2680,15 +2680,15 @@ public:
ImmutableCallSite &Call) {
RetTy = ResultType;
IsInReg = Call.paramHasAttr(0, Attribute::InReg);
IsInReg = Call.hasRetAttr(Attribute::InReg);
DoesNotReturn =
Call.doesNotReturn() ||
(!Call.isInvoke() &&
isa<UnreachableInst>(Call.getInstruction()->getNextNode()));
IsVarArg = FTy->isVarArg();
IsReturnValueUsed = !Call.getInstruction()->use_empty();
RetSExt = Call.paramHasAttr(0, Attribute::SExt);
RetZExt = Call.paramHasAttr(0, Attribute::ZExt);
RetSExt = Call.hasRetAttr(Attribute::SExt);
RetZExt = Call.hasRetAttr(Attribute::ZExt);
Callee = Target;

View File

@ -697,7 +697,7 @@ AAResults llvm::createLegacyPMAAResults(Pass &P, Function &F,
bool llvm::isNoAliasCall(const Value *V) {
if (auto CS = ImmutableCallSite(V))
return CS.paramHasAttr(0, Attribute::NoAlias);
return CS.hasRetAttr(Attribute::NoAlias);
return false;
}

View File

@ -637,7 +637,7 @@ FunctionModRefBehavior BasicAAResult::getModRefBehavior(const Function *F) {
/// Returns true if this is a writeonly (i.e Mod only) parameter.
static bool isWriteOnlyParam(ImmutableCallSite CS, unsigned ArgIdx,
const TargetLibraryInfo &TLI) {
if (CS.paramHasAttr(ArgIdx + 1, Attribute::WriteOnly))
if (CS.paramHasAttr(ArgIdx, Attribute::WriteOnly))
return true;
// We can bound the aliasing properties of memset_pattern16 just as we can
@ -666,10 +666,10 @@ ModRefInfo BasicAAResult::getArgModRefInfo(ImmutableCallSite CS,
if (isWriteOnlyParam(CS, ArgIdx, TLI))
return MRI_Mod;
if (CS.paramHasAttr(ArgIdx + 1, Attribute::ReadOnly))
if (CS.paramHasAttr(ArgIdx, Attribute::ReadOnly))
return MRI_Ref;
if (CS.paramHasAttr(ArgIdx + 1, Attribute::ReadNone))
if (CS.paramHasAttr(ArgIdx, Attribute::ReadNone))
return MRI_NoModRef;
return AAResultBase::getArgModRefInfo(CS, ArgIdx);

View File

@ -583,8 +583,7 @@ bool CallAnalyzer::visitUnaryInstruction(UnaryInstruction &I) {
}
bool CallAnalyzer::paramHasAttr(Argument *A, Attribute::AttrKind Attr) {
unsigned ArgNo = A->getArgNo();
return CandidateCS.paramHasAttr(ArgNo + 1, Attr);
return CandidateCS.paramHasAttr(A->getArgNo(), Attr);
}
bool CallAnalyzer::isKnownNonNullInCallee(Value *V) {

View File

@ -183,7 +183,7 @@ static Optional<AllocFnsTy> getAllocationSize(const Value *V,
static bool hasNoAliasAttr(const Value *V, bool LookThroughBitCast) {
ImmutableCallSite CS(LookThroughBitCast ? V->stripPointerCasts() : V);
return CS && CS.paramHasAttr(AttributeList::ReturnIndex, Attribute::NoAlias);
return CS && CS.hasRetAttr(Attribute::NoAlias);
}

View File

@ -694,10 +694,8 @@ bool FastISel::lowerCallOperands(const CallInst *CI, unsigned ArgIdx,
Args.reserve(NumArgs);
// Populate the argument list.
// Attributes for args start at offset 1, after the return attribute.
ImmutableCallSite CS(CI);
for (unsigned ArgI = ArgIdx, ArgE = ArgIdx + NumArgs, AttrI = ArgIdx + 1;
ArgI != ArgE; ++ArgI) {
for (unsigned ArgI = ArgIdx, ArgE = ArgIdx + NumArgs; ArgI != ArgE; ++ArgI) {
Value *V = CI->getOperand(ArgI);
assert(!V->getType()->isEmptyTy() && "Empty type passed to intrinsic.");
@ -705,7 +703,7 @@ bool FastISel::lowerCallOperands(const CallInst *CI, unsigned ArgIdx,
ArgListEntry Entry;
Entry.Val = V;
Entry.Ty = V->getType();
Entry.setAttributes(&CS, AttrI);
Entry.setAttributes(&CS, ArgIdx);
Args.push_back(Entry);
}
@ -907,7 +905,7 @@ bool FastISel::lowerCallTo(const CallInst *CI, MCSymbol *Symbol,
ArgListEntry Entry;
Entry.Val = V;
Entry.Ty = V->getType();
Entry.setAttributes(&CS, ArgI + 1);
Entry.setAttributes(&CS, ArgI);
Args.push_back(Entry);
}
TLI.markLibCallAttributes(MF, CS.getCallingConv(), Args);
@ -1044,7 +1042,7 @@ bool FastISel::lowerCall(const CallInst *CI) {
Entry.Ty = V->getType();
// Skip the first return-type Attribute to get to params.
Entry.setAttributes(&CS, i - CS.arg_begin() + 1);
Entry.setAttributes(&CS, i - CS.arg_begin());
Args.push_back(Entry);
}

View File

@ -5876,8 +5876,7 @@ void SelectionDAGBuilder::LowerCallTo(ImmutableCallSite CS, SDValue Callee,
SDValue ArgNode = getValue(V);
Entry.Node = ArgNode; Entry.Ty = V->getType();
// Skip the first return-type Attribute to get to params.
Entry.setAttributes(&CS, i - CS.arg_begin() + 1);
Entry.setAttributes(&CS, i - CS.arg_begin());
// Use swifterror virtual register as input to the call.
if (Entry.IsSwiftError && TLI.supportSwiftError()) {
@ -7340,7 +7339,7 @@ void SelectionDAGBuilder::populateCallLoweringInfo(
// Populate the argument list.
// Attributes for args start at offset 1, after the return attribute.
for (unsigned ArgI = ArgIdx, ArgE = ArgIdx + NumArgs, AttrI = ArgIdx + 1;
for (unsigned ArgI = ArgIdx, ArgE = ArgIdx + NumArgs;
ArgI != ArgE; ++ArgI) {
const Value *V = CS->getOperand(ArgI);
@ -7349,7 +7348,7 @@ void SelectionDAGBuilder::populateCallLoweringInfo(
TargetLowering::ArgListEntry Entry;
Entry.Node = getValue(V);
Entry.Ty = V->getType();
Entry.setAttributes(&CS, AttrI);
Entry.setAttributes(&CS, ArgIdx);
Args.push_back(Entry);
}

View File

@ -98,18 +98,19 @@ bool TargetLowering::parametersInCSRMatch(const MachineRegisterInfo &MRI,
/// \brief Set CallLoweringInfo attribute flags based on a call instruction
/// and called function attributes.
void TargetLoweringBase::ArgListEntry::setAttributes(ImmutableCallSite *CS,
unsigned AttrIdx) {
IsSExt = CS->paramHasAttr(AttrIdx, Attribute::SExt);
IsZExt = CS->paramHasAttr(AttrIdx, Attribute::ZExt);
IsInReg = CS->paramHasAttr(AttrIdx, Attribute::InReg);
IsSRet = CS->paramHasAttr(AttrIdx, Attribute::StructRet);
IsNest = CS->paramHasAttr(AttrIdx, Attribute::Nest);
IsByVal = CS->paramHasAttr(AttrIdx, Attribute::ByVal);
IsInAlloca = CS->paramHasAttr(AttrIdx, Attribute::InAlloca);
IsReturned = CS->paramHasAttr(AttrIdx, Attribute::Returned);
IsSwiftSelf = CS->paramHasAttr(AttrIdx, Attribute::SwiftSelf);
IsSwiftError = CS->paramHasAttr(AttrIdx, Attribute::SwiftError);
Alignment = CS->getParamAlignment(AttrIdx);
unsigned ArgIdx) {
IsSExt = CS->paramHasAttr(ArgIdx, Attribute::SExt);
IsZExt = CS->paramHasAttr(ArgIdx, Attribute::ZExt);
IsInReg = CS->paramHasAttr(ArgIdx, Attribute::InReg);
IsSRet = CS->paramHasAttr(ArgIdx, Attribute::StructRet);
IsNest = CS->paramHasAttr(ArgIdx, Attribute::Nest);
IsByVal = CS->paramHasAttr(ArgIdx, Attribute::ByVal);
IsInAlloca = CS->paramHasAttr(ArgIdx, Attribute::InAlloca);
IsReturned = CS->paramHasAttr(ArgIdx, Attribute::Returned);
IsSwiftSelf = CS->paramHasAttr(ArgIdx, Attribute::SwiftSelf);
IsSwiftError = CS->paramHasAttr(ArgIdx, Attribute::SwiftError);
// FIXME: getParamAlignment is off by one from argument index.
Alignment = CS->getParamAlignment(ArgIdx + 1);
}
/// Generate a libcall taking the given operands as arguments and returning a

View File

@ -380,13 +380,23 @@ void CallInst::addDereferenceableOrNullAttr(unsigned i, uint64_t Bytes) {
setAttributes(PAL);
}
bool CallInst::paramHasAttr(unsigned i, Attribute::AttrKind Kind) const {
assert(i < (getNumArgOperands() + 1) && "Param index out of bounds!");
bool CallInst::hasRetAttr(Attribute::AttrKind Kind) const {
if (Attrs.hasAttribute(AttributeList::ReturnIndex, Kind))
return true;
if (Attrs.hasAttribute(i, Kind))
// Look at the callee, if available.
if (const Function *F = getCalledFunction())
return F->getAttributes().hasAttribute(AttributeList::ReturnIndex, Kind);
return false;
}
bool CallInst::paramHasAttr(unsigned i, Attribute::AttrKind Kind) const {
assert(i < getNumArgOperands() && "Param index out of bounds!");
if (Attrs.hasParamAttribute(i, Kind))
return true;
if (const Function *F = getCalledFunction())
return F->getAttributes().hasAttribute(i, Kind);
return F->getAttributes().hasParamAttribute(i, Kind);
return false;
}
@ -400,8 +410,10 @@ bool CallInst::dataOperandHasImpliedAttr(unsigned i,
// question is a call argument; or be indirectly implied by the kind of its
// containing operand bundle, if the operand is a bundle operand.
// FIXME: Avoid these i - 1 calculations and update the API to use zero-based
// indices.
if (i < (getNumArgOperands() + 1))
return paramHasAttr(i, Kind);
return paramHasAttr(i - 1, Kind);
assert(hasOperandBundles() && i >= (getBundleOperandsStartIndex() + 1) &&
"Must be either a call argument or an operand bundle!");
@ -691,13 +703,23 @@ Value *InvokeInst::getReturnedArgOperand() const {
return nullptr;
}
bool InvokeInst::paramHasAttr(unsigned i, Attribute::AttrKind Kind) const {
assert(i < (getNumArgOperands() + 1) && "Param index out of bounds!");
bool InvokeInst::hasRetAttr(Attribute::AttrKind Kind) const {
if (Attrs.hasAttribute(AttributeList::ReturnIndex, Kind))
return true;
if (Attrs.hasAttribute(i, Kind))
// Look at the callee, if available.
if (const Function *F = getCalledFunction())
return F->getAttributes().hasAttribute(AttributeList::ReturnIndex, Kind);
return false;
}
bool InvokeInst::paramHasAttr(unsigned i, Attribute::AttrKind Kind) const {
assert(i < getNumArgOperands() && "Param index out of bounds!");
if (Attrs.hasParamAttribute(i, Kind))
return true;
if (const Function *F = getCalledFunction())
return F->getAttributes().hasAttribute(i, Kind);
return F->getAttributes().hasParamAttribute(i, Kind);
return false;
}
@ -711,8 +733,10 @@ bool InvokeInst::dataOperandHasImpliedAttr(unsigned i,
// question is an invoke argument; or be indirectly implied by the kind of its
// containing operand bundle, if the operand is a bundle operand.
// FIXME: Avoid these i - 1 calculations and update the API to use zero-based
// indices.
if (i < (getNumArgOperands() + 1))
return paramHasAttr(i, Kind);
return paramHasAttr(i - 1, Kind);
assert(hasOperandBundles() && i >= (getBundleOperandsStartIndex() + 1) &&
"Must be either an invoke argument or an operand bundle!");

View File

@ -2619,7 +2619,7 @@ void Verifier::verifyCallSite(CallSite CS) {
// make sure the underlying alloca/parameter it comes from has a swifterror as
// well.
for (unsigned i = 0, e = FTy->getNumParams(); i != e; ++i)
if (CS.paramHasAttr(i+1, Attribute::SwiftError)) {
if (CS.paramHasAttr(i, Attribute::SwiftError)) {
Value *SwiftErrorArg = CS.getArgument(i);
if (auto AI = dyn_cast<AllocaInst>(SwiftErrorArg->stripInBoundsOffsets())) {
Assert(AI->isSwiftError(),
@ -3114,7 +3114,7 @@ void Verifier::verifySwiftErrorCallSite(CallSite CS,
for (CallSite::arg_iterator I = CS.arg_begin(), E = CS.arg_end();
I != E; ++I, ++Idx) {
if (*I == SwiftErrorVal) {
Assert(CS.paramHasAttr(Idx+1, Attribute::SwiftError),
Assert(CS.paramHasAttr(Idx, Attribute::SwiftError),
"swifterror value when used in a callsite should be marked "
"with swifterror attribute",
SwiftErrorVal, CS);

View File

@ -2351,19 +2351,19 @@ bool ARMFastISel::SelectCall(const Instruction *I,
break;
ISD::ArgFlagsTy Flags;
unsigned AttrInd = i - CS.arg_begin() + 1;
if (CS.paramHasAttr(AttrInd, Attribute::SExt))
unsigned ArgIdx = i - CS.arg_begin();
if (CS.paramHasAttr(ArgIdx, Attribute::SExt))
Flags.setSExt();
if (CS.paramHasAttr(AttrInd, Attribute::ZExt))
if (CS.paramHasAttr(ArgIdx, Attribute::ZExt))
Flags.setZExt();
// FIXME: Only handle *easy* calls for now.
if (CS.paramHasAttr(AttrInd, Attribute::InReg) ||
CS.paramHasAttr(AttrInd, Attribute::StructRet) ||
CS.paramHasAttr(AttrInd, Attribute::SwiftSelf) ||
CS.paramHasAttr(AttrInd, Attribute::SwiftError) ||
CS.paramHasAttr(AttrInd, Attribute::Nest) ||
CS.paramHasAttr(AttrInd, Attribute::ByVal))
if (CS.paramHasAttr(ArgIdx, Attribute::InReg) ||
CS.paramHasAttr(ArgIdx, Attribute::StructRet) ||
CS.paramHasAttr(ArgIdx, Attribute::SwiftSelf) ||
CS.paramHasAttr(ArgIdx, Attribute::SwiftError) ||
CS.paramHasAttr(ArgIdx, Attribute::Nest) ||
CS.paramHasAttr(ArgIdx, Attribute::ByVal))
return false;
Type *ArgTy = (*i)->getType();

View File

@ -54,7 +54,7 @@ FunctionPass *llvm::createWebAssemblyOptimizeReturned() {
void OptimizeReturned::visitCallSite(CallSite CS) {
for (unsigned i = 0, e = CS.getNumArgOperands(); i < e; ++i)
if (CS.paramHasAttr(1 + i, Attribute::Returned)) {
if (CS.paramHasAttr(0, Attribute::Returned)) {
Instruction *Inst = CS.getInstruction();
Value *Arg = CS.getArgOperand(i);
// Ignore constants, globals, undef, etc.

View File

@ -3161,8 +3161,8 @@ static unsigned computeBytesPoppedByCalleeForSRet(const X86Subtarget *Subtarget,
return 0;
if (CS)
if (CS->arg_empty() || !CS->paramHasAttr(1, Attribute::StructRet) ||
CS->paramHasAttr(1, Attribute::InReg) || Subtarget->isTargetMCU())
if (CS->arg_empty() || !CS->paramHasAttr(0, Attribute::StructRet) ||
CS->paramHasAttr(0, Attribute::InReg) || Subtarget->isTargetMCU())
return 0;
return 4;

View File

@ -828,7 +828,7 @@ static bool isFunctionMallocLike(Function *F, const SCCNodeSet &SCCNodes) {
case Instruction::Call:
case Instruction::Invoke: {
CallSite CS(RVI);
if (CS.paramHasAttr(0, Attribute::NoAlias))
if (CS.hasRetAttr(Attribute::NoAlias))
break;
if (CS.getCalledFunction() && SCCNodes.count(CS.getCalledFunction()))
break;

View File

@ -3793,7 +3793,7 @@ Instruction *InstCombiner::visitCallSite(CallSite CS) {
for (Value *V : CS.args()) {
if (V->getType()->isPointerTy() &&
!CS.paramHasAttr(ArgNo + 1, Attribute::NonNull) &&
!CS.paramHasAttr(ArgNo, Attribute::NonNull) &&
isKnownNonNullAt(V, CS.getInstruction(), &DT))
Indices.push_back(ArgNo + 1);
ArgNo++;

View File

@ -2638,7 +2638,7 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
" Shadow: " << *ArgShadow << "\n");
bool ArgIsInitialized = false;
const DataLayout &DL = F.getParent()->getDataLayout();
if (CS.paramHasAttr(i + 1, Attribute::ByVal)) {
if (CS.paramHasAttr(i, Attribute::ByVal)) {
assert(A->getType()->isPointerTy() &&
"ByVal argument is not a pointer!");
Size = DL.getTypeAllocSize(A->getType()->getPointerElementType());
@ -2976,7 +2976,7 @@ struct VarArgAMD64Helper : public VarArgHelper {
Value *A = *ArgIt;
unsigned ArgNo = CS.getArgumentNo(ArgIt);
bool IsFixed = ArgNo < CS.getFunctionType()->getNumParams();
bool IsByVal = CS.paramHasAttr(ArgNo + 1, Attribute::ByVal);
bool IsByVal = CS.paramHasAttr(ArgNo, Attribute::ByVal);
if (IsByVal) {
// ByVal arguments always go to the overflow area.
// Fixed arguments passed through the overflow area will be stepped
@ -3497,7 +3497,7 @@ struct VarArgPowerPC64Helper : public VarArgHelper {
Value *A = *ArgIt;
unsigned ArgNo = CS.getArgumentNo(ArgIt);
bool IsFixed = ArgNo < CS.getFunctionType()->getNumParams();
bool IsByVal = CS.paramHasAttr(ArgNo + 1, Attribute::ByVal);
bool IsByVal = CS.paramHasAttr(ArgNo, Attribute::ByVal);
if (IsByVal) {
assert(A->getType()->isPointerTy());
Type *RealTy = A->getType()->getPointerElementType();

View File

@ -313,7 +313,7 @@ static bool processCallSite(CallSite CS, LazyValueInfo *LVI) {
// Try to mark pointer typed parameters as non-null. We skip the
// relatively expensive analysis for constants which are obviously either
// null or non-null to start with.
if (Type && !CS.paramHasAttr(ArgNo + 1, Attribute::NonNull) &&
if (Type && !CS.paramHasAttr(ArgNo, Attribute::NonNull) &&
!isa<Constant>(V) &&
LVI->getPredicateAt(ICmpInst::ICMP_EQ, V,
ConstantPointerNull::get(Type),

View File

@ -42,7 +42,7 @@ TEST(IndirectionUtilsTest, MakeStub) {
EXPECT_TRUE(Call->isTailCall()) << "Indirect call from stub should be tail call.";
EXPECT_TRUE(Call->hasStructRetAttr())
<< "makeStub should propagate sret attr on 1st argument.";
EXPECT_TRUE(Call->paramHasAttr(2U, Attribute::ByVal))
EXPECT_TRUE(Call->paramHasAttr(1U, Attribute::ByVal))
<< "makeStub should propagate byval attr on 2nd argument.";
}