-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[SandboxVectorizer][NFCI] Fix use of possibly-uninitialized scalar. #122201
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
The `EraseCallbackID` field is not always initialized in the ctor for SeedCollector, if not, it will be used uninitialized by its dtor. This could potentially lead to the erasure of a random callback, leading to a bug. Fixed by initializing to a purposefully invalid ID (`std::numeric_limits<ContextID>::max()`)
@llvm/pr-subscribers-llvm-transforms @llvm/pr-subscribers-vectorizers Author: Tyler Lanphear (tylanphear) ChangesThe Fixed by initializing to a purposefully invalid ID ( Full diff: https://github.com/llvm/llvm-project/pull/122201.diff 1 Files Affected:
diff --git a/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/SeedCollector.h b/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/SeedCollector.h
index 6e16a84d832e5e..cc4ebb5c508414 100644
--- a/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/SeedCollector.h
+++ b/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/SeedCollector.h
@@ -292,7 +292,9 @@ class SeedCollector {
SeedContainer StoreSeeds;
SeedContainer LoadSeeds;
Context &Ctx;
- Context::CallbackID EraseCallbackID;
+ Context::CallbackID EraseCallbackID =
+ std::numeric_limits<Context::CallbackID>::max();
+
/// \Returns the number of SeedBundle groups for all seed types.
/// This is to be used for limiting compilation time.
unsigned totalNumSeedGroups() const {
|
@Sterling-Augustine shouldn't we always register the callback in the constructor, before the early return? @tylanphear Setting it to max() may not be the correct fix, because |
Nice find! I think the right place to fix this is in the
and this way unregistering an uninitialized ID from anywhere would always trigger an assertion failure (in an asserts-enabled build), or at least not collide with any registered IDs. What do you think? |
It seems like unconditionally setting the callback ID is a reasonable solution. Using an opaque ID (with a default initializer set to an invalid ID) also seems reasonable, though perhaps a broader change than I'd be comfortable committing without further approvals. |
The fact that CallbackID is a uint64_t is an implementation detail, so we should discourage having the user initialize it with an integer value. Also the user should not have to worry about initializing it at all. So I am in favor of the opaque ID fix. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the patch! It looks good in general, just a few minor comments.
public: | ||
// Uses a 64-bit integer so we don't have to worry about the unlikely case | ||
// of overflowing a 32-bit counter. | ||
using ReprTy = uint64_t; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What does "Repr" stand for in ReprTy
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Representation, as uint64_t
is the underlying representation. Open to suggestion on the naming here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wdyt about ValTy
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems reasonable to me.
// Uses a 64-bit integer so we don't have to worry about the unlikely case | ||
// of overflowing a 32-bit counter. | ||
using ReprTy = uint64_t; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: I would define the reserved uninitialized value here as a public value:
static constexpr const ReprTy UninitVal = std::numeric_limits<ReprTy>::max();
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done, called it InvalidVal
.
@@ -686,7 +686,7 @@ void Context::runMoveInstrCallbacks(Instruction *I, const BBIterator &WhereIt) { | |||
Context::CallbackID Context::registerEraseInstrCallback(EraseInstrCallback CB) { | |||
assert(EraseInstrCallbacks.size() <= MaxRegisteredCallbacks && | |||
"EraseInstrCallbacks size limit exceeded"); | |||
CallbackID ID = NextCallbackID++; | |||
CallbackID ID{NextCallbackID++}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should probably have a check here that NextCallbackID
is not equal to the reserved value, with something like:
assert(NextCallbackID != CallbackID::UninitVal && "Matches the reserved value!");
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm it's probably better to put this check in the constructor.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Makes sense; put an assert
in the constructor.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the changes! LGTM. @slackito any other comments?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good, thank you!
…lvm#122201) The `EraseCallbackID` field is not always initialized in the ctor for SeedCollector; if not, it will be used uninitialized by its dtor. This could potentially lead to the erasure of a random callback, leading to a bug. Fixed by making `CallbackID` an opaque type, which is always default-initialized to an invalid ID.
The
EraseCallbackID
field is not always initialized in the ctor for SeedCollector; if not, it will be used uninitialized by its dtor. This could potentially lead to the erasure of a random callback, leading to a bug.Fixed by making
CallbackID
an opaque type, which is always default-initialized to an invalid ID.