Skip to content

[CIR] Upstream scalar support for ParenExpr #136332

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 18, 2025
Merged

Conversation

andykaylor
Copy link
Contributor

This change adds support for handling ParenExpr in scalar expressions. A few more places will need to be updated after structure assignment and complex type support is in place.

This change adds support for handling ParenExpr in scalar expressions.
A few more places will need to be updated after structure assignment and
complex type support is in place.
@llvmbot llvmbot added clang Clang issues not falling into any other category ClangIR Anything related to the ClangIR project labels Apr 18, 2025
@llvmbot
Copy link
Member

llvmbot commented Apr 18, 2025

@llvm/pr-subscribers-clangir

Author: Andy Kaylor (andykaylor)

Changes

This change adds support for handling ParenExpr in scalar expressions. A few more places will need to be updated after structure assignment and complex type support is in place.


Full diff: https://github.com/llvm/llvm-project/pull/136332.diff

3 Files Affected:

  • (modified) clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp (+2)
  • (modified) clang/lib/CIR/CodeGen/CIRGenFunction.cpp (+2)
  • (modified) clang/test/CIR/CodeGen/basic.c (+63)
diff --git a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
index 3dae26dc86f85..1bef1b976a4b5 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
@@ -116,6 +116,8 @@ class ScalarExprEmitter : public StmtVisitor<ScalarExprEmitter, mlir::Value> {
     return {};
   }
 
+  mlir::Value VisitParenExpr(ParenExpr *pe) { return Visit(pe->getSubExpr()); }
+
   /// Emits the address of the l-value, then loads and returns the result.
   mlir::Value emitLoadOfLValue(const Expr *e) {
     LValue lv = cgf.emitLValue(e);
diff --git a/clang/lib/CIR/CodeGen/CIRGenFunction.cpp b/clang/lib/CIR/CodeGen/CIRGenFunction.cpp
index 9dace721e7417..76e9ca4fd61a8 100644
--- a/clang/lib/CIR/CodeGen/CIRGenFunction.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenFunction.cpp
@@ -515,6 +515,8 @@ LValue CIRGenFunction::emitLValue(const Expr *e) {
     return emitUnaryOpLValue(cast<UnaryOperator>(e));
   case Expr::BinaryOperatorClass:
     return emitBinaryOperatorLValue(cast<BinaryOperator>(e));
+  case Expr::ParenExprClass:
+    return emitLValue(cast<ParenExpr>(e)->getSubExpr());
   case Expr::DeclRefExprClass:
     return emitDeclRefLValue(cast<DeclRefExpr>(e));
   }
diff --git a/clang/test/CIR/CodeGen/basic.c b/clang/test/CIR/CodeGen/basic.c
index cf687e44044c4..8ce8106b0c6cc 100644
--- a/clang/test/CIR/CodeGen/basic.c
+++ b/clang/test/CIR/CodeGen/basic.c
@@ -169,3 +169,66 @@ int f6(void) {
 // OGCG-NEXT: entry:
 // OGCG-NEXT:   %[[GV:.*]] = load i32, ptr @gv, align 4
 // OGCG-NEXT:   ret i32 %[[GV]]
+
+int f7(int a, int b, int c) {
+  return a + (b + c);
+}
+
+// CIR: cir.func @f7
+// CIR:  %[[A_PTR:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["a", init]
+// CIR:  %[[B_PTR:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["b", init]
+// CIR:  %[[C_PTR:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["c", init]
+// CIR:  %[[A:.*]] = cir.load %[[A_PTR]] : !cir.ptr<!s32i>, !s32i
+// CIR:  %[[B:.*]] = cir.load %[[B_PTR]] : !cir.ptr<!s32i>, !s32i
+// CIR:  %[[C:.*]] = cir.load %[[C_PTR]] : !cir.ptr<!s32i>, !s32i
+// CIR:  %[[B_PLUS_C:.*]] = cir.binop(add, %[[B]], %[[C]]) nsw : !s32i
+// CIR:  %[[RETVAL:.*]] = cir.binop(add, %[[A]], %[[B_PLUS_C]]) nsw : !s32i
+
+// LLVM: define i32 @f7
+// LLVM:   %[[A_PTR:.*]] = alloca i32, i64 1, align 4
+// LLVM:   %[[B_PTR:.*]] = alloca i32, i64 1, align 4
+// LLVM:   %[[C_PTR:.*]] = alloca i32, i64 1, align 4
+// LLVM:   %[[A:.*]] = load i32, ptr %[[A_PTR]], align 4
+// LLVM:   %[[B:.*]] = load i32, ptr %[[B_PTR]], align 4
+// LLVM:   %[[C:.*]] = load i32, ptr %[[C_PTR]], align 4
+// LLVM:   %[[B_PLUS_C:.*]] = add nsw i32 %[[B]], %[[C]]
+// LLVM:   %[[RETVAL:.*]] = add nsw i32 %[[A]], %[[B_PLUS_C]]
+
+// OGCG: define{{.*}} i32 @f7
+// OGCG: entry:
+// OGCG:   %[[A_PTR:.*]] = alloca i32, align 4
+// OGCG:   %[[B_PTR:.*]] = alloca i32, align 4
+// OGCG:   %[[C_PTR:.*]] = alloca i32, align 4
+// OGCG:   %[[A:.*]] = load i32, ptr %[[A_PTR]], align 4
+// OGCG:   %[[B:.*]] = load i32, ptr %[[B_PTR]], align 4
+// OGCG:   %[[C:.*]] = load i32, ptr %[[C_PTR]], align 4
+// OGCG:   %[[B_PLUS_C:.*]] = add nsw i32 %[[B]], %[[C]]
+// OGCG:   %[[RETVAL:.*]] = add nsw i32 %[[A]], %[[B_PLUS_C]]
+
+int f8(int *p) {
+  (*p) = 2;
+  return (*p);
+}
+
+// CIR: cir.func @f8
+// CIR:    %[[P_PTR:.*]] = cir.alloca !cir.ptr<!s32i>, !cir.ptr<!cir.ptr<!s32i>>, ["p", init]
+// CIR:    %[[TWO:.*]] = cir.const #cir.int<2> : !s32i
+// CIR:    %[[P:.*]] = cir.load deref %[[P_PTR]] : !cir.ptr<!cir.ptr<!s32i>>, !cir.ptr<!s32i>
+// CIR:    cir.store %[[TWO]], %[[P]] : !s32i, !cir.ptr<!s32i>
+// CIR:    %[[P2:.*]] = cir.load deref %[[P_PTR]] : !cir.ptr<!cir.ptr<!s32i>>, !cir.ptr<!s32i>
+// CIR:    %[[STAR_P:.*]] = cir.load %[[P2]] : !cir.ptr<!s32i>, !s32i
+
+// LLVM: define i32 @f8
+// LLVM:   %[[P_PTR:.*]] = alloca ptr, i64 1, align 8
+// LLVM:   %[[P:.*]] = load ptr, ptr %[[P_PTR]], align 8
+// LLVM:   store i32 2, ptr %[[P]], align 4
+// LLVM:   %[[P2:.*]] = load ptr, ptr %[[P_PTR]], align 8
+// LLVM:   %[[STAR_P:.*]] = load i32, ptr %[[P2]], align 4
+
+// OGCG: define{{.*}} i32 @f8
+// OGCG: entry:
+// OGCG:   %[[P_PTR:.*]] = alloca ptr, align 8
+// OGCG:   %[[P:.*]] = load ptr, ptr %[[P_PTR]], align 8
+// OGCG:   store i32 2, ptr %[[P]], align 4
+// OGCG:   %[[P2:.*]] = load ptr, ptr %[[P_PTR]], align 8
+// OGCG:   %[[STAR_P:.*]] = load i32, ptr %[[P2]], align 4

@llvmbot
Copy link
Member

llvmbot commented Apr 18, 2025

@llvm/pr-subscribers-clang

Author: Andy Kaylor (andykaylor)

Changes

This change adds support for handling ParenExpr in scalar expressions. A few more places will need to be updated after structure assignment and complex type support is in place.


Full diff: https://github.com/llvm/llvm-project/pull/136332.diff

3 Files Affected:

  • (modified) clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp (+2)
  • (modified) clang/lib/CIR/CodeGen/CIRGenFunction.cpp (+2)
  • (modified) clang/test/CIR/CodeGen/basic.c (+63)
diff --git a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
index 3dae26dc86f85..1bef1b976a4b5 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
@@ -116,6 +116,8 @@ class ScalarExprEmitter : public StmtVisitor<ScalarExprEmitter, mlir::Value> {
     return {};
   }
 
+  mlir::Value VisitParenExpr(ParenExpr *pe) { return Visit(pe->getSubExpr()); }
+
   /// Emits the address of the l-value, then loads and returns the result.
   mlir::Value emitLoadOfLValue(const Expr *e) {
     LValue lv = cgf.emitLValue(e);
diff --git a/clang/lib/CIR/CodeGen/CIRGenFunction.cpp b/clang/lib/CIR/CodeGen/CIRGenFunction.cpp
index 9dace721e7417..76e9ca4fd61a8 100644
--- a/clang/lib/CIR/CodeGen/CIRGenFunction.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenFunction.cpp
@@ -515,6 +515,8 @@ LValue CIRGenFunction::emitLValue(const Expr *e) {
     return emitUnaryOpLValue(cast<UnaryOperator>(e));
   case Expr::BinaryOperatorClass:
     return emitBinaryOperatorLValue(cast<BinaryOperator>(e));
+  case Expr::ParenExprClass:
+    return emitLValue(cast<ParenExpr>(e)->getSubExpr());
   case Expr::DeclRefExprClass:
     return emitDeclRefLValue(cast<DeclRefExpr>(e));
   }
diff --git a/clang/test/CIR/CodeGen/basic.c b/clang/test/CIR/CodeGen/basic.c
index cf687e44044c4..8ce8106b0c6cc 100644
--- a/clang/test/CIR/CodeGen/basic.c
+++ b/clang/test/CIR/CodeGen/basic.c
@@ -169,3 +169,66 @@ int f6(void) {
 // OGCG-NEXT: entry:
 // OGCG-NEXT:   %[[GV:.*]] = load i32, ptr @gv, align 4
 // OGCG-NEXT:   ret i32 %[[GV]]
+
+int f7(int a, int b, int c) {
+  return a + (b + c);
+}
+
+// CIR: cir.func @f7
+// CIR:  %[[A_PTR:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["a", init]
+// CIR:  %[[B_PTR:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["b", init]
+// CIR:  %[[C_PTR:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["c", init]
+// CIR:  %[[A:.*]] = cir.load %[[A_PTR]] : !cir.ptr<!s32i>, !s32i
+// CIR:  %[[B:.*]] = cir.load %[[B_PTR]] : !cir.ptr<!s32i>, !s32i
+// CIR:  %[[C:.*]] = cir.load %[[C_PTR]] : !cir.ptr<!s32i>, !s32i
+// CIR:  %[[B_PLUS_C:.*]] = cir.binop(add, %[[B]], %[[C]]) nsw : !s32i
+// CIR:  %[[RETVAL:.*]] = cir.binop(add, %[[A]], %[[B_PLUS_C]]) nsw : !s32i
+
+// LLVM: define i32 @f7
+// LLVM:   %[[A_PTR:.*]] = alloca i32, i64 1, align 4
+// LLVM:   %[[B_PTR:.*]] = alloca i32, i64 1, align 4
+// LLVM:   %[[C_PTR:.*]] = alloca i32, i64 1, align 4
+// LLVM:   %[[A:.*]] = load i32, ptr %[[A_PTR]], align 4
+// LLVM:   %[[B:.*]] = load i32, ptr %[[B_PTR]], align 4
+// LLVM:   %[[C:.*]] = load i32, ptr %[[C_PTR]], align 4
+// LLVM:   %[[B_PLUS_C:.*]] = add nsw i32 %[[B]], %[[C]]
+// LLVM:   %[[RETVAL:.*]] = add nsw i32 %[[A]], %[[B_PLUS_C]]
+
+// OGCG: define{{.*}} i32 @f7
+// OGCG: entry:
+// OGCG:   %[[A_PTR:.*]] = alloca i32, align 4
+// OGCG:   %[[B_PTR:.*]] = alloca i32, align 4
+// OGCG:   %[[C_PTR:.*]] = alloca i32, align 4
+// OGCG:   %[[A:.*]] = load i32, ptr %[[A_PTR]], align 4
+// OGCG:   %[[B:.*]] = load i32, ptr %[[B_PTR]], align 4
+// OGCG:   %[[C:.*]] = load i32, ptr %[[C_PTR]], align 4
+// OGCG:   %[[B_PLUS_C:.*]] = add nsw i32 %[[B]], %[[C]]
+// OGCG:   %[[RETVAL:.*]] = add nsw i32 %[[A]], %[[B_PLUS_C]]
+
+int f8(int *p) {
+  (*p) = 2;
+  return (*p);
+}
+
+// CIR: cir.func @f8
+// CIR:    %[[P_PTR:.*]] = cir.alloca !cir.ptr<!s32i>, !cir.ptr<!cir.ptr<!s32i>>, ["p", init]
+// CIR:    %[[TWO:.*]] = cir.const #cir.int<2> : !s32i
+// CIR:    %[[P:.*]] = cir.load deref %[[P_PTR]] : !cir.ptr<!cir.ptr<!s32i>>, !cir.ptr<!s32i>
+// CIR:    cir.store %[[TWO]], %[[P]] : !s32i, !cir.ptr<!s32i>
+// CIR:    %[[P2:.*]] = cir.load deref %[[P_PTR]] : !cir.ptr<!cir.ptr<!s32i>>, !cir.ptr<!s32i>
+// CIR:    %[[STAR_P:.*]] = cir.load %[[P2]] : !cir.ptr<!s32i>, !s32i
+
+// LLVM: define i32 @f8
+// LLVM:   %[[P_PTR:.*]] = alloca ptr, i64 1, align 8
+// LLVM:   %[[P:.*]] = load ptr, ptr %[[P_PTR]], align 8
+// LLVM:   store i32 2, ptr %[[P]], align 4
+// LLVM:   %[[P2:.*]] = load ptr, ptr %[[P_PTR]], align 8
+// LLVM:   %[[STAR_P:.*]] = load i32, ptr %[[P2]], align 4
+
+// OGCG: define{{.*}} i32 @f8
+// OGCG: entry:
+// OGCG:   %[[P_PTR:.*]] = alloca ptr, align 8
+// OGCG:   %[[P:.*]] = load ptr, ptr %[[P_PTR]], align 8
+// OGCG:   store i32 2, ptr %[[P]], align 4
+// OGCG:   %[[P2:.*]] = load ptr, ptr %[[P_PTR]], align 8
+// OGCG:   %[[STAR_P:.*]] = load i32, ptr %[[P2]], align 4

@andykaylor andykaylor merged commit 7c51e42 into llvm:main Apr 18, 2025
14 checks passed
@andykaylor andykaylor deleted the cir-paren branch April 18, 2025 18:25
IanWood1 pushed a commit to IanWood1/llvm-project that referenced this pull request May 6, 2025
This change adds support for handling ParenExpr in scalar expressions. A
few more places will need to be updated after structure assignment and
complex type support is in place.
IanWood1 pushed a commit to IanWood1/llvm-project that referenced this pull request May 6, 2025
This change adds support for handling ParenExpr in scalar expressions. A
few more places will need to be updated after structure assignment and
complex type support is in place.
IanWood1 pushed a commit to IanWood1/llvm-project that referenced this pull request May 6, 2025
This change adds support for handling ParenExpr in scalar expressions. A
few more places will need to be updated after structure assignment and
complex type support is in place.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang Clang issues not falling into any other category ClangIR Anything related to the ClangIR project
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants