This is an archive of the discontinued LLVM Phabricator instance.

[RS4GC] Handle special cases in unreachable code for memcpy/memmov
ClosedPublic

Authored by mkazantsev on Jul 12 2022, 6:44 AM.

Details

Summary

The existing code doesn't expect dummy values (undef, poison, null-derived
constants etc) as arguments of these intrinsics. However, they can be there
in unreached code. Currently we fail trying to find base for them.

Handle these cases separately.

Diff Detail

Event Timeline

mkazantsev created this revision.Jul 12 2022, 6:44 AM
Herald added a project: Restricted Project. · View Herald TranscriptJul 12 2022, 6:44 AM
Herald added a subscriber: hiraditya. · View Herald Transcript
mkazantsev requested review of this revision.Jul 12 2022, 6:44 AM
Herald added a project: Restricted Project. · View Herald TranscriptJul 12 2022, 6:44 AM
apilipenko added inline comments.Jul 15 2022, 3:02 PM
llvm/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp
1705

I suggest handling the undef case explicitly. Just return undef if the input is undef.

mkazantsev added inline comments.Jul 18 2022, 2:21 AM
llvm/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp
1705

Same goes for poison I guess.

mkazantsev added inline comments.Jul 18 2022, 6:04 AM
llvm/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp
1705

It's a no-go. Aside from undef and poison, here can be things like

i32 addrspace(1)* bitcast (i8 addrspace(1)* getelementptr inbounds (i8, i8 addrspace(1)* null, i64 16) to i32 addrspace(1)*)

etc. So the expression can be arbitrarily complex.

mkazantsev added inline comments.Jul 18 2022, 6:22 AM
llvm/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp
1705

General idea is that undef may not be the immediate value, but a part of any other expression. Therefore, there is no way to guarantee it's not involved somewhere. The assert is just over-conservative w.r.t. this situation.

apilipenko added inline comments.Jul 18 2022, 7:41 PM
llvm/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp
1705

I see your point.

Looks like RS4GC doesn't track liveness for constants. Instead, it assumes null base for them. See https://github.com/llvm/llvm-project/blob/main/llvm/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp#L537
I think we should do the same here to be consistent.

mkazantsev added inline comments.Jul 18 2022, 10:46 PM
llvm/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp
1705

No, we can't do it. Imagine you had smth like

i32 addrspace(1)* bitcast (i8 addrspace(1)* getelementptr inbounds (i8, i8 addrspace(1)* %base, i64 16) to i32 addrspace(1)*)

and then unreached code opt made it into

i32 addrspace(1)* bitcast (i8 addrspace(1)* getelementptr inbounds (i8, i8 addrspace(1)* %base, i64 undef) to i32 addrspace(1)*)

It's unreached code opts. We can't make any assumptions here.

apilipenko added inline comments.Jul 19 2022, 10:09 AM
llvm/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp
1705

In this case, the pointer should be in the live set.

mkazantsev added inline comments.Jul 19 2022, 9:31 PM
llvm/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp
1705

No it's not. Just run the patch's test and see.

mkazantsev added inline comments.Jul 19 2022, 9:41 PM
llvm/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp
1705

I'm wrong here, I was checking only null constant and that's why.

mkazantsev planned changes to this revision.Jul 19 2022, 10:29 PM
mkazantsev retitled this revision from [RS4GC] Fix over-restrictive assert in atomic memcpy/move handling to [RS4GC] Handle special cases in unreachable code for memcpy/memmov.
mkazantsev edited the summary of this revision. (Show Details)
apilipenko added inline comments.Jul 20 2022, 8:30 AM
llvm/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp
1711

Undef and poison fall under the constant clause. I don't think that they need a special handling.

mkazantsev added inline comments.Jul 20 2022, 9:00 PM
llvm/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp
1711

Err, you are right.

apilipenko accepted this revision.Jul 21 2022, 8:55 AM
This revision is now accepted and ready to land.Jul 21 2022, 8:55 AM
apilipenko added inline comments.Jul 21 2022, 9:32 AM
llvm/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp
1706

I would add to the comment that taking null as a base is consistent with the handling in the main algorithm in findBaseDefiningValue.

This revision was landed with ongoing or failed builds.Jul 21 2022, 9:55 PM
This revision was automatically updated to reflect the committed changes.