This is an archive of the discontinued LLVM Phabricator instance.

SCCP: Don't assert on constantexpr casts of function uses
ClosedPublic

Authored by arsenm on Dec 20 2022, 8:59 AM.

Details

Summary

This includes 2 different, related fixes:

1. Fix asserting on direct assume-like intrinsic uses of a function
   address

2. Fix asserting on constant expression casts used by assume-like
   intrinsics.

By default hasAddressTaken permits assume-like intrinsic uses, which
ignores assume-like calls and pointer casts of the address used by
assume-like calls.

Fixes issue 59602, but there are additional issues I encountered when
debugging this. For instance, the original failing bitcast expression
was really unused. Clang tentatively created it for the function type,
but was unnecessary after applyGlobalValReplacements. That did not
clean up the now dead ConstantExpr which hung around oun the user
list, so this assert only reproduced when running clang from the
original testcase, and didn't just running opt -passes=ipsccp. I don't
know who is responsible for cleaning up unused ConstantExprs, but I've
run into similar issues several times recently.

Additionally, I found a few assertions with llvm.ssa.copy with
functions and casts of functions as the argument.

Another issue theoretically exists if hasAddressTaken chooses to
respect nocapture when passed function addresses. The search here
would need to do additional work to look at the users of the constant
cast to see if any call sites need returned to be stripped.

Diff Detail

Event Timeline

arsenm created this revision.Dec 20 2022, 8:59 AM
Herald added a project: Restricted Project. · View Herald TranscriptDec 20 2022, 8:59 AM
arsenm requested review of this revision.Dec 20 2022, 8:59 AM
Herald added a project: Restricted Project. · View Herald TranscriptDec 20 2022, 8:59 AM
Herald added a subscriber: wdng. · View Herald Transcript
nikic accepted this revision.Dec 21 2022, 2:59 AM

LG

I don't know who is responsible for cleaning up unused ConstantExprs, but I've run into similar issues several times recently.

I guess in this particular case SCCP could clean them up (it already does so for GlobalVariables, see the removeDeadConstantUsers() call). It's also possible to ignore them via hasZeroLiveUses().

llvm/lib/Transforms/IPO/SCCP.cpp
357

If I understood things correctly, I don't think so: We only look through casts for assume-like intrinsics, and for those it's not a call use, so there's no attributes to drop.

This revision is now accepted and ready to land.Dec 21 2022, 2:59 AM
fhahn added a comment.Dec 21 2022, 3:01 AM

Thanks for the patch!

llvm/lib/Transforms/IPO/SCCP.cpp
87

It would probably be good to add a comment here explaining why we skip assume-like intrinsics here.

355–358

IIUC we only want to adjust the attributes for direct calls, and skip assume-like calls, so something like below?

if (CB->getCalledFunction() != F) {
   assert(cast<IntrinsicInst>(CB)->isAssumeLikeIntrinsic());
   continue;
 }
fhahn added a comment.Dec 21 2022, 3:03 AM

It would also be good to include Fixes #59602 in the description to have GitHub auto-close the issue.

arsenm added inline comments.Dec 21 2022, 6:15 AM
llvm/lib/Transforms/IPO/SCCP.cpp
357

I think if hasAddressTaken looked at nocapture attributes, we could reach here

arsenm added inline comments.Dec 21 2022, 6:19 AM
llvm/lib/Transforms/IPO/SCCP.cpp
355–358

In principle yes, but ConstantExpr makes everything more difficult as always. The case that failed here is actually the constantexpr cast, and then you need to consider the users.

arsenm added inline comments.Dec 21 2022, 6:27 AM
llvm/lib/Transforms/IPO/SCCP.cpp
355–358

Well almost, it's really the existing isa<BlockAddress> or a dead constantexpr here. IntrinsicInst satisfies CallBase

arsenm updated this revision to Diff 484562.Dec 21 2022, 6:32 AM

Add assert