This is an archive of the discontinued LLVM Phabricator instance.

[CodeGenPrepare] Delete intrinsic call to llvm.assume to enable more tailcall
ClosedPublic

Authored by Carrot on Mar 21 2020, 1:17 AM.

Details

Summary

The attached test case is simplified from tcmalloc. Both function calls should be optimized as tailcall. But llvm can only optimize the first call. The second call can't be optimized because function dupRetToEnableTailCallOpts failed to duplicate ret into block case2.

There 2 problems blocked the duplication:

1 Intrinsic call llvm.assume is not handled by dupRetToEnableTailCallOpts
2 The control flow is more complex than expected, dupRetToEnableTailCallOpts can only duplicate ret into its predecessor, but here we have an intermediate block between call and ret.

The solutions:

1 Since CodeGenPrepare is already at the end of LLVM IR phase, we can simply delete the intrinsic call to llvm.assume.
2 A general solution to the complex control flow is hard, but for this case, after exit2 is duplicated into case1, exit2 is the only successor of exit1 and exit1 is the only predecessor of exit2, so they can be combined through eliminateFallThrough. But this function is called too late, there is no more dupRetToEnableTailCallOpts after it. We can add an earlier call to eliminateFallThrough to solve it.

Diff Detail

Event Timeline

Carrot created this revision.Mar 21 2020, 1:17 AM
Herald added a project: Restricted Project. · View Herald TranscriptMar 21 2020, 1:17 AM
arsenm added inline comments.Mar 22 2020, 7:57 AM
llvm/lib/CodeGen/CodeGenPrepare.cpp
1989–1990

I would expect like object size/is_constant this would have been lowered already? I do disagree with using unreachable to error on this case though

Carrot marked an inline comment as done.Mar 23 2020, 9:43 AM
Carrot added inline comments.
llvm/lib/CodeGen/CodeGenPrepare.cpp
1989–1990

This is not in my patch.
Do you want me to delete these 2 cases in the same patch?

arsenm added inline comments.Mar 23 2020, 10:17 AM
llvm/lib/CodeGen/CodeGenPrepare.cpp
1989–1990

I know, but I would expect this case to be handle the same way. These should also not be deleted, just upgraded to an error that won't be deleted in a release build

Carrot marked an inline comment as done.Mar 23 2020, 5:13 PM
Carrot added inline comments.
llvm/lib/CodeGen/CodeGenPrepare.cpp
1989–1990

objectsize and is_constant are lowered at LowerConstantIntrinsics, Intrinsic::assume does not generate instructions, so was simply ignored at SelectionDAG. Do you mean delete it at LowerConstantIntrinsics?

Also does "just upgraded to an error that won't be deleted in a release build" mean Ctx.emitError()?

thanks!

arsenm added inline comments.Mar 24 2020, 9:14 AM
llvm/lib/CodeGen/CodeGenPrepare.cpp
1989–1990

That or report_fatal_error

arsenm added inline comments.Mar 24 2020, 9:19 AM
llvm/test/CodeGen/X86/tailcall-assume-xbb.ll
1 ↗(On Diff #251827)

Move to test/CodeGenPrepare/X86?

2 ↗(On Diff #251827)

Add a comment explaining what this tests?

Carrot updated this revision to Diff 252362.Mar 24 2020, 10:13 AM
Carrot marked 4 inline comments as done.
Carrot added inline comments.
llvm/lib/CodeGen/CodeGenPrepare.cpp
1989–1990

Also delete Intrinsic::assume in LowerConstantIntrinsics?

llvm/test/CodeGen/X86/tailcall-assume-xbb.ll
1 ↗(On Diff #251827)

I assume you mean test/Transforms/CodeGenPrepare/X86.

arsenm added inline comments.Mar 24 2020, 11:14 AM
llvm/lib/CodeGen/CodeGenPrepare.cpp
1989–1990

It's not handled there as you said, so I'm not sure what you're asking?

Carrot marked an inline comment as done.Mar 24 2020, 12:28 PM
Carrot added inline comments.
llvm/lib/CodeGen/CodeGenPrepare.cpp
1989–1990

Sorry for my bad English :(

Is this version OK now?

xbolva00 added inline comments.Mar 29 2020, 9:46 AM
llvm/lib/CodeGen/CodeGenPrepare.cpp
1971

Do we need to run RecursivelyDeleteTriviallyDeadInstructions on arg?

1992

Split these changes to new patch?

Carrot updated this revision to Diff 253699.Mar 30 2020, 2:09 PM
Carrot marked 2 inline comments as done.
Carrot added inline comments.
llvm/lib/CodeGen/CodeGenPrepare.cpp
1971

This function is called in a "while (MadeChange)" loop in function runOnFunction, so the instruction generates the assume condition will be deleted in next iteration. Either or not call RecursivelyDeleteTriviallyDeadInstructions are both OK.

xbolva00 accepted this revision.Mar 30 2020, 2:32 PM

Ok, thanks.

This revision is now accepted and ready to land.Mar 30 2020, 2:32 PM
This revision was automatically updated to reflect the committed changes.
thakis added a subscriber: thakis.Mar 31 2020, 1:41 PM

This likely broke many tests on Windows: http://45.33.8.238/win/11741/step_7.txt / http://lab.llvm.org:8011/builders/clang-x64-windows-msvc/builds/15029

Can you take a look, and revert while you investigate if it takes a while?

This patch doesn't do any register level changes, so it looks unlike the root cause of the failure, maybe some unrelated bug was uncovered by this patch.

Do you have a linux reproduction? This test passed on my linux desktop.

I took a look at the first failed test case amdgpu-hip-implicit-kernarg.cu, it contains an empty kernel function, it should not trigger any optimization code.

Does https://reviews.llvm.org/rG7e4e9f4a2fcb096778fb81fc96da6bb8aa966661 fixed this failure?