diff --git a/clang/include/clang/CIR/CIRGenerator.h b/clang/include/clang/CIR/CIRGenerator.h index 414eba80b88b8..f167ade4d578d 100644 --- a/clang/include/clang/CIR/CIRGenerator.h +++ b/clang/include/clang/CIR/CIRGenerator.h @@ -55,6 +55,8 @@ class CIRGenerator : public clang::ASTConsumer { void Initialize(clang::ASTContext &astContext) override; bool HandleTopLevelDecl(clang::DeclGroupRef group) override; mlir::ModuleOp getModule() const; + mlir::MLIRContext &getMLIRContext() { return *mlirContext; } + const mlir::MLIRContext &getMLIRContext() const { return *mlirContext; } }; } // namespace cir diff --git a/clang/include/clang/CIR/FrontendAction/CIRGenAction.h b/clang/include/clang/CIR/FrontendAction/CIRGenAction.h index 99495f4718c5f..1ffffac1719c4 100644 --- a/clang/include/clang/CIR/FrontendAction/CIRGenAction.h +++ b/clang/include/clang/CIR/FrontendAction/CIRGenAction.h @@ -29,6 +29,7 @@ class CIRGenAction : public clang::ASTFrontendAction { EmitCIR, EmitLLVM, EmitBC, + EmitMLIR, EmitObj, }; @@ -59,6 +60,13 @@ class EmitCIRAction : public CIRGenAction { EmitCIRAction(mlir::MLIRContext *MLIRCtx = nullptr); }; +class EmitMLIRAction : public CIRGenAction { + virtual void anchor(); + +public: + EmitMLIRAction(mlir::MLIRContext *MLIRCtx = nullptr); +}; + class EmitLLVMAction : public CIRGenAction { virtual void anchor(); diff --git a/clang/include/clang/CIR/LowerToLLVM.h b/clang/include/clang/CIR/LowerToLLVM.h index 6e1b0270fcd2b..e780a5a747730 100644 --- a/clang/include/clang/CIR/LowerToLLVM.h +++ b/clang/include/clang/CIR/LowerToLLVM.h @@ -20,6 +20,7 @@ class Module; } // namespace llvm namespace mlir { +class MLIRContext; class ModuleOp; } // namespace mlir @@ -30,6 +31,9 @@ std::unique_ptr lowerDirectlyFromCIRToLLVMIR(mlir::ModuleOp mlirModule, llvm::LLVMContext &llvmCtx); } // namespace direct + +mlir::ModuleOp lowerFromCIRToMLIR(mlir::ModuleOp mlirModule, + mlir::MLIRContext &mlirCtx); } // namespace cir #endif // CLANG_CIR_LOWERTOLLVM_H diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 5ad187926e710..ced1944a3574c 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -2958,6 +2958,13 @@ defm clangir : BoolFOption<"clangir", BothFlags<[], [ClangOption, CC1Option], "">>; def emit_cir : Flag<["-"], "emit-cir">, Visibility<[ClangOption, CC1Option]>, Group, HelpText<"Build ASTs and then lower to ClangIR">; +def emit_mlir_EQ : Joined<["-"], "emit-mlir=">, Visibility<[CC1Option]>, Group, + HelpText<"Build ASTs and then generate/lower to the selected MLIR dialect, emit the .mlir or .cir file. " + "Allowed values are `core` for MLIR core dialects and `cir` for ClangIR">, + Values<"core,cir">, + NormalizedValuesScope<"clang::frontend">, + NormalizedValues<["MLIR_Core", "MLIR_CIR"]>, + MarshallingInfoEnum, "MLIR_CIR">; /// ClangIR-specific options - END def flto_EQ : Joined<["-"], "flto=">, diff --git a/clang/include/clang/Frontend/FrontendOptions.h b/clang/include/clang/Frontend/FrontendOptions.h index 99b2d9a98ed1f..62094a0d2abac 100644 --- a/clang/include/clang/Frontend/FrontendOptions.h +++ b/clang/include/clang/Frontend/FrontendOptions.h @@ -68,6 +68,9 @@ enum ActionKind { /// Emit a .cir file EmitCIR, + /// Emit a .mlir file + EmitMLIR, + /// Emit a .ll file. EmitLLVM, @@ -148,6 +151,8 @@ enum ActionKind { PrintDependencyDirectivesSourceMinimizerOutput }; +enum MLIRDialectKind { MLIR_CIR, MLIR_Core }; + } // namespace frontend /// The kind of a file that we've been handed as an input. @@ -417,6 +422,8 @@ class FrontendOptions { /// Specifies the output format of the AST. ASTDumpOutputFormat ASTDumpFormat = ADOF_Default; + frontend::MLIRDialectKind MLIRTargetDialect = frontend::MLIR_CIR; + /// The input kind, either specified via -x argument or deduced from the input /// file name. InputKind DashX; diff --git a/clang/lib/CIR/FrontendAction/CIRGenAction.cpp b/clang/lib/CIR/FrontendAction/CIRGenAction.cpp index 0f686a36b982b..16b32ed62ae5a 100644 --- a/clang/lib/CIR/FrontendAction/CIRGenAction.cpp +++ b/clang/lib/CIR/FrontendAction/CIRGenAction.cpp @@ -13,6 +13,7 @@ #include "clang/CIR/LowerToLLVM.h" #include "clang/CodeGen/BackendUtil.h" #include "clang/Frontend/CompilerInstance.h" +#include "clang/Frontend/FrontendOptions.h" #include "llvm/IR/Module.h" using namespace cir; @@ -24,6 +25,7 @@ static BackendAction getBackendActionFromOutputType(CIRGenAction::OutputType Action) { switch (Action) { case CIRGenAction::OutputType::EmitCIR: + case CIRGenAction::OutputType::EmitMLIR: assert(false && "Unsupported output type for getBackendActionFromOutputType!"); break; // Unreachable, but fall through to report that @@ -82,14 +84,30 @@ class CIRGenConsumer : public clang::ASTConsumer { void HandleTranslationUnit(ASTContext &C) override { Gen->HandleTranslationUnit(C); mlir::ModuleOp MlirModule = Gen->getModule(); + mlir::MLIRContext &MlirCtx = Gen->getMLIRContext(); switch (Action) { case CIRGenAction::OutputType::EmitCIR: - if (OutputStream && MlirModule) { + assert(CI.getFrontendOpts().MLIRTargetDialect == frontend::MLIR_CIR); + case CIRGenAction::OutputType::EmitMLIR: { + switch (CI.getFrontendOpts().MLIRTargetDialect) { + case frontend::MLIR_CIR: + if (OutputStream && MlirModule) { + mlir::OpPrintingFlags Flags; + Flags.enableDebugInfo(/*enable=*/true, /*prettyForm=*/false); + MlirModule->print(*OutputStream, Flags); + } + break; + case frontend::MLIR_Core: + mlir::ModuleOp LoweredMlirModule = + lowerFromCIRToMLIR(MlirModule, MlirCtx); + assert(OutputStream && "No output stream when lowering to MLIR!"); + // FIXME: we cannot roundtrip prettyForm=true right now. mlir::OpPrintingFlags Flags; Flags.enableDebugInfo(/*enable=*/true, /*prettyForm=*/false); - MlirModule->print(*OutputStream, Flags); + LoweredMlirModule->print(*OutputStream, Flags); + break; } - break; + } case CIRGenAction::OutputType::EmitLLVM: case CIRGenAction::OutputType::EmitBC: case CIRGenAction::OutputType::EmitObj: @@ -124,6 +142,8 @@ getOutputStream(CompilerInstance &CI, StringRef InFile, return CI.createDefaultOutputFile(false, InFile, "s"); case CIRGenAction::OutputType::EmitCIR: return CI.createDefaultOutputFile(false, InFile, "cir"); + case CIRGenAction::OutputType::EmitMLIR: + return CI.createDefaultOutputFile(false, InFile, "mlir"); case CIRGenAction::OutputType::EmitLLVM: return CI.createDefaultOutputFile(false, InFile, "ll"); case CIRGenAction::OutputType::EmitBC: @@ -155,6 +175,10 @@ void EmitCIRAction::anchor() {} EmitCIRAction::EmitCIRAction(mlir::MLIRContext *MLIRCtx) : CIRGenAction(OutputType::EmitCIR, MLIRCtx) {} +void EmitMLIRAction::anchor() {} +EmitMLIRAction::EmitMLIRAction(mlir::MLIRContext *MLIRCtx) + : CIRGenAction(OutputType::EmitMLIR, MLIRCtx) {} + void EmitLLVMAction::anchor() {} EmitLLVMAction::EmitLLVMAction(mlir::MLIRContext *MLIRCtx) : CIRGenAction(OutputType::EmitLLVM, MLIRCtx) {} diff --git a/clang/lib/CIR/FrontendAction/CMakeLists.txt b/clang/lib/CIR/FrontendAction/CMakeLists.txt index ac2b857239d07..e22013575b3c9 100644 --- a/clang/lib/CIR/FrontendAction/CMakeLists.txt +++ b/clang/lib/CIR/FrontendAction/CMakeLists.txt @@ -13,6 +13,7 @@ add_clang_library(clangCIRFrontendAction clangFrontend clangCIR clangCIRLoweringDirectToLLVM + clangCIRLoweringThroughMLIR clangCodeGen MLIRCIR MLIRIR diff --git a/clang/lib/CIR/Lowering/CMakeLists.txt b/clang/lib/CIR/Lowering/CMakeLists.txt index 95c304ded9183..f720e597ecb0f 100644 --- a/clang/lib/CIR/Lowering/CMakeLists.txt +++ b/clang/lib/CIR/Lowering/CMakeLists.txt @@ -1 +1,2 @@ add_subdirectory(DirectToLLVM) +add_subdirectory(ThroughMLIR) diff --git a/clang/lib/CIR/Lowering/ThroughMLIR/CMakeLists.txt b/clang/lib/CIR/Lowering/ThroughMLIR/CMakeLists.txt new file mode 100644 index 0000000000000..81fc9703ff0ae --- /dev/null +++ b/clang/lib/CIR/Lowering/ThroughMLIR/CMakeLists.txt @@ -0,0 +1,16 @@ +set(LLVM_LINK_COMPONENTS + Core + Support + ) + +get_property(dialect_libs GLOBAL PROPERTY MLIR_DIALECT_LIBS) + +add_clang_library(clangCIRLoweringThroughMLIR + LowerCIRToMLIR.cpp + + DEPENDS + LINK_LIBS + MLIRIR + ${dialect_libs} + MLIRCIR +) diff --git a/clang/lib/CIR/Lowering/ThroughMLIR/LowerCIRToMLIR.cpp b/clang/lib/CIR/Lowering/ThroughMLIR/LowerCIRToMLIR.cpp new file mode 100644 index 0000000000000..3f3b7f2440350 --- /dev/null +++ b/clang/lib/CIR/Lowering/ThroughMLIR/LowerCIRToMLIR.cpp @@ -0,0 +1,201 @@ +//====- LowerCIRToMLIR.cpp - Lowering from CIR to MLIR --------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file implements lowering of CIR operations to MLIR. +// +//===----------------------------------------------------------------------===// + +#include "mlir/Dialect/MemRef/IR/MemRef.h" +#include "mlir/IR/BuiltinDialect.h" +#include "mlir/Pass/Pass.h" +#include "mlir/Pass/PassManager.h" +#include "mlir/Transforms/DialectConversion.h" +#include "clang/CIR/Dialect/IR/CIRDialect.h" +#include "clang/CIR/Dialect/IR/CIRTypes.h" +#include "clang/CIR/LowerToLLVM.h" +#include "clang/CIR/MissingFeatures.h" +#include "llvm/ADT/TypeSwitch.h" +#include "llvm/Support/TimeProfiler.h" + +using namespace cir; +using namespace llvm; + +namespace cir { + +struct ConvertCIRToMLIRPass + : public mlir::PassWrapper> { + void getDependentDialects(mlir::DialectRegistry ®istry) const override { + registry.insert(); + } + void runOnOperation() final; + + StringRef getDescription() const override { + return "Convert the CIR dialect module to MLIR standard dialects"; + } + + StringRef getArgument() const override { return "cir-to-mlir"; } +}; + +class CIRGlobalOpLowering : public mlir::OpConversionPattern { +public: + using OpConversionPattern::OpConversionPattern; + mlir::LogicalResult + matchAndRewrite(cir::GlobalOp op, OpAdaptor adaptor, + mlir::ConversionPatternRewriter &rewriter) const override { + mlir::ModuleOp moduleOp = op->getParentOfType(); + if (!moduleOp) + return mlir::failure(); + + mlir::OpBuilder b(moduleOp.getContext()); + + const mlir::Type cirSymType = op.getSymType(); + assert(!cir::MissingFeatures::convertTypeForMemory()); + mlir::Type convertedType = getTypeConverter()->convertType(cirSymType); + if (!convertedType) + return mlir::failure(); + auto memrefType = dyn_cast(convertedType); + if (!memrefType) + memrefType = mlir::MemRefType::get({}, convertedType); + // Add an optional alignment to the global memref. + assert(!cir::MissingFeatures::opGlobalAlignment()); + mlir::IntegerAttr memrefAlignment = mlir::IntegerAttr(); + // Add an optional initial value to the global memref. + mlir::Attribute initialValue = mlir::Attribute(); + std::optional init = op.getInitialValue(); + if (init.has_value()) { + initialValue = + llvm::TypeSwitch(init.value()) + .Case([&](cir::IntAttr attr) { + auto rtt = mlir::RankedTensorType::get({}, convertedType); + return mlir::DenseIntElementsAttr::get(rtt, attr.getValue()); + }) + .Case([&](cir::FPAttr attr) { + auto rtt = mlir::RankedTensorType::get({}, convertedType); + return mlir::DenseFPElementsAttr::get(rtt, attr.getValue()); + }) + .Default([&](mlir::Attribute attr) { + llvm_unreachable("GlobalOp lowering with initial value is not " + "fully supported yet"); + return mlir::Attribute(); + }); + } + + // Add symbol visibility + assert(!cir::MissingFeatures::opGlobalLinkage()); + std::string symVisibility = "public"; + + assert(!cir::MissingFeatures::opGlobalConstant()); + bool isConstant = false; + + rewriter.replaceOpWithNewOp( + op, b.getStringAttr(op.getSymName()), + /*sym_visibility=*/b.getStringAttr(symVisibility), + /*type=*/memrefType, initialValue, + /*constant=*/isConstant, + /*alignment=*/memrefAlignment); + + return mlir::success(); + } +}; + +void populateCIRToMLIRConversionPatterns(mlir::RewritePatternSet &patterns, + mlir::TypeConverter &converter) { + patterns.add(converter, patterns.getContext()); +} + +static mlir::TypeConverter prepareTypeConverter() { + mlir::TypeConverter converter; + converter.addConversion([&](cir::PointerType type) -> mlir::Type { + assert(!cir::MissingFeatures::convertTypeForMemory()); + mlir::Type ty = converter.convertType(type.getPointee()); + // FIXME: The pointee type might not be converted (e.g. struct) + if (!ty) + return nullptr; + return mlir::MemRefType::get({}, ty); + }); + converter.addConversion( + [&](mlir::IntegerType type) -> mlir::Type { return type; }); + converter.addConversion( + [&](mlir::FloatType type) -> mlir::Type { return type; }); + converter.addConversion([&](cir::VoidType type) -> mlir::Type { return {}; }); + converter.addConversion([&](cir::IntType type) -> mlir::Type { + // arith dialect ops doesn't take signed integer -- drop cir sign here + return mlir::IntegerType::get( + type.getContext(), type.getWidth(), + mlir::IntegerType::SignednessSemantics::Signless); + }); + converter.addConversion([&](cir::SingleType type) -> mlir::Type { + return mlir::Float32Type::get(type.getContext()); + }); + converter.addConversion([&](cir::DoubleType type) -> mlir::Type { + return mlir::Float64Type::get(type.getContext()); + }); + converter.addConversion([&](cir::FP80Type type) -> mlir::Type { + return mlir::Float80Type::get(type.getContext()); + }); + converter.addConversion([&](cir::LongDoubleType type) -> mlir::Type { + return converter.convertType(type.getUnderlying()); + }); + converter.addConversion([&](cir::FP128Type type) -> mlir::Type { + return mlir::Float128Type::get(type.getContext()); + }); + converter.addConversion([&](cir::FP16Type type) -> mlir::Type { + return mlir::Float16Type::get(type.getContext()); + }); + converter.addConversion([&](cir::BF16Type type) -> mlir::Type { + return mlir::BFloat16Type::get(type.getContext()); + }); + + return converter; +} + +void ConvertCIRToMLIRPass::runOnOperation() { + mlir::ModuleOp module = getOperation(); + + mlir::TypeConverter converter = prepareTypeConverter(); + + mlir::RewritePatternSet patterns(&getContext()); + + populateCIRToMLIRConversionPatterns(patterns, converter); + + mlir::ConversionTarget target(getContext()); + target.addLegalOp(); + target.addLegalDialect(); + target.addIllegalDialect(); + + if (failed(applyPartialConversion(module, target, std::move(patterns)))) + signalPassFailure(); +} + +std::unique_ptr createConvertCIRToMLIRPass() { + return std::make_unique(); +} + +mlir::ModuleOp lowerFromCIRToMLIR(mlir::ModuleOp mlirModule, + mlir::MLIRContext &mlirCtx) { + llvm::TimeTraceScope scope("Lower CIR To MLIR"); + + mlir::PassManager pm(&mlirCtx); + + pm.addPass(createConvertCIRToMLIRPass()); + + bool result = !mlir::failed(pm.run(mlirModule)); + if (!result) + llvm::report_fatal_error( + "The pass manager failed to lower CIR to MLIR standard dialects!"); + + // Now that we ran all the lowering passes, verify the final output. + if (mlirModule.verify().failed()) + llvm::report_fatal_error( + "Verification of the final MLIR in standard dialects failed!"); + + return mlirModule; +} + +} // namespace cir diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index 4eb743acf327f..fc52e3516f7d1 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -2740,6 +2740,7 @@ static const auto &getFrontendActionTable() { {frontend::EmitAssembly, OPT_S}, {frontend::EmitBC, OPT_emit_llvm_bc}, {frontend::EmitCIR, OPT_emit_cir}, + {frontend::EmitMLIR, OPT_emit_mlir_EQ}, {frontend::EmitHTML, OPT_emit_html}, {frontend::EmitLLVM, OPT_emit_llvm}, {frontend::EmitLLVMOnly, OPT_emit_llvm_only}, @@ -2856,6 +2857,13 @@ static void GenerateFrontendArgs(const FrontendOptions &Opts, }; } + if (Opts.ProgramAction == frontend::EmitMLIR) { + GenerateProgramAction = [&]() { + if (Opts.MLIRTargetDialect == frontend::MLIR_CIR) + GenerateArg(Consumer, OPT_emit_cir); + }; + } + GenerateProgramAction(); for (const auto &PluginArgs : Opts.PluginArgs) { @@ -4631,6 +4639,7 @@ static bool isStrictlyPreprocessorAction(frontend::ActionKind Action) { case frontend::EmitAssembly: case frontend::EmitBC: case frontend::EmitCIR: + case frontend::EmitMLIR: case frontend::EmitHTML: case frontend::EmitLLVM: case frontend::EmitLLVMOnly: diff --git a/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp b/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp index bb3bb0aac78bf..ec0949c2b6941 100644 --- a/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp +++ b/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp @@ -79,6 +79,12 @@ CreateFrontendBaseAction(CompilerInstance &CI) { return std::make_unique(); #else llvm_unreachable("CIR suppport not built into clang"); +#endif + case EmitMLIR: +#if CLANG_ENABLE_CIR + return std::make_unique(); +#else + llvm_unreachable("CIR suppport not built into clang"); #endif case EmitHTML: return std::make_unique(); case EmitLLVM: { diff --git a/clang/test/CIR/Lowering/ThroughMLIR/global-ptrs.cpp b/clang/test/CIR/Lowering/ThroughMLIR/global-ptrs.cpp new file mode 100644 index 0000000000000..16a81c1a3afa0 --- /dev/null +++ b/clang/test/CIR/Lowering/ThroughMLIR/global-ptrs.cpp @@ -0,0 +1,29 @@ +// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-linux-gnu -fclangir -emit-mlir=core %s -o %t.mlir +// RUN: FileCheck --input-file=%t.mlir %s + +// XFAIL: * + +// Note: This is here to track the failed lowering of global pointers. When +// this test starts passing, the checks should be updated with more +// specifics. + +void *vp; +// CHECK: memref.global "public" @vp + +int *ip = 0; +// CHECK: memref.global "public" @ip + +double *dp; +// CHECK: memref.global "public" @dp + +char **cpp; +// CHECK: memref.global "public" @cpp + +void (*fp)(); +// CHECK: memref.global "public" @fp + +int (*fpii)(int) = 0; +// CHECK: memref.global "public" @fpii + +void (*fpvar)(int, ...); +// CHECK: memref.global "public" @fpvar diff --git a/clang/test/CIR/Lowering/ThroughMLIR/global.cpp b/clang/test/CIR/Lowering/ThroughMLIR/global.cpp new file mode 100644 index 0000000000000..e8e68ec8259c6 --- /dev/null +++ b/clang/test/CIR/Lowering/ThroughMLIR/global.cpp @@ -0,0 +1,79 @@ +// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-linux-gnu -fclangir -emit-mlir=core %s -o %t.mlir +// RUN: FileCheck --input-file=%t.mlir %s + +char c; +// CHECK: memref.global "public" @c : memref + +signed char sc; +// CHECK: memref.global "public" @sc : memref + +unsigned char uc; +// CHECK: memref.global "public" @uc : memref + +short ss; +// CHECK: memref.global "public" @ss : memref + +unsigned short us = 100; +// CHECK: memref.global "public" @us : memref = dense<100> + +int si = 42; +// CHECK: memref.global "public" @si : memref = dense<42> + +unsigned ui; +// CHECK: memref.global "public" @ui : memref + +long sl; +// CHECK: memref.global "public" @sl : memref + +unsigned long ul; +// CHECK: memref.global "public" @ul : memref + +long long sll; +// CHECK: memref.global "public" @sll : memref + +unsigned long long ull = 123456; +// CHECK: memref.global "public" @ull : memref = dense<123456> + +__int128 s128; +// CHECK: memref.global "public" @s128 : memref + +unsigned __int128 u128; +// CHECK: memref.global "public" @u128 : memref + +wchar_t wc; +// CHECK: memref.global "public" @wc : memref + +char8_t c8; +// CHECK: memref.global "public" @c8 : memref + +char16_t c16; +// CHECK: memref.global "public" @c16 : memref + +char32_t c32; +// CHECK: memref.global "public" @c32 : memref + +_BitInt(20) sb20; +// CHECK: memref.global "public" @sb20 : memref + +unsigned _BitInt(48) ub48; +// CHECK: memref.global "public" @ub48 : memref + +_Float16 f16; +// CHECK: memref.global "public" @f16 : memref + +__bf16 bf16; +// CHECK: memref.global "public" @bf16 : memref + +float f; +// CHECK: memref.global "public" @f : memref + +double d = 1.25; +// CHECK: memref.global "public" @d : memref = dense<1.250000e+00> + +long double ld; +// CHECK: memref.global "public" @ld : memref + +__float128 f128; +// CHECK: memref.global "public" @f128 : memref + +// FIXME: Add global pointers when they can be lowered to MLIR diff --git a/clang/test/CIR/global-var-simple.cpp b/clang/test/CIR/global-var-simple.cpp index ffcc3ef71a6c7..f63b619efbb5f 100644 --- a/clang/test/CIR/global-var-simple.cpp +++ b/clang/test/CIR/global-var-simple.cpp @@ -1,5 +1,5 @@ // Global variables of intergal types -// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o - | FileCheck %s +// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-linux-gnu -fclangir -emit-mlir=cir %s -o - | FileCheck %s char c; // CHECK: cir.global @c : !cir.int diff --git a/clang/test/CIR/hello.c b/clang/test/CIR/hello.c index 4b07c04994aa8..023e9e00e1cbd 100644 --- a/clang/test/CIR/hello.c +++ b/clang/test/CIR/hello.c @@ -1,4 +1,5 @@ // Smoke test for ClangIR code generation +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-mlir=cir %s -o - | FileCheck %s // RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o - | FileCheck %s void foo() {}