This is an archive of the discontinued LLVM Phabricator instance.

[GlobalISel] Tail call memcpy/memmove/memset even in the presence of copies
ClosedPublic

Authored by jroelofs on Jul 2 2021, 4:49 PM.

Details

Diff Detail

Event Timeline

jroelofs created this revision.Jul 2 2021, 4:49 PM
jroelofs requested review of this revision.Jul 2 2021, 4:49 PM
Herald added a project: Restricted Project. · View Herald TranscriptJul 2 2021, 4:49 PM
jroelofs added inline comments.Jul 2 2021, 5:08 PM
llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
549

hm. This isn't quite right. It shouldn't be allowed to fire on this case:

%0:_(p0) = COPY $x1
%1:_(p0) = COPY $x0
%2:_(s64) = COPY $x2
G_MEMCPY %0(p0), %1(p0), %2(s64), 1 :: (store (s8)), (load (s8))
$x1 = COPY %0(p0)
RET_ReallyLR implicit $x0
paquette added inline comments.Jul 6 2021, 10:27 AM
llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
504–509

This comment is out of date with this change.

514

Would be nice if this could be done for thisreturn callees in general, not just the memcpy/memmove/memset calls? Maybe a TODO?

549

I guess you need to check that the register is implicit on the return? So, you probably also have to check that there is a return in the block as well?

Also, what happens if there's more than one copy after the call?

e.g. I think this would do the wrong thing here too:

%0:_(p0) = COPY $x1
%1:_(p0) = COPY $x0
%2:_(s64) = COPY $x2
G_MEMCPY %0(p0), %1(p0), %2(s64), 1 :: (store (s8)), (load (s8))
$x1 = COPY %0(p0)
$x1 = COPY %1(p0)
RET_ReallyLR implicit $x1
jroelofs updated this revision to Diff 356790.Jul 6 2021, 11:39 AM
jroelofs marked an inline comment as done and an inline comment as not done.Jul 6 2021, 11:44 AM
jroelofs added inline comments.
llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
514

The only other case is G_BZERO. Updated to give the default case an unreachable to make this clear.

549

I guess you need to check that the register is implicit on the return?

oh, right, thanks!

I believe the tailcall; copy; whatever; ret case is covered in the next line:

if (Next == MBB.instr_end() || TII.isTailCall(*Next) || !Next->isReturn())
   return false;

... since the preceding block skips at most a single copy instruction (+ debug insts) after the call. Added this as a test case for good measure.

aemerson added inline comments.Jul 16 2021, 2:28 PM
llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
504–509

Why is it necessary to check for %0 = COPY $x0?

It seems the condition we need to check is that there's a write to $x0 (or whatever register is the return register) of the same vreg value as the first argument to G_MEMCPY.

G_MEMCPY %0, %1, %2
$x0 = COPY %0
RET_ReallyLR implicit $x0
jroelofs added inline comments.Jul 16 2021, 2:44 PM
llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
504–509

On further thought, it isn't necessary. I was thinking that was needed to guarantee that %0's whole live range was assigned to $x0, but I don't think we actually need that.

So, this is always assuming we can treat G_MEMCPY and friends as thisreturn, right?

In D105671, @rjmccall mentioned that this may only be correct in terms of using it for ARC. Can we guarantee that we only do this for ARC here too?

So, this is always assuming we can treat G_MEMCPY and friends as thisreturn, right?

In D105671, @rjmccall mentioned that this may only be correct in terms of using it for ARC. Can we guarantee that we only do this for ARC here too?

I read that comment to mean those only affected the objc functions, not memcpy.

ah ok then disregard

So, this is always assuming we can treat G_MEMCPY and friends as thisreturn, right?

The patch this one depends on makes that guarantee.

In D105671, @rjmccall mentioned that this may only be correct in terms of using it for ARC. Can we guarantee that we only do this for ARC here too?

The ARC thing was about doing the same for objc_retain.

jroelofs updated this revision to Diff 359502.Jul 16 2021, 5:24 PM

Drop requirement that the destination argument be initially copied from the returned register.

aemerson accepted this revision.Jul 20 2021, 4:13 PM
This revision is now accepted and ready to land.Jul 20 2021, 4:13 PM
jroelofs closed this revision.Jul 26 2021, 10:38 AM

I typo'd "Differentail" in the commit message.

This was landed here: a14b4e34a4569bb000ccdd4501628e1b891bcb38