if old (replaced) call has a tail call hint, use it.
Diff Detail
- Repository
- rG LLVM Github Monorepo
Unit Tests
Event Timeline
llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp | ||
---|---|---|
1741 | Can omptimizeCall ever break the tail requirements, e.g., create an alloca and pass it? |
llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp | ||
---|---|---|
1741 | I don't like this approach. I mean, I get the motivation, but I'm not sure this is the right way to address it. Three issues:
|
llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp | ||
---|---|---|
1735–1736 | If we're not replacing CI with the simplified version With, why do we even bother to compute With? This guard looks to me like it should be hoisted above the call to LibCallSimplifier::optimizeCall. Otherwise NumSimplified seems like a useless statistic. Who cares that I made a simplification if I didn't even use it? I'm also curious why CI is returned rather than nullptr? | |
1738–1739 | As discusses in D107872, this should probably be: diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp index aa806325bcf5..f749aca6083f 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp @@ -2433,13 +2433,13 @@ Instruction *InstCombinerImpl::tryOptimizeCall(CallInst *CI) { if (auto *NewCI = dyn_cast<CallInst>(With)) NewCI->setTailCallKind(CI->getTailCallKind()); + else if (CI->isMustTailCall()) + return nullptr; + ++NumSimplified; The the update to NumSimplified stat should come after the potential return nullptr. | |
1741 | After spending lots of time on this in D107872, this does look like the best approach to me. Regarding @efriedma points above, corresponding responses:
|
llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp | ||
---|---|---|
1741 | The plain "tail" marker is a marker for optimization: it means the called function doesn't refer to the caller's stack frame (allocas etc.). That's complicated to deduce. And sometimes the frontend has extra information which isn't represented otherwise. Also, the information is actually used in a few places outside of codegen (see BasicAAResult::getModRefInfo). So it's not as simple as just "make the backend compute it". It was arguably a mistake that "notail" is stored in the same enum as plain "tail". In theory, a "tail notail" call is reasonable. It would mean that the callee doesn't refer to the caller's stack frame, but we're forbidden from tail calling for some other reason. I think it ended up the way it did because musttail implies tail, and nobody reconsidered when notail was added. Two specific cases where I'm concerned this patch breaks down:
|
llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp | ||
---|---|---|
1741 | Thanks for the additional info/feedback. Then the alternative is to sprinkle these "copy the tail call kind unless musttail" checks in basically every transform, carefully, on a case-by-case basis. ie. as is done in https://reviews.llvm.org/D107872. Are you ok with that approach then? Based on what you've written above, I think the asserts I added to llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp are ok to stay? Can you please comment on the alternate approach taken in https://reviews.llvm.org/D107872? |
If we're not replacing CI with the simplified version With, why do we even bother to compute With? This guard looks to me like it should be hoisted above the call to LibCallSimplifier::optimizeCall. Otherwise NumSimplified seems like a useless statistic. Who cares that I made a simplification if I didn't even use it?
I'm also curious why CI is returned rather than nullptr?