@@ -1352,18 +1352,40 @@ static void AddParamAndFnBasicAttributes(const CallBase &CB,
1352
1352
auto &Context = CalledFunction->getContext ();
1353
1353
1354
1354
// Collect valid attributes for all params.
1355
- SmallVector<AttrBuilder> ValidParamAttrs ;
1355
+ SmallVector<AttrBuilder> ValidObjParamAttrs, ValidExactParamAttrs ;
1356
1356
bool HasAttrToPropagate = false ;
1357
1357
1358
1358
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 ()});
1360
1361
// Access attributes can be propagated to any param with the same underlying
1361
1362
// object as the argument.
1362
1363
if (CB.paramHasAttr (I, Attribute::ReadNone))
1363
- ValidParamAttrs .back ().addAttribute (Attribute::ReadNone);
1364
+ ValidObjParamAttrs .back ().addAttribute (Attribute::ReadNone);
1364
1365
if (CB.paramHasAttr (I, Attribute::ReadOnly))
1365
- ValidParamAttrs.back ().addAttribute (Attribute::ReadOnly);
1366
- HasAttrToPropagate |= ValidParamAttrs.back ().hasAttributes ();
1366
+ ValidObjParamAttrs.back ().addAttribute (Attribute::ReadOnly);
1367
+ HasAttrToPropagate |= ValidObjParamAttrs.back ().hasAttributes ();
1368
+
1369
+ // Attributes we can only propagate if the exact parameter is forwarded.
1370
+
1371
+ // We can propagate both poison generating and UB generating attributes
1372
+ // without any extra checks. The only attribute that is tricky to propagate
1373
+ // is `noundef` (skipped for now) as that can create new UB where previous
1374
+ // behavior was just using a poison value.
1375
+ if (auto DerefBytes = CB.getParamDereferenceableBytes (I))
1376
+ ValidExactParamAttrs.back ().addDereferenceableAttr (DerefBytes);
1377
+ if (auto DerefOrNullBytes = CB.getParamDereferenceableOrNullBytes (I))
1378
+ ValidExactParamAttrs.back ().addDereferenceableOrNullAttr (
1379
+ DerefOrNullBytes);
1380
+ if (CB.paramHasAttr (I, Attribute::NoFree))
1381
+ ValidExactParamAttrs.back ().addAttribute (Attribute::NoFree);
1382
+ if (CB.paramHasAttr (I, Attribute::NonNull))
1383
+ ValidExactParamAttrs.back ().addAttribute (Attribute::NonNull);
1384
+ if (auto Align = CB.getParamAlign (I))
1385
+ ValidExactParamAttrs.back ().addAlignmentAttr (Align);
1386
+
1387
+ HasAttrToPropagate |= ValidObjParamAttrs.back ().hasAttributes ();
1388
+ HasAttrToPropagate |= ValidExactParamAttrs.back ().hasAttributes ();
1367
1389
}
1368
1390
1369
1391
// Won't be able to propagate anything.
@@ -1381,21 +1403,49 @@ static void AddParamAndFnBasicAttributes(const CallBase &CB,
1381
1403
AttributeList AL = NewInnerCB->getAttributes ();
1382
1404
for (unsigned I = 0 , E = InnerCB->arg_size (); I < E; ++I) {
1383
1405
// Check if the underlying value for the parameter is an argument.
1384
- const Value *UnderlyingV =
1385
- getUnderlyingObject (InnerCB->getArgOperand (I));
1386
- const Argument *Arg = dyn_cast<Argument>(UnderlyingV);
1387
- if (!Arg)
1388
- continue ;
1406
+ const Argument *Arg = dyn_cast<Argument>(InnerCB->getArgOperand (I));
1407
+ unsigned ArgNo;
1408
+ if (Arg) {
1409
+ ArgNo = Arg->getArgNo ();
1410
+ // For dereferenceable, dereferenceable_or_null, align, etc...
1411
+ // we don't want to propagate if the existing param has the same
1412
+ // attribute with "better" constraints. So, only remove from the
1413
+ // existing AL if the region of the existing param is smaller than
1414
+ // what we can propagate. AttributeList's merge API honours the
1415
+ // already existing attribute value so we choose the "better"
1416
+ // attribute by removing if the existing one is worse.
1417
+ if (AL.getParamDereferenceableBytes (I) <
1418
+ ValidExactParamAttrs[ArgNo].getDereferenceableBytes ())
1419
+ AL =
1420
+ AL.removeParamAttribute (Context, I, Attribute::Dereferenceable);
1421
+ if (AL.getParamDereferenceableOrNullBytes (I) <
1422
+ ValidExactParamAttrs[ArgNo].getDereferenceableOrNullBytes ())
1423
+ AL =
1424
+ AL.removeParamAttribute (Context, I, Attribute::Dereferenceable);
1425
+ if (AL.getParamAlignment (I).valueOrOne () <
1426
+ ValidExactParamAttrs[ArgNo].getAlignment ().valueOrOne ())
1427
+ AL = AL.removeParamAttribute (Context, I, Attribute::Alignment);
1428
+
1429
+ AL = AL.addParamAttributes (Context, I, ValidExactParamAttrs[ArgNo]);
1430
+
1431
+ } else {
1432
+ // Check if the underlying value for the parameter is an argument.
1433
+ const Value *UnderlyingV =
1434
+ getUnderlyingObject (InnerCB->getArgOperand (I));
1435
+ Arg = dyn_cast<Argument>(UnderlyingV);
1436
+ if (!Arg)
1437
+ continue ;
1438
+ ArgNo = Arg->getArgNo ();
1439
+ }
1389
1440
1390
1441
if (AL.hasParamAttr (I, Attribute::ByVal))
1391
1442
// It's unsound to propagate memory attributes to byval arguments.
1392
1443
// Even if CalledFunction doesn't e.g. write to the argument,
1393
1444
// the call to NewInnerCB may write to its by-value copy.
1394
1445
continue ;
1395
1446
1396
- unsigned ArgNo = Arg->getArgNo ();
1397
1447
// If so, propagate its access attributes.
1398
- AL = AL.addParamAttributes (Context, I, ValidParamAttrs [ArgNo]);
1448
+ AL = AL.addParamAttributes (Context, I, ValidObjParamAttrs [ArgNo]);
1399
1449
// We can have conflicting attributes from the inner callsite and
1400
1450
// to-be-inlined callsite. In that case, choose the most
1401
1451
// restrictive.
0 commit comments