Skip to content

Conversation

@Andres-Salamanca
Copy link
Contributor

This PR adds lowering of BlockAddressOp. It uses two maps, blockInfoToTagOp and unresolvedBlockAddressOp, to defer matching mlir::LLVM::BlockAddressOp to its corresponding mlir::LLVM::BlockTagOp in cases where the matching label has not yet been emitted.

If the BlockTagOp is not emitted, a placeholder value std::numeric_limits<uint32_t>::max() is used, which will later be resolved in resolveBlockAddressOp. Support for indirect goto and label differences will be added in a future PR.

Copy link
Member

@bcardosolopes bcardosolopes left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Few nits and LGTM

private:
// Maps a (function name, label name) pair to the corresponding BlockTagOp.
// Used to resolve CIR LabelOps into their LLVM BlockTagOp.
llvm::DenseMap<std::pair<llvm::StringRef, llvm::StringRef>,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of std::pair<llvm::StringRef, llvm::StringRef>, it might be more MLIR and clean to create an attribute that wraps these two, just like LLVM dialect does. Can you add the attribute? It's fine if you do that in a follow up PR though, just let me know.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I’d prefer to handle this in a future PR. Also, what do you think about changing LabelOp to always use this attribute? I think that would be better, because right now I’m looking at IndirectBrOpand with what we have now, I imagine it could look something like this:

cir.blockaddress(@B, "B") -> !cir.ptr<!void> // here we just have a string, not the actual label

^bb2
  cir.label "A"
  ...

^bb3
  cir.label "B"
  ...

^indirectBr(%addr : !cir.ptr<!void>):  // this would act like a PHI node for each block address
  cir.indirectBr %addr : !cir.ptr<!void> [ ^bb2, ^bb3 ] // we don’t have enough info to get the block of the label

(This is just a rough idea for now.)

The problem is that each blockaddress only has a string, so we don’t actually know the block associated with the label. I think with an attribute we could link the label to the block—but I don’t fully understand how that would work yet.
(@andykaylor, I’d appreciate your input on this as welll)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what do you think about changing LabelOp to always use this attribute?

Sure thing, once you introduce new attributes they should be used wherever it makes sense.

I imagine it could look something like this:

What's the C/C++ code that might lead to this? Note that in LLVM if you don't have the label hints it's undefined behavior (https://llvm.org/docs/LangRef.html#indirectbr-instruction) so I wouldn't worry about imaginary use cases.

The problem is that each blockaddress only has a string, so we don’t actually know the block associated with the label

For the case where this isn't undefined behavior: the new attribute has to be within the same function and part of one of the cir.labels used. (a) you can walk the blocks and find out (the slow options) the cir.labels, or (b) you can book keep the blocks as you go about emitting the "cir.label" instructions. If it's expensive to find the all block sources, we could just use the superset of all the ones we've seen cir.labels in (but I'd like to see a C/C++ source exercising that)

@bcardosolopes bcardosolopes merged commit ab27364 into llvm:main Sep 23, 2025
9 checks passed
bcardosolopes pushed a commit that referenced this pull request Sep 29, 2025
This PR adds the new attribute `CIR_BlockAddrInfoAttr`, requested in
[#1909](#1909), which is used in
`BlockAddressOp` and `LabelOp`. I also created a custom builder to
simplify construction so that we don’t have to call
`mlir::FlatSymbolRefAttr::get` and `mlir::StringAttr::get` every time.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants