[clang] [CIR] Upstream support for emitting ignored statements (PR #130869)
https://github.com/erichkeane approved this pull request. 2 nits, else LGTM. https://github.com/llvm/llvm-project/pull/130869 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Upstream support for emitting ignored statements (PR #130869)
https://github.com/erichkeane edited https://github.com/llvm/llvm-project/pull/130869 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Upstream support for emitting ignored statements (PR #130869)
@@ -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 bcardosolopes wrote: The reason we've been doing that is solely making our lives as developers more efficient. I guess YMMV but whenever I'm investigating a test failure, it's very convenient not to have to pipe the output myself in a file and open in the editor, output is already there and gets updated automatically, etc - in VSCode it's specially handy, cause you click the output file name in the terminal and voila. Our idea is that whenever we hit a certain maturity state we'll probably bulk change those to use pipes instead, but they are still extremely useful on a daily basis. https://github.com/llvm/llvm-project/pull/130869 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Upstream support for emitting ignored statements (PR #130869)
@@ -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(s)); erichkeane wrote: StmtNodes.inc makes anything that inherits from `Expr` fall to this too. So it looks to me that `UnaryOperator` would hit this, plus just about everything else there. Perhaps we do a good job making sure we don't call `EmitStmt` with any other sort of expression? https://github.com/llvm/llvm-project/pull/130869 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Upstream support for emitting ignored statements (PR #130869)
https://github.com/andykaylor closed https://github.com/llvm/llvm-project/pull/130869 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Upstream support for emitting ignored statements (PR #130869)
https://github.com/bcardosolopes approved this pull request. https://github.com/llvm/llvm-project/pull/130869 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Upstream support for emitting ignored statements (PR #130869)
@@ -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 loc({{.*}})) -> !cir.int +// CIR-NEXT: %[[I_PTR:.*]] = cir.alloca !cir.int, !cir.ptr>, ["i", init] {alignment = 4 : i64} +// CIR-NEXT: cir.store %arg0, %[[I_PTR]] : !cir.int, !cir.ptr> +// CIR-NEXT: %[[I_IGNORED:.*]] = cir.load %[[I_PTR]] : !cir.ptr>, !cir.int +// CIR-NEXT: %[[I:.*]] = cir.load %[[I_PTR]] : !cir.ptr>, !cir.int +// CIR-NEXT: cir.return %[[I]] : !cir.int + +// LLVM: define i32 @f1(i32 %[[I:.*]]) bcardosolopes wrote: The more the merrier :) https://github.com/llvm/llvm-project/pull/130869 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Upstream support for emitting ignored statements (PR #130869)
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 Date: Tue, 11 Mar 2025 17:01:44 -0700 Subject: [PATCH 1/2] [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##Clas
[clang] [CIR] Upstream support for emitting ignored statements (PR #130869)
@@ -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); andykaylor wrote: Oh, yeah. I meant to split this out into separate call and return statements. I was actually a bit surprised that this even works. https://github.com/llvm/llvm-project/pull/130869 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Upstream support for emitting ignored statements (PR #130869)
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 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##Clas
[clang] [CIR] Upstream support for emitting ignored statements (PR #130869)
@@ -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 andykaylor wrote: I thought the intermediate files got automatically deleted. I can put this back to using the intermediate files. https://github.com/llvm/llvm-project/pull/130869 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Upstream support for emitting ignored statements (PR #130869)
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 Date: Tue, 11 Mar 2025 17:01:44 -0700 Subject: [PATCH 1/3] [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##Clas
[clang] [CIR] Upstream support for emitting ignored statements (PR #130869)
@@ -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 andykaylor wrote: Good point. I don't see any reason for that. https://github.com/llvm/llvm-project/pull/130869 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Upstream support for emitting ignored statements (PR #130869)
https://github.com/bcardosolopes edited https://github.com/llvm/llvm-project/pull/130869 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Upstream support for emitting ignored statements (PR #130869)
@@ -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); erichkeane wrote: I'd vastly prefer this not have a default argument https://github.com/llvm/llvm-project/pull/130869 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Upstream support for emitting ignored statements (PR #130869)
@@ -165,6 +165,34 @@ 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) { erichkeane wrote: is `ignoreResult` used anywhere?Might need a cast-to-void here to prevent diagnostics. https://github.com/llvm/llvm-project/pull/130869 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Upstream support for emitting ignored statements (PR #130869)
@@ -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 erichkeane wrote: Actually curious why these use an intermediary file instead of just a pipe? IIRC this ends up slowing the test down slightly. https://github.com/llvm/llvm-project/pull/130869 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Upstream support for emitting ignored statements (PR #130869)
@@ -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 loc({{.*}})) -> !cir.int +// CIR-NEXT: %[[I_PTR:.*]] = cir.alloca !cir.int, !cir.ptr>, ["i", init] {alignment = 4 : i64} +// CIR-NEXT: cir.store %arg0, %[[I_PTR]] : !cir.int, !cir.ptr> +// CIR-NEXT: %[[I_IGNORED:.*]] = cir.load %[[I_PTR]] : !cir.ptr>, !cir.int +// CIR-NEXT: %[[I:.*]] = cir.load %[[I_PTR]] : !cir.ptr>, !cir.int +// CIR-NEXT: cir.return %[[I]] : !cir.int + +// LLVM: define i32 @f1(i32 %[[I:.*]]) andykaylor wrote: Recording our discussion here for the benefit of those who weren't present, we agreed that although this will require a bit of extra work for each test, it will have at least two significant benefits: (1) it will allow reviewers to easily compare the LLVM IR generated via CIR to that generated by classic codegen, and (2) it will alert us via a failed test when something changes in the classic codegen that we might also want to consider in the CIR path. Conclusion: yes, this is worth doing. https://github.com/llvm/llvm-project/pull/130869 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Upstream support for emitting ignored statements (PR #130869)
https://github.com/erichkeane approved this pull request. Would be neat if the IR test was: ->CIR ->CIR->LLVM AND ->LLVM it sets the precedent for our 'future' and makes it easier to have a test form of the "converted" tests later, and makes it easier to review for correctness, but I'm willing ot let the group discuss it. Else, I'm good with this. https://github.com/llvm/llvm-project/pull/130869 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Upstream support for emitting ignored statements (PR #130869)
@@ -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(s)); erichkeane wrote: OH, wait, I see it now. The point is that this is an expression that _IS_ ignored, meaning we're not doing anything with the result. So this is appropriate for any expression where its return value/result/etc isn't dealt with. https://github.com/llvm/llvm-project/pull/130869 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Upstream support for emitting ignored statements (PR #130869)
@@ -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 loc({{.*}})) -> !cir.int +// CIR-NEXT: %[[I_PTR:.*]] = cir.alloca !cir.int, !cir.ptr>, ["i", init] {alignment = 4 : i64} +// CIR-NEXT: cir.store %arg0, %[[I_PTR]] : !cir.int, !cir.ptr> +// CIR-NEXT: %[[I_IGNORED:.*]] = cir.load %[[I_PTR]] : !cir.ptr>, !cir.int +// CIR-NEXT: %[[I:.*]] = cir.load %[[I_PTR]] : !cir.ptr>, !cir.int +// CIR-NEXT: cir.return %[[I]] : !cir.int + +// LLVM: define i32 @f1(i32 %[[I:.*]]) erichkeane wrote: would be neat if we had all 3? WDYT? https://github.com/llvm/llvm-project/pull/130869 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Upstream support for emitting ignored statements (PR #130869)
@@ -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(s)); andykaylor wrote: Yes, this is far from obvious. StmtNodes.inc uses a system of macros and preprocessors statements, so when it is included what you get for each one is somewhat determined by which of the macros the client has defined. In this case, we're getting expressions that are neither statements or abstract statements (because we define STMT and ABSTRACT_STMT but do nothing with them). The exact list, of course, depends on what's in StmtNodes.td and how things are defined there. FWIW, this matches the handling in the classic codegen (https://github.com/llvm/llvm-project/blob/1a626e63b5a009075eea87c01f0661144b1ec010/clang/lib/CodeGen/CGStmt.cpp#L130). https://github.com/llvm/llvm-project/pull/130869 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Upstream support for emitting ignored statements (PR #130869)
@@ -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 loc({{.*}})) -> !cir.int +// CIR-NEXT: %[[I_PTR:.*]] = cir.alloca !cir.int, !cir.ptr>, ["i", init] {alignment = 4 : i64} +// CIR-NEXT: cir.store %arg0, %[[I_PTR]] : !cir.int, !cir.ptr> +// CIR-NEXT: %[[I_IGNORED:.*]] = cir.load %[[I_PTR]] : !cir.ptr>, !cir.int +// CIR-NEXT: %[[I:.*]] = cir.load %[[I_PTR]] : !cir.ptr>, !cir.int +// CIR-NEXT: cir.return %[[I]] : !cir.int + +// LLVM: define i32 @f1(i32 %[[I:.*]]) andykaylor wrote: That's lowering through clangir to llvm ir. https://github.com/llvm/llvm-project/pull/130869 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Upstream support for emitting ignored statements (PR #130869)
@@ -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(s)); erichkeane wrote: Can you explain what is happening here? We are emitting EVERY expression type as an ignored expression? https://github.com/llvm/llvm-project/pull/130869 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Upstream support for emitting ignored statements (PR #130869)
@@ -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 loc({{.*}})) -> !cir.int +// CIR-NEXT: %[[I_PTR:.*]] = cir.alloca !cir.int, !cir.ptr>, ["i", init] {alignment = 4 : i64} +// CIR-NEXT: cir.store %arg0, %[[I_PTR]] : !cir.int, !cir.ptr> +// CIR-NEXT: %[[I_IGNORED:.*]] = cir.load %[[I_PTR]] : !cir.ptr>, !cir.int +// CIR-NEXT: %[[I:.*]] = cir.load %[[I_PTR]] : !cir.ptr>, !cir.int +// CIR-NEXT: cir.return %[[I]] : !cir.int + +// LLVM: define i32 @f1(i32 %[[I:.*]]) erichkeane wrote: Is this llvm from clang itself, or via lowering from CIR? https://github.com/llvm/llvm-project/pull/130869 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Upstream support for emitting ignored statements (PR #130869)
@@ -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); erichkeane wrote: hah, this line is perhaps overly cute. https://github.com/llvm/llvm-project/pull/130869 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits