https://github.com/andykaylor created 
https://github.com/llvm/llvm-project/pull/136332

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.

>From 15a892df17d7d2fcd3232209ce7091d68182e095 Mon Sep 17 00:00:00 2001
From: Andy Kaylor <akay...@nvidia.com>
Date: Tue, 15 Apr 2025 17:41:06 -0700
Subject: [PATCH] [CIR] Upstream scalar support for ParenExpr

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.
---
 clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp |  2 +
 clang/lib/CIR/CodeGen/CIRGenFunction.cpp   |  2 +
 clang/test/CIR/CodeGen/basic.c             | 63 ++++++++++++++++++++++
 3 files changed, 67 insertions(+)

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

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to