[clang] [CIR] Upstream Unary Inc/Dec for ComplexType (PR #149162)

2025-07-18 Thread Amr Hesham via cfe-commits


@@ -56,6 +56,26 @@ class ComplexExprEmitter : public 
StmtVisitor {
   mlir::Value VisitParenExpr(ParenExpr *e);
   mlir::Value
   VisitSubstNonTypeTemplateParmExpr(SubstNonTypeTemplateParmExpr *e);
+
+  mlir::Value VisitPrePostIncDec(const UnaryOperator *e, bool isInc,
+ bool isPre);
+
+  mlir::Value VisitUnaryPostDec(const UnaryOperator *e) {

AmrDeveloper wrote:

> You can assert to expect inc/dec?

M, Yes, I will create a PR now

https://github.com/llvm/llvm-project/pull/149162
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [CIR] Upstream Unary Inc/Dec for ComplexType (PR #149162)

2025-07-18 Thread Henrich Lauko via cfe-commits


@@ -56,6 +56,26 @@ class ComplexExprEmitter : public 
StmtVisitor {
   mlir::Value VisitParenExpr(ParenExpr *e);
   mlir::Value
   VisitSubstNonTypeTemplateParmExpr(SubstNonTypeTemplateParmExpr *e);
+
+  mlir::Value VisitPrePostIncDec(const UnaryOperator *e, bool isInc,
+ bool isPre);
+
+  mlir::Value VisitUnaryPostDec(const UnaryOperator *e) {

xlauko wrote:

You can assert to expect inc/dec?

https://github.com/llvm/llvm-project/pull/149162
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [CIR] Upstream Unary Inc/Dec for ComplexType (PR #149162)

2025-07-18 Thread Amr Hesham via cfe-commits


@@ -56,6 +56,26 @@ class ComplexExprEmitter : public 
StmtVisitor {
   mlir::Value VisitParenExpr(ParenExpr *e);
   mlir::Value
   VisitSubstNonTypeTemplateParmExpr(SubstNonTypeTemplateParmExpr *e);
+
+  mlir::Value VisitPrePostIncDec(const UnaryOperator *e, bool isInc,
+ bool isPre);
+
+  mlir::Value VisitUnaryPostDec(const UnaryOperator *e) {

AmrDeveloper wrote:

I implemented it locally, but I was thinking that there are no checks on unary 
op, and anyone can call the function with `cir::UnaryOpKind::Not, Minus or 
Plus` and it will generate CIR code that will crash only when we lower to LLVM 
🤔, do you think this is the best option or maybe we should rename the booleans 
in a better way @xlauko 

https://github.com/llvm/llvm-project/pull/149162
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [CIR] Upstream Unary Inc/Dec for ComplexType (PR #149162)

2025-07-18 Thread Amr Hesham via cfe-commits


@@ -56,6 +56,26 @@ class ComplexExprEmitter : public 
StmtVisitor {
   mlir::Value VisitParenExpr(ParenExpr *e);
   mlir::Value
   VisitSubstNonTypeTemplateParmExpr(SubstNonTypeTemplateParmExpr *e);
+
+  mlir::Value VisitPrePostIncDec(const UnaryOperator *e, bool isInc,
+ bool isPre);
+
+  mlir::Value VisitUnaryPostDec(const UnaryOperator *e) {

AmrDeveloper wrote:

Sure, I will create another PR for it, Thanks

https://github.com/llvm/llvm-project/pull/149162
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [CIR] Upstream Unary Inc/Dec for ComplexType (PR #149162)

2025-07-18 Thread Henrich Lauko via cfe-commits


@@ -56,6 +56,26 @@ class ComplexExprEmitter : public 
StmtVisitor {
   mlir::Value VisitParenExpr(ParenExpr *e);
   mlir::Value
   VisitSubstNonTypeTemplateParmExpr(SubstNonTypeTemplateParmExpr *e);
+
+  mlir::Value VisitPrePostIncDec(const UnaryOperator *e, bool isInc,
+ bool isPre);
+
+  mlir::Value VisitUnaryPostDec(const UnaryOperator *e) {

xlauko wrote:

I know this is already merged, but it would be nicer to pass `cir::UnaryOpKind` 
as second argument instead of ambiguous bool. @AmrDeveloper  can you fix this 
in additional PR please?

https://github.com/llvm/llvm-project/pull/149162
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [CIR] Upstream Unary Inc/Dec for ComplexType (PR #149162)

2025-07-17 Thread Amr Hesham via cfe-commits

https://github.com/AmrDeveloper closed 
https://github.com/llvm/llvm-project/pull/149162
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [CIR] Upstream Unary Inc/Dec for ComplexType (PR #149162)

2025-07-16 Thread Andy Kaylor via cfe-commits

https://github.com/andykaylor approved this pull request.

This looks good, but I'm asking for changes to make the tests more readable.

https://github.com/llvm/llvm-project/pull/149162
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [CIR] Upstream Unary Inc/Dec for ComplexType (PR #149162)

2025-07-16 Thread Andy Kaylor via cfe-commits


@@ -83,8 +83,204 @@ void foo2() {
 // OGCG: %[[A_REAL:.*]] = load float, ptr %[[A_REAL_PTR]], align 4
 // OGCG: %[[A_IMAG_PTR:.*]] = getelementptr inbounds nuw { float, float }, ptr 
%[[COMPLEX]], i32 0, i32 1
 // OGCG: %[[A_IMAG:.*]] = load float, ptr %[[A_IMAG_PTR]], align 4
-// OGCG: %[[A_IMAG_MINUS:.*]] = fneg float  %[[A_IMAG]]
+// OGCG: %[[A_IMAG_MINUS:.*]] = fneg float %[[A_IMAG]]
 // OGCG: %[[RESULT_REAL_PTR:.*]] = getelementptr inbounds nuw { float, float 
}, ptr %[[RESULT]], i32 0, i32 0
 // OGCG: %[[RESULT_IMAG_PTR:.*]] = getelementptr inbounds nuw { float, float 
}, ptr %[[RESULT]], i32 0, i32 1
 // OGCG: store float %[[A_REAL]], ptr %[[RESULT_REAL_PTR]], align 4
 // OGCG: store float %[[A_IMAG_MINUS]], ptr %[[RESULT_IMAG_PTR]], align 4
+
+void foo3() {
+  float _Complex a;
+  float _Complex b = a++;
+}
+
+// CIR-BEFORE: %[[COMPLEX:.*]] = cir.alloca !cir.complex, 
!cir.ptr>, ["a"]
+// CIR-BEFORE: %[[RESULT:.*]] = cir.alloca !cir.complex, 
!cir.ptr>, ["b", init]
+// CIR-BEFORE: %[[TMP:.*]] = cir.load{{.*}} %[[COMPLEX]] : 
!cir.ptr>, !cir.complex
+// CIR-BEFORE: %[[COMPLEX_INC:.*]] = cir.unary(inc, %[[TMP]]) : 
!cir.complex, !cir.complex
+// CIR-BEFORE: cir.store{{.*}} %[[COMPLEX_INC]], %[[COMPLEX]] : 
!cir.complex, !cir.ptr>
+// CIR-BEFORE: cir.store{{.*}} %[[TMP]], %[[RESULT]] : 
!cir.complex, !cir.ptr>
+
+// CIR-AFTER: %[[COMPLEX:.*]] = cir.alloca !cir.complex, 
!cir.ptr>, ["a"]
+// CIR-AFTER: %[[RESULT:.*]] = cir.alloca !cir.complex, 
!cir.ptr>, ["b", init]
+// CIR-AFTER: %[[TMP:.*]] = cir.load{{.*}} %[[COMPLEX]] : 
!cir.ptr>, !cir.complex
+// CIR-AFTER: %[[REAL:.*]] = cir.complex.real %[[TMP]] : 
!cir.complex -> !cir.float
+// CIR-AFTER: %[[IMAG:.*]] = cir.complex.imag %[[TMP]] : 
!cir.complex -> !cir.float
+// CIR-AFTER: %[[REAL_INC:.*]] = cir.unary(inc, %[[REAL]]) : !cir.float, 
!cir.float
+// CIR-AFTER: %[[NEW_COMPLEX:.*]] = cir.complex.create %[[REAL_INC]], 
%[[IMAG]] : !cir.float -> !cir.complex
+// CIR-AFTER: cir.store{{.*}} %[[NEW_COMPLEX]], %[[COMPLEX]] : 
!cir.complex, !cir.ptr>
+// CIR-AFTER: cir.store{{.*}} %[[TMP]], %[[RESULT]] : 
!cir.complex, !cir.ptr>
+
+// LLVM: %[[COMPLEX:.*]] = alloca { float, float }, i64 1, align 4
+// LLVM: %[[RESULT:.*]] = alloca { float, float }, i64 1, align 4

andykaylor wrote:

```suggestion
// LLVM: %[[A_ADDR:.*]] = alloca { float, float }, i64 1, align 4
// LLVM: %[[B_ADDR:.*]] = alloca { float, float }, i64 1, align 4
```
This, along with other changes this imples, should make the checks more 
readable. And, of course, I'm suggesting this change throughout the new tests.

https://github.com/llvm/llvm-project/pull/149162
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [CIR] Upstream Unary Inc/Dec for ComplexType (PR #149162)

2025-07-16 Thread Andy Kaylor via cfe-commits

https://github.com/andykaylor edited 
https://github.com/llvm/llvm-project/pull/149162
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [CIR] Upstream Unary Inc/Dec for ComplexType (PR #149162)

2025-07-16 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang

Author: Amr Hesham (AmrDeveloper)


Changes

This change adds support for unary inc/dec operators for ComplexType

https://github.com/llvm/llvm-project/issues/141365

---

Patch is 20.30 KiB, truncated to 20.00 KiB below, full version: 
https://github.com/llvm/llvm-project/pull/149162.diff


4 Files Affected:

- (modified) clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp (+49) 
- (modified) clang/lib/CIR/CodeGen/CIRGenFunction.h (+6) 
- (modified) clang/lib/CIR/Dialect/Transforms/LoweringPrepare.cpp (+2-1) 
- (modified) clang/test/CIR/CodeGen/complex-unary.cpp (+197-1) 


``diff
diff --git a/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp 
b/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp
index 6663f5ea1e758..3489e6d17332e 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp
@@ -56,6 +56,26 @@ class ComplexExprEmitter : public 
StmtVisitor {
   mlir::Value VisitParenExpr(ParenExpr *e);
   mlir::Value
   VisitSubstNonTypeTemplateParmExpr(SubstNonTypeTemplateParmExpr *e);
+
+  mlir::Value VisitPrePostIncDec(const UnaryOperator *e, bool isInc,
+ bool isPre);
+
+  mlir::Value VisitUnaryPostDec(const UnaryOperator *e) {
+return VisitPrePostIncDec(e, false, false);
+  }
+
+  mlir::Value VisitUnaryPostInc(const UnaryOperator *e) {
+return VisitPrePostIncDec(e, true, false);
+  }
+
+  mlir::Value VisitUnaryPreDec(const UnaryOperator *e) {
+return VisitPrePostIncDec(e, false, true);
+  }
+
+  mlir::Value VisitUnaryPreInc(const UnaryOperator *e) {
+return VisitPrePostIncDec(e, true, true);
+  }
+
   mlir::Value VisitUnaryDeref(const Expr *e);
   mlir::Value VisitUnaryNot(const UnaryOperator *e);
 
@@ -335,6 +355,12 @@ mlir::Value 
ComplexExprEmitter::VisitSubstNonTypeTemplateParmExpr(
   return Visit(e->getReplacement());
 }
 
+mlir::Value ComplexExprEmitter::VisitPrePostIncDec(const UnaryOperator *e,
+   bool isInc, bool isPre) {
+  LValue lv = cgf.emitLValue(e->getSubExpr());
+  return cgf.emitComplexPrePostIncDec(e, lv, isInc, isPre);
+}
+
 mlir::Value ComplexExprEmitter::VisitUnaryDeref(const Expr *e) {
   return emitLoadOfLValue(e);
 }
@@ -423,6 +449,29 @@ mlir::Value CIRGenFunction::emitComplexExpr(const Expr *e) 
{
   return ComplexExprEmitter(*this).Visit(const_cast(e));
 }
 
+mlir::Value CIRGenFunction::emitComplexPrePostIncDec(const UnaryOperator *e,
+ LValue lv, bool isInc,
+ bool isPre) {
+  mlir::Value inVal = emitLoadOfComplex(lv, e->getExprLoc());
+  mlir::Location loc = getLoc(e->getExprLoc());
+  auto opKind = isInc ? cir::UnaryOpKind::Inc : cir::UnaryOpKind::Dec;
+  mlir::Value incVal = builder.createUnaryOp(loc, opKind, inVal);
+
+  // Store the updated result through the lvalue.
+  emitStoreOfComplex(loc, incVal, lv, /*isInit=*/false);
+
+  if (getLangOpts().OpenMP)
+cgm.errorNYI(loc, "emitComplexPrePostIncDec OpenMP");
+
+  // If this is a postinc, return the value read from memory, otherwise use the
+  // updated value.
+  return isPre ? incVal : inVal;
+}
+
+mlir::Value CIRGenFunction::emitLoadOfComplex(LValue src, SourceLocation loc) {
+  return ComplexExprEmitter(*this).emitLoadOfLValue(src, loc);
+}
+
 void CIRGenFunction::emitStoreOfComplex(mlir::Location loc, mlir::Value v,
 LValue dest, bool isInit) {
   ComplexExprEmitter(*this).emitStoreOfComplex(loc, v, dest, isInit);
diff --git a/clang/lib/CIR/CodeGen/CIRGenFunction.h 
b/clang/lib/CIR/CodeGen/CIRGenFunction.h
index 3baabba5adfe1..9541f4f0725eb 100644
--- a/clang/lib/CIR/CodeGen/CIRGenFunction.h
+++ b/clang/lib/CIR/CodeGen/CIRGenFunction.h
@@ -930,6 +930,9 @@ class CIRGenFunction : public CIRGenTypeCache {
   /// returning the result.
   mlir::Value emitComplexExpr(const Expr *e);
 
+  mlir::Value emitComplexPrePostIncDec(const UnaryOperator *e, LValue lv,
+   bool isInc, bool isPre);
+
   LValue emitComplexAssignmentLValue(const BinaryOperator *e);
 
   void emitCompoundStmt(const clang::CompoundStmt &s);
@@ -980,6 +983,9 @@ class CIRGenFunction : public CIRGenTypeCache {
 
   RValue emitLoadOfBitfieldLValue(LValue lv, SourceLocation loc);
 
+  /// Load a complex number from the specified l-value.
+  mlir::Value emitLoadOfComplex(LValue src, SourceLocation loc);
+
   /// Given an expression that represents a value lvalue, this method emits
   /// the address of the lvalue, then loads the result as an rvalue,
   /// returning the rvalue.
diff --git a/clang/lib/CIR/Dialect/Transforms/LoweringPrepare.cpp 
b/clang/lib/CIR/Dialect/Transforms/LoweringPrepare.cpp
index c708cf9d9fa61..8f848c7345610 100644
--- a/clang/lib/CIR/Dialect/Transforms/LoweringPrepare.cpp
+++ b/clang/lib/CIR/Dialect/Transforms/LoweringPrepare.cpp
@@ -50,7 +50,8 @@ void LoweringPreparePass::lowerUn

[clang] [CIR] Upstream Unary Inc/Dec for ComplexType (PR #149162)

2025-07-16 Thread Amr Hesham via cfe-commits

https://github.com/AmrDeveloper created 
https://github.com/llvm/llvm-project/pull/149162

This change adds support for unary inc/dec operators for ComplexType

https://github.com/llvm/llvm-project/issues/141365

>From f4ceabdb20a3104166aa0682d69fedbcfe0a6f34 Mon Sep 17 00:00:00 2001
From: AmrDeveloper 
Date: Wed, 16 Jul 2025 19:52:49 +0200
Subject: [PATCH] [CIR] Upstream Unary Inc/Dec for ComplexType

---
 clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp   |  49 +
 clang/lib/CIR/CodeGen/CIRGenFunction.h|   6 +
 .../Dialect/Transforms/LoweringPrepare.cpp|   3 +-
 clang/test/CIR/CodeGen/complex-unary.cpp  | 198 +-
 4 files changed, 254 insertions(+), 2 deletions(-)

diff --git a/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp 
b/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp
index 6663f5ea1e758..3489e6d17332e 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp
@@ -56,6 +56,26 @@ class ComplexExprEmitter : public 
StmtVisitor {
   mlir::Value VisitParenExpr(ParenExpr *e);
   mlir::Value
   VisitSubstNonTypeTemplateParmExpr(SubstNonTypeTemplateParmExpr *e);
+
+  mlir::Value VisitPrePostIncDec(const UnaryOperator *e, bool isInc,
+ bool isPre);
+
+  mlir::Value VisitUnaryPostDec(const UnaryOperator *e) {
+return VisitPrePostIncDec(e, false, false);
+  }
+
+  mlir::Value VisitUnaryPostInc(const UnaryOperator *e) {
+return VisitPrePostIncDec(e, true, false);
+  }
+
+  mlir::Value VisitUnaryPreDec(const UnaryOperator *e) {
+return VisitPrePostIncDec(e, false, true);
+  }
+
+  mlir::Value VisitUnaryPreInc(const UnaryOperator *e) {
+return VisitPrePostIncDec(e, true, true);
+  }
+
   mlir::Value VisitUnaryDeref(const Expr *e);
   mlir::Value VisitUnaryNot(const UnaryOperator *e);
 
@@ -335,6 +355,12 @@ mlir::Value 
ComplexExprEmitter::VisitSubstNonTypeTemplateParmExpr(
   return Visit(e->getReplacement());
 }
 
+mlir::Value ComplexExprEmitter::VisitPrePostIncDec(const UnaryOperator *e,
+   bool isInc, bool isPre) {
+  LValue lv = cgf.emitLValue(e->getSubExpr());
+  return cgf.emitComplexPrePostIncDec(e, lv, isInc, isPre);
+}
+
 mlir::Value ComplexExprEmitter::VisitUnaryDeref(const Expr *e) {
   return emitLoadOfLValue(e);
 }
@@ -423,6 +449,29 @@ mlir::Value CIRGenFunction::emitComplexExpr(const Expr *e) 
{
   return ComplexExprEmitter(*this).Visit(const_cast(e));
 }
 
+mlir::Value CIRGenFunction::emitComplexPrePostIncDec(const UnaryOperator *e,
+ LValue lv, bool isInc,
+ bool isPre) {
+  mlir::Value inVal = emitLoadOfComplex(lv, e->getExprLoc());
+  mlir::Location loc = getLoc(e->getExprLoc());
+  auto opKind = isInc ? cir::UnaryOpKind::Inc : cir::UnaryOpKind::Dec;
+  mlir::Value incVal = builder.createUnaryOp(loc, opKind, inVal);
+
+  // Store the updated result through the lvalue.
+  emitStoreOfComplex(loc, incVal, lv, /*isInit=*/false);
+
+  if (getLangOpts().OpenMP)
+cgm.errorNYI(loc, "emitComplexPrePostIncDec OpenMP");
+
+  // If this is a postinc, return the value read from memory, otherwise use the
+  // updated value.
+  return isPre ? incVal : inVal;
+}
+
+mlir::Value CIRGenFunction::emitLoadOfComplex(LValue src, SourceLocation loc) {
+  return ComplexExprEmitter(*this).emitLoadOfLValue(src, loc);
+}
+
 void CIRGenFunction::emitStoreOfComplex(mlir::Location loc, mlir::Value v,
 LValue dest, bool isInit) {
   ComplexExprEmitter(*this).emitStoreOfComplex(loc, v, dest, isInit);
diff --git a/clang/lib/CIR/CodeGen/CIRGenFunction.h 
b/clang/lib/CIR/CodeGen/CIRGenFunction.h
index 3baabba5adfe1..9541f4f0725eb 100644
--- a/clang/lib/CIR/CodeGen/CIRGenFunction.h
+++ b/clang/lib/CIR/CodeGen/CIRGenFunction.h
@@ -930,6 +930,9 @@ class CIRGenFunction : public CIRGenTypeCache {
   /// returning the result.
   mlir::Value emitComplexExpr(const Expr *e);
 
+  mlir::Value emitComplexPrePostIncDec(const UnaryOperator *e, LValue lv,
+   bool isInc, bool isPre);
+
   LValue emitComplexAssignmentLValue(const BinaryOperator *e);
 
   void emitCompoundStmt(const clang::CompoundStmt &s);
@@ -980,6 +983,9 @@ class CIRGenFunction : public CIRGenTypeCache {
 
   RValue emitLoadOfBitfieldLValue(LValue lv, SourceLocation loc);
 
+  /// Load a complex number from the specified l-value.
+  mlir::Value emitLoadOfComplex(LValue src, SourceLocation loc);
+
   /// Given an expression that represents a value lvalue, this method emits
   /// the address of the lvalue, then loads the result as an rvalue,
   /// returning the rvalue.
diff --git a/clang/lib/CIR/Dialect/Transforms/LoweringPrepare.cpp 
b/clang/lib/CIR/Dialect/Transforms/LoweringPrepare.cpp
index c708cf9d9fa61..8f848c7345610 100644
--- a/clang/lib/CIR/Dialect/Transforms/LoweringPrepare.cpp
+++ b/clang/lib/CIR/Dialect/Transforms/Lo