This is an archive of the discontinued LLVM Phabricator instance.

[Attributes] Make attribute addition behavior consistent
ClosedPublic

Authored by nikic on Jan 18 2022, 3:05 AM.

Details

Summary

Currently, the behavior when adding an attribute with the same key as an existing attribute is inconsistent, depending on the type of the attribute and the method used to add it. When going through AttrBuilder::addAttribute(), the new attribute always overwrites the old one. When going through AttrBuilder::merge() the new attribute overwrites the existing one if it is a string attribute, not keeps the existing one for int and type attributes. One particular API also asserts that you can't overwrite an align attribute, but does not handle any of the other int, type or string attributes.

This patch makes the behavior consistent by always overwriting with the new attribute, which is the behavior I would intuitively expect. Two tests are affected, which now make a different (but equally valid) choice. Those tests could be improved by taking the maximum deref bytes, but I haven't bothered with that, since this is testing a degenerate case -- the important bit is that it doesn't crash.

The main alternative I see is to instead assert that you cannot add an attribute that already exists, unless it has the same value, forcing the user to handle this explicitly by removing the old attribute first.

Diff Detail

Event Timeline

nikic created this revision.Jan 18 2022, 3:05 AM
nikic requested review of this revision.Jan 18 2022, 3:05 AM
Herald added a project: Restricted Project. · View Herald TranscriptJan 18 2022, 3:05 AM
aeubanks accepted this revision.Jan 18 2022, 10:41 AM
This revision is now accepted and ready to land.Jan 18 2022, 10:41 AM
llvm/lib/IR/Attributes.cpp
1737

It seems to me this could just be IntAttrs |= B.IntAttrs which is probably faster.

nikic added inline comments.Jan 19 2022, 12:14 AM
llvm/lib/IR/Attributes.cpp
1737

I don't think that std::array has an operator|= overload, and it probably wouldn't do what we want here (if it just works elementwise): For example, for dereferenceable(1) and deferenceable(2) we don't want to get back dereferenceable(3).

This revision was landed with ongoing or failed builds.Jan 19 2022, 3:05 AM
This revision was automatically updated to reflect the committed changes.