This is an archive of the discontinued LLVM Phabricator instance.

[CodeGenPrepare]Skip sext promotion if operands for multiple users is detected
Needs ReviewPublic

Authored by junbuml on Apr 6 2017, 11:59 AM.

Details

Summary

Do not allow address type promtion if detecting an instruction which has multiple users in the middle of promotion. In such case, ISel could lose opportunities to fold the extension as part of address modes. The added test case should show the case.

Diff Detail

Event Timeline

junbuml created this revision.Apr 6 2017, 11:59 AM
eastig added inline comments.Apr 7 2017, 5:08 AM
lib/CodeGen/CodeGenPrepare.cpp
3361–3362

Don't you think a caller of getAction can get this information itself?

bool hasMultiUserOperand = false;
if (Instruction *ExtOpnd = dyn_cast<Instruction>(I->getOperand(0)))
   hasMultiUserOperand = !ExtOpnd->hasOneUse();
getAction(I, ...);

'getAction' does not use hasMultiUserOperand nor puts it into Action. This parameter looks like exposing internal calculations of the getAction function. If something is changed in the function and there is no hasOneUse call the function would have to continue calculating hasMultiUserOperand as a part of the contract.

4572–4573

Do you assume that the Exts vector always has only one instruction? Otherwise the value of hasMultiUserOperand can be changed from true to false.

4815

The calculation of hasMultiUserOperand is too far from its use. Is it possible to bring it closer?
Do we need other calculations/actions if we know an operand has many users before trying to promote?
What I see we try to promote and discard results if hasMultiUserOperand is true. 'hasMultiUserOperand' can be set up before and transformations. Are there cases when hasMultiUserOperand is set up after transformations?

test/CodeGen/AArch64/arm64-addr-type-promotion.ll
99–100

Does this guarantee lowering to multi usage? Is it possible to write a test in MIR?

junbuml added inline comments.Apr 10 2017, 12:18 PM
lib/CodeGen/CodeGenPrepare.cpp
3361–3362

I think it's possible to calculate hasMultiUserOperand in caller as we need this only for address type promotion.

4572–4573

I do not assume only one instruction in Exts. After hasMultiUserOperand is initialized as false in optimizeExt(), hasMultiUserOperand can turn into true only when encountering any operand used by multiple users. I cannot see the case where hasMultiUserOperand turn from true to false ? Please let me know if you see such case.

4815

We try to promote sext speculatively which is used in two optimizations : 1) for ExtLoad and 2) address type promotion (initially implemented in aarch64-type-promotion pass) and hasMultiUserOperand is used only for the address type promotion. I think the speculative promotion during the profitability check is just reasonable, and reusing the result of speculative promotions for address type promotion is also reasonable.

I agree that the calculation of hasMultiUserOperand is too far from its use, but I cannot see any other better way of doing this while reusing the result of speculative promotions.

Quentin, do you have any suggestion ?

test/CodeGen/AArch64/arm64-addr-type-promotion.ll
99–100

In this test, I intended to make %add have two users: 1) in %sext1 and 2) in %j.l. In such case, we do not allow moving %sext up through %add.

eastig added inline comments.Apr 24 2017, 4:20 AM
lib/CodeGen/CodeGenPrepare.cpp
4572–4573

Yes, you are right. It can be changed only from false to true and never back.

test/CodeGen/AArch64/arm64-addr-type-promotion.ll
99–100

I see. Thank you for explanation.