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