After RS4GC, we should drop metadata that is no longer valid. These metadata is used by optimizations scheduled after RS4GC, and can cause a miscompile. One such metadata is invariant.load which is used by LICM sinking transform. After rewriting statepoints, the address of a load maybe relocated. With invariant.load metadata on a load instruction, LICM sinking assumes the loaded value (from a dererenceable address) to be invariant, and rematerializes the load operand and the load at the exit block. This transforms the IR to have an unrelocated use of the address after a statepoint, which is incorrect. Other metadata we conservatively remove are related to dereferenceability and noalias metadata. This patch drops such metadata on store and load instructions after rewriting statepoints.
Details
Diff Detail
- Repository
- rL LLVM
Event Timeline
lib/Transforms/Scalar/RewriteStatepointsForGC.cpp | ||
---|---|---|
2318 ↗ | (On Diff #100962) | Can you order these values in the order provided in IR/LLVMContext.h? Makes it easier to see which ones are missing if the ordering is the same. |
lib/Transforms/Scalar/RewriteStatepointsForGC.cpp | ||
---|---|---|
2318 ↗ | (On Diff #101927) | Why drop MD_nontemporal? |
lib/Transforms/Scalar/RewriteStatepointsForGC.cpp | ||
---|---|---|
2351 ↗ | (On Diff #101927) | I think that a better factoring on this would be to factor out something from RemoveNonValidAttrAtIndex which works on a load, call it on a load, then add !invariant.load to that list. This is not specific to invariant load. Really, we'd just completely failed to think about loads in implementing this. |
lib/Transforms/Scalar/RewriteStatepointsForGC.cpp | ||
---|---|---|
2351 ↗ | (On Diff #101927) | I don't think we can factor out anything from RemoveNonValidAttrAtIndex. We are trying to remove metadata and not attributes. Also, there is no way to specify something like I.removeMetadata(invariant_load), and such a function should *not* be added in Instruction class. The reason being we need to keep auditing code for correctness to keep track of all new metadata that gets added to langref. The dropUnknownNonDebugMetadata(knownIDs) works *correctly* without any changes even when new metadata gets added. Also, I.dropUnknownNonDebugMetadata updates private members in Instruction once no metadata is left behind in that instruction. I can introduce a function like DropInvalidMetadataOnInstruction and call it on a load instruction. Does that work? |
lib/Transforms/Scalar/RewriteStatepointsForGC.cpp | ||
---|---|---|
2351 ↗ | (On Diff #101927) | Talked to Philip offline, and he agreed with my analysis (since we are dealing with metadata and not attributes). I'm going to update the comments and code to make this distinction clearer. |
Updated code to remove invalid metadata on load and stores.
Now, we remove also noalias and dereferenceability metadata (which are analogous to their attribute counterparts).
Added some comments and renamed function names.