This is an archive of the discontinued LLVM Phabricator instance.

[IR] Prefer not to delete blocks that have their address taken
AbandonedPublic

Authored by lebedev.ri on May 19 2021, 5:48 AM.

Details

Summary

Honestly, i don't know what should happen when we want to delete
a block that has their address taken.

Currently, when that happens, the i8* blockaddress(@fun, %bb)
is replaced with i8* inttoptr i32 1 to i8*. Which is obviously
no longer an address of a block, and iff the use semantically required
it to actually be an address of a block, e.g. AArch64's S constaint
in llvm/test/CodeGen/AArch64/inlineasm-S-constraint.ll,
then the IR suddenly becomes invalid.

I have only noticed this because that test starts to fail
after some SimplifyCFG changes.

So, since, the blocks practically never have their addresses taken,
i would propose to:

  1. forbid DeleteDeadBlocks() from deleting blocks that have their addresses taken. This will allow to catch the precise codepath that is missing aa precondition.
  2. Don't delete blocks that have their addresses taken
  3. Allow to delete unreachable that have their addresses taken - taking an address does not count as block reachability.

Diff Detail

Event Timeline

lebedev.ri created this revision.May 19 2021, 5:48 AM
lebedev.ri requested review of this revision.May 19 2021, 5:48 AM
jrtc27 added a comment.EditedMay 19 2021, 6:01 AM

What about something like https://godbolt.org/z/47eoabYMe? The evil address-of-label/indirect-goto GNU extension makes it possible to generate this kind of thing in C, it's not just buggy IR generation.

My inclination is to say that address of should be treated the same as branching for BB liveness.

jrtc27 added inline comments.May 19 2021, 6:07 AM
llvm/test/CodeGen/RISCV/codemodel-lowering.ll
34

Seems this test has always highlighted the broken behaviour :( should have caught that in review...

My inclination is to say that address of should be treated the same as branching for BB liveness.

I'm not really sure how that would look.
It will, for sure, require LangRef changes, and somewhat invasive changes to the code.
Here i mostly only have enough motivation to avoid encountering/creating verifier errors,
not fixing the entirety of potentially-misdesigned BlockAddress thingy.

Allow to delete unreachable that have their addresses taken - taking an address does not count as block reachability.

Though, i guess this isn't enough. We could still end up with a case
where AArch64's S constaint was expecting an address of a now-unreachable block.
So once again, i do not understand the rules.

Which is obviously no longer an address of a block, and iff the use semantically required it to actually be an address of a block, e.g. AArch64's S constaint in llvm/test/CodeGen/AArch64/inlineasm-S-constraint.ll, then the IR suddenly becomes invalid.

Not completely sure what you mean by "semantically required"; you mean it has to point somewhere in the same section?

We could add support for blockaddress(@lower_blockaddress, null) or something like that, I guess. I don't think it makes sense to block the elimination of unreachable blocks; that's likely to cause other issues.

lebedev.ri added a comment.EditedMay 19 2021, 11:41 AM

Which is obviously no longer an address of a block, and iff the use semantically required it to actually be an address of a block, e.g. AArch64's S constaint in llvm/test/CodeGen/AArch64/inlineasm-S-constraint.ll, then the IR suddenly becomes invalid.

Not completely sure what you mean by "semantically required"; you mean it has to point somewhere in the same section?

For example, if we, for some reason, decide to delete block %loc in @test_inline_constraint_S_label(),
(i8* blockaddress(@test_inline_constraint_S_label, %loc)) will be replaced with e.g. (i8* inttoptr(i32 1 to i8*)),
and whoops: https://godbolt.org/z/Ee1Y6sbEf

We could add support for blockaddress(@lower_blockaddress, null) or something like that, I guess.

I don't think it makes sense to block the elimination of unreachable blocks; that's likely to cause other issues.

Yeah, i'm still unsure how we are supposed to deal with blockaddress thing :/

Ok, how about this common ground approach?
This is pretty horrible, but i'm not quite sure what alternative there is.

Rather than a "zombie" BB, my suggestion is to invent a new kind of blockaddress that doesn't refer to a bb at all. The backend would then just point it at the entry block or something like that. Makes blockaddress handling a bit more complicated, but it makes CFG handling simpler, which seems more important. (Our current CFG rules are hard enough to understand.)

lebedev.ri abandoned this revision.May 20 2021, 2:53 AM

Hmm. This is looking more and more complicated by the comment.
I'm afraid i just don't have enough interest in BlockAddress to deal with this.