[clang] [CIR] Upstream support for emitting ignored statements (PR #130869)
Andy Kaylor via cfe-commits
cfe-commits at lists.llvm.org
Wed Mar 12 13:09:30 PDT 2025
https://github.com/andykaylor updated https://github.com/llvm/llvm-project/pull/130869
>From a4e8aa13f97a6c73389822f6fdcf6f5970792462 Mon Sep 17 00:00:00 2001
From: Andy Kaylor <akaylor at nvidia.com>
Date: Tue, 11 Mar 2025 17:01:44 -0700
Subject: [PATCH 1/5] [CIR] Upstream support for emitting ignored statements
This adds support for emitting ClangIR for statements whose value
is ignored. The test case being added (CIR/CodeGen/basic.c) tests
a few more things. The "f1" test case is the only part that's
immediately relevant to this change, but the other cases were
part of the same test in the incubator and they are supported so
I brought in the entire test.
---
clang/include/clang/CIR/MissingFeatures.h | 1 +
clang/lib/CIR/CodeGen/CIRGenExpr.cpp | 27 ++++
clang/lib/CIR/CodeGen/CIRGenFunction.h | 10 ++
clang/lib/CIR/CodeGen/CIRGenStmt.cpp | 152 +++++++++++++++++++++-
clang/test/CIR/CodeGen/basic.c | 53 ++++++++
5 files changed, 239 insertions(+), 4 deletions(-)
create mode 100644 clang/test/CIR/CodeGen/basic.c
diff --git a/clang/include/clang/CIR/MissingFeatures.h b/clang/include/clang/CIR/MissingFeatures.h
index ddfe654009644..e8d3eff79d0b2 100644
--- a/clang/include/clang/CIR/MissingFeatures.h
+++ b/clang/include/clang/CIR/MissingFeatures.h
@@ -83,6 +83,7 @@ struct MissingFeatures {
static bool emitNullabilityCheck() { return false; }
static bool astVarDeclInterface() { return false; }
static bool stackSaveOp() { return false; }
+ static bool aggValueSlot() { return false; }
};
} // namespace cir
diff --git a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
index 07fb4cf8f1513..a33aa45f8a4fc 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
@@ -165,6 +165,33 @@ LValue CIRGenFunction::emitDeclRefLValue(const DeclRefExpr *e) {
return LValue();
}
+/// Emit code to compute the specified expression which
+/// can have any type. The result is returned as an RValue struct.
+RValue CIRGenFunction::emitAnyExpr(const Expr *e, bool ignoreResult) {
+ switch (CIRGenFunction::getEvaluationKind(e->getType())) {
+ case cir::TEK_Scalar:
+ return RValue::get(emitScalarExpr(e));
+ case cir::TEK_Complex:
+ cgm.errorNYI(e->getSourceRange(), "emitAnyExpr: complex type");
+ return RValue::get(nullptr);
+ case cir::TEK_Aggregate:
+ cgm.errorNYI(e->getSourceRange(), "emitAnyExpr: aggregate type");
+ return RValue::get(nullptr);
+ }
+ llvm_unreachable("bad evaluation kind");
+}
+
+/// Emit code to compute the specified expression, ignoring the result.
+void CIRGenFunction::emitIgnoredExpr(const Expr *e) {
+ if (e->isPRValue()) {
+ assert(!cir::MissingFeatures::aggValueSlot());
+ return (void)emitAnyExpr(e, true);
+ }
+
+ // Just emit it as an l-value and drop the result.
+ emitLValue(e);
+}
+
mlir::Value CIRGenFunction::emitAlloca(StringRef name, mlir::Type ty,
mlir::Location loc,
CharUnits alignment) {
diff --git a/clang/lib/CIR/CodeGen/CIRGenFunction.h b/clang/lib/CIR/CodeGen/CIRGenFunction.h
index 72445f62232a4..ddb1c1c5dd229 100644
--- a/clang/lib/CIR/CodeGen/CIRGenFunction.h
+++ b/clang/lib/CIR/CodeGen/CIRGenFunction.h
@@ -154,6 +154,12 @@ class CIRGenFunction : public CIRGenTypeCache {
const clang::LangOptions &getLangOpts() const { return cgm.getLangOpts(); }
+ /// Emit code to compute the specified expression which can have any type. The
+ /// result is returned as an RValue struct. If this is an aggregate
+ /// expression, the aggloc/agglocvolatile arguments indicate where the result
+ /// should be returned.
+ RValue emitAnyExpr(const clang::Expr *e, bool ignoreResult = false);
+
void finishFunction(SourceLocation endLoc);
mlir::LogicalResult emitFunctionBody(const clang::Stmt *body);
@@ -170,6 +176,10 @@ class CIRGenFunction : public CIRGenTypeCache {
void emitCompoundStmtWithoutScope(const clang::CompoundStmt &s);
+ /// Emit code to compute the specified expression,
+ /// ignoring the result.
+ void emitIgnoredExpr(const clang::Expr *e);
+
mlir::LogicalResult emitDeclStmt(const clang::DeclStmt &s);
mlir::LogicalResult emitReturnStmt(const clang::ReturnStmt &s);
diff --git a/clang/lib/CIR/CodeGen/CIRGenStmt.cpp b/clang/lib/CIR/CodeGen/CIRGenStmt.cpp
index ed5d87a39704a..91627d5d5985a 100644
--- a/clang/lib/CIR/CodeGen/CIRGenStmt.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenStmt.cpp
@@ -55,10 +55,154 @@ mlir::LogicalResult CIRGenFunction::emitStmt(const Stmt *s,
if (mlir::succeeded(emitSimpleStmt(s, useCurrentScope)))
return mlir::success();
- // Only a subset of simple statements are supported at the moment. When more
- // kinds of statements are supported, a
- // switch (s->getStmtClass()) {
- // will be added here.
+ switch (s->getStmtClass()) {
+
+#define STMT(Type, Base)
+#define ABSTRACT_STMT(Op)
+#define EXPR(Type, Base) case Stmt::Type##Class:
+#include "clang/AST/StmtNodes.inc"
+ {
+ // Remember the block we came in on.
+ mlir::Block *incoming = builder.getInsertionBlock();
+ assert(incoming && "expression emission must have an insertion point");
+
+ emitIgnoredExpr(cast<Expr>(s));
+
+ mlir::Block *outgoing = builder.getInsertionBlock();
+ assert(outgoing && "expression emission cleared block!");
+ return mlir::success();
+ }
+
+ case Stmt::OMPScopeDirectiveClass:
+ case Stmt::OMPErrorDirectiveClass:
+ case Stmt::NoStmtClass:
+ case Stmt::CXXCatchStmtClass:
+ case Stmt::SEHExceptStmtClass:
+ case Stmt::SEHFinallyStmtClass:
+ case Stmt::MSDependentExistsStmtClass:
+ case Stmt::NullStmtClass:
+ case Stmt::CompoundStmtClass:
+ case Stmt::DeclStmtClass:
+ case Stmt::LabelStmtClass:
+ case Stmt::AttributedStmtClass:
+ case Stmt::GotoStmtClass:
+ case Stmt::BreakStmtClass:
+ case Stmt::ContinueStmtClass:
+ case Stmt::DefaultStmtClass:
+ case Stmt::CaseStmtClass:
+ case Stmt::SEHLeaveStmtClass:
+ case Stmt::SYCLKernelCallStmtClass:
+ case Stmt::IfStmtClass:
+ case Stmt::SwitchStmtClass:
+ case Stmt::ForStmtClass:
+ case Stmt::WhileStmtClass:
+ case Stmt::DoStmtClass:
+ case Stmt::CoroutineBodyStmtClass:
+ case Stmt::CoreturnStmtClass:
+ case Stmt::CXXTryStmtClass:
+ case Stmt::CXXForRangeStmtClass:
+ case Stmt::IndirectGotoStmtClass:
+ case Stmt::ReturnStmtClass:
+ case Stmt::GCCAsmStmtClass:
+ case Stmt::MSAsmStmtClass:
+ case Stmt::OMPParallelDirectiveClass:
+ case Stmt::OMPTaskwaitDirectiveClass:
+ case Stmt::OMPTaskyieldDirectiveClass:
+ case Stmt::OMPBarrierDirectiveClass:
+ case Stmt::CapturedStmtClass:
+ case Stmt::ObjCAtTryStmtClass:
+ case Stmt::ObjCAtThrowStmtClass:
+ case Stmt::ObjCAtSynchronizedStmtClass:
+ case Stmt::ObjCForCollectionStmtClass:
+ case Stmt::ObjCAutoreleasePoolStmtClass:
+ case Stmt::SEHTryStmtClass:
+ case Stmt::OMPMetaDirectiveClass:
+ case Stmt::OMPCanonicalLoopClass:
+ case Stmt::OMPSimdDirectiveClass:
+ case Stmt::OMPTileDirectiveClass:
+ case Stmt::OMPUnrollDirectiveClass:
+ case Stmt::OMPForDirectiveClass:
+ case Stmt::OMPForSimdDirectiveClass:
+ case Stmt::OMPSectionsDirectiveClass:
+ case Stmt::OMPSectionDirectiveClass:
+ case Stmt::OMPSingleDirectiveClass:
+ case Stmt::OMPMasterDirectiveClass:
+ case Stmt::OMPCriticalDirectiveClass:
+ case Stmt::OMPParallelForDirectiveClass:
+ case Stmt::OMPParallelForSimdDirectiveClass:
+ case Stmt::OMPParallelMasterDirectiveClass:
+ case Stmt::OMPParallelSectionsDirectiveClass:
+ case Stmt::OMPTaskDirectiveClass:
+ case Stmt::OMPTaskgroupDirectiveClass:
+ case Stmt::OMPFlushDirectiveClass:
+ case Stmt::OMPDepobjDirectiveClass:
+ case Stmt::OMPScanDirectiveClass:
+ case Stmt::OMPOrderedDirectiveClass:
+ case Stmt::OMPAtomicDirectiveClass:
+ case Stmt::OMPTargetDirectiveClass:
+ case Stmt::OMPTeamsDirectiveClass:
+ case Stmt::OMPCancellationPointDirectiveClass:
+ case Stmt::OMPCancelDirectiveClass:
+ case Stmt::OMPTargetDataDirectiveClass:
+ case Stmt::OMPTargetEnterDataDirectiveClass:
+ case Stmt::OMPTargetExitDataDirectiveClass:
+ case Stmt::OMPTargetParallelDirectiveClass:
+ case Stmt::OMPTargetParallelForDirectiveClass:
+ case Stmt::OMPTaskLoopDirectiveClass:
+ case Stmt::OMPTaskLoopSimdDirectiveClass:
+ case Stmt::OMPMaskedTaskLoopDirectiveClass:
+ case Stmt::OMPMaskedTaskLoopSimdDirectiveClass:
+ case Stmt::OMPMasterTaskLoopDirectiveClass:
+ case Stmt::OMPMasterTaskLoopSimdDirectiveClass:
+ case Stmt::OMPParallelGenericLoopDirectiveClass:
+ case Stmt::OMPParallelMaskedDirectiveClass:
+ case Stmt::OMPParallelMaskedTaskLoopDirectiveClass:
+ case Stmt::OMPParallelMaskedTaskLoopSimdDirectiveClass:
+ case Stmt::OMPParallelMasterTaskLoopDirectiveClass:
+ case Stmt::OMPParallelMasterTaskLoopSimdDirectiveClass:
+ case Stmt::OMPDistributeDirectiveClass:
+ case Stmt::OMPDistributeParallelForDirectiveClass:
+ case Stmt::OMPDistributeParallelForSimdDirectiveClass:
+ case Stmt::OMPDistributeSimdDirectiveClass:
+ case Stmt::OMPTargetParallelGenericLoopDirectiveClass:
+ case Stmt::OMPTargetParallelForSimdDirectiveClass:
+ case Stmt::OMPTargetSimdDirectiveClass:
+ case Stmt::OMPTargetTeamsGenericLoopDirectiveClass:
+ case Stmt::OMPTargetUpdateDirectiveClass:
+ case Stmt::OMPTeamsDistributeDirectiveClass:
+ case Stmt::OMPTeamsDistributeSimdDirectiveClass:
+ case Stmt::OMPTeamsDistributeParallelForSimdDirectiveClass:
+ case Stmt::OMPTeamsDistributeParallelForDirectiveClass:
+ case Stmt::OMPTeamsGenericLoopDirectiveClass:
+ case Stmt::OMPTargetTeamsDirectiveClass:
+ case Stmt::OMPTargetTeamsDistributeDirectiveClass:
+ case Stmt::OMPTargetTeamsDistributeParallelForDirectiveClass:
+ case Stmt::OMPTargetTeamsDistributeParallelForSimdDirectiveClass:
+ case Stmt::OMPTargetTeamsDistributeSimdDirectiveClass:
+ case Stmt::OMPInteropDirectiveClass:
+ case Stmt::OMPDispatchDirectiveClass:
+ case Stmt::OMPGenericLoopDirectiveClass:
+ case Stmt::OMPReverseDirectiveClass:
+ case Stmt::OMPInterchangeDirectiveClass:
+ case Stmt::OMPAssumeDirectiveClass:
+ case Stmt::OMPMaskedDirectiveClass:
+ case Stmt::OpenACCComputeConstructClass:
+ case Stmt::OpenACCLoopConstructClass:
+ case Stmt::OpenACCCombinedConstructClass:
+ case Stmt::OpenACCDataConstructClass:
+ case Stmt::OpenACCEnterDataConstructClass:
+ case Stmt::OpenACCExitDataConstructClass:
+ case Stmt::OpenACCHostDataConstructClass:
+ case Stmt::OpenACCWaitConstructClass:
+ case Stmt::OpenACCInitConstructClass:
+ case Stmt::OpenACCShutdownConstructClass:
+ case Stmt::OpenACCSetConstructClass:
+ case Stmt::OpenACCUpdateConstructClass:
+ case Stmt::ObjCAtCatchStmtClass:
+ case Stmt::ObjCAtFinallyStmtClass:
+ cgm.errorNYI(s->getSourceRange(),
+ std::string("emitStmt: ") + s->getStmtClassName());
+ }
return mlir::failure();
}
diff --git a/clang/test/CIR/CodeGen/basic.c b/clang/test/CIR/CodeGen/basic.c
new file mode 100644
index 0000000000000..8d067aefded66
--- /dev/null
+++ b/clang/test/CIR/CodeGen/basic.c
@@ -0,0 +1,53 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -Wno-unused-value -fclangir -emit-cir %s -o %t.cir
+// RUN: FileCheck --input-file=%t.cir %s -check-prefix=CIR
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -Wno-unused-value -fclangir -emit-llvm %s -o %t.ll
+// RUN: FileCheck --input-file=%t.ll %s -check-prefix=LLVM
+
+int f1(int i);
+
+int f1(int i) {
+ i;
+ return i;
+}
+
+// CIR: module
+// CIR-NEXT: cir.func @f1(%arg0: !cir.int<s, 32> loc({{.*}})) -> !cir.int<s, 32>
+// CIR-NEXT: %[[I_PTR:.*]] = cir.alloca !cir.int<s, 32>, !cir.ptr<!cir.int<s, 32>>, ["i", init] {alignment = 4 : i64}
+// CIR-NEXT: cir.store %arg0, %[[I_PTR]] : !cir.int<s, 32>, !cir.ptr<!cir.int<s, 32>>
+// CIR-NEXT: %[[I_IGNORED:.*]] = cir.load %[[I_PTR]] : !cir.ptr<!cir.int<s, 32>>, !cir.int<s, 32>
+// CIR-NEXT: %[[I:.*]] = cir.load %[[I_PTR]] : !cir.ptr<!cir.int<s, 32>>, !cir.int<s, 32>
+// CIR-NEXT: cir.return %[[I]] : !cir.int<s, 32>
+
+// LLVM: define i32 @f1(i32 %[[I:.*]])
+// LLVM-NEXT: %[[I_PTR:.*]] = alloca i32, i64 1, align 4
+// LLVM-NEXT: store i32 %[[I]], ptr %[[I_PTR]], align 4
+// LLVM-NEXT: %[[I_IGNORED:.*]] = load i32, ptr %[[I_PTR]], align 4
+// LLVM-NEXT: %[[I:.*]] = load i32, ptr %[[I_PTR]], align 4
+// LLVM-NEXT: ret i32 %[[I]]
+
+int f2(void) { return 3; }
+
+// CIR: cir.func @f2() -> !cir.int<s, 32>
+// CIR-NEXT: %[[THREE:.*]] = cir.const #cir.int<3> : !cir.int<s, 32>
+// CIR-NEXT: cir.return %[[THREE]] : !cir.int<s, 32>
+
+// LLVM: define i32 @f2()
+// LLVM-NEXT: ret i32 3
+
+int f3(void) {
+ int i = 3;
+ return i;
+}
+
+// CIR: cir.func @f3() -> !cir.int<s, 32>
+// CIR-NEXT: %[[I_PTR:.*]] = cir.alloca !cir.int<s, 32>, !cir.ptr<!cir.int<s, 32>>, ["i", init] {alignment = 4 : i64}
+// CIR-NEXT: %[[THREE:.*]] = cir.const #cir.int<3> : !cir.int<s, 32>
+// CIR-NEXT: cir.store %[[THREE]], %[[I_PTR]] : !cir.int<s, 32>, !cir.ptr<!cir.int<s, 32>>
+// CIR-NEXT: %[[I:.*]] = cir.load %[[I_PTR]] : !cir.ptr<!cir.int<s, 32>>, !cir.int<s, 32>
+// CIR-NEXT: cir.return %[[I]] : !cir.int<s, 32>
+
+// LLVM: define i32 @f3()
+// LLVM-NEXT: %[[I_PTR:.*]] = alloca i32, i64 1, align 4
+// LLVM-NEXT: store i32 3, ptr %[[I_PTR]], align 4
+// LLVM-NEXT: %[[I:.*]] = load i32, ptr %[[I_PTR]], align 4
+// LLVM-NEXT: ret i32 %[[I]]
>From cf692675df6f83a0b799666e5bd637ee8d7e7188 Mon Sep 17 00:00:00 2001
From: Andy Kaylor <akaylor at nvidia.com>
Date: Wed, 12 Mar 2025 11:45:37 -0700
Subject: [PATCH 2/5] Add test checks for classic codegen, minor cleanup
---
clang/lib/CIR/CodeGen/CIRGenExpr.cpp | 3 ++-
clang/lib/CIR/CodeGen/CIRGenStmt.cpp | 7 ++++++-
clang/test/CIR/CodeGen/basic.c | 25 +++++++++++++++++++++++--
3 files changed, 31 insertions(+), 4 deletions(-)
diff --git a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
index a33aa45f8a4fc..2d9ec41452a9d 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
@@ -185,7 +185,8 @@ RValue CIRGenFunction::emitAnyExpr(const Expr *e, bool ignoreResult) {
void CIRGenFunction::emitIgnoredExpr(const Expr *e) {
if (e->isPRValue()) {
assert(!cir::MissingFeatures::aggValueSlot());
- return (void)emitAnyExpr(e, true);
+ emitAnyExpr(e, true);
+ return;
}
// Just emit it as an l-value and drop the result.
diff --git a/clang/lib/CIR/CodeGen/CIRGenStmt.cpp b/clang/lib/CIR/CodeGen/CIRGenStmt.cpp
index 91627d5d5985a..d4476a5e9fa17 100644
--- a/clang/lib/CIR/CodeGen/CIRGenStmt.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenStmt.cpp
@@ -186,6 +186,7 @@ mlir::LogicalResult CIRGenFunction::emitStmt(const Stmt *s,
case Stmt::OMPInterchangeDirectiveClass:
case Stmt::OMPAssumeDirectiveClass:
case Stmt::OMPMaskedDirectiveClass:
+ case Stmt::OMPStripeDirectiveClass:
case Stmt::OpenACCComputeConstructClass:
case Stmt::OpenACCLoopConstructClass:
case Stmt::OpenACCCombinedConstructClass:
@@ -198,12 +199,16 @@ mlir::LogicalResult CIRGenFunction::emitStmt(const Stmt *s,
case Stmt::OpenACCShutdownConstructClass:
case Stmt::OpenACCSetConstructClass:
case Stmt::OpenACCUpdateConstructClass:
+ case Stmt::OpenACCCacheConstructClass:
+ case Stmt::OpenACCAtomicConstructClass:
case Stmt::ObjCAtCatchStmtClass:
case Stmt::ObjCAtFinallyStmtClass:
cgm.errorNYI(s->getSourceRange(),
std::string("emitStmt: ") + s->getStmtClassName());
+ return mlir::failure();
}
- return mlir::failure();
+
+ llvm_unreachable("Unexpected statement class");
}
mlir::LogicalResult CIRGenFunction::emitSimpleStmt(const Stmt *s,
diff --git a/clang/test/CIR/CodeGen/basic.c b/clang/test/CIR/CodeGen/basic.c
index 8d067aefded66..754f11f1361ba 100644
--- a/clang/test/CIR/CodeGen/basic.c
+++ b/clang/test/CIR/CodeGen/basic.c
@@ -1,7 +1,9 @@
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -Wno-unused-value -fclangir -emit-cir %s -o %t.cir
// RUN: FileCheck --input-file=%t.cir %s -check-prefix=CIR
-// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -Wno-unused-value -fclangir -emit-llvm %s -o %t.ll
-// RUN: FileCheck --input-file=%t.ll %s -check-prefix=LLVM
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -Wno-unused-value -fclangir -emit-llvm %s -o %t-cir.ll
+// RUN: FileCheck --input-file=%t-cir.ll %s -check-prefix=LLVM
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -Wno-unused-value -emit-llvm %s -o %t.ll
+// RUN: FileCheck --input-file=%t.ll %s -check-prefix=OGCG
int f1(int i);
@@ -25,6 +27,14 @@ int f1(int i) {
// LLVM-NEXT: %[[I:.*]] = load i32, ptr %[[I_PTR]], align 4
// LLVM-NEXT: ret i32 %[[I]]
+// OGCG: define{{.*}} i32 @f1(i32 noundef %[[I:.*]])
+// OGCG-NEXT: entry:
+// OGCG-NEXT: %[[I_PTR:.*]] = alloca i32, align 4
+// OGCG-NEXT: store i32 %[[I]], ptr %[[I_PTR]], align 4
+// OGCG-NEXT: %[[I_IGNORED:.*]] = load i32, ptr %[[I_PTR]], align 4
+// OGCG-NEXT: %[[I:.*]] = load i32, ptr %[[I_PTR]], align 4
+// OGCG-NEXT: ret i32 %[[I]]
+
int f2(void) { return 3; }
// CIR: cir.func @f2() -> !cir.int<s, 32>
@@ -34,6 +44,10 @@ int f2(void) { return 3; }
// LLVM: define i32 @f2()
// LLVM-NEXT: ret i32 3
+// OGCG: define{{.*}} i32 @f2()
+// OGCG-NEXT: entry:
+// OGCG-NEXT: ret i32 3
+
int f3(void) {
int i = 3;
return i;
@@ -51,3 +65,10 @@ int f3(void) {
// LLVM-NEXT: store i32 3, ptr %[[I_PTR]], align 4
// LLVM-NEXT: %[[I:.*]] = load i32, ptr %[[I_PTR]], align 4
// LLVM-NEXT: ret i32 %[[I]]
+
+// OGCG: define{{.*}} i32 @f3
+// OGCG-NEXT: entry:
+// OGCG-NEXT: %[[I_PTR:.*]] = alloca i32, align 4
+// OGCG-NEXT: store i32 3, ptr %[[I_PTR]], align 4
+// OGCG-NEXT: %[[I:.*]] = load i32, ptr %[[I_PTR]], align 4
+// OGCG-NEXT: ret i32 %[[I]]
>From 2b37483e380b1c7ac2c9b39814f39a2957706e94 Mon Sep 17 00:00:00 2001
From: Andy Kaylor <akaylor at nvidia.com>
Date: Wed, 12 Mar 2025 11:59:45 -0700
Subject: [PATCH 3/5] Stop using intermediate files for lit test
---
clang/test/CIR/CodeGen/basic.c | 9 +++------
1 file changed, 3 insertions(+), 6 deletions(-)
diff --git a/clang/test/CIR/CodeGen/basic.c b/clang/test/CIR/CodeGen/basic.c
index 754f11f1361ba..7ae3bcbd79cb8 100644
--- a/clang/test/CIR/CodeGen/basic.c
+++ b/clang/test/CIR/CodeGen/basic.c
@@ -1,9 +1,6 @@
-// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -Wno-unused-value -fclangir -emit-cir %s -o %t.cir
-// RUN: FileCheck --input-file=%t.cir %s -check-prefix=CIR
-// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -Wno-unused-value -fclangir -emit-llvm %s -o %t-cir.ll
-// RUN: FileCheck --input-file=%t-cir.ll %s -check-prefix=LLVM
-// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -Wno-unused-value -emit-llvm %s -o %t.ll
-// RUN: FileCheck --input-file=%t.ll %s -check-prefix=OGCG
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -Wno-unused-value -fclangir -emit-cir %s -o - | FileCheck %s -check-prefix=CIR
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -Wno-unused-value -fclangir -emit-llvm %s -o - | FileCheck %s -check-prefix=LLVM
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -Wno-unused-value -emit-llvm %s -o - | FileCheck %s -check-prefix=OGCG
int f1(int i);
>From bff3185894f3cb4f08e960a8dde83d105cb83f57 Mon Sep 17 00:00:00 2001
From: Andy Kaylor <akaylor at nvidia.com>
Date: Wed, 12 Mar 2025 12:57:45 -0700
Subject: [PATCH 4/5] Return to using intermediate files for lit test
---
clang/test/CIR/CodeGen/basic.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/clang/test/CIR/CodeGen/basic.c b/clang/test/CIR/CodeGen/basic.c
index 7ae3bcbd79cb8..754f11f1361ba 100644
--- a/clang/test/CIR/CodeGen/basic.c
+++ b/clang/test/CIR/CodeGen/basic.c
@@ -1,6 +1,9 @@
-// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -Wno-unused-value -fclangir -emit-cir %s -o - | FileCheck %s -check-prefix=CIR
-// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -Wno-unused-value -fclangir -emit-llvm %s -o - | FileCheck %s -check-prefix=LLVM
-// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -Wno-unused-value -emit-llvm %s -o - | FileCheck %s -check-prefix=OGCG
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -Wno-unused-value -fclangir -emit-cir %s -o %t.cir
+// RUN: FileCheck --input-file=%t.cir %s -check-prefix=CIR
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -Wno-unused-value -fclangir -emit-llvm %s -o %t-cir.ll
+// RUN: FileCheck --input-file=%t-cir.ll %s -check-prefix=LLVM
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -Wno-unused-value -emit-llvm %s -o %t.ll
+// RUN: FileCheck --input-file=%t.ll %s -check-prefix=OGCG
int f1(int i);
>From 7434462453bb7f4a5d723db786d9ee47c6d8ac5b Mon Sep 17 00:00:00 2001
From: Andy Kaylor <akaylor at nvidia.com>
Date: Wed, 12 Mar 2025 13:08:37 -0700
Subject: [PATCH 5/5] Remove unused argument to emitAnyExpr, address a TODO
comment
---
clang/lib/CIR/CodeGen/CIRGenExpr.cpp | 4 ++--
clang/lib/CIR/CodeGen/CIRGenFunction.h | 2 +-
clang/lib/CIR/CodeGen/CIRGenStmt.cpp | 13 ++++---------
3 files changed, 7 insertions(+), 12 deletions(-)
diff --git a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
index 2d9ec41452a9d..5b81fe172e645 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
@@ -167,7 +167,7 @@ LValue CIRGenFunction::emitDeclRefLValue(const DeclRefExpr *e) {
/// Emit code to compute the specified expression which
/// can have any type. The result is returned as an RValue struct.
-RValue CIRGenFunction::emitAnyExpr(const Expr *e, bool ignoreResult) {
+RValue CIRGenFunction::emitAnyExpr(const Expr *e) {
switch (CIRGenFunction::getEvaluationKind(e->getType())) {
case cir::TEK_Scalar:
return RValue::get(emitScalarExpr(e));
@@ -185,7 +185,7 @@ RValue CIRGenFunction::emitAnyExpr(const Expr *e, bool ignoreResult) {
void CIRGenFunction::emitIgnoredExpr(const Expr *e) {
if (e->isPRValue()) {
assert(!cir::MissingFeatures::aggValueSlot());
- emitAnyExpr(e, true);
+ emitAnyExpr(e);
return;
}
diff --git a/clang/lib/CIR/CodeGen/CIRGenFunction.h b/clang/lib/CIR/CodeGen/CIRGenFunction.h
index ddb1c1c5dd229..5ab882666f3e0 100644
--- a/clang/lib/CIR/CodeGen/CIRGenFunction.h
+++ b/clang/lib/CIR/CodeGen/CIRGenFunction.h
@@ -158,7 +158,7 @@ class CIRGenFunction : public CIRGenTypeCache {
/// result is returned as an RValue struct. If this is an aggregate
/// expression, the aggloc/agglocvolatile arguments indicate where the result
/// should be returned.
- RValue emitAnyExpr(const clang::Expr *e, bool ignoreResult = false);
+ RValue emitAnyExpr(const clang::Expr *e);
void finishFunction(SourceLocation endLoc);
mlir::LogicalResult emitFunctionBody(const clang::Stmt *body);
diff --git a/clang/lib/CIR/CodeGen/CIRGenStmt.cpp b/clang/lib/CIR/CodeGen/CIRGenStmt.cpp
index d4476a5e9fa17..7a38f9838b290 100644
--- a/clang/lib/CIR/CodeGen/CIRGenStmt.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenStmt.cpp
@@ -255,16 +255,11 @@ mlir::LogicalResult CIRGenFunction::emitReturnStmt(const ReturnStmt &s) {
// this section will do nothing. But for now a ReturnOp is necessary.
builder.create<ReturnOp>(loc);
} else if (rv->getType()->isVoidType()) {
- // No return value. Emit the return expression for its side effects.
- // TODO(CIR): Once emitAnyExpr(e) has been upstreamed, get rid of the check
- // and just call emitAnyExpr(rv) here.
- if (CIRGenFunction::hasScalarEvaluationKind(rv->getType())) {
- emitScalarExpr(rv);
- } else {
- getCIRGenModule().errorNYI(s.getSourceRange(),
- "non-scalar function return type");
+ // Make sure not to return anything, but evaluate the expression
+ // for side effects.
+ if (rv) {
+ emitAnyExpr(rv);
}
- builder.create<ReturnOp>(loc);
} else if (fnRetTy->isReferenceType()) {
getCIRGenModule().errorNYI(s.getSourceRange(),
"function return type that is a reference");
More information about the cfe-commits
mailing list