================ @@ -1391,22 +1411,60 @@ static void AddParamAndFnBasicAttributes(const CallBase &CB, AttributeList AL = NewInnerCB->getAttributes(); for (unsigned I = 0, E = InnerCB->arg_size(); I < E; ++I) { - // Check if the underlying value for the parameter is an argument. - const Value *UnderlyingV = - getUnderlyingObject(InnerCB->getArgOperand(I)); - const Argument *Arg = dyn_cast<Argument>(UnderlyingV); - if (!Arg) + // It's unsound or requires special handling to propagate + // attributes to byval arguments. Even if CalledFunction + // doesn't e.g. write to the argument (readonly), the call to + // NewInnerCB may write to its by-value copy. + if (AL.hasParamAttr(I, Attribute::ByVal)) continue; - if (AL.hasParamAttr(I, Attribute::ByVal)) - // It's unsound to propagate memory attributes to byval arguments. - // Even if CalledFunction doesn't e.g. write to the argument, - // the call to NewInnerCB may write to its by-value copy. + // Don't bother propagating attrs to constants. + if (match(NewInnerCB->getArgOperand(I), + llvm::PatternMatch::m_ImmConstant())) continue; - unsigned ArgNo = Arg->getArgNo(); + // Check if the underlying value for the parameter is an argument. + const Argument *Arg = dyn_cast<Argument>(InnerCB->getArgOperand(I)); + unsigned ArgNo; + if (Arg) { + ArgNo = Arg->getArgNo(); + // For dereferenceable, dereferenceable_or_null, align, etc... + // we don't want to propagate if the existing param has the same + // attribute with "better" constraints. So remove from the + // new AL if the region of the existing param is larger than + // what we can propagate. + AttrBuilder NewAB{ + Context, AttributeSet::get(Context, ValidExactParamAttrs[ArgNo])}; + if (AL.getParamDereferenceableBytes(I) > + NewAB.getDereferenceableBytes()) + NewAB.removeAttribute(Attribute::Dereferenceable); + if (AL.getParamDereferenceableOrNullBytes(I) > + NewAB.getDereferenceableOrNullBytes()) + NewAB.removeAttribute(Attribute::DereferenceableOrNull); + if (AL.getParamAlignment(I).valueOrOne() > + NewAB.getAlignment().valueOrOne()) + NewAB.removeAttribute(Attribute::Alignment); + if (auto ExistingRange = AL.getParamRange(I)) { + if (auto NewRange = NewAB.getRange()) { + ConstantRange CombinedRange = + ExistingRange->intersectWith(*NewRange); + NewAB.removeAttribute(Attribute::Range); + NewAB.addRangeAttr(CombinedRange); + } + } ---------------- nikic wrote:
Code is expected to query attributes on CallBase, not the underlying attribute list. If everything works on CallBase, and CallBase implements attribute inheritance correctly, there should not be any special cases relative to the current code. https://github.com/llvm/llvm-project/pull/91101 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits