https://github.com/ianayl updated https://github.com/llvm/llvm-project/pull/230003
>From 3d967e6f36629898ecef72528512b269f163eddb Mon Sep 17 00:00:00 2001 From: "Li, Ian" <[email protected]> Date: Wed, 7 Oct 2026 16:41:26 -0700 Subject: [PATCH 01/16] issue diagnostics on bad cir.triple instead of asserts --- .../CIR/Dialect/Transforms/CXXABILowering.cpp | 12 ++++---- .../Dialect/Transforms/LoweringPrepare.cpp | 10 +++++-- .../CIR/Dialect/Transforms/TargetLowering.cpp | 12 ++++---- .../Transforms/TargetLowering/LowerModule.cpp | 30 +++++++++++++++---- .../Transforms/TargetLowering/LowerModule.h | 4 ++- 5 files changed, 49 insertions(+), 19 deletions(-) diff --git a/clang/lib/CIR/Dialect/Transforms/CXXABILowering.cpp b/clang/lib/CIR/Dialect/Transforms/CXXABILowering.cpp index 735146b04c64f..b57b994bea88c 100644 --- a/clang/lib/CIR/Dialect/Transforms/CXXABILowering.cpp +++ b/clang/lib/CIR/Dialect/Transforms/CXXABILowering.cpp @@ -893,13 +893,15 @@ void CXXABILoweringPass::runOnOperation() { auto mod = mlir::cast<mlir::ModuleOp>(getOperation()); mlir::MLIRContext *ctx = mod.getContext(); - std::unique_ptr<cir::LowerModule> lowerModule = cir::createLowerModule(mod); + auto diag = [&] { + return mod.emitWarning("cannot create a CIR lower module, skipping the ") + << getName() << " pass: "; + }; + std::unique_ptr<cir::LowerModule> lowerModule = cir::createLowerModule( + mod, diag); // If lower module is not available, skip the ABI lowering pass. - if (!lowerModule) { - mod.emitWarning("Cannot create a CIR lower module, skipping the ") - << getName() << " pass"; + if (!lowerModule) return; - } mlir::DataLayout dataLayout(mod); CIRABITypeConverter typeConverter(*ctx, dataLayout, *lowerModule); diff --git a/clang/lib/CIR/Dialect/Transforms/LoweringPrepare.cpp b/clang/lib/CIR/Dialect/Transforms/LoweringPrepare.cpp index 23fb81e2f706d..106298629c65e 100644 --- a/clang/lib/CIR/Dialect/Transforms/LoweringPrepare.cpp +++ b/clang/lib/CIR/Dialect/Transforms/LoweringPrepare.cpp @@ -3061,9 +3061,13 @@ void LoweringPreparePass::buildCUDARegisterVars(cir::CIRBaseBuilderTy &builder, void LoweringPreparePass::runOnOperation() { mlirModule = getOperation(); - // CIRGen always sets the triple, so this cannot fail. - lowerModule = cir::createLowerModule(mlirModule); - assert(lowerModule && "requires a module with a triple"); + auto diag = [&] { + return mlirModule.emitError("cannot create a CIR lower module for ") + << getName() << " pass: "; + }; + lowerModule = cir::createLowerModule(mlirModule, diag); + if (!lowerModule) + return signalPassFailure(); llvm::SmallVector<mlir::Operation *> opsToTransform; diff --git a/clang/lib/CIR/Dialect/Transforms/TargetLowering.cpp b/clang/lib/CIR/Dialect/Transforms/TargetLowering.cpp index 76ca7114ee5ce..e978acda6cca9 100644 --- a/clang/lib/CIR/Dialect/Transforms/TargetLowering.cpp +++ b/clang/lib/CIR/Dialect/Transforms/TargetLowering.cpp @@ -296,13 +296,15 @@ populateTargetLoweringConversionTarget(mlir::ConversionTarget &target, void TargetLoweringPass::runOnOperation() { auto mod = mlir::cast<mlir::ModuleOp>(getOperation()); - std::unique_ptr<cir::LowerModule> lowerModule = cir::createLowerModule(mod); + auto diag = [&] { + return mod.emitWarning("cannot create a CIR lower module, skipping the ") + << getName() << " pass: "; + }; + std::unique_ptr<cir::LowerModule> lowerModule = cir::createLowerModule( + mod, diag); // If lower module is not available, skip the target lowering pass. - if (!lowerModule) { - mod.emitWarning("Cannot create a CIR lower module, skipping the ") - << getName() << " pass"; + if (!lowerModule) return; - } const auto &targetInfo = lowerModule->getTargetLoweringInfo(); diff --git a/clang/lib/CIR/Dialect/Transforms/TargetLowering/LowerModule.cpp b/clang/lib/CIR/Dialect/Transforms/TargetLowering/LowerModule.cpp index 03044286e8cf7..313661ba959f4 100644 --- a/clang/lib/CIR/Dialect/Transforms/TargetLowering/LowerModule.cpp +++ b/clang/lib/CIR/Dialect/Transforms/TargetLowering/LowerModule.cpp @@ -79,20 +79,39 @@ const TargetLoweringInfo &LowerModule::getTargetLoweringInfo() { } // TODO: not to create it every time -std::unique_ptr<LowerModule> createLowerModule(mlir::ModuleOp module) { +std::unique_ptr<LowerModule> +createLowerModule(mlir::ModuleOp module, + llvm::function_ref<mlir::InFlightDiagnostic()> emitDiag) { // If the triple is not present, e.g. CIR modules parsed from text, we // cannot init LowerModule properly. assert(!cir::MissingFeatures::makeTripleAlwaysPresent()); - if (!module->hasAttr(cir::CIRDialect::getTripleAttrName())) + // TODO(triple) what this line do? ^^^ + if (!module->hasAttr(cir::CIRDialect::getTripleAttrName())) { + if (emitDiag) + emitDiag() << "module is missing " << cir::CIRDialect::getTripleAttrName() + << " attribute"; return nullptr; + } // Fetch target information. - llvm::Triple triple(mlir::cast<mlir::StringAttr>( - module->getAttr(cir::CIRDialect::getTripleAttrName())) - .getValue()); + auto tripleAttr = module->getAttrOfType<mlir::StringAttr>( + cir::CIRDialect::getTripleAttrName()); + if (!tripleAttr) { + if (emitDiag) + emitDiag() << "expected module's " << cir::CIRDialect::getTripleAttrName() + << " attribute to be a string"; + return nullptr; + } + llvm::Triple triple(tripleAttr.getValue()); clang::TargetOptions targetOptions; targetOptions.Triple = triple.str(); auto targetInfo = clang::targets::AllocateTarget(triple, targetOptions); + if (!targetInfo) { + if (emitDiag) + emitDiag() << "unknown triple '" << tripleAttr.getValue() << "' in " + << cir::CIRDialect::getTripleAttrName() << " attribute"; + return nullptr; + } // Populate the lowering-relevant LangOptions from the module's // #cir.lowering_lang_options attribute so a reloaded .cir lowers the same @@ -120,6 +139,7 @@ std::unique_ptr<LowerModule> createLowerModule(mlir::ModuleOp module) { assert(!cir::MissingFeatures::lowerModuleCodeGenOpts()); clang::CodeGenOptions codeGenOpts; + // TODO(optinfo): this cast should be more secure? if (auto optInfo = mlir::cast_if_present<cir::OptInfoAttr>( module->getAttr(cir::CIRDialect::getOptInfoAttrName()))) { codeGenOpts.OptimizationLevel = optInfo.getLevel(); diff --git a/clang/lib/CIR/Dialect/Transforms/TargetLowering/LowerModule.h b/clang/lib/CIR/Dialect/Transforms/TargetLowering/LowerModule.h index 56fcd0a9b58cd..588bc496bdaba 100644 --- a/clang/lib/CIR/Dialect/Transforms/TargetLowering/LowerModule.h +++ b/clang/lib/CIR/Dialect/Transforms/TargetLowering/LowerModule.h @@ -57,7 +57,9 @@ class LowerModule { const TargetLoweringInfo &getTargetLoweringInfo(); }; -std::unique_ptr<LowerModule> createLowerModule(mlir::ModuleOp module); +std::unique_ptr<LowerModule> +createLowerModule(mlir::ModuleOp module, + llvm::function_ref<mlir::InFlightDiagnostic()> emitDiag = nullptr); } // namespace cir >From 7148a33516414e640d560bff21c033763da991cc Mon Sep 17 00:00:00 2001 From: "Li, Ian" <[email protected]> Date: Wed, 7 Oct 2026 17:13:28 -0700 Subject: [PATCH 02/16] issue diagnostics on malformed opt_info attrs --- .../Dialect/Transforms/TargetLowering/LowerModule.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/clang/lib/CIR/Dialect/Transforms/TargetLowering/LowerModule.cpp b/clang/lib/CIR/Dialect/Transforms/TargetLowering/LowerModule.cpp index 313661ba959f4..afbacbd7987a6 100644 --- a/clang/lib/CIR/Dialect/Transforms/TargetLowering/LowerModule.cpp +++ b/clang/lib/CIR/Dialect/Transforms/TargetLowering/LowerModule.cpp @@ -139,9 +139,14 @@ createLowerModule(mlir::ModuleOp module, assert(!cir::MissingFeatures::lowerModuleCodeGenOpts()); clang::CodeGenOptions codeGenOpts; - // TODO(optinfo): this cast should be more secure? - if (auto optInfo = mlir::cast_if_present<cir::OptInfoAttr>( - module->getAttr(cir::CIRDialect::getOptInfoAttrName()))) { + if (auto optAttr = module->getAttr(cir::CIRDialect::getOptInfoAttrName())) { + auto optInfo = mlir::dyn_cast<cir::OptInfoAttr>(optAttr); + if (!optInfo) { + if (emitDiag) + emitDiag() << "malformed " << cir::CIRDialect::getOptInfoAttrName() + << " attribute"; + return nullptr; + } codeGenOpts.OptimizationLevel = optInfo.getLevel(); codeGenOpts.OptimizeSize = optInfo.getSize(); } >From 9a939caf75ae9d058a1a5ef55ff8268191096264 Mon Sep 17 00:00:00 2001 From: "Li, Ian" <[email protected]> Date: Wed, 7 Oct 2026 18:28:46 -0700 Subject: [PATCH 03/16] patch up reading triples for cpuid op lowering --- .../Transforms/TargetLowering/LowerModule.cpp | 1 - .../CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp | 18 ++++++++++++++---- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/clang/lib/CIR/Dialect/Transforms/TargetLowering/LowerModule.cpp b/clang/lib/CIR/Dialect/Transforms/TargetLowering/LowerModule.cpp index afbacbd7987a6..4190947e0cb4d 100644 --- a/clang/lib/CIR/Dialect/Transforms/TargetLowering/LowerModule.cpp +++ b/clang/lib/CIR/Dialect/Transforms/TargetLowering/LowerModule.cpp @@ -85,7 +85,6 @@ createLowerModule(mlir::ModuleOp module, // If the triple is not present, e.g. CIR modules parsed from text, we // cannot init LowerModule properly. assert(!cir::MissingFeatures::makeTripleAlwaysPresent()); - // TODO(triple) what this line do? ^^^ if (!module->hasAttr(cir::CIRDialect::getTripleAttrName())) { if (emitDiag) emitDiag() << "module is missing " << cir::CIRDialect::getTripleAttrName() diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp index 6426841e6237f..d539ad50db866 100644 --- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp +++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp @@ -4508,6 +4508,7 @@ void ConvertCIRToLLVMPass::processCIRAttrs(mlir::ModuleOp module) { module->getAttr(cir::CIRDialect::getTripleAttrName())) module->setAttr(mlir::LLVM::LLVMDialect::getTargetTripleAttrName(), tripleAttr); + // TODO(triple) handle triple exception here? if (mlir::Attribute asmAttr = module->getAttr(cir::CIRDialect::getModuleLevelAsmAttrName())) @@ -5819,10 +5820,19 @@ mlir::LogicalResult CIRToLLVMCpuIdOpLowering::matchAndRewrite( StringRef asmString, constraints; mlir::ModuleOp moduleOp = op->getParentOfType<mlir::ModuleOp>(); - llvm::Triple triple( - mlir::cast<mlir::StringAttr>( - moduleOp->getAttr(cir::CIRDialect::getTripleAttrName())) - .getValue()); + auto tripleAttr = moduleOp->getAttr(cir::CIRDialect::getTripleAttrName()); + if (!tripleAttr) { + moduleOp->emitError("module is missing a ") + << cir::CIRDialect::getTripleAttrName() << " attribute"; + return mlir::failure(); + } + mlir::StringAttr tripleStr = mlir::dyn_cast<mlir::StringAttr>(tripleAttr); + if (!tripleStr) { + moduleOp->emitError("expected string from module ") + << cir::CIRDialect::getTripleAttrName() << " attribute"; + return mlir::failure(); + } + llvm::Triple triple(tripleStr.getValue()); if (triple.getArch() == llvm::Triple::x86) { asmString = "cpuid"; constraints = "={ax},={bx},={cx},={dx},{ax},{cx}"; >From fd373da1e099dbad33241e2ab7c8afd94ebe7f7b Mon Sep 17 00:00:00 2001 From: "Li, Ian" <[email protected]> Date: Wed, 7 Oct 2026 21:04:51 -0700 Subject: [PATCH 04/16] switch to unified helper for triple processing --- .../include/clang/CIR/Dialect/IR/CIRDialect.h | 6 +++++ clang/lib/CIR/Dialect/IR/CIRDialect.cpp | 22 +++++++++++++++++++ .../CIR/Dialect/Transforms/EHABILowering.cpp | 10 +++------ .../Transforms/TargetLowering/LowerModule.cpp | 22 +++++-------------- clang/lib/CIR/Lowering/CIRPasses.cpp | 12 +++++----- .../CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp | 18 ++++----------- 6 files changed, 45 insertions(+), 45 deletions(-) diff --git a/clang/include/clang/CIR/Dialect/IR/CIRDialect.h b/clang/include/clang/CIR/Dialect/IR/CIRDialect.h index d9018e93628b6..baece7ab02fc7 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIRDialect.h +++ b/clang/include/clang/CIR/Dialect/IR/CIRDialect.h @@ -99,6 +99,12 @@ RecordLayoutAttr getRecordLayout(mlir::ModuleOp mod, mlir::StringAttr name); /// Same lookup as getRecordLayout, but returns a null attribute instead of /// asserting when the record has no layout entry. RecordLayoutAttr tryGetRecordLayout(mlir::ModuleOp mod, mlir::StringAttr name); + +/// Attempts to construct an llvm::Triple from a module's cir.triple attribute. +/// If emitDiag is not null, additional diagnostics information is passed into +/// emitDiag upon failure. +mlir::FailureOr<llvm::Triple> +getTripleFromModule(mlir::ModuleOp mod, llvm::function_ref<mlir::InFlightDiagnostic()> emitDiag = nullptr); } // namespace cir // TableGen'erated files for MLIR dialects require that a macro be defined when diff --git a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp index 2a5cb9a908a1d..caa3527a02f11 100644 --- a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp +++ b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp @@ -402,6 +402,28 @@ static LogicalResult verifyProducedBy(Operation *op, Value operand, return success(); } +mlir::FailureOr<llvm::Triple> cir::getTripleFromModule( + mlir::ModuleOp mod, + llvm::function_ref<mlir::InFlightDiagnostic()> emitDiag) { + if (!mod->hasAttr(cir::CIRDialect::getTripleAttrName())) { + if (emitDiag) + emitDiag() << "module is missing " << cir::CIRDialect::getTripleAttrName() + << " attribute"; + return mlir::failure(); + } + + auto tripleAttr = mod->getAttrOfType<mlir::StringAttr>( + cir::CIRDialect::getTripleAttrName()); + if (!tripleAttr) { + if (emitDiag) + emitDiag() << "expected a string from module attribute " + << cir::CIRDialect::getTripleAttrName(); + return mlir::failure(); + } + + return llvm::Triple{tripleAttr.getValue()}; +} + //===----------------------------------------------------------------------===// // InlineKindAttr (FIXME: remove once FuncOp uses assembly format) //===----------------------------------------------------------------------===// diff --git a/clang/lib/CIR/Dialect/Transforms/EHABILowering.cpp b/clang/lib/CIR/Dialect/Transforms/EHABILowering.cpp index 77ce7434c8ed3..e3306227aac5e 100644 --- a/clang/lib/CIR/Dialect/Transforms/EHABILowering.cpp +++ b/clang/lib/CIR/Dialect/Transforms/EHABILowering.cpp @@ -1088,19 +1088,15 @@ void CIREHABILoweringPass::runOnOperation() { // The target triple is attached to the module as the "cir.triple" // attribute. If it is absent (e.g. a CIR module parsed from text without a // triple) we cannot determine the ABI and must skip the pass. - auto tripleAttr = mlir::dyn_cast_if_present<mlir::StringAttr>( - mod->getAttr(cir::CIRDialect::getTripleAttrName())); - if (!tripleAttr) { - mod.emitError("Module has no target triple"); + auto triple = cir::getTripleFromModule(mod, [&] { return mod.emitWarning(); }); + if (mlir::failed(triple)) return; - } // Select the ABI-specific lowering handler from the triple. The Microsoft // C++ ABI targets a Windows MSVC environment; everything else uses Itanium. // Extend this when Microsoft ABI lowering is added. - llvm::Triple triple(tripleAttr.getValue()); std::unique_ptr<EHABILowering> lowering; - if (triple.isWindowsMSVCEnvironment()) { + if (triple->isWindowsMSVCEnvironment()) { mod.emitError( "EH ABI lowering is not yet implemented for the Microsoft ABI"); return signalPassFailure(); diff --git a/clang/lib/CIR/Dialect/Transforms/TargetLowering/LowerModule.cpp b/clang/lib/CIR/Dialect/Transforms/TargetLowering/LowerModule.cpp index 4190947e0cb4d..91a6f27ea8b16 100644 --- a/clang/lib/CIR/Dialect/Transforms/TargetLowering/LowerModule.cpp +++ b/clang/lib/CIR/Dialect/Transforms/TargetLowering/LowerModule.cpp @@ -85,29 +85,17 @@ createLowerModule(mlir::ModuleOp module, // If the triple is not present, e.g. CIR modules parsed from text, we // cannot init LowerModule properly. assert(!cir::MissingFeatures::makeTripleAlwaysPresent()); - if (!module->hasAttr(cir::CIRDialect::getTripleAttrName())) { - if (emitDiag) - emitDiag() << "module is missing " << cir::CIRDialect::getTripleAttrName() - << " attribute"; - return nullptr; - } // Fetch target information. - auto tripleAttr = module->getAttrOfType<mlir::StringAttr>( - cir::CIRDialect::getTripleAttrName()); - if (!tripleAttr) { - if (emitDiag) - emitDiag() << "expected module's " << cir::CIRDialect::getTripleAttrName() - << " attribute to be a string"; + auto triple = cir::getTripleFromModule(module, emitDiag); + if (mlir::failed(triple)) return nullptr; - } - llvm::Triple triple(tripleAttr.getValue()); clang::TargetOptions targetOptions; - targetOptions.Triple = triple.str(); - auto targetInfo = clang::targets::AllocateTarget(triple, targetOptions); + targetOptions.Triple = triple->str(); + auto targetInfo = clang::targets::AllocateTarget(*triple, targetOptions); if (!targetInfo) { if (emitDiag) - emitDiag() << "unknown triple '" << tripleAttr.getValue() << "' in " + emitDiag() << "unknown triple '" << triple->str() << "' in " << cir::CIRDialect::getTripleAttrName() << " attribute"; return nullptr; } diff --git a/clang/lib/CIR/Lowering/CIRPasses.cpp b/clang/lib/CIR/Lowering/CIRPasses.cpp index 6e75ce03d14ff..dc4e3128ca26d 100644 --- a/clang/lib/CIR/Lowering/CIRPasses.cpp +++ b/clang/lib/CIR/Lowering/CIRPasses.cpp @@ -78,13 +78,11 @@ runCIRToCIRPasses(mlir::ModuleOp theModule, mlir::MLIRContext &mlirContext, llvm::TimeTraceScope scope("CIR To CIR Passes"); - auto tripleAttr = theModule->getAttrOfType<mlir::StringAttr>( - cir::CIRDialect::getTripleAttrName()); - if (!tripleAttr) - return theModule.emitError() - << "missing '" << cir::CIRDialect::getTripleAttrName() - << "' attribute"; - llvm::Triple triple(tripleAttr.getValue()); + auto maybeTriple = cir::getTripleFromModule(theModule, + [&]{ return theModule.emitError(); }); + if (mlir::failed(maybeTriple)) + return mlir::LogicalResult::failure(); + llvm::Triple &triple = *maybeTriple; auto abiAttr = theModule->getAttrOfType<mlir::StringAttr>( cir::CIRDialect::getTargetABIAttrName()); diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp index d539ad50db866..628dc160e251d 100644 --- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp +++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp @@ -4508,7 +4508,6 @@ void ConvertCIRToLLVMPass::processCIRAttrs(mlir::ModuleOp module) { module->getAttr(cir::CIRDialect::getTripleAttrName())) module->setAttr(mlir::LLVM::LLVMDialect::getTargetTripleAttrName(), tripleAttr); - // TODO(triple) handle triple exception here? if (mlir::Attribute asmAttr = module->getAttr(cir::CIRDialect::getModuleLevelAsmAttrName())) @@ -5820,20 +5819,11 @@ mlir::LogicalResult CIRToLLVMCpuIdOpLowering::matchAndRewrite( StringRef asmString, constraints; mlir::ModuleOp moduleOp = op->getParentOfType<mlir::ModuleOp>(); - auto tripleAttr = moduleOp->getAttr(cir::CIRDialect::getTripleAttrName()); - if (!tripleAttr) { - moduleOp->emitError("module is missing a ") - << cir::CIRDialect::getTripleAttrName() << " attribute"; + auto triple = cir::getTripleFromModule(moduleOp, + [&] { return moduleOp.emitError(); }); + if (mlir::failed(triple)) return mlir::failure(); - } - mlir::StringAttr tripleStr = mlir::dyn_cast<mlir::StringAttr>(tripleAttr); - if (!tripleStr) { - moduleOp->emitError("expected string from module ") - << cir::CIRDialect::getTripleAttrName() << " attribute"; - return mlir::failure(); - } - llvm::Triple triple(tripleStr.getValue()); - if (triple.getArch() == llvm::Triple::x86) { + if (triple->getArch() == llvm::Triple::x86) { asmString = "cpuid"; constraints = "={ax},={bx},={cx},={dx},{ax},{cx}"; } else { >From 3c65330e55b1a8fc479a554123683a9587b785cb Mon Sep 17 00:00:00 2001 From: "Li, Ian" <[email protected]> Date: Wed, 7 Oct 2026 21:16:22 -0700 Subject: [PATCH 05/16] I don't think there were any tangible benefits to using mlir::FailureOr, and if anything it reads worse than std::optional --- clang/include/clang/CIR/Dialect/IR/CIRDialect.h | 2 +- clang/lib/CIR/Dialect/IR/CIRDialect.cpp | 6 +++--- clang/lib/CIR/Dialect/Transforms/EHABILowering.cpp | 4 ++-- .../Dialect/Transforms/TargetLowering/LowerModule.cpp | 4 ++-- clang/lib/CIR/Lowering/CIRPasses.cpp | 11 +++++------ clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp | 4 ++-- 6 files changed, 15 insertions(+), 16 deletions(-) diff --git a/clang/include/clang/CIR/Dialect/IR/CIRDialect.h b/clang/include/clang/CIR/Dialect/IR/CIRDialect.h index baece7ab02fc7..732d065f81cb3 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIRDialect.h +++ b/clang/include/clang/CIR/Dialect/IR/CIRDialect.h @@ -103,7 +103,7 @@ RecordLayoutAttr tryGetRecordLayout(mlir::ModuleOp mod, mlir::StringAttr name); /// Attempts to construct an llvm::Triple from a module's cir.triple attribute. /// If emitDiag is not null, additional diagnostics information is passed into /// emitDiag upon failure. -mlir::FailureOr<llvm::Triple> +std::optional<llvm::Triple> getTripleFromModule(mlir::ModuleOp mod, llvm::function_ref<mlir::InFlightDiagnostic()> emitDiag = nullptr); } // namespace cir diff --git a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp index caa3527a02f11..0136ed1ccd0dc 100644 --- a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp +++ b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp @@ -402,14 +402,14 @@ static LogicalResult verifyProducedBy(Operation *op, Value operand, return success(); } -mlir::FailureOr<llvm::Triple> cir::getTripleFromModule( +std::optional<llvm::Triple> cir::getTripleFromModule( mlir::ModuleOp mod, llvm::function_ref<mlir::InFlightDiagnostic()> emitDiag) { if (!mod->hasAttr(cir::CIRDialect::getTripleAttrName())) { if (emitDiag) emitDiag() << "module is missing " << cir::CIRDialect::getTripleAttrName() << " attribute"; - return mlir::failure(); + return std::nullopt; } auto tripleAttr = mod->getAttrOfType<mlir::StringAttr>( @@ -418,7 +418,7 @@ mlir::FailureOr<llvm::Triple> cir::getTripleFromModule( if (emitDiag) emitDiag() << "expected a string from module attribute " << cir::CIRDialect::getTripleAttrName(); - return mlir::failure(); + return std::nullopt; } return llvm::Triple{tripleAttr.getValue()}; diff --git a/clang/lib/CIR/Dialect/Transforms/EHABILowering.cpp b/clang/lib/CIR/Dialect/Transforms/EHABILowering.cpp index e3306227aac5e..72f9c786db08e 100644 --- a/clang/lib/CIR/Dialect/Transforms/EHABILowering.cpp +++ b/clang/lib/CIR/Dialect/Transforms/EHABILowering.cpp @@ -1088,8 +1088,8 @@ void CIREHABILoweringPass::runOnOperation() { // The target triple is attached to the module as the "cir.triple" // attribute. If it is absent (e.g. a CIR module parsed from text without a // triple) we cannot determine the ABI and must skip the pass. - auto triple = cir::getTripleFromModule(mod, [&] { return mod.emitWarning(); }); - if (mlir::failed(triple)) + std::optional<llvm::Triple> triple = cir::getTripleFromModule(mod, [&] { return mod.emitWarning(); }); + if (!triple) return; // Select the ABI-specific lowering handler from the triple. The Microsoft diff --git a/clang/lib/CIR/Dialect/Transforms/TargetLowering/LowerModule.cpp b/clang/lib/CIR/Dialect/Transforms/TargetLowering/LowerModule.cpp index 91a6f27ea8b16..b6f6031ddaf2d 100644 --- a/clang/lib/CIR/Dialect/Transforms/TargetLowering/LowerModule.cpp +++ b/clang/lib/CIR/Dialect/Transforms/TargetLowering/LowerModule.cpp @@ -87,8 +87,8 @@ createLowerModule(mlir::ModuleOp module, assert(!cir::MissingFeatures::makeTripleAlwaysPresent()); // Fetch target information. - auto triple = cir::getTripleFromModule(module, emitDiag); - if (mlir::failed(triple)) + std::optional<llvm::Triple> triple = cir::getTripleFromModule(module, emitDiag); + if (!triple) return nullptr; clang::TargetOptions targetOptions; targetOptions.Triple = triple->str(); diff --git a/clang/lib/CIR/Lowering/CIRPasses.cpp b/clang/lib/CIR/Lowering/CIRPasses.cpp index dc4e3128ca26d..0158c7fe37309 100644 --- a/clang/lib/CIR/Lowering/CIRPasses.cpp +++ b/clang/lib/CIR/Lowering/CIRPasses.cpp @@ -78,11 +78,10 @@ runCIRToCIRPasses(mlir::ModuleOp theModule, mlir::MLIRContext &mlirContext, llvm::TimeTraceScope scope("CIR To CIR Passes"); - auto maybeTriple = cir::getTripleFromModule(theModule, + std::optional<llvm::Triple> triple = cir::getTripleFromModule(theModule, [&]{ return theModule.emitError(); }); - if (mlir::failed(maybeTriple)) + if (!triple) return mlir::LogicalResult::failure(); - llvm::Triple &triple = *maybeTriple; auto abiAttr = theModule->getAttrOfType<mlir::StringAttr>( cir::CIRDialect::getTargetABIAttrName()); @@ -126,7 +125,7 @@ runCIRToCIRPasses(mlir::ModuleOp theModule, mlir::MLIRContext &mlirContext, // so it must run after CXXABILowering has lowered C++ ABI types to plain // records the classifier can handle. Only the x86_64 System V classifier // is implemented; other targets are left unchanged. - CallConvTarget target = getCallConvTarget(triple); + CallConvTarget target = getCallConvTarget(triple.value()); if (target != CallConvTarget::None) { // Source the ABI-compatibility version from the module's serialized // #cir.lowering_lang_options so a reloaded .cir classifies the same way @@ -141,8 +140,8 @@ runCIRToCIRPasses(mlir::ModuleOp theModule, mlir::MLIRContext &mlirContext, loweringLangOpts.getClangAbiCompat()); pm.addPass(mlir::createCallConvLoweringPass( target, getX86AVXABILevel(abiAttr.getValue()), - allowsX86TargetAttrAvx(triple, compat), - getX86ABICompatInfo(triple, compat))); + allowsX86TargetAttrAvx(triple.value(), compat), + getX86ABICompatInfo(triple.value(), compat))); } } diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp index 628dc160e251d..0903de9c77f20 100644 --- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp +++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp @@ -5819,9 +5819,9 @@ mlir::LogicalResult CIRToLLVMCpuIdOpLowering::matchAndRewrite( StringRef asmString, constraints; mlir::ModuleOp moduleOp = op->getParentOfType<mlir::ModuleOp>(); - auto triple = cir::getTripleFromModule(moduleOp, + std::optional<llvm::Triple> triple = cir::getTripleFromModule(moduleOp, [&] { return moduleOp.emitError(); }); - if (mlir::failed(triple)) + if (!triple) return mlir::failure(); if (triple->getArch() == llvm::Triple::x86) { asmString = "cpuid"; >From 72963ed03bbd69e613943ae2dbdf68a030dcc87a Mon Sep 17 00:00:00 2001 From: "Li, Ian" <[email protected]> Date: Wed, 7 Oct 2026 21:21:56 -0700 Subject: [PATCH 06/16] copy cir-opt additions from #229575 --- clang/tools/cir-opt/cir-opt.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/clang/tools/cir-opt/cir-opt.cpp b/clang/tools/cir-opt/cir-opt.cpp index fdaf405441003..0a0c791ae494e 100644 --- a/clang/tools/cir-opt/cir-opt.cpp +++ b/clang/tools/cir-opt/cir-opt.cpp @@ -82,6 +82,18 @@ int main(int argc, char **argv) { return mlir::createCXXABILoweringPass(); }); + ::mlir::registerPass([]() -> std::unique_ptr<::mlir::Pass> { + return mlir::createTargetLoweringPass(); + }); + + ::mlir::registerPass([]() -> std::unique_ptr<::mlir::Pass> { + return mlir::createLoweringPreparePass(); + }); + + ::mlir::registerPass([]() -> std::unique_ptr<::mlir::Pass> { + return mlir::createLibOptPass(); + }); + ::mlir::registerPass([]() -> std::unique_ptr<::mlir::Pass> { return mlir::createIdiomRecognizerPass(); }); >From 362290cca48ef863cc0ad67290338d0d85fbca7e Mon Sep 17 00:00:00 2001 From: "Li, Ian" <[email protected]> Date: Wed, 7 Oct 2026 21:35:01 -0700 Subject: [PATCH 07/16] clang-format --- clang/include/clang/CIR/Dialect/IR/CIRDialect.h | 5 +++-- clang/lib/CIR/Dialect/IR/CIRDialect.cpp | 4 ++-- clang/lib/CIR/Dialect/Transforms/CXXABILowering.cpp | 6 +++--- clang/lib/CIR/Dialect/Transforms/EHABILowering.cpp | 3 ++- clang/lib/CIR/Dialect/Transforms/LoweringPrepare.cpp | 2 +- clang/lib/CIR/Dialect/Transforms/TargetLowering.cpp | 6 +++--- .../CIR/Dialect/Transforms/TargetLowering/LowerModule.cpp | 3 ++- .../lib/CIR/Dialect/Transforms/TargetLowering/LowerModule.h | 4 ++-- clang/lib/CIR/Lowering/CIRPasses.cpp | 4 ++-- clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp | 4 ++-- 10 files changed, 22 insertions(+), 19 deletions(-) diff --git a/clang/include/clang/CIR/Dialect/IR/CIRDialect.h b/clang/include/clang/CIR/Dialect/IR/CIRDialect.h index 732d065f81cb3..662942fdeda04 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIRDialect.h +++ b/clang/include/clang/CIR/Dialect/IR/CIRDialect.h @@ -103,8 +103,9 @@ RecordLayoutAttr tryGetRecordLayout(mlir::ModuleOp mod, mlir::StringAttr name); /// Attempts to construct an llvm::Triple from a module's cir.triple attribute. /// If emitDiag is not null, additional diagnostics information is passed into /// emitDiag upon failure. -std::optional<llvm::Triple> -getTripleFromModule(mlir::ModuleOp mod, llvm::function_ref<mlir::InFlightDiagnostic()> emitDiag = nullptr); +std::optional<llvm::Triple> getTripleFromModule( + mlir::ModuleOp mod, + llvm::function_ref<mlir::InFlightDiagnostic()> emitDiag = nullptr); } // namespace cir // TableGen'erated files for MLIR dialects require that a macro be defined when diff --git a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp index 0136ed1ccd0dc..7a208cf4f1b00 100644 --- a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp +++ b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp @@ -403,8 +403,8 @@ static LogicalResult verifyProducedBy(Operation *op, Value operand, } std::optional<llvm::Triple> cir::getTripleFromModule( - mlir::ModuleOp mod, - llvm::function_ref<mlir::InFlightDiagnostic()> emitDiag) { + mlir::ModuleOp mod, + llvm::function_ref<mlir::InFlightDiagnostic()> emitDiag) { if (!mod->hasAttr(cir::CIRDialect::getTripleAttrName())) { if (emitDiag) emitDiag() << "module is missing " << cir::CIRDialect::getTripleAttrName() diff --git a/clang/lib/CIR/Dialect/Transforms/CXXABILowering.cpp b/clang/lib/CIR/Dialect/Transforms/CXXABILowering.cpp index b57b994bea88c..7c7de931fdc70 100644 --- a/clang/lib/CIR/Dialect/Transforms/CXXABILowering.cpp +++ b/clang/lib/CIR/Dialect/Transforms/CXXABILowering.cpp @@ -895,10 +895,10 @@ void CXXABILoweringPass::runOnOperation() { auto diag = [&] { return mod.emitWarning("cannot create a CIR lower module, skipping the ") - << getName() << " pass: "; + << getName() << " pass: "; }; - std::unique_ptr<cir::LowerModule> lowerModule = cir::createLowerModule( - mod, diag); + std::unique_ptr<cir::LowerModule> lowerModule = + cir::createLowerModule(mod, diag); // If lower module is not available, skip the ABI lowering pass. if (!lowerModule) return; diff --git a/clang/lib/CIR/Dialect/Transforms/EHABILowering.cpp b/clang/lib/CIR/Dialect/Transforms/EHABILowering.cpp index 72f9c786db08e..668016a432308 100644 --- a/clang/lib/CIR/Dialect/Transforms/EHABILowering.cpp +++ b/clang/lib/CIR/Dialect/Transforms/EHABILowering.cpp @@ -1088,7 +1088,8 @@ void CIREHABILoweringPass::runOnOperation() { // The target triple is attached to the module as the "cir.triple" // attribute. If it is absent (e.g. a CIR module parsed from text without a // triple) we cannot determine the ABI and must skip the pass. - std::optional<llvm::Triple> triple = cir::getTripleFromModule(mod, [&] { return mod.emitWarning(); }); + std::optional<llvm::Triple> triple = + cir::getTripleFromModule(mod, [&] { return mod.emitWarning(); }); if (!triple) return; diff --git a/clang/lib/CIR/Dialect/Transforms/LoweringPrepare.cpp b/clang/lib/CIR/Dialect/Transforms/LoweringPrepare.cpp index 106298629c65e..e35eb52fabda2 100644 --- a/clang/lib/CIR/Dialect/Transforms/LoweringPrepare.cpp +++ b/clang/lib/CIR/Dialect/Transforms/LoweringPrepare.cpp @@ -3063,7 +3063,7 @@ void LoweringPreparePass::runOnOperation() { auto diag = [&] { return mlirModule.emitError("cannot create a CIR lower module for ") - << getName() << " pass: "; + << getName() << " pass: "; }; lowerModule = cir::createLowerModule(mlirModule, diag); if (!lowerModule) diff --git a/clang/lib/CIR/Dialect/Transforms/TargetLowering.cpp b/clang/lib/CIR/Dialect/Transforms/TargetLowering.cpp index e978acda6cca9..f545fbb6bbecf 100644 --- a/clang/lib/CIR/Dialect/Transforms/TargetLowering.cpp +++ b/clang/lib/CIR/Dialect/Transforms/TargetLowering.cpp @@ -298,10 +298,10 @@ void TargetLoweringPass::runOnOperation() { auto mod = mlir::cast<mlir::ModuleOp>(getOperation()); auto diag = [&] { return mod.emitWarning("cannot create a CIR lower module, skipping the ") - << getName() << " pass: "; + << getName() << " pass: "; }; - std::unique_ptr<cir::LowerModule> lowerModule = cir::createLowerModule( - mod, diag); + std::unique_ptr<cir::LowerModule> lowerModule = + cir::createLowerModule(mod, diag); // If lower module is not available, skip the target lowering pass. if (!lowerModule) return; diff --git a/clang/lib/CIR/Dialect/Transforms/TargetLowering/LowerModule.cpp b/clang/lib/CIR/Dialect/Transforms/TargetLowering/LowerModule.cpp index b6f6031ddaf2d..a5ee43c544344 100644 --- a/clang/lib/CIR/Dialect/Transforms/TargetLowering/LowerModule.cpp +++ b/clang/lib/CIR/Dialect/Transforms/TargetLowering/LowerModule.cpp @@ -87,7 +87,8 @@ createLowerModule(mlir::ModuleOp module, assert(!cir::MissingFeatures::makeTripleAlwaysPresent()); // Fetch target information. - std::optional<llvm::Triple> triple = cir::getTripleFromModule(module, emitDiag); + std::optional<llvm::Triple> triple = + cir::getTripleFromModule(module, emitDiag); if (!triple) return nullptr; clang::TargetOptions targetOptions; diff --git a/clang/lib/CIR/Dialect/Transforms/TargetLowering/LowerModule.h b/clang/lib/CIR/Dialect/Transforms/TargetLowering/LowerModule.h index 588bc496bdaba..dbd28430c6df3 100644 --- a/clang/lib/CIR/Dialect/Transforms/TargetLowering/LowerModule.h +++ b/clang/lib/CIR/Dialect/Transforms/TargetLowering/LowerModule.h @@ -57,8 +57,8 @@ class LowerModule { const TargetLoweringInfo &getTargetLoweringInfo(); }; -std::unique_ptr<LowerModule> -createLowerModule(mlir::ModuleOp module, +std::unique_ptr<LowerModule> createLowerModule( + mlir::ModuleOp module, llvm::function_ref<mlir::InFlightDiagnostic()> emitDiag = nullptr); } // namespace cir diff --git a/clang/lib/CIR/Lowering/CIRPasses.cpp b/clang/lib/CIR/Lowering/CIRPasses.cpp index 0158c7fe37309..cbc0c515bf275 100644 --- a/clang/lib/CIR/Lowering/CIRPasses.cpp +++ b/clang/lib/CIR/Lowering/CIRPasses.cpp @@ -78,8 +78,8 @@ runCIRToCIRPasses(mlir::ModuleOp theModule, mlir::MLIRContext &mlirContext, llvm::TimeTraceScope scope("CIR To CIR Passes"); - std::optional<llvm::Triple> triple = cir::getTripleFromModule(theModule, - [&]{ return theModule.emitError(); }); + std::optional<llvm::Triple> triple = cir::getTripleFromModule( + theModule, [&] { return theModule.emitError(); }); if (!triple) return mlir::LogicalResult::failure(); diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp index 0903de9c77f20..dc99dd0b439b0 100644 --- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp +++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp @@ -5819,8 +5819,8 @@ mlir::LogicalResult CIRToLLVMCpuIdOpLowering::matchAndRewrite( StringRef asmString, constraints; mlir::ModuleOp moduleOp = op->getParentOfType<mlir::ModuleOp>(); - std::optional<llvm::Triple> triple = cir::getTripleFromModule(moduleOp, - [&] { return moduleOp.emitError(); }); + std::optional<llvm::Triple> triple = + cir::getTripleFromModule(moduleOp, [&] { return moduleOp.emitError(); }); if (!triple) return mlir::failure(); if (triple->getArch() == llvm::Triple::x86) { >From 15677e38ac14face59e9174713c7cc2e87596d00 Mon Sep 17 00:00:00 2001 From: "Li, Ian" <[email protected]> Date: Wed, 7 Oct 2026 23:36:53 -0700 Subject: [PATCH 08/16] draft up test cases --- .../CIR/Lowering/cir-to-llvm-module-attrs.cir | 49 +++++++ .../Transforms/cxx-abi-lowering-bad-attrs.cir | 137 ++++++++++++++++++ .../Transforms/eh-abi-lowering-bad-attrs.cir | 41 ++++++ .../lowering-prepare-module-attrs.cir | 130 +++++++++++++++++ .../target-lowering-module-attrs.cir | 137 ++++++++++++++++++ 5 files changed, 494 insertions(+) create mode 100644 clang/test/CIR/Lowering/cir-to-llvm-module-attrs.cir create mode 100644 clang/test/CIR/Transforms/cxx-abi-lowering-bad-attrs.cir create mode 100644 clang/test/CIR/Transforms/eh-abi-lowering-bad-attrs.cir create mode 100644 clang/test/CIR/Transforms/lowering-prepare-module-attrs.cir create mode 100644 clang/test/CIR/Transforms/target-lowering-module-attrs.cir diff --git a/clang/test/CIR/Lowering/cir-to-llvm-module-attrs.cir b/clang/test/CIR/Lowering/cir-to-llvm-module-attrs.cir new file mode 100644 index 0000000000000..ed861075a5c36 --- /dev/null +++ b/clang/test/CIR/Lowering/cir-to-llvm-module-attrs.cir @@ -0,0 +1,49 @@ +// RUN: cir-opt %s -cir-to-llvm -verify-diagnostics -split-input-file +// RUN: not cir-opt %s -cir-to-llvm -split-input-file 2>/dev/null \ +// RUN: | FileCheck %s --implicit-check-not=llvm.func + +// -cir-to-llvm relies on cir.triple module attributes: Check that missing or +// malformed cir.triple attributes read by -cir-to-llvm do not cause asserts or +// compiler crashes, and are diagnosed properly. + + +// Missing cir.triple. + +!s32i = !cir.int<s, 32> +// expected-warning @below {{module is missing cir.triple attribute}} +// expected-error @below {{module is missing cir.triple attribute}} +module { + cir.func @missing_triple(%p: !cir.ptr<!s32i>, %a: !s32i, %b: !s32i) { + // expected-error @below {{failed to legalize operation 'cir.cpuid'}} + cir.cpuid %p, %a, %b : !cir.ptr<!s32i>, !s32i, !s32i + cir.return + } +} + +// ----- + +// Non-string cir.triple. + +!s32i = !cir.int<s, 32> +// expected-warning @below {{expected a string from module attribute cir.triple}} +// expected-error @below {{expected a string from module attribute cir.triple}} +module attributes {cir.triple = 42 : i32} { + cir.func @non_string_triple(%p: !cir.ptr<!s32i>, %a: !s32i, %b: !s32i) { + // expected-error @below {{failed to legalize operation 'cir.cpuid'}} + cir.cpuid %p, %a, %b : !cir.ptr<!s32i>, !s32i, !s32i + cir.return + } +} + +// ----- + +// Valid cir.triple. + +!s32i = !cir.int<s, 32> +module attributes {cir.triple = "x86_64-unknown-linux-gnu"} { + // CHECK-LABEL: llvm.func @valid_triple( + cir.func @valid_triple(%p: !cir.ptr<!s32i>, %a: !s32i, %b: !s32i) { + cir.cpuid %p, %a, %b : !cir.ptr<!s32i>, !s32i, !s32i + cir.return + } +} diff --git a/clang/test/CIR/Transforms/cxx-abi-lowering-bad-attrs.cir b/clang/test/CIR/Transforms/cxx-abi-lowering-bad-attrs.cir new file mode 100644 index 0000000000000..5d13956c63af4 --- /dev/null +++ b/clang/test/CIR/Transforms/cxx-abi-lowering-bad-attrs.cir @@ -0,0 +1,137 @@ +// RUN: cir-opt %s -cir-cxxabi-lowering -verify-diagnostics -split-input-file +// RUN: cir-opt %s -cir-cxxabi-lowering -split-input-file 2>/dev/null | FileCheck %s + +// Check that missing or malformed module attributes required/used by +// -cir-cxxabi-lowering do not cause asserts or compiler crashes, and are +// diagnosed properly. The pass should warn and skip instead of failing, so +// every module is still printed. + + +// Missing cir.triple. + +// expected-warning @below {{cannot create a CIR lower module, skipping the CXXABILowering pass: module is missing cir.triple attribute}} +module { + // CHECK-LABEL: cir.func @missing_triple( + cir.func @missing_triple() { + cir.return + } +} + +// ----- + +// Non-string cir.triple. + +// expected-warning @below {{cannot create a CIR lower module, skipping the CXXABILowering pass: expected a string from module attribute cir.triple}} +module attributes {cir.triple = 42 : i32} { + // CHECK-LABEL: cir.func @non_string_triple( + cir.func @non_string_triple() { + cir.return + } +} + +// ----- + +// Empty cir.triple. + +// expected-warning @below {{cannot create a CIR lower module, skipping the CXXABILowering pass: unknown triple '' in cir.triple attribute}} +module attributes {cir.triple = ""} { + // CHECK-LABEL: cir.func @empty_triple( + cir.func @empty_triple() { + cir.return + } +} + +// ----- + +// Malformed cir.triple. + +// expected-warning @below {{cannot create a CIR lower module, skipping the CXXABILowering pass: unknown triple 'garbage' in cir.triple attribute}} +module attributes {cir.triple = "garbage"} { + // CHECK-LABEL: cir.func @malformed_triple( + cir.func @malformed_triple() { + cir.return + } +} + +// ----- + +// Well-formed cir.triple with an unknown target. + +// expected-warning @below {{cannot create a CIR lower module, skipping the CXXABILowering pass: unknown triple 'foobar-unknown-unknown' in cir.triple attribute}} +module attributes {cir.triple = "foobar-unknown-unknown"} { + // CHECK-LABEL: cir.func @unknown_triple( + cir.func @unknown_triple() { + cir.return + } +} + +// ----- + +// Valid cir.triple without cir.opt_info. + +module attributes {cir.triple = "x86_64-unknown-linux-gnu"} { + // CHECK-LABEL: cir.func @valid_triple( + cir.func @valid_triple() { + cir.return + } +} + +// ----- + +// Valid cir.triple with a valid cir.opt_info. + +module attributes { + cir.triple = "x86_64-unknown-linux-gnu", + cir.opt_info = #cir.opt_info<level = 2, size = 1> +} { + // CHECK-LABEL: cir.func @valid_opt_info( + cir.func @valid_opt_info() { + cir.return + } +} + +// ----- + +// Valid cir.triple with a cir.opt_info that is not an OptInfoAttr. + +// expected-warning @below {{cannot create a CIR lower module, skipping the CXXABILowering pass: malformed cir.opt_info attribute}} +module attributes { + cir.triple = "x86_64-unknown-linux-gnu", + cir.opt_info = 1 : i32 +} { + // CHECK-LABEL: cir.func @malformed_opt_info( + cir.func @malformed_opt_info() { + cir.return + } +} + +// ----- + +// Valid cir.triple with a string cir.opt_info. + +// expected-warning @below {{cannot create a CIR lower module, skipping the CXXABILowering pass: malformed cir.opt_info attribute}} +module attributes { + cir.triple = "x86_64-unknown-linux-gnu", + cir.opt_info = "O2" +} { + // CHECK-LABEL: cir.func @string_opt_info( + cir.func @string_opt_info() { + cir.return + } +} + +// ----- + +// Valid cir.triple with a dictionary cir.opt_info that mimics OptInfoAttr's +// fields. + +// expected-warning @below {{cannot create a CIR lower module, skipping the CXXABILowering pass: malformed cir.opt_info attribute}} +module attributes { + cir.triple = "x86_64-unknown-linux-gnu", + cir.opt_info = {level = 2 : i32, size = 1 : i32} +} { + // CHECK-LABEL: cir.func @dict_opt_info( + cir.func @dict_opt_info() { + cir.return + } +} diff --git a/clang/test/CIR/Transforms/eh-abi-lowering-bad-attrs.cir b/clang/test/CIR/Transforms/eh-abi-lowering-bad-attrs.cir new file mode 100644 index 0000000000000..fc4be2550cb3b --- /dev/null +++ b/clang/test/CIR/Transforms/eh-abi-lowering-bad-attrs.cir @@ -0,0 +1,41 @@ +// RUN: cir-opt %s -cir-eh-abi-lowering -verify-diagnostics -split-input-file +// RUN: cir-opt %s -cir-eh-abi-lowering -split-input-file 2>/dev/null | FileCheck %s + +// Check that missing or malformed cir.triple attributes required by +// -cir-eh-abi-lowering do not cause asserts or compiler crashes, and are +// diagnosed properly. The pass should warn and skip instead of failing, so +// every module is still printed. + + +// Missing cir.triple. + +// expected-warning @below {{module is missing cir.triple attribute}} +module { + // CHECK-LABEL: cir.func @missing_triple( + cir.func @missing_triple() { + cir.return + } +} + +// ----- + +// Non-string cir.triple. + +// expected-warning @below {{expected a string from module attribute cir.triple}} +module attributes {cir.triple = 42 : i32} { + // CHECK-LABEL: cir.func @non_string_triple( + cir.func @non_string_triple() { + cir.return + } +} + +// ----- + +// Valid cir.triple. + +module attributes {cir.triple = "x86_64-unknown-linux-gnu"} { + // CHECK-LABEL: cir.func @valid_triple( + cir.func @valid_triple() { + cir.return + } +} diff --git a/clang/test/CIR/Transforms/lowering-prepare-module-attrs.cir b/clang/test/CIR/Transforms/lowering-prepare-module-attrs.cir new file mode 100644 index 0000000000000..f42bad16d7bc3 --- /dev/null +++ b/clang/test/CIR/Transforms/lowering-prepare-module-attrs.cir @@ -0,0 +1,130 @@ +// RUN: cir-opt %s -cir-lowering-prepare -verify-diagnostics -split-input-file +// RUN: not cir-opt %s -cir-lowering-prepare -split-input-file 2>/dev/null \ +// RUN: | FileCheck %s --implicit-check-not=cir.func + +// Check that missing or malformed module attributes required/used by +// -cir-lowering-prepare do not cause asserts or compiler crashes, and are +// diagnosed properly. The pass should fail on bad attributes, so only modules +// with valid attributes are printed. + + +// Missing cir.triple. + +// expected-error @below {{cannot create a CIR lower module for LoweringPrepare pass: module is missing cir.triple attribute}} +module { + cir.func @missing_triple() { + cir.return + } +} + +// ----- + +// Non-string cir.triple. + +// expected-error @below {{cannot create a CIR lower module for LoweringPrepare pass: expected a string from module attribute cir.triple}} +module attributes {cir.triple = 42 : i32} { + cir.func @non_string_triple() { + cir.return + } +} + +// ----- + +// Empty cir.triple. + +// expected-error @below {{cannot create a CIR lower module for LoweringPrepare pass: unknown triple '' in cir.triple attribute}} +module attributes {cir.triple = ""} { + cir.func @empty_triple() { + cir.return + } +} + +// ----- + +// Malformed cir.triple. + +// expected-error @below {{cannot create a CIR lower module for LoweringPrepare pass: unknown triple 'garbage' in cir.triple attribute}} +module attributes {cir.triple = "garbage"} { + cir.func @malformed_triple() { + cir.return + } +} + +// ----- + +// Well-formed cir.triple with an unknown target. + +// expected-error @below {{cannot create a CIR lower module for LoweringPrepare pass: unknown triple 'foobar-unknown-unknown' in cir.triple attribute}} +module attributes {cir.triple = "foobar-unknown-unknown"} { + cir.func @unknown_triple() { + cir.return + } +} + +// ----- + +// Valid cir.triple without cir.opt_info. + +module attributes {cir.triple = "x86_64-unknown-linux-gnu"} { + // CHECK-LABEL: cir.func @valid_triple( + cir.func @valid_triple() { + cir.return + } +} + +// ----- + +// Valid cir.triple with a valid cir.opt_info. + +module attributes { + cir.triple = "x86_64-unknown-linux-gnu", + cir.opt_info = #cir.opt_info<level = 2, size = 1> +} { + // CHECK-LABEL: cir.func @valid_opt_info( + cir.func @valid_opt_info() { + cir.return + } +} + +// ----- + +// Valid cir.triple with a cir.opt_info that is not an OptInfoAttr. + +// expected-error @below {{cannot create a CIR lower module for LoweringPrepare pass: malformed cir.opt_info attribute}} +module attributes { + cir.triple = "x86_64-unknown-linux-gnu", + cir.opt_info = 1 : i32 +} { + cir.func @malformed_opt_info() { + cir.return + } +} + +// ----- + +// Valid cir.triple with a string cir.opt_info. + +// expected-error @below {{cannot create a CIR lower module for LoweringPrepare pass: malformed cir.opt_info attribute}} +module attributes { + cir.triple = "x86_64-unknown-linux-gnu", + cir.opt_info = "O2" +} { + cir.func @string_opt_info() { + cir.return + } +} + +// ----- + +// Valid cir.triple with a dictionary cir.opt_info that mimics OptInfoAttr's +// fields. + +// expected-error @below {{cannot create a CIR lower module for LoweringPrepare pass: malformed cir.opt_info attribute}} +module attributes { + cir.triple = "x86_64-unknown-linux-gnu", + cir.opt_info = {level = 2 : i32, size = 1 : i32} +} { + cir.func @dict_opt_info() { + cir.return + } +} diff --git a/clang/test/CIR/Transforms/target-lowering-module-attrs.cir b/clang/test/CIR/Transforms/target-lowering-module-attrs.cir new file mode 100644 index 0000000000000..36813d4d707a4 --- /dev/null +++ b/clang/test/CIR/Transforms/target-lowering-module-attrs.cir @@ -0,0 +1,137 @@ +// RUN: cir-opt %s -cir-target-lowering -verify-diagnostics -split-input-file +// RUN: cir-opt %s -cir-target-lowering -split-input-file 2>/dev/null | FileCheck %s + +// Check that missing or malformed module attributes required/used by +// -cir-target-lowering do not cause asserts or compiler crashes, and are +// diagnosed properly. The pass should warn and skip instead of failing, so +// every module is still printed. + + +// Missing cir.triple. + +// expected-warning @below {{cannot create a CIR lower module, skipping the TargetLowering pass: module is missing cir.triple attribute}} +module { + // CHECK-LABEL: cir.func @missing_triple( + cir.func @missing_triple() { + cir.return + } +} + +// ----- + +// Non-string cir.triple. + +// expected-warning @below {{cannot create a CIR lower module, skipping the TargetLowering pass: expected a string from module attribute cir.triple}} +module attributes {cir.triple = 42 : i32} { + // CHECK-LABEL: cir.func @non_string_triple( + cir.func @non_string_triple() { + cir.return + } +} + +// ----- + +// Empty cir.triple. + +// expected-warning @below {{cannot create a CIR lower module, skipping the TargetLowering pass: unknown triple '' in cir.triple attribute}} +module attributes {cir.triple = ""} { + // CHECK-LABEL: cir.func @empty_triple( + cir.func @empty_triple() { + cir.return + } +} + +// ----- + +// Malformed cir.triple. + +// expected-warning @below {{cannot create a CIR lower module, skipping the TargetLowering pass: unknown triple 'garbage' in cir.triple attribute}} +module attributes {cir.triple = "garbage"} { + // CHECK-LABEL: cir.func @malformed_triple( + cir.func @malformed_triple() { + cir.return + } +} + +// ----- + +// Well-formed cir.triple with an unknown target. + +// expected-warning @below {{cannot create a CIR lower module, skipping the TargetLowering pass: unknown triple 'foobar-unknown-unknown' in cir.triple attribute}} +module attributes {cir.triple = "foobar-unknown-unknown"} { + // CHECK-LABEL: cir.func @unknown_triple( + cir.func @unknown_triple() { + cir.return + } +} + +// ----- + +// Valid cir.triple without cir.opt_info. + +module attributes {cir.triple = "x86_64-unknown-linux-gnu"} { + // CHECK-LABEL: cir.func @valid_triple( + cir.func @valid_triple() { + cir.return + } +} + +// ----- + +// Valid cir.triple with a valid cir.opt_info. + +module attributes { + cir.triple = "x86_64-unknown-linux-gnu", + cir.opt_info = #cir.opt_info<level = 2, size = 1> +} { + // CHECK-LABEL: cir.func @valid_opt_info( + cir.func @valid_opt_info() { + cir.return + } +} + +// ----- + +// Valid cir.triple with a cir.opt_info that is not an OptInfoAttr. + +// expected-warning @below {{cannot create a CIR lower module, skipping the TargetLowering pass: malformed cir.opt_info attribute}} +module attributes { + cir.triple = "x86_64-unknown-linux-gnu", + cir.opt_info = 1 : i32 +} { + // CHECK-LABEL: cir.func @malformed_opt_info( + cir.func @malformed_opt_info() { + cir.return + } +} + +// ----- + +// Valid cir.triple with a string cir.opt_info. + +// expected-warning @below {{cannot create a CIR lower module, skipping the TargetLowering pass: malformed cir.opt_info attribute}} +module attributes { + cir.triple = "x86_64-unknown-linux-gnu", + cir.opt_info = "O2" +} { + // CHECK-LABEL: cir.func @string_opt_info( + cir.func @string_opt_info() { + cir.return + } +} + +// ----- + +// Valid cir.triple with a dictionary cir.opt_info that mimics OptInfoAttr's +// fields. + +// expected-warning @below {{cannot create a CIR lower module, skipping the TargetLowering pass: malformed cir.opt_info attribute}} +module attributes { + cir.triple = "x86_64-unknown-linux-gnu", + cir.opt_info = {level = 2 : i32, size = 1 : i32} +} { + // CHECK-LABEL: cir.func @dict_opt_info( + cir.func @dict_opt_info() { + cir.return + } +} >From aeaa75c8a3307620b83229d3d6a8b2ad12815926 Mon Sep 17 00:00:00 2001 From: "Li, Ian" <[email protected]> Date: Thu, 8 Oct 2026 00:28:43 -0700 Subject: [PATCH 09/16] this test case is already covered in lowering-prepare-module-attrs.cir --- clang/test/CIR/Transforms/lowering-prepare-no-triple.cir | 5 ----- 1 file changed, 5 deletions(-) delete mode 100644 clang/test/CIR/Transforms/lowering-prepare-no-triple.cir diff --git a/clang/test/CIR/Transforms/lowering-prepare-no-triple.cir b/clang/test/CIR/Transforms/lowering-prepare-no-triple.cir deleted file mode 100644 index bebdf3dd57f73..0000000000000 --- a/clang/test/CIR/Transforms/lowering-prepare-no-triple.cir +++ /dev/null @@ -1,5 +0,0 @@ -// RUN: cir-opt %s --cir-lowering-prepare -verify-diagnostics - -// expected-error @below {{cir-lowering-prepare requires a module with a triple}} -module { -} >From 12140d978c541100c9fbad75c5a79a12ae5d839e Mon Sep 17 00:00:00 2001 From: "Li, Ian" <[email protected]> Date: Thu, 8 Oct 2026 18:53:32 -0700 Subject: [PATCH 10/16] update cir.cpuid op lowering diagnostics to provide more info --- clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp | 7 +++++-- clang/test/CIR/Lowering/cir-to-llvm-module-attrs.cir | 10 +++++----- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp index a74cdbff3d3bd..8a49790120c5f 100644 --- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp +++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp @@ -5830,8 +5830,11 @@ mlir::LogicalResult CIRToLLVMCpuIdOpLowering::matchAndRewrite( StringRef asmString, constraints; mlir::ModuleOp moduleOp = op->getParentOfType<mlir::ModuleOp>(); - std::optional<llvm::Triple> triple = - cir::getTripleFromModule(moduleOp, [&] { return moduleOp.emitError(); }); + auto diag = [&] { + return moduleOp.emitError("cannot lower ") + << op.getOperationName() << " op: "; + }; + std::optional<llvm::Triple> triple = cir::getTripleFromModule(moduleOp, diag); if (!triple) return mlir::failure(); if (triple->getArch() == llvm::Triple::x86) { diff --git a/clang/test/CIR/Lowering/cir-to-llvm-module-attrs.cir b/clang/test/CIR/Lowering/cir-to-llvm-module-attrs.cir index ed861075a5c36..0cf5c4a3327c3 100644 --- a/clang/test/CIR/Lowering/cir-to-llvm-module-attrs.cir +++ b/clang/test/CIR/Lowering/cir-to-llvm-module-attrs.cir @@ -2,16 +2,16 @@ // RUN: not cir-opt %s -cir-to-llvm -split-input-file 2>/dev/null \ // RUN: | FileCheck %s --implicit-check-not=llvm.func -// -cir-to-llvm relies on cir.triple module attributes: Check that missing or -// malformed cir.triple attributes read by -cir-to-llvm do not cause asserts or -// compiler crashes, and are diagnosed properly. +// -cir-to-llvm relies on cir.triple module attributes to handle cir.cpuid ops: +// Check that missing or malformed cir.triple attributes read by -cir-to-llvm do +// not cause asserts or compiler crashes, and are diagnosed properly. // Missing cir.triple. !s32i = !cir.int<s, 32> // expected-warning @below {{module is missing cir.triple attribute}} -// expected-error @below {{module is missing cir.triple attribute}} +// expected-error @below {{cannot lower cir.cpuid op: module is missing cir.triple attribute}} module { cir.func @missing_triple(%p: !cir.ptr<!s32i>, %a: !s32i, %b: !s32i) { // expected-error @below {{failed to legalize operation 'cir.cpuid'}} @@ -26,7 +26,7 @@ module { !s32i = !cir.int<s, 32> // expected-warning @below {{expected a string from module attribute cir.triple}} -// expected-error @below {{expected a string from module attribute cir.triple}} +// expected-error @below {{cannot lower cir.cpuid op: expected a string from module attribute cir.triple}} module attributes {cir.triple = 42 : i32} { cir.func @non_string_triple(%p: !cir.ptr<!s32i>, %a: !s32i, %b: !s32i) { // expected-error @below {{failed to legalize operation 'cir.cpuid'}} >From 9f08e15b96a4302654f397cd5302e788c0b282ff Mon Sep 17 00:00:00 2001 From: "Li, Ian" <[email protected]> Date: Tue, 13 Oct 2026 13:05:35 -0700 Subject: [PATCH 11/16] WIP: remove diagnostics from createLowerModule and move checking and validation to verifyOperationAttrs --- .../include/clang/CIR/Dialect/IR/CIRDialect.h | 6 +-- clang/lib/CIR/Dialect/IR/CIRDialect.cpp | 45 +++++++++++++------ .../CIR/Dialect/Transforms/CXXABILowering.cpp | 12 +++-- .../Dialect/Transforms/LoweringPrepare.cpp | 9 ++-- .../CIR/Dialect/Transforms/TargetLowering.cpp | 12 +++-- .../Transforms/TargetLowering/LowerModule.cpp | 18 ++------ .../Transforms/TargetLowering/LowerModule.h | 4 +- 7 files changed, 52 insertions(+), 54 deletions(-) diff --git a/clang/include/clang/CIR/Dialect/IR/CIRDialect.h b/clang/include/clang/CIR/Dialect/IR/CIRDialect.h index 662942fdeda04..764a48787dbd0 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIRDialect.h +++ b/clang/include/clang/CIR/Dialect/IR/CIRDialect.h @@ -101,11 +101,7 @@ RecordLayoutAttr getRecordLayout(mlir::ModuleOp mod, mlir::StringAttr name); RecordLayoutAttr tryGetRecordLayout(mlir::ModuleOp mod, mlir::StringAttr name); /// Attempts to construct an llvm::Triple from a module's cir.triple attribute. -/// If emitDiag is not null, additional diagnostics information is passed into -/// emitDiag upon failure. -std::optional<llvm::Triple> getTripleFromModule( - mlir::ModuleOp mod, - llvm::function_ref<mlir::InFlightDiagnostic()> emitDiag = nullptr); +std::optional<llvm::Triple> getTripleFromModule(mlir::ModuleOp mod); } // namespace cir // TableGen'erated files for MLIR dialects require that a macro be defined when diff --git a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp index f7c4955d9ba53..4d62441f26d2c 100644 --- a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp +++ b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp @@ -12,6 +12,7 @@ #include "clang/CIR/Dialect/IR/CIRDialect.h" +#include "clang/Basic/TargetInfo.h" #include "clang/CIR/Dialect/IR/CIRAttrs.h" #include "clang/CIR/Dialect/IR/CIROpsEnums.h" #include "clang/CIR/Dialect/IR/CIRTypes.h" @@ -287,6 +288,31 @@ cir::CIRDialect::verifyOperationAttribute(mlir::Operation *op, /*trailingZerosNum=*/0); } + if (attrName == getTripleAttrName()) { + auto tripleStr = mlir::dyn_cast<mlir::StringAttr>(attr.getValue()); + if (!tripleStr) + return op->emitOpError() << "expects '" << getTripleAttrName() << "' to " + << " be a string"; + llvm::Triple triple = llvm::Triple(tripleStr.getValue()); + clang::TargetOptions targetOptions; + targetOptions.Triple = tripleStr.getValue(); + // "Validate" our triple by checking if it can successfully initialize into + // a TargetInfo: + if (!clang::targets::AllocateTarget(triple, targetOptions)) { + return op->emitOpError() << "unknown triple '" << tripleStr.getValue() + << "' in '" << getTripleAttrName() + << "' attribute"; + } + } + + if (attrName == getOptInfoAttrName()) { + auto optInfo = mlir::dyn_cast<cir::OptInfoAttr>(attr.getValue()); + if (!optInfo) + return op->emitOpError() << "malformed " + << cir::CIRDialect::getOptInfoAttrName() + << " attribute"; + } + return success(); } @@ -402,24 +428,17 @@ static LogicalResult verifyProducedBy(Operation *op, Value operand, return success(); } -std::optional<llvm::Triple> cir::getTripleFromModule( - mlir::ModuleOp mod, - llvm::function_ref<mlir::InFlightDiagnostic()> emitDiag) { - if (!mod->hasAttr(cir::CIRDialect::getTripleAttrName())) { - if (emitDiag) - emitDiag() << "module is missing " << cir::CIRDialect::getTripleAttrName() - << " attribute"; +std::optional<llvm::Triple> cir::getTripleFromModule(mlir::ModuleOp mod) { + // Verifying the validity of the triple attribute happens in + // cir::CIRDialect::verifyOperationAttribute; verifyOperationAttribute + // should error first if we have an invalid attribute. + if (!mod->hasAttr(cir::CIRDialect::getTripleAttrName())) return std::nullopt; - } auto tripleAttr = mod->getAttrOfType<mlir::StringAttr>( cir::CIRDialect::getTripleAttrName()); - if (!tripleAttr) { - if (emitDiag) - emitDiag() << "expected a string from module attribute " - << cir::CIRDialect::getTripleAttrName(); + if (!tripleAttr) return std::nullopt; - } return llvm::Triple{tripleAttr.getValue()}; } diff --git a/clang/lib/CIR/Dialect/Transforms/CXXABILowering.cpp b/clang/lib/CIR/Dialect/Transforms/CXXABILowering.cpp index c7aa0dc68f686..6f4fa4176890c 100644 --- a/clang/lib/CIR/Dialect/Transforms/CXXABILowering.cpp +++ b/clang/lib/CIR/Dialect/Transforms/CXXABILowering.cpp @@ -900,15 +900,13 @@ void CXXABILoweringPass::runOnOperation() { auto mod = mlir::cast<mlir::ModuleOp>(getOperation()); mlir::MLIRContext *ctx = mod.getContext(); - auto diag = [&] { - return mod.emitWarning("cannot create a CIR lower module, skipping the ") - << getName() << " pass: "; - }; - std::unique_ptr<cir::LowerModule> lowerModule = - cir::createLowerModule(mod, diag); + std::unique_ptr<cir::LowerModule> lowerModule = cir::createLowerModule(mod); // If lower module is not available, skip the ABI lowering pass. - if (!lowerModule) + if (!lowerModule) { + mod.emitWarning("cannot create a CIR lower module, skipping the ") + << getName() << " pass: "; return; + } mlir::DataLayout dataLayout(mod); CIRABITypeConverter typeConverter(*ctx, dataLayout, *lowerModule); diff --git a/clang/lib/CIR/Dialect/Transforms/LoweringPrepare.cpp b/clang/lib/CIR/Dialect/Transforms/LoweringPrepare.cpp index 5d846af5b64dc..13d12012423c6 100644 --- a/clang/lib/CIR/Dialect/Transforms/LoweringPrepare.cpp +++ b/clang/lib/CIR/Dialect/Transforms/LoweringPrepare.cpp @@ -3181,13 +3181,12 @@ void LoweringPreparePass::buildCUDARegisterVars(cir::CIRBaseBuilderTy &builder, void LoweringPreparePass::runOnOperation() { mlirModule = getOperation(); - auto diag = [&] { - return mlirModule.emitError("cannot create a CIR lower module for ") + lowerModule = cir::createLowerModule(mlirModule); + if (!lowerModule) { + mlirModule.emitError("cannot create a CIR lower module for ") << getName() << " pass: "; - }; - lowerModule = cir::createLowerModule(mlirModule, diag); - if (!lowerModule) return signalPassFailure(); + } llvm::SmallVector<mlir::Operation *> opsToTransform; diff --git a/clang/lib/CIR/Dialect/Transforms/TargetLowering.cpp b/clang/lib/CIR/Dialect/Transforms/TargetLowering.cpp index f545fbb6bbecf..40e956c540471 100644 --- a/clang/lib/CIR/Dialect/Transforms/TargetLowering.cpp +++ b/clang/lib/CIR/Dialect/Transforms/TargetLowering.cpp @@ -296,15 +296,13 @@ populateTargetLoweringConversionTarget(mlir::ConversionTarget &target, void TargetLoweringPass::runOnOperation() { auto mod = mlir::cast<mlir::ModuleOp>(getOperation()); - auto diag = [&] { - return mod.emitWarning("cannot create a CIR lower module, skipping the ") - << getName() << " pass: "; - }; - std::unique_ptr<cir::LowerModule> lowerModule = - cir::createLowerModule(mod, diag); + std::unique_ptr<cir::LowerModule> lowerModule = cir::createLowerModule(mod); // If lower module is not available, skip the target lowering pass. - if (!lowerModule) + if (!lowerModule) { + mod.emitWarning("cannot create a CIR lower module, skipping the ") + << getName() << " pass: "; return; + } const auto &targetInfo = lowerModule->getTargetLoweringInfo(); diff --git a/clang/lib/CIR/Dialect/Transforms/TargetLowering/LowerModule.cpp b/clang/lib/CIR/Dialect/Transforms/TargetLowering/LowerModule.cpp index a5ee43c544344..f05fe7a1645c0 100644 --- a/clang/lib/CIR/Dialect/Transforms/TargetLowering/LowerModule.cpp +++ b/clang/lib/CIR/Dialect/Transforms/TargetLowering/LowerModule.cpp @@ -80,26 +80,20 @@ const TargetLoweringInfo &LowerModule::getTargetLoweringInfo() { // TODO: not to create it every time std::unique_ptr<LowerModule> -createLowerModule(mlir::ModuleOp module, - llvm::function_ref<mlir::InFlightDiagnostic()> emitDiag) { +createLowerModule(mlir::ModuleOp module) { // If the triple is not present, e.g. CIR modules parsed from text, we // cannot init LowerModule properly. assert(!cir::MissingFeatures::makeTripleAlwaysPresent()); // Fetch target information. - std::optional<llvm::Triple> triple = - cir::getTripleFromModule(module, emitDiag); + std::optional<llvm::Triple> triple = cir::getTripleFromModule(module); if (!triple) return nullptr; clang::TargetOptions targetOptions; targetOptions.Triple = triple->str(); auto targetInfo = clang::targets::AllocateTarget(*triple, targetOptions); - if (!targetInfo) { - if (emitDiag) - emitDiag() << "unknown triple '" << triple->str() << "' in " - << cir::CIRDialect::getTripleAttrName() << " attribute"; + if (!targetInfo) return nullptr; - } // Populate the lowering-relevant LangOptions from the module's // #cir.lowering_lang_options attribute so a reloaded .cir lowers the same @@ -129,12 +123,8 @@ createLowerModule(mlir::ModuleOp module, if (auto optAttr = module->getAttr(cir::CIRDialect::getOptInfoAttrName())) { auto optInfo = mlir::dyn_cast<cir::OptInfoAttr>(optAttr); - if (!optInfo) { - if (emitDiag) - emitDiag() << "malformed " << cir::CIRDialect::getOptInfoAttrName() - << " attribute"; + if (!optInfo) return nullptr; - } codeGenOpts.OptimizationLevel = optInfo.getLevel(); codeGenOpts.OptimizeSize = optInfo.getSize(); } diff --git a/clang/lib/CIR/Dialect/Transforms/TargetLowering/LowerModule.h b/clang/lib/CIR/Dialect/Transforms/TargetLowering/LowerModule.h index dbd28430c6df3..56fcd0a9b58cd 100644 --- a/clang/lib/CIR/Dialect/Transforms/TargetLowering/LowerModule.h +++ b/clang/lib/CIR/Dialect/Transforms/TargetLowering/LowerModule.h @@ -57,9 +57,7 @@ class LowerModule { const TargetLoweringInfo &getTargetLoweringInfo(); }; -std::unique_ptr<LowerModule> createLowerModule( - mlir::ModuleOp module, - llvm::function_ref<mlir::InFlightDiagnostic()> emitDiag = nullptr); +std::unique_ptr<LowerModule> createLowerModule(mlir::ModuleOp module); } // namespace cir >From 7cac1228b6ec312044ba83075e68ff5ea33c94a4 Mon Sep 17 00:00:00 2001 From: "Li, Ian" <[email protected]> Date: Tue, 13 Oct 2026 21:16:31 -0700 Subject: [PATCH 12/16] complete removing diags and moving validation to verifyOperationAttrs --- clang/lib/CIR/Dialect/IR/CIRDialect.cpp | 2 +- clang/lib/CIR/Lowering/CIRPasses.cpp | 3 +-- clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp | 6 +----- clang/test/CIR/Input/cir-input-invalid.cir | 5 +++-- 4 files changed, 6 insertions(+), 10 deletions(-) diff --git a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp index 4d62441f26d2c..06c88dfb78d48 100644 --- a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp +++ b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp @@ -292,7 +292,7 @@ cir::CIRDialect::verifyOperationAttribute(mlir::Operation *op, auto tripleStr = mlir::dyn_cast<mlir::StringAttr>(attr.getValue()); if (!tripleStr) return op->emitOpError() << "expects '" << getTripleAttrName() << "' to " - << " be a string"; + << "be a string"; llvm::Triple triple = llvm::Triple(tripleStr.getValue()); clang::TargetOptions targetOptions; targetOptions.Triple = tripleStr.getValue(); diff --git a/clang/lib/CIR/Lowering/CIRPasses.cpp b/clang/lib/CIR/Lowering/CIRPasses.cpp index cbc0c515bf275..11e8a3ee341f7 100644 --- a/clang/lib/CIR/Lowering/CIRPasses.cpp +++ b/clang/lib/CIR/Lowering/CIRPasses.cpp @@ -78,8 +78,7 @@ runCIRToCIRPasses(mlir::ModuleOp theModule, mlir::MLIRContext &mlirContext, llvm::TimeTraceScope scope("CIR To CIR Passes"); - std::optional<llvm::Triple> triple = cir::getTripleFromModule( - theModule, [&] { return theModule.emitError(); }); + std::optional<llvm::Triple> triple = cir::getTripleFromModule(theModule); if (!triple) return mlir::LogicalResult::failure(); diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp index 8a49790120c5f..0c77affa835ad 100644 --- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp +++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp @@ -5830,11 +5830,7 @@ mlir::LogicalResult CIRToLLVMCpuIdOpLowering::matchAndRewrite( StringRef asmString, constraints; mlir::ModuleOp moduleOp = op->getParentOfType<mlir::ModuleOp>(); - auto diag = [&] { - return moduleOp.emitError("cannot lower ") - << op.getOperationName() << " op: "; - }; - std::optional<llvm::Triple> triple = cir::getTripleFromModule(moduleOp, diag); + std::optional<llvm::Triple> triple = cir::getTripleFromModule(moduleOp); if (!triple) return mlir::failure(); if (triple->getArch() == llvm::Triple::x86) { diff --git a/clang/test/CIR/Input/cir-input-invalid.cir b/clang/test/CIR/Input/cir-input-invalid.cir index 1a791d843bb0a..7b41ca296fefc 100644 --- a/clang/test/CIR/Input/cir-input-invalid.cir +++ b/clang/test/CIR/Input/cir-input-invalid.cir @@ -25,11 +25,12 @@ // RUN: not %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-cir %t/no-triple.cir -o - 2>&1 \ // RUN: | FileCheck %s --check-prefix=NO-TRIPLE --implicit-check-not=error: -// RUN: not %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-cir %t/int-triple.cir -o - 2>&1 \ -// RUN: | FileCheck %s --check-prefix=NO-TRIPLE --implicit-check-not=error: // RUN: not %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-obj %t/no-triple.cir -o /dev/null 2>&1 \ // RUN: | FileCheck %s --check-prefix=NO-TRIPLE --implicit-check-not=error: // NO-TRIPLE: error: missing target triple in ClangIR input +// RUN: not %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-cir %t/int-triple.cir -o - 2>&1 \ +// RUN: | FileCheck %s --check-prefix=BAD-TRIPLE --implicit-check-not=error: +// BAD-TRIPLE: error: 'builtin.module' op expects 'cir.triple' to be a string // RUN: not %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-cir %t/mismatch.cir -o - 2>&1 \ // RUN: | FileCheck %s --check-prefix=MISMATCH --implicit-check-not=error: >From 66d12d03046af3dfb3909ee672afb4dcf116262a Mon Sep 17 00:00:00 2001 From: "Li, Ian" <[email protected]> Date: Tue, 13 Oct 2026 21:17:13 -0700 Subject: [PATCH 13/16] Delete changes to EHABILowering; should be another PR --- .../CIR/Dialect/Transforms/EHABILowering.cpp | 11 +++-- .../Transforms/eh-abi-lowering-bad-attrs.cir | 41 ------------------- 2 files changed, 7 insertions(+), 45 deletions(-) delete mode 100644 clang/test/CIR/Transforms/eh-abi-lowering-bad-attrs.cir diff --git a/clang/lib/CIR/Dialect/Transforms/EHABILowering.cpp b/clang/lib/CIR/Dialect/Transforms/EHABILowering.cpp index ed93a41978811..72a8cffc3b060 100644 --- a/clang/lib/CIR/Dialect/Transforms/EHABILowering.cpp +++ b/clang/lib/CIR/Dialect/Transforms/EHABILowering.cpp @@ -1113,16 +1113,19 @@ void CIREHABILoweringPass::runOnOperation() { // The target triple is attached to the module as the "cir.triple" // attribute. If it is absent (e.g. a CIR module parsed from text without a // triple) we cannot determine the ABI and must skip the pass. - std::optional<llvm::Triple> triple = - cir::getTripleFromModule(mod, [&] { return mod.emitWarning(); }); - if (!triple) + auto tripleAttr = mlir::dyn_cast_if_present<mlir::StringAttr>( + mod->getAttr(cir::CIRDialect::getTripleAttrName())); + if (!tripleAttr) { + mod.emitError("Module has no target triple"); return; + } // Select the ABI-specific lowering handler from the triple. The Microsoft // C++ ABI targets a Windows MSVC environment; everything else uses Itanium. // Extend this when Microsoft ABI lowering is added. + llvm::Triple triple(tripleAttr.getValue()); std::unique_ptr<EHABILowering> lowering; - if (triple->isWindowsMSVCEnvironment()) { + if (triple.isWindowsMSVCEnvironment()) { mod.emitError( "EH ABI lowering is not yet implemented for the Microsoft ABI"); return signalPassFailure(); diff --git a/clang/test/CIR/Transforms/eh-abi-lowering-bad-attrs.cir b/clang/test/CIR/Transforms/eh-abi-lowering-bad-attrs.cir deleted file mode 100644 index fc4be2550cb3b..0000000000000 --- a/clang/test/CIR/Transforms/eh-abi-lowering-bad-attrs.cir +++ /dev/null @@ -1,41 +0,0 @@ -// RUN: cir-opt %s -cir-eh-abi-lowering -verify-diagnostics -split-input-file -// RUN: cir-opt %s -cir-eh-abi-lowering -split-input-file 2>/dev/null | FileCheck %s - -// Check that missing or malformed cir.triple attributes required by -// -cir-eh-abi-lowering do not cause asserts or compiler crashes, and are -// diagnosed properly. The pass should warn and skip instead of failing, so -// every module is still printed. - - -// Missing cir.triple. - -// expected-warning @below {{module is missing cir.triple attribute}} -module { - // CHECK-LABEL: cir.func @missing_triple( - cir.func @missing_triple() { - cir.return - } -} - -// ----- - -// Non-string cir.triple. - -// expected-warning @below {{expected a string from module attribute cir.triple}} -module attributes {cir.triple = 42 : i32} { - // CHECK-LABEL: cir.func @non_string_triple( - cir.func @non_string_triple() { - cir.return - } -} - -// ----- - -// Valid cir.triple. - -module attributes {cir.triple = "x86_64-unknown-linux-gnu"} { - // CHECK-LABEL: cir.func @valid_triple( - cir.func @valid_triple() { - cir.return - } -} >From b273d9ffd00b492b517e330c96e5abb6b0625b84 Mon Sep 17 00:00:00 2001 From: "Li, Ian" <[email protected]> Date: Tue, 13 Oct 2026 21:30:52 -0700 Subject: [PATCH 14/16] add tests for new CIR dialect verifier behavior --- clang/test/CIR/IR/invalid-opt-info.cir | 21 ++++ clang/test/CIR/IR/invalid-triple.cir | 27 +++++ .../Transforms/cxx-abi-lowering-bad-attrs.cir | 104 ++---------------- 3 files changed, 59 insertions(+), 93 deletions(-) create mode 100644 clang/test/CIR/IR/invalid-triple.cir diff --git a/clang/test/CIR/IR/invalid-opt-info.cir b/clang/test/CIR/IR/invalid-opt-info.cir index 52d6afd2c6974..20ccb83694db5 100644 --- a/clang/test/CIR/IR/invalid-opt-info.cir +++ b/clang/test/CIR/IR/invalid-opt-info.cir @@ -11,3 +11,24 @@ module attributes { // expected-error @below {{size optimization level must be between 0 and 2 inclusive}} cir.opt_info = #cir.opt_info<level = 0, size = 3> } {} + +// ----- + +// cir.opt_info that is not an OptInfoAttr. + +// expected-error @below {{'builtin.module' op malformed cir.opt_info attribute}} +module attributes {cir.opt_info = 1 : i32} {} + +// ----- + +// String cir.opt_info. + +// expected-error @below {{'builtin.module' op malformed cir.opt_info attribute}} +module attributes {cir.opt_info = "O2"} {} + +// ----- + +// Dictionary cir.opt_info that mimics OptInfoAttr's fields. + +// expected-error @below {{'builtin.module' op malformed cir.opt_info attribute}} +module attributes {cir.opt_info = {level = 2 : i32, size = 1 : i32}} {} diff --git a/clang/test/CIR/IR/invalid-triple.cir b/clang/test/CIR/IR/invalid-triple.cir new file mode 100644 index 0000000000000..a52ae9768689e --- /dev/null +++ b/clang/test/CIR/IR/invalid-triple.cir @@ -0,0 +1,27 @@ +// RUN: cir-opt %s -verify-diagnostics -split-input-file + +// Non-string cir.triple. + +// expected-error @below {{'builtin.module' op expects 'cir.triple' to be a string}} +module attributes {cir.triple = 42 : i32} {} + +// ----- + +// Empty cir.triple. + +// expected-error @below {{'builtin.module' op unknown triple '' in 'cir.triple' attribute}} +module attributes {cir.triple = ""} {} + +// ----- + +// Malformed cir.triple. + +// expected-error @below {{'builtin.module' op unknown triple 'garbage' in 'cir.triple' attribute}} +module attributes {cir.triple = "garbage"} {} + +// ----- + +// Well-formed cir.triple with an unknown target. + +// expected-error @below {{'builtin.module' op unknown triple 'foobar-unknown-unknown' in 'cir.triple' attribute}} +module attributes {cir.triple = "foobar-unknown-unknown"} {} diff --git a/clang/test/CIR/Transforms/cxx-abi-lowering-bad-attrs.cir b/clang/test/CIR/Transforms/cxx-abi-lowering-bad-attrs.cir index 5d13956c63af4..b6ce3bbf0e6c2 100644 --- a/clang/test/CIR/Transforms/cxx-abi-lowering-bad-attrs.cir +++ b/clang/test/CIR/Transforms/cxx-abi-lowering-bad-attrs.cir @@ -1,15 +1,17 @@ // RUN: cir-opt %s -cir-cxxabi-lowering -verify-diagnostics -split-input-file // RUN: cir-opt %s -cir-cxxabi-lowering -split-input-file 2>/dev/null | FileCheck %s -// Check that missing or malformed module attributes required/used by -// -cir-cxxabi-lowering do not cause asserts or compiler crashes, and are -// diagnosed properly. The pass should warn and skip instead of failing, so -// every module is still printed. +// Check that missing cir.triple module attribute does not cause asserts or +// compiler crashes in -cir-cxxabi-lowering, and is diagnosed properly. The pass +// should warn and skip instead of failing. so every module is still printed. +// +// Malformed cir.triple and cir.opt_info attributes are rejected by the CIR +// dialect verifier; see IR/invalid-triple.cir and IR/invalid-opt-info.cir. // Missing cir.triple. -// expected-warning @below {{cannot create a CIR lower module, skipping the CXXABILowering pass: module is missing cir.triple attribute}} +// expected-warning @below {{cannot create a CIR lower module, skipping the CXXABILowering pass}} module { // CHECK-LABEL: cir.func @missing_triple( cir.func @missing_triple() { @@ -19,48 +21,10 @@ module { // ----- -// Non-string cir.triple. - -// expected-warning @below {{cannot create a CIR lower module, skipping the CXXABILowering pass: expected a string from module attribute cir.triple}} -module attributes {cir.triple = 42 : i32} { - // CHECK-LABEL: cir.func @non_string_triple( - cir.func @non_string_triple() { - cir.return - } -} - -// ----- - -// Empty cir.triple. - -// expected-warning @below {{cannot create a CIR lower module, skipping the CXXABILowering pass: unknown triple '' in cir.triple attribute}} -module attributes {cir.triple = ""} { - // CHECK-LABEL: cir.func @empty_triple( - cir.func @empty_triple() { - cir.return - } -} - -// ----- - -// Malformed cir.triple. - -// expected-warning @below {{cannot create a CIR lower module, skipping the CXXABILowering pass: unknown triple 'garbage' in cir.triple attribute}} -module attributes {cir.triple = "garbage"} { - // CHECK-LABEL: cir.func @malformed_triple( - cir.func @malformed_triple() { - cir.return - } -} - -// ----- - -// Well-formed cir.triple with an unknown target. - -// expected-warning @below {{cannot create a CIR lower module, skipping the CXXABILowering pass: unknown triple 'foobar-unknown-unknown' in cir.triple attribute}} -module attributes {cir.triple = "foobar-unknown-unknown"} { - // CHECK-LABEL: cir.func @unknown_triple( - cir.func @unknown_triple() { +// expected-warning @below {{cannot create a CIR lower module, skipping the CXXABILowering pass}} +module attributes {cir.opt_info = #cir.opt_info<level = 0, size = 1>} { + // CHECK-LABEL: cir.func @missing_triple( + cir.func @missing_triple() { cir.return } } @@ -89,49 +53,3 @@ module attributes { cir.return } } - -// ----- - -// Valid cir.triple with a cir.opt_info that is not an OptInfoAttr. - -// expected-warning @below {{cannot create a CIR lower module, skipping the CXXABILowering pass: malformed cir.opt_info attribute}} -module attributes { - cir.triple = "x86_64-unknown-linux-gnu", - cir.opt_info = 1 : i32 -} { - // CHECK-LABEL: cir.func @malformed_opt_info( - cir.func @malformed_opt_info() { - cir.return - } -} - -// ----- - -// Valid cir.triple with a string cir.opt_info. - -// expected-warning @below {{cannot create a CIR lower module, skipping the CXXABILowering pass: malformed cir.opt_info attribute}} -module attributes { - cir.triple = "x86_64-unknown-linux-gnu", - cir.opt_info = "O2" -} { - // CHECK-LABEL: cir.func @string_opt_info( - cir.func @string_opt_info() { - cir.return - } -} - -// ----- - -// Valid cir.triple with a dictionary cir.opt_info that mimics OptInfoAttr's -// fields. - -// expected-warning @below {{cannot create a CIR lower module, skipping the CXXABILowering pass: malformed cir.opt_info attribute}} -module attributes { - cir.triple = "x86_64-unknown-linux-gnu", - cir.opt_info = {level = 2 : i32, size = 1 : i32} -} { - // CHECK-LABEL: cir.func @dict_opt_info( - cir.func @dict_opt_info() { - cir.return - } -} >From 58a6435d2db545602ec6dc9ef5fb2a3508d3403e Mon Sep 17 00:00:00 2001 From: "Li, Ian" <[email protected]> Date: Tue, 13 Oct 2026 21:33:20 -0700 Subject: [PATCH 15/16] add comment --- clang/lib/CIR/Dialect/IR/CIRDialect.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp index 06c88dfb78d48..a80c311d42a93 100644 --- a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp +++ b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp @@ -307,6 +307,8 @@ cir::CIRDialect::verifyOperationAttribute(mlir::Operation *op, if (attrName == getOptInfoAttrName()) { auto optInfo = mlir::dyn_cast<cir::OptInfoAttr>(attr.getValue()); + // Checks whether or not OptInfoAttr is even parseable; opt info range + // sanity checks are done in OptInfoAttr::verify. if (!optInfo) return op->emitOpError() << "malformed " << cir::CIRDialect::getOptInfoAttrName() >From 6928e7efbe589945a0bb85052e4658a89cb28463 Mon Sep 17 00:00:00 2001 From: "Li, Ian" <[email protected]> Date: Tue, 13 Oct 2026 21:52:44 -0700 Subject: [PATCH 16/16] delete a crap ton of test code; this feels good but I'll get rid of the rest later --- .../CIR/Lowering/cir-to-llvm-module-attrs.cir | 21 +--- .../lowering-prepare-module-attrs.cir | 92 +---------------- .../target-lowering-module-attrs.cir | 99 +------------------ 3 files changed, 12 insertions(+), 200 deletions(-) diff --git a/clang/test/CIR/Lowering/cir-to-llvm-module-attrs.cir b/clang/test/CIR/Lowering/cir-to-llvm-module-attrs.cir index 0cf5c4a3327c3..6c208074c1b9f 100644 --- a/clang/test/CIR/Lowering/cir-to-llvm-module-attrs.cir +++ b/clang/test/CIR/Lowering/cir-to-llvm-module-attrs.cir @@ -5,13 +5,15 @@ // -cir-to-llvm relies on cir.triple module attributes to handle cir.cpuid ops: // Check that missing or malformed cir.triple attributes read by -cir-to-llvm do // not cause asserts or compiler crashes, and are diagnosed properly. +// +// Malformed cir.triple attributes are rejected by the CIR dialect verifier; see +// IR/invalid-triple.cir. // Missing cir.triple. !s32i = !cir.int<s, 32> -// expected-warning @below {{module is missing cir.triple attribute}} -// expected-error @below {{cannot lower cir.cpuid op: module is missing cir.triple attribute}} +// expected-error @below {{Module has no target triple}} module { cir.func @missing_triple(%p: !cir.ptr<!s32i>, %a: !s32i, %b: !s32i) { // expected-error @below {{failed to legalize operation 'cir.cpuid'}} @@ -22,21 +24,6 @@ module { // ----- -// Non-string cir.triple. - -!s32i = !cir.int<s, 32> -// expected-warning @below {{expected a string from module attribute cir.triple}} -// expected-error @below {{cannot lower cir.cpuid op: expected a string from module attribute cir.triple}} -module attributes {cir.triple = 42 : i32} { - cir.func @non_string_triple(%p: !cir.ptr<!s32i>, %a: !s32i, %b: !s32i) { - // expected-error @below {{failed to legalize operation 'cir.cpuid'}} - cir.cpuid %p, %a, %b : !cir.ptr<!s32i>, !s32i, !s32i - cir.return - } -} - -// ----- - // Valid cir.triple. !s32i = !cir.int<s, 32> diff --git a/clang/test/CIR/Transforms/lowering-prepare-module-attrs.cir b/clang/test/CIR/Transforms/lowering-prepare-module-attrs.cir index f42bad16d7bc3..8ff76ba35e370 100644 --- a/clang/test/CIR/Transforms/lowering-prepare-module-attrs.cir +++ b/clang/test/CIR/Transforms/lowering-prepare-module-attrs.cir @@ -6,11 +6,14 @@ // -cir-lowering-prepare do not cause asserts or compiler crashes, and are // diagnosed properly. The pass should fail on bad attributes, so only modules // with valid attributes are printed. +// +// Malformed cir.triple and cir.opt_info attributes are rejected by the CIR +// dialect verifier; see IR/invalid-triple.cir and IR/invalid-opt-info.cir. // Missing cir.triple. -// expected-error @below {{cannot create a CIR lower module for LoweringPrepare pass: module is missing cir.triple attribute}} +// expected-error @below {{cannot create a CIR lower module for LoweringPrepare pass}} module { cir.func @missing_triple() { cir.return @@ -19,50 +22,6 @@ module { // ----- -// Non-string cir.triple. - -// expected-error @below {{cannot create a CIR lower module for LoweringPrepare pass: expected a string from module attribute cir.triple}} -module attributes {cir.triple = 42 : i32} { - cir.func @non_string_triple() { - cir.return - } -} - -// ----- - -// Empty cir.triple. - -// expected-error @below {{cannot create a CIR lower module for LoweringPrepare pass: unknown triple '' in cir.triple attribute}} -module attributes {cir.triple = ""} { - cir.func @empty_triple() { - cir.return - } -} - -// ----- - -// Malformed cir.triple. - -// expected-error @below {{cannot create a CIR lower module for LoweringPrepare pass: unknown triple 'garbage' in cir.triple attribute}} -module attributes {cir.triple = "garbage"} { - cir.func @malformed_triple() { - cir.return - } -} - -// ----- - -// Well-formed cir.triple with an unknown target. - -// expected-error @below {{cannot create a CIR lower module for LoweringPrepare pass: unknown triple 'foobar-unknown-unknown' in cir.triple attribute}} -module attributes {cir.triple = "foobar-unknown-unknown"} { - cir.func @unknown_triple() { - cir.return - } -} - -// ----- - // Valid cir.triple without cir.opt_info. module attributes {cir.triple = "x86_64-unknown-linux-gnu"} { @@ -85,46 +44,3 @@ module attributes { cir.return } } - -// ----- - -// Valid cir.triple with a cir.opt_info that is not an OptInfoAttr. - -// expected-error @below {{cannot create a CIR lower module for LoweringPrepare pass: malformed cir.opt_info attribute}} -module attributes { - cir.triple = "x86_64-unknown-linux-gnu", - cir.opt_info = 1 : i32 -} { - cir.func @malformed_opt_info() { - cir.return - } -} - -// ----- - -// Valid cir.triple with a string cir.opt_info. - -// expected-error @below {{cannot create a CIR lower module for LoweringPrepare pass: malformed cir.opt_info attribute}} -module attributes { - cir.triple = "x86_64-unknown-linux-gnu", - cir.opt_info = "O2" -} { - cir.func @string_opt_info() { - cir.return - } -} - -// ----- - -// Valid cir.triple with a dictionary cir.opt_info that mimics OptInfoAttr's -// fields. - -// expected-error @below {{cannot create a CIR lower module for LoweringPrepare pass: malformed cir.opt_info attribute}} -module attributes { - cir.triple = "x86_64-unknown-linux-gnu", - cir.opt_info = {level = 2 : i32, size = 1 : i32} -} { - cir.func @dict_opt_info() { - cir.return - } -} diff --git a/clang/test/CIR/Transforms/target-lowering-module-attrs.cir b/clang/test/CIR/Transforms/target-lowering-module-attrs.cir index 36813d4d707a4..6c507cd2d5597 100644 --- a/clang/test/CIR/Transforms/target-lowering-module-attrs.cir +++ b/clang/test/CIR/Transforms/target-lowering-module-attrs.cir @@ -5,11 +5,14 @@ // -cir-target-lowering do not cause asserts or compiler crashes, and are // diagnosed properly. The pass should warn and skip instead of failing, so // every module is still printed. +// +// Malformed cir.triple and cir.opt_info attributes are rejected by the CIR +// dialect verifier; see IR/invalid-triple.cir and IR/invalid-opt-info.cir. // Missing cir.triple. -// expected-warning @below {{cannot create a CIR lower module, skipping the TargetLowering pass: module is missing cir.triple attribute}} +// expected-warning @below {{cannot create a CIR lower module, skipping the TargetLowering pass}} module { // CHECK-LABEL: cir.func @missing_triple( cir.func @missing_triple() { @@ -19,54 +22,6 @@ module { // ----- -// Non-string cir.triple. - -// expected-warning @below {{cannot create a CIR lower module, skipping the TargetLowering pass: expected a string from module attribute cir.triple}} -module attributes {cir.triple = 42 : i32} { - // CHECK-LABEL: cir.func @non_string_triple( - cir.func @non_string_triple() { - cir.return - } -} - -// ----- - -// Empty cir.triple. - -// expected-warning @below {{cannot create a CIR lower module, skipping the TargetLowering pass: unknown triple '' in cir.triple attribute}} -module attributes {cir.triple = ""} { - // CHECK-LABEL: cir.func @empty_triple( - cir.func @empty_triple() { - cir.return - } -} - -// ----- - -// Malformed cir.triple. - -// expected-warning @below {{cannot create a CIR lower module, skipping the TargetLowering pass: unknown triple 'garbage' in cir.triple attribute}} -module attributes {cir.triple = "garbage"} { - // CHECK-LABEL: cir.func @malformed_triple( - cir.func @malformed_triple() { - cir.return - } -} - -// ----- - -// Well-formed cir.triple with an unknown target. - -// expected-warning @below {{cannot create a CIR lower module, skipping the TargetLowering pass: unknown triple 'foobar-unknown-unknown' in cir.triple attribute}} -module attributes {cir.triple = "foobar-unknown-unknown"} { - // CHECK-LABEL: cir.func @unknown_triple( - cir.func @unknown_triple() { - cir.return - } -} - -// ----- - // Valid cir.triple without cir.opt_info. module attributes {cir.triple = "x86_64-unknown-linux-gnu"} { @@ -89,49 +44,3 @@ module attributes { cir.return } } - -// ----- - -// Valid cir.triple with a cir.opt_info that is not an OptInfoAttr. - -// expected-warning @below {{cannot create a CIR lower module, skipping the TargetLowering pass: malformed cir.opt_info attribute}} -module attributes { - cir.triple = "x86_64-unknown-linux-gnu", - cir.opt_info = 1 : i32 -} { - // CHECK-LABEL: cir.func @malformed_opt_info( - cir.func @malformed_opt_info() { - cir.return - } -} - -// ----- - -// Valid cir.triple with a string cir.opt_info. - -// expected-warning @below {{cannot create a CIR lower module, skipping the TargetLowering pass: malformed cir.opt_info attribute}} -module attributes { - cir.triple = "x86_64-unknown-linux-gnu", - cir.opt_info = "O2" -} { - // CHECK-LABEL: cir.func @string_opt_info( - cir.func @string_opt_info() { - cir.return - } -} - -// ----- - -// Valid cir.triple with a dictionary cir.opt_info that mimics OptInfoAttr's -// fields. - -// expected-warning @below {{cannot create a CIR lower module, skipping the TargetLowering pass: malformed cir.opt_info attribute}} -module attributes { - cir.triple = "x86_64-unknown-linux-gnu", - cir.opt_info = {level = 2 : i32, size = 1 : i32} -} { - // CHECK-LABEL: cir.func @dict_opt_info( - cir.func @dict_opt_info() { - cir.return - } -} _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
