Skip to content

Conversation

@badumbatish
Copy link
Contributor

@badumbatish badumbatish commented Sep 29, 2025

Related to #1913.

Added alias op and verifier for call op. Failing two tests related to constructor and destructor aliases

Clang :: CIR/CodeGen/ctor-alias.cpp
Clang :: CIR/CodeGen/virtual-destructor-calls.cpp

Right now cir::FuncOp CIRGenModule::GetOrCreateCIRFunction is being used in a lot of place where if we switch to using Alias in emitAliasForGlobal, we'll hit cast type error. I'm not quite sure if i should change the function result type to be mlir::Operation* or something that encompasses both function and alias or not

Pilot test case

class A {
public:
  A();
} A;
A::A() {}

el-ev and others added 30 commits August 10, 2025 19:42
Closes llvm#1367

---------

Co-authored-by: Sirui Mu <msrlancern@gmail.com>
Co-authored-by: Amr Hesham <amr96@programmer.net>
Co-authored-by: Chibuoyim (Wilson) Ogbonna <ogbonnachibuoyim12@gmail.com>
Co-authored-by: Yue Huang <30948580+AdUhTkJm@users.noreply.github.com>
Co-authored-by: Morris Hafner <mmha@users.noreply.github.com>
Co-authored-by: Morris Hafner <mhafner@nvidia.com>
Co-authored-by: Sharp-Edged <48861530+Sharp-Edged@users.noreply.github.com>
Co-authored-by: Bruno Cardoso Lopes <bruno.cardoso@gmail.com>
Co-authored-by: Letu Ren <fantasquex@gmail.com>
…#1521)

- Part of llvm#70

This is not very useful now, as both branches of interest are NYI. I
will try to implement the real features in subsequent patches.
…ity and maintainability (llvm#1525)

As noted in [this
comment](llvm#1442 (comment)),
the nested if-arms in `GlobalOpLowering` are somewhat confusing and
error-prone. This PR simplifies the logic into more straightforward
components.

Since LLVM's GlobalOp accepts two types of initializers (either an
initializer value or an initializer region), we've extracted the
decision logic into a separate function called `lowerInitializer`. This
function takes two inout arguments: `mlir::Attribute &init` (for the
attribute value) and `bool useInitializerRegion` (as the decision
indicator). All code paths then converge at a common epilogue that
handles the operation rewriting.

The previous implementation for lowering `DataMemberAttr` initializers
relied on recursion between MLIR rewrite calls, which made the control
flow somewhat opaque. The new version makes this explicit by using a
clear self-recursive pattern within `lowerInitializer`.
Fix llvm#1371.

Not sure about whether we could remove `convertTypeForMem` completely.
Let's fix the doc first.
This change moves all declarations of emit* functions in
CIRGenFunction.h into a common location and sorts them alphabetically.
The goal of this change is to make it easier to keep upstream and
incubator code in a consistent location, making functions easier to find
for upstreaming and minimizing conflicts in the incubator when rebasing.

I did most of this sort manually, and I've probably been inconsistent in
how I treat sorting of uppercase versus lowercase. I made no attempt to
provide a rule for ordering different declarations of functions with the
same name. We can improve on that over time if anyone feels the need.

I tried very hard not to drop comments (one of the reasons I had to do
this manually), but I may have lost a few.

This change loses the grouping of some declarations that were co-located
by common purpose, but most of the declarations lacked a coherent
ordering, so I think this is a step forward overall.
This is a rebased version of the inactive PR llvm#1380.

---------

Co-authored-by: koparasy <parasyris1@llnl.gov>
Adds implementation for ATanOp's lowering ThroughMLIR.
Adds implementation for ACosOp's lowering ThroughMLIR.
Adds implementation for ASinOp's lowering ThroughMLIR.
In the review for upstreaming unary operation support
(llvm/llvm-project#131369), it was suggested
that the VisitPlus and VisitMinus functions should be combined. This is
a backport of that refactoring.
This also removes some unused `#include`s.

I choose to allow lowering to LLVM dialect when we're lowering CIR to
MLIR core dialects, because some operations don't have their
counterparts in these dialects (for example, `UnreachableOp ->
llvm.unreachable` and `LLVMIntrinsicCallOp -> cir.llvm.intr.xxx`). I
don't think we can delay them to the MLIR->LLVM pass as it seems we
assume all CIR operations have been lowered after CIR->MLIR conversion.

Co-authored-by: Yue Huang <yh548@cam.ac.uk>
Update getZeroInitAttr to cover more FP types, Backport from
(llvm/llvm-project#133100)
Adds implementation for TanOp's lowering via ThroughMLIR.
Upstream commit changed behavior
llvm/llvm-project@ff585fe
I tested in original clang and it produced the same IR with clangir.
Related: llvm#1497
…nmvq_f32 (llvm#1546)

ower vminnmv_f32, vminnmvq_f64 and vminnmvq_f32
…llvm#1547)

When a pointer variable is initialized with a null pointer, the AST
contains a NullToPointer cast. If we just emit a null pointer of the
correct type, we will miss any side effects that occur in the
initializer. This change adds code to emit the initializer expression if
it is not a simple constant.

This results in an extra null pointer constant being emitted when the
expression has side effects, but the constant emitted while visiting the
expression does not have the correct type, so the alternative would be
to capture the emitted constant and bitcast it to the correct type. An
extra constant seems less intrusive than an unnecessary bitcast.
llvm#1552)

These entries exist in OG but are not present in CIR codegen.
Added:
- `cos`
- `floor`
- `round`
- `rint`
- `nearbyint`
- `sin`
- `sqrt`
- `tan`
- `trunc`
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.

Thanks for the PR, besides comments, this also needs testcases and LLVM lowering support.

mlir::OpBuilder::InsertionGuard guard(builder);

// Some global emissions are triggered while emitting a function, e.g.
// void s() { x.method() }
Copy link
Member

Choose a reason for hiding this comment

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

This doesn't seem to apply here.

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 think i need some help and explanation on this comment in the OG createCIRFunction to understand more why it's not applicable.

// Be sure to insert a new function before a current one.
auto *curCGF = getCurrCIRGenFun();
if (curCGF)
builder.setInsertionPoint(curCGF->CurFn);
Copy link
Member

Choose a reason for hiding this comment

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

is this ever the case? I can't see how one might want to insert an alias op outside the module level scope

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'm not quite sure what you mean here? don't we want to reset the insertion point if we're inside a function?

>;

def CIR_AliasOp : CIR_Op<"alias", [AutomaticAllocationScope, CallableOpInterface,
FunctionOpInterface, IsolatedFromAbove]> {
Copy link
Member

Choose a reason for hiding this comment

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

You need to add a description, examples, etc, see others for inspiration

/// Returns the region on the current operation that is callable. This may
/// return null in the case of an external callable object, e.g. an external
/// function.
::mlir::Region *getCallableRegion() {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Will this operation also be used for global variable aliases?

Copy link
Contributor Author

@badumbatish badumbatish Oct 1, 2025

Choose a reason for hiding this comment

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

hi Andy, I want to have a simple lowering to LLVM_AliasOp but not sure how messy if the same op has two different functionalities. I want to try using 1 op first. I can change the comments

@badumbatish
Copy link
Contributor Author

This looks a bit odd. Looks like both fn and alias implement the came callable interfaces, so why not refactor this in terms of the needed interface?

I've refactored the code to use CIRCallableOpInterface instead of FuncOp now but was wondering if it is ergonomic to do so. Right now if some person wants to use some methods that exists in FunctionOpInterface, they need to search up the return type and the argument type and add it to the CIRCallableOpInterface first, if they dont want to cast it to FunctionOpInterface. It stinks a bit but on top of my mind i can't see another cleaner way to do this.

Only test case that doesn't pass is the test case that both requires alias as well as lowering to llvm. will handle that soon

@bcardosolopes
Copy link
Member

bcardosolopes commented Oct 3, 2025

This is changing too much, and became way harder to review. What I was trying to suggest is that we shouldn't be duplicating code that can be covered with interfaces, meaning that if you are free to create a new one if it makes more sense, I'm basically alluding to the existing ones, it doesn't mean they have to be used.

In LLVM, there are two cases for alias, function aliases and global aliases. I suggest you start a new PR looking at C/C++ examples that create aliases for both globals and function, and find out via that what it's the abstraction you really need. Right now, as you noticed, we have clunky support for alias functions in CIR, because LLVM dialect didn't have AliasOp until I added it some months ago, so you'd need to think about the design here.

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.