@@ -1352,20 +1352,41 @@ static void AddParamAndFnBasicAttributes(const CallBase &CB,
13521352 auto &Context = CalledFunction->getContext ();
13531353
13541354 // Collect valid attributes for all params.
1355- SmallVector<AttrBuilder> ValidParamAttrs ;
1355+ SmallVector<AttrBuilder> ValidObjParamAttrs, ValidExactParamAttrs ;
13561356 bool HasAttrToPropagate = false ;
13571357
13581358 for (unsigned I = 0 , E = CB.arg_size (); I < E; ++I) {
1359- ValidParamAttrs.emplace_back (AttrBuilder{CB.getContext ()});
1359+ ValidObjParamAttrs.emplace_back (AttrBuilder{CB.getContext ()});
1360+ ValidExactParamAttrs.emplace_back (AttrBuilder{CB.getContext ()});
13601361 // Access attributes can be propagated to any param with the same underlying
13611362 // object as the argument.
13621363 if (CB.paramHasAttr (I, Attribute::ReadNone))
1363- ValidParamAttrs .back ().addAttribute (Attribute::ReadNone);
1364+ ValidObjParamAttrs .back ().addAttribute (Attribute::ReadNone);
13641365 if (CB.paramHasAttr (I, Attribute::ReadOnly))
1365- ValidParamAttrs .back ().addAttribute (Attribute::ReadOnly);
1366+ ValidObjParamAttrs .back ().addAttribute (Attribute::ReadOnly);
13661367 if (CB.paramHasAttr (I, Attribute::WriteOnly))
1367- ValidParamAttrs.back ().addAttribute (Attribute::WriteOnly);
1368- HasAttrToPropagate |= ValidParamAttrs.back ().hasAttributes ();
1368+ ValidObjParamAttrs.back ().addAttribute (Attribute::WriteOnly);
1369+
1370+ // Attributes we can only propagate if the exact parameter is forwarded.
1371+
1372+ // We can propagate both poison generating and UB generating attributes
1373+ // without any extra checks. The only attribute that is tricky to propagate
1374+ // is `noundef` (skipped for now) as that can create new UB where previous
1375+ // behavior was just using a poison value.
1376+ if (auto DerefBytes = CB.getParamDereferenceableBytes (I))
1377+ ValidExactParamAttrs.back ().addDereferenceableAttr (DerefBytes);
1378+ if (auto DerefOrNullBytes = CB.getParamDereferenceableOrNullBytes (I))
1379+ ValidExactParamAttrs.back ().addDereferenceableOrNullAttr (
1380+ DerefOrNullBytes);
1381+ if (CB.paramHasAttr (I, Attribute::NoFree))
1382+ ValidExactParamAttrs.back ().addAttribute (Attribute::NoFree);
1383+ if (CB.paramHasAttr (I, Attribute::NonNull))
1384+ ValidExactParamAttrs.back ().addAttribute (Attribute::NonNull);
1385+ if (auto Align = CB.getParamAlign (I))
1386+ ValidExactParamAttrs.back ().addAlignmentAttr (Align);
1387+
1388+ HasAttrToPropagate |= ValidObjParamAttrs.back ().hasAttributes ();
1389+ HasAttrToPropagate |= ValidExactParamAttrs.back ().hasAttributes ();
13691390 }
13701391
13711392 // Won't be able to propagate anything.
@@ -1383,15 +1404,43 @@ static void AddParamAndFnBasicAttributes(const CallBase &CB,
13831404 AttributeList AL = NewInnerCB->getAttributes ();
13841405 for (unsigned I = 0 , E = InnerCB->arg_size (); I < E; ++I) {
13851406 // Check if the underlying value for the parameter is an argument.
1386- const Value *UnderlyingV =
1387- getUnderlyingObject (InnerCB->getArgOperand (I));
1388- const Argument *Arg = dyn_cast<Argument>(UnderlyingV);
1389- if (!Arg)
1390- continue ;
1407+ const Argument *Arg = dyn_cast<Argument>(InnerCB->getArgOperand (I));
1408+ unsigned ArgNo;
1409+ if (Arg) {
1410+ ArgNo = Arg->getArgNo ();
1411+ // For dereferenceable, dereferenceable_or_null, align, etc...
1412+ // we don't want to propagate if the existing param has the same
1413+ // attribute with "better" constraints. So, only remove from the
1414+ // existing AL if the region of the existing param is smaller than
1415+ // what we can propagate. AttributeList's merge API honours the
1416+ // already existing attribute value so we choose the "better"
1417+ // attribute by removing if the existing one is worse.
1418+ if (AL.getParamDereferenceableBytes (I) <
1419+ ValidExactParamAttrs[ArgNo].getDereferenceableBytes ())
1420+ AL =
1421+ AL.removeParamAttribute (Context, I, Attribute::Dereferenceable);
1422+ if (AL.getParamDereferenceableOrNullBytes (I) <
1423+ ValidExactParamAttrs[ArgNo].getDereferenceableOrNullBytes ())
1424+ AL =
1425+ AL.removeParamAttribute (Context, I, Attribute::Dereferenceable);
1426+ if (AL.getParamAlignment (I).valueOrOne () <
1427+ ValidExactParamAttrs[ArgNo].getAlignment ().valueOrOne ())
1428+ AL = AL.removeParamAttribute (Context, I, Attribute::Alignment);
1429+
1430+ AL = AL.addParamAttributes (Context, I, ValidExactParamAttrs[ArgNo]);
1431+
1432+ } else {
1433+ // Check if the underlying value for the parameter is an argument.
1434+ const Value *UnderlyingV =
1435+ getUnderlyingObject (InnerCB->getArgOperand (I));
1436+ Arg = dyn_cast<Argument>(UnderlyingV);
1437+ if (!Arg)
1438+ continue ;
1439+ ArgNo = Arg->getArgNo ();
1440+ }
13911441
1392- unsigned ArgNo = Arg->getArgNo ();
13931442 // If so, propagate its access attributes.
1394- AL = AL.addParamAttributes (Context, I, ValidParamAttrs [ArgNo]);
1443+ AL = AL.addParamAttributes (Context, I, ValidObjParamAttrs [ArgNo]);
13951444 // We can have conflicting attributes from the inner callsite and
13961445 // to-be-inlined callsite. In that case, choose the most
13971446 // restrictive.
0 commit comments