Skip to content

Conversation

badumbatish
Copy link
Contributor

From the comment on PR review #1844, it seems like we're missing the flags for GEP.

I'm opening the PR to add the flags.

The first commit is just a prototype to gather opinions and reviews to see if I'm heading to the right direction with this.

Copy link

github-actions bot commented Aug 26, 2025

✅ With the latest revision this PR passed the C/C++ code formatter.

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.

Nice! This also needs CIRGen changes and lowering to LLVM support, but looks like a good start

@tommymcm
Copy link
Collaborator

It might make sense for cir.get_element to get the same treatment. Maybe we should have it inherit from ptr_stride to avoid duplicating everything? get_element is essentially just a ptr_stride with 'better' type information.

@badumbatish
Copy link
Contributor Author

is there any historical reason why we didn't consolidate the two?

@tommymcm
Copy link
Collaborator

is there any historical reason why we didn't consolidate the two?

Nope, I introduced get_element recently-ish. It just didn't have any meaningful overlap until this. Other option is having them share a parent (some kind of "ptr_arith" base class).
This can all be handled in a later PR though.

@andykaylor
Copy link
Collaborator

I like get_element as a separate operation, because it does something logically different than ptr_stride, but if we can share code between them, we should.

@badumbatish
Copy link
Contributor Author

I added lowering and codegen, I added OGCG test initially but was reluctant if i should push it.

I also didn't remove the missing feature check, i'm not sure how feature ready this is compared to OG.

Copy link
Collaborator

@xlauko xlauko left a comment

Choose a reason for hiding this comment

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

Can this be first ported to incubator then mirrored here.

def GEPInbounds : BitEnumCaseGroup<"inbounds", [GEPInboundsFlag, GEPNusw]>;

def GEPNoWrapFlags
: I32BitEnum<"GEPNoWrapFlags", "::cir::GEPNoWrapFlags",
Copy link
Collaborator

Choose a reason for hiding this comment

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

We should add CIR_I32BitEnum similar to CIR_I32Enum.

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'll add a test implement but would love another review on this

Copy link
Collaborator

Choose a reason for hiding this comment

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

Could we just replace these with CIR_I32Enum instead? That way it would match the other enums we use.

Copy link
Contributor Author

@badumbatish badumbatish Sep 4, 2025

Choose a reason for hiding this comment

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

i'm more keen on keeping the 1-to-1 mapping between the LLVM dialect and this PR, but i can change if need to

Copy link
Collaborator

Choose a reason for hiding this comment

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

Oh I see, they're fundamentally different types.

Comment on lines 402 to 404
def GEPNoWrapFlagsProp : EnumProp<GEPNoWrapFlags> {
let defaultValue = interfaceType#"::none";
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

Ay reason for property here, and in operation? Named attributes in operations are defaulted to properties, no need to wrap it.

Copy link
Contributor Author

@badumbatish badumbatish Sep 4, 2025

Choose a reason for hiding this comment

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

this is just copied verbatim from the LLVM dialect, i'll incorporate your comments to the next push

Using GEPNoWrapFlags directly resulted in this

/Users/jjasmine/Developer/igalia/clangir/clang/include/clang/CIR/Dialect/IR/CIROps.td:406:5: error: unexpected def type; only defs deriving from TypeConstraint or Attr or Property are allowed
def CIR_PtrStrideOp : CIR_Op<"ptr_stride",[
    ^

Comment on lines +428 to 429
`(` $base `:` qualified(type($base)) `,` $stride `:` qualified(type($stride))(`,` $noWrapFlags^)?`)`
`,` qualified(type($result)) attr-dict
Copy link
Collaborator

Choose a reason for hiding this comment

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

This should have been $base, $stride : funstional-type attr-dict in the first place. We can fix that fist in separate PR.

Then I would suggest ($noWrapFlags^)? $base, $stride : funstional-type attr-dict.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yeah i can file an issue for that

@badumbatish
Copy link
Contributor Author

Can this be first ported to incubator then mirrored here.

I dont quite follow, this repo is the incubator yes?

- Add CIR_I32BitEnum similar to CIR_I32Enum.
- Add usage example where we use enums
- Use look up table instead of static cast when converting from CIR to
  LLVM
Copy link
Collaborator

@tommymcm tommymcm left a comment

Choose a reason for hiding this comment

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

Need to update the CIR-to-LLVM GEP flag function. Also some formatting nits.

Comment on lines +18 to +19
class CIR_I32BitEnum<string name, string summary, list<BitEnumCaseBase> cases>
: I32BitEnum<name, summary, cases> {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Looking at other dialects, I think this should be:

Suggested change
class CIR_I32BitEnum<string name, string summary, list<BitEnumCaseBase> cases>
: I32BitEnum<name, summary, cases> {
class CIR_I32BitEnumAttr<string name, string summary, list<BitEnumCaseBase> cases>
: I32BitEnumAttr<name, summary, cases> {

Comment on lines +421 to +423
%4 = cir.ptr_stride(%2 : !cir.ptr<i32>, %3 : i32, inbounds), !cir.ptr<i32>

%4 = cir.ptr_stride(%2 : !cir.ptr<i32>, %3 : i32, inbounds|nuw), !cir.ptr<i32>
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
%4 = cir.ptr_stride(%2 : !cir.ptr<i32>, %3 : i32, inbounds), !cir.ptr<i32>
%4 = cir.ptr_stride(%2 : !cir.ptr<i32>, %3 : i32, inbounds|nuw), !cir.ptr<i32>
%5 = cir.ptr_stride(%2 : !cir.ptr<i32>, %3 : i32, inbounds), !cir.ptr<i32>
%6 = cir.ptr_stride(%2 : !cir.ptr<i32>, %3 : i32, inbounds|nuw), !cir.ptr<i32>

Comment on lines +98 to +111
static std::unordered_map<cir::CIR_GEPNoWrapFlags, mlir::LLVM::GEPNoWrapFlags>
mp = {
{cir::CIR_GEPNoWrapFlags::none, mlir::LLVM::GEPNoWrapFlags::none},
{cir::CIR_GEPNoWrapFlags::inbounds,
mlir::LLVM::GEPNoWrapFlags::inbounds},
{cir::CIR_GEPNoWrapFlags::inboundsFlag,
mlir::LLVM::GEPNoWrapFlags::inboundsFlag},
{cir::CIR_GEPNoWrapFlags::nusw, mlir::LLVM::GEPNoWrapFlags::nusw},
{cir::CIR_GEPNoWrapFlags::nuw, mlir::LLVM::GEPNoWrapFlags::nuw},
};
mlir::LLVM::GEPNoWrapFlags x = mlir::LLVM::GEPNoWrapFlags::none;
for (auto [key, _] : mp)
x = x | mp.at(flags & key);
return x;
Copy link
Collaborator

Choose a reason for hiding this comment

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

Don't use a static map like this, it introduces shared state.

This should just be a series of if (flags & cir::CIR_GEP...) x |= mlir::LLVM::GEP...;

bcardosolopes pushed a commit that referenced this pull request Sep 5, 2025
tommymcm pushed a commit to tommymcm/clangir that referenced this pull request Sep 5, 2025
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.

5 participants