diff options
| author | Aiden Grossman <aidengrossman@google.com> | 2025-08-29 19:51:31 +0000 |
|---|---|---|
| committer | Aiden Grossman <aidengrossman@google.com> | 2025-08-29 19:51:31 +0000 |
| commit | f1c66003a3be0e5296de0aaaab1cb1b804e8cbe7 (patch) | |
| tree | 4b5fbe67499bfe3fa1568c336aad08082f2480be | |
| parent | 328a8372b5362b8de7bc2c33fb75c7e046a00673 (diff) | |
| parent | 80c21797901b9c5a787774fdb94046ea285c1b83 (diff) | |
[𝘀𝗽𝗿] changes introduced through rebaseusers/boomanaiden154/main.bolt-enable-lit-internal-shell-by-default
Created using spr 1.3.6
[skip ci]
43 files changed, 768 insertions, 202 deletions
diff --git a/.ci/compute_projects.py b/.ci/compute_projects.py index 95351c46fad5..1aa5f02b85e6 100644 --- a/.ci/compute_projects.py +++ b/.ci/compute_projects.py @@ -26,6 +26,7 @@ PROJECT_DEPENDENCIES = { "libc": {"clang", "lld"}, "openmp": {"clang", "lld"}, "flang": {"llvm", "clang"}, + "flang-rt": {"flang"}, "lldb": {"llvm", "clang"}, "libclc": {"llvm", "clang"}, "lld": {"llvm"}, @@ -80,7 +81,9 @@ DEPENDENT_RUNTIMES_TO_TEST = { "clang-tools-extra": {"libc"}, "libc": {"libc"}, "compiler-rt": {"compiler-rt"}, - ".ci": {"compiler-rt", "libc"}, + "flang": {"flang-rt"}, + "flang-rt": {"flang-rt"}, + ".ci": {"compiler-rt", "libc", "flang-rt"}, } DEPENDENT_RUNTIMES_TO_TEST_NEEDS_RECONFIG = { "llvm": {"libcxx", "libcxxabi", "libunwind"}, @@ -103,6 +106,7 @@ EXCLUDE_WINDOWS = { "libcxx", "libcxxabi", "libunwind", + "flang-rt", } # These are projects that we should test if the project itself is changed but @@ -140,6 +144,7 @@ PROJECT_CHECK_TARGETS = { "bolt": "check-bolt", "lld": "check-lld", "flang": "check-flang", + "flang-rt": "check-flang-rt", "libc": "check-libc", "lld": "check-lld", "lldb": "check-lldb", @@ -148,7 +153,7 @@ PROJECT_CHECK_TARGETS = { "polly": "check-polly", } -RUNTIMES = {"libcxx", "libcxxabi", "libunwind", "compiler-rt", "libc"} +RUNTIMES = {"libcxx", "libcxxabi", "libunwind", "compiler-rt", "libc", "flang-rt"} # Meta projects are projects that need explicit handling but do not reside # in their own top level folder. To add a meta project, the start of the path diff --git a/.ci/compute_projects_test.py b/.ci/compute_projects_test.py index 7d780b51ca5d..89e9f58a873b 100644 --- a/.ci/compute_projects_test.py +++ b/.ci/compute_projects_test.py @@ -216,8 +216,8 @@ class TestComputeProjects(unittest.TestCase): ) self.assertEqual(env_variables["projects_to_build"], "clang;flang;llvm") self.assertEqual(env_variables["project_check_targets"], "check-flang") - self.assertEqual(env_variables["runtimes_to_build"], "") - self.assertEqual(env_variables["runtimes_check_targets"], "") + self.assertEqual(env_variables["runtimes_to_build"], "flang-rt") + self.assertEqual(env_variables["runtimes_check_targets"], "check-flang-rt") self.assertEqual(env_variables["runtimes_check_targets_needs_reconfig"], "") self.assertEqual(env_variables["enable_cir"], "OFF") @@ -293,11 +293,11 @@ class TestComputeProjects(unittest.TestCase): ) self.assertEqual( env_variables["runtimes_to_build"], - "compiler-rt;libc;libcxx;libcxxabi;libunwind", + "compiler-rt;flang-rt;libc;libcxx;libcxxabi;libunwind", ) self.assertEqual( env_variables["runtimes_check_targets"], - "check-compiler-rt check-libc", + "check-compiler-rt check-flang-rt check-libc", ) self.assertEqual( env_variables["runtimes_check_targets_needs_reconfig"], @@ -367,11 +367,11 @@ class TestComputeProjects(unittest.TestCase): ) self.assertEqual( env_variables["runtimes_to_build"], - "compiler-rt;libc;libcxx;libcxxabi;libunwind", + "compiler-rt;flang-rt;libc;libcxx;libcxxabi;libunwind", ) self.assertEqual( env_variables["runtimes_check_targets"], - "check-compiler-rt check-libc", + "check-compiler-rt check-flang-rt check-libc", ) self.assertEqual( env_variables["runtimes_check_targets_needs_reconfig"], @@ -402,11 +402,11 @@ class TestComputeProjects(unittest.TestCase): ) self.assertEqual( env_variables["runtimes_to_build"], - "compiler-rt;libc;libcxx;libcxxabi;libunwind", + "compiler-rt;flang-rt;libc;libcxx;libcxxabi;libunwind", ) self.assertEqual( env_variables["runtimes_check_targets"], - "check-compiler-rt check-libc", + "check-compiler-rt check-flang-rt check-libc", ) self.assertEqual( env_variables["runtimes_check_targets_needs_reconfig"], diff --git a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h index d29e5687d254..96f55f5c6607 100644 --- a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h +++ b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h @@ -19,7 +19,6 @@ #include "mlir/IR/Builders.h" #include "mlir/IR/BuiltinAttributes.h" -#include "mlir/IR/BuiltinTypes.h" #include "mlir/IR/Location.h" #include "mlir/IR/Types.h" @@ -313,6 +312,25 @@ public: resOperands, attrs); } + cir::CallOp createTryCallOp( + mlir::Location loc, mlir::SymbolRefAttr callee = mlir::SymbolRefAttr(), + mlir::Type returnType = cir::VoidType(), + mlir::ValueRange operands = mlir::ValueRange(), + [[maybe_unused]] cir::SideEffect sideEffect = cir::SideEffect::All) { + assert(!cir::MissingFeatures::opCallCallConv()); + assert(!cir::MissingFeatures::opCallSideEffect()); + return createCallOp(loc, callee, returnType, operands); + } + + cir::CallOp createTryCallOp( + mlir::Location loc, cir::FuncOp callee, mlir::ValueRange operands, + [[maybe_unused]] cir::SideEffect sideEffect = cir::SideEffect::All) { + assert(!cir::MissingFeatures::opCallCallConv()); + assert(!cir::MissingFeatures::opCallSideEffect()); + return createTryCallOp(loc, mlir::SymbolRefAttr::get(callee), + callee.getFunctionType().getReturnType(), operands); + } + //===--------------------------------------------------------------------===// // Cast/Conversion Operators //===--------------------------------------------------------------------===// diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td b/clang/include/clang/CIR/Dialect/IR/CIROps.td index 2b7a709b80c2..982533f5e3b8 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIROps.td +++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td @@ -3864,4 +3864,63 @@ def CIR_VAArgOp : CIR_Op<"va_arg"> { }]; } +//===----------------------------------------------------------------------===// +// ThrowOp +//===----------------------------------------------------------------------===// + +def CIR_ThrowOp : CIR_Op<"throw"> { + let summary = "(Re)Throws an exception"; + let description = [{ + This operation is equivalent to either __cxa_throw or __cxa_rethrow, + depending on the arguments. + + The absense of arguments for `cir.throw` means it rethrows. + + For the no-rethrow version, it must have at least two operands, the RTTI + information, a pointer to the exception object (likely allocated via + `cir.alloc_exception`) and finally an optional dtor, which might run as + part of this operation. + + Example: + + ```mlir + // re-throw; + cir.throw + + // if (b == 0) + // throw "Division by zero condition!"; + + // Type info for char const* + cir.global "private" constant external @_ZTIPKc : !cir.ptr<!u8i> + cir.if %cond { + %exception_addr = cir.alloc_exception 8 -> !cir.ptr<!void> + ... + // Store string addr for "Division by zero condition!" + cir.store %string_addr, %exception_addr : !cir.ptr<!s8i>, + !cir.ptr<!cir.ptr<!s8i>> + cir.throw %exception_addr : !cir.ptr<!cir.ptr<!u8i>>, + @_ZTIPKc + ``` + }]; + + let arguments = (ins + Optional<CIR_PointerType>:$exception_ptr, + OptionalAttr<FlatSymbolRefAttr>:$type_info, + OptionalAttr<FlatSymbolRefAttr>:$dtor + ); + + let assemblyFormat = [{ + ($exception_ptr^ `:` type($exception_ptr))? + (`,` $type_info^)? + (`,` $dtor^)? + attr-dict + }]; + + let extraClassDeclaration = [{ + bool rethrows() { return getNumOperands() == 0; } + }]; + + let hasVerifier = 1; +} + #endif // CLANG_CIR_DIALECT_IR_CIROPS_TD diff --git a/clang/include/clang/CIR/MissingFeatures.h b/clang/include/clang/CIR/MissingFeatures.h index a8be2a2374d6..6a8bab2b7f06 100644 --- a/clang/include/clang/CIR/MissingFeatures.h +++ b/clang/include/clang/CIR/MissingFeatures.h @@ -93,6 +93,7 @@ struct MissingFeatures { static bool opCallReturn() { return false; } static bool opCallArgEvaluationOrder() { return false; } static bool opCallCallConv() { return false; } + static bool opCallSideEffect() { return false; } static bool opCallMustTail() { return false; } static bool opCallInAlloca() { return false; } static bool opCallAttrs() { return false; } diff --git a/clang/lib/CIR/CodeGen/CIRGenCXXABI.h b/clang/lib/CIR/CodeGen/CIRGenCXXABI.h index df7ffbb4a275..7c620301499f 100644 --- a/clang/lib/CIR/CodeGen/CIRGenCXXABI.h +++ b/clang/lib/CIR/CodeGen/CIRGenCXXABI.h @@ -53,9 +53,11 @@ public: } /// Emit the ABI-specific prolog for the function - virtual void emitInstanceFunctionProlog(SourceLocation Loc, + virtual void emitInstanceFunctionProlog(SourceLocation loc, CIRGenFunction &cgf) = 0; + virtual void emitRethrow(CIRGenFunction &cgf, bool isNoReturn) = 0; + /// Get the type of the implicit "this" parameter used by a method. May return /// zero if no specific type is applicable, e.g. if the ABI expects the "this" /// parameter to point to some artificial offset in a complete object due to diff --git a/clang/lib/CIR/CodeGen/CIRGenException.cpp b/clang/lib/CIR/CodeGen/CIRGenException.cpp new file mode 100644 index 000000000000..7fcb39a2b74c --- /dev/null +++ b/clang/lib/CIR/CodeGen/CIRGenException.cpp @@ -0,0 +1,41 @@ +//===--- CIRGenException.cpp - Emit CIR Code for C++ exceptions -*- C++ -*-===// +// +// 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 contains code dealing with C++ exception related code generation. +// +//===----------------------------------------------------------------------===// + +#include "CIRGenCXXABI.h" +#include "CIRGenFunction.h" + +#include "clang/AST/StmtVisitor.h" + +using namespace clang; +using namespace clang::CIRGen; + +void CIRGenFunction::emitCXXThrowExpr(const CXXThrowExpr *e) { + const llvm::Triple &triple = getTarget().getTriple(); + if (cgm.getLangOpts().OpenMPIsTargetDevice && + (triple.isNVPTX() || triple.isAMDGCN())) { + cgm.errorNYI("emitCXXThrowExpr OpenMP with NVPTX or AMDGCN Triples"); + return; + } + + if (const Expr *subExpr = e->getSubExpr()) { + QualType throwType = subExpr->getType(); + if (throwType->isObjCObjectPointerType()) { + cgm.errorNYI("emitCXXThrowExpr ObjCObjectPointerType"); + return; + } else { + cgm.errorNYI("emitCXXThrowExpr with subExpr"); + return; + } + } else { + cgm.getCXXABI().emitRethrow(*this, /*isNoReturn=*/true); + } +} diff --git a/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp b/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp index 41364f516691..5b282fa98487 100644 --- a/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp @@ -327,10 +327,8 @@ mlir::Value ComplexExprEmitter::emitCast(CastKind ck, Expr *op, mlir::Value ComplexExprEmitter::VisitUnaryPlus(const UnaryOperator *e) { QualType promotionTy = getPromotionType(e->getSubExpr()->getType()); mlir::Value result = VisitPlusMinus(e, cir::UnaryOpKind::Plus, promotionTy); - if (!promotionTy.isNull()) { - cgf.cgm.errorNYI("ComplexExprEmitter::VisitUnaryPlus emitUnPromotedValue"); - return {}; - } + if (!promotionTy.isNull()) + return cgf.emitUnPromotedValue(result, e->getSubExpr()->getType()); return result; } @@ -352,10 +350,8 @@ mlir::Value ComplexExprEmitter::VisitPlusMinus(const UnaryOperator *e, mlir::Value ComplexExprEmitter::VisitUnaryMinus(const UnaryOperator *e) { QualType promotionTy = getPromotionType(e->getSubExpr()->getType()); mlir::Value result = VisitPlusMinus(e, cir::UnaryOpKind::Minus, promotionTy); - if (!promotionTy.isNull()) { - cgf.cgm.errorNYI("ComplexExprEmitter::VisitUnaryMinus emitUnPromotedValue"); - return {}; - } + if (!promotionTy.isNull()) + return cgf.emitUnPromotedValue(result, e->getSubExpr()->getType()); return result; } diff --git a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp index 9fe37b7cbbab..0e000cc49406 100644 --- a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp @@ -668,6 +668,11 @@ public: return cgf.emitCXXNewExpr(e); } + mlir::Value VisitCXXThrowExpr(const CXXThrowExpr *e) { + cgf.emitCXXThrowExpr(e); + return {}; + } + /// Emit a conversion from the specified type to the specified destination /// type, both of which are CIR scalar types. /// TODO: do we need ScalarConversionOpts here? Should be done in another diff --git a/clang/lib/CIR/CodeGen/CIRGenFunction.h b/clang/lib/CIR/CodeGen/CIRGenFunction.h index c799ecdc2753..39bacfb97a3e 100644 --- a/clang/lib/CIR/CodeGen/CIRGenFunction.h +++ b/clang/lib/CIR/CodeGen/CIRGenFunction.h @@ -1143,6 +1143,8 @@ public: RValue emitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *expr); + void emitCXXThrowExpr(const CXXThrowExpr *e); + void emitCtorPrologue(const clang::CXXConstructorDecl *ctor, clang::CXXCtorType ctorType, FunctionArgList &args); diff --git a/clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp b/clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp index 4fd5a278e1a9..ab7a0699637b 100644 --- a/clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp @@ -56,6 +56,8 @@ public: bool delegating, Address thisAddr, QualType thisTy) override; + void emitRethrow(CIRGenFunction &cgf, bool isNoReturn) override; + bool useThunkForDtorVariant(const CXXDestructorDecl *dtor, CXXDtorType dt) const override { // Itanium does not emit any destructor variant as an inline thunk. @@ -352,6 +354,44 @@ void CIRGenItaniumCXXABI::emitDestructorCall( vttTy, nullptr); } +// The idea here is creating a separate block for the throw with an +// `UnreachableOp` as the terminator. So, we branch from the current block +// to the throw block and create a block for the remaining operations. +static void insertThrowAndSplit(mlir::OpBuilder &builder, mlir::Location loc, + mlir::Value exceptionPtr = {}, + mlir::FlatSymbolRefAttr typeInfo = {}, + mlir::FlatSymbolRefAttr dtor = {}) { + mlir::Block *currentBlock = builder.getInsertionBlock(); + mlir::Region *region = currentBlock->getParent(); + + if (currentBlock->empty()) { + cir::ThrowOp::create(builder, loc, exceptionPtr, typeInfo, dtor); + cir::UnreachableOp::create(builder, loc); + } else { + mlir::Block *throwBlock = builder.createBlock(region); + + cir::ThrowOp::create(builder, loc, exceptionPtr, typeInfo, dtor); + cir::UnreachableOp::create(builder, loc); + + builder.setInsertionPointToEnd(currentBlock); + cir::BrOp::create(builder, loc, throwBlock); + } + + (void)builder.createBlock(region); +} + +void CIRGenItaniumCXXABI::emitRethrow(CIRGenFunction &cgf, bool isNoReturn) { + // void __cxa_rethrow(); + if (isNoReturn) { + CIRGenBuilderTy &builder = cgf.getBuilder(); + assert(cgf.currSrcLoc && "expected source location"); + mlir::Location loc = *cgf.currSrcLoc; + insertThrowAndSplit(builder, loc); + } else { + cgm.errorNYI("emitRethrow with isNoReturn false"); + } +} + CIRGenCXXABI *clang::CIRGen::CreateCIRGenItaniumCXXABI(CIRGenModule &cgm) { switch (cgm.getASTContext().getCXXABIKind()) { case TargetCXXABI::GenericItanium: diff --git a/clang/lib/CIR/CodeGen/CMakeLists.txt b/clang/lib/CIR/CodeGen/CMakeLists.txt index 7366446a33c6..6d7072ad1869 100644 --- a/clang/lib/CIR/CodeGen/CMakeLists.txt +++ b/clang/lib/CIR/CodeGen/CMakeLists.txt @@ -20,6 +20,7 @@ add_clang_library(clangCIR CIRGenBuiltin.cpp CIRGenDecl.cpp CIRGenDeclOpenACC.cpp + CIRGenException.cpp CIRGenExpr.cpp CIRGenExprAggregate.cpp CIRGenExprComplex.cpp diff --git a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp index 83fff09d4fab..80ca2d371792 100644 --- a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp +++ b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp @@ -2698,6 +2698,24 @@ ParseResult cir::InlineAsmOp::parse(OpAsmParser &parser, } //===----------------------------------------------------------------------===// +// ThrowOp +//===----------------------------------------------------------------------===// + +mlir::LogicalResult cir::ThrowOp::verify() { + // For the no-rethrow version, it must have at least the exception pointer. + if (rethrows()) + return success(); + + if (getNumOperands() != 0) { + if (getTypeInfo()) + return success(); + return emitOpError() << "'type_info' symbol attribute missing"; + } + + return failure(); +} + +//===----------------------------------------------------------------------===// // TableGen'd op method definitions //===----------------------------------------------------------------------===// diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp index 03955dc73782..f1fdfed166bb 100644 --- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp +++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp @@ -2435,6 +2435,7 @@ void ConvertCIRToLLVMPass::runOnOperation() { CIRToLLVMStackRestoreOpLowering, CIRToLLVMStackSaveOpLowering, CIRToLLVMSwitchFlatOpLowering, + CIRToLLVMThrowOpLowering, CIRToLLVMTrapOpLowering, CIRToLLVMUnaryOpLowering, CIRToLLVMUnreachableOpLowering, @@ -2515,6 +2516,42 @@ mlir::LogicalResult CIRToLLVMUnreachableOpLowering::matchAndRewrite( return mlir::success(); } +void createLLVMFuncOpIfNotExist(mlir::ConversionPatternRewriter &rewriter, + mlir::Operation *srcOp, llvm::StringRef fnName, + mlir::Type fnTy) { + auto modOp = srcOp->getParentOfType<mlir::ModuleOp>(); + auto enclosingFnOp = srcOp->getParentOfType<mlir::LLVM::LLVMFuncOp>(); + mlir::Operation *sourceSymbol = + mlir::SymbolTable::lookupSymbolIn(modOp, fnName); + if (!sourceSymbol) { + mlir::OpBuilder::InsertionGuard guard(rewriter); + rewriter.setInsertionPoint(enclosingFnOp); + rewriter.create<mlir::LLVM::LLVMFuncOp>(srcOp->getLoc(), fnName, fnTy); + } +} + +mlir::LogicalResult CIRToLLVMThrowOpLowering::matchAndRewrite( + cir::ThrowOp op, OpAdaptor adaptor, + mlir::ConversionPatternRewriter &rewriter) const { + if (op.rethrows()) { + auto voidTy = mlir::LLVM::LLVMVoidType::get(getContext()); + auto funcTy = + mlir::LLVM::LLVMFunctionType::get(getContext(), voidTy, {}, false); + + auto mlirModule = op->getParentOfType<mlir::ModuleOp>(); + rewriter.setInsertionPointToStart(&mlirModule.getBodyRegion().front()); + + const llvm::StringRef functionName = "__cxa_rethrow"; + createLLVMFuncOpIfNotExist(rewriter, op, functionName, funcTy); + + rewriter.setInsertionPointAfter(op.getOperation()); + rewriter.replaceOpWithNewOp<mlir::LLVM::CallOp>( + op, mlir::TypeRange{}, functionName, mlir::ValueRange{}); + } + + return mlir::success(); +} + mlir::LogicalResult CIRToLLVMTrapOpLowering::matchAndRewrite( cir::TrapOp op, OpAdaptor adaptor, mlir::ConversionPatternRewriter &rewriter) const { @@ -3160,7 +3197,7 @@ mlir::LogicalResult CIRToLLVMInlineAsmOpLowering::matchAndRewrite( SmallVector<mlir::Value> llvmOperands; SmallVector<mlir::Value> cirOperands; - for (auto const&[llvmOp, cirOp] : + for (auto const &[llvmOp, cirOp] : zip(adaptor.getAsmOperands(), op.getAsmOperands())) { append_range(llvmOperands, llvmOp); append_range(cirOperands, cirOp); @@ -3168,15 +3205,15 @@ mlir::LogicalResult CIRToLLVMInlineAsmOpLowering::matchAndRewrite( // so far we infer the llvm dialect element type attr from // CIR operand type. - for (auto const&[cirOpAttr, cirOp] : zip(op.getOperandAttrs(), cirOperands)) { + for (auto const &[cirOpAttr, cirOp] : + zip(op.getOperandAttrs(), cirOperands)) { if (!cirOpAttr) { opAttrs.push_back(mlir::Attribute()); continue; } llvm::SmallVector<mlir::NamedAttribute, 1> attrs; - cir::PointerType typ = - mlir::cast<cir::PointerType>(cirOp.getType()); + cir::PointerType typ = mlir::cast<cir::PointerType>(cirOp.getType()); mlir::TypeAttr typAttr = mlir::TypeAttr::get(convertTypeForMemory( *getTypeConverter(), dataLayout, typ.getPointee())); diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.h b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.h index 513ad37839f1..da7df8982d34 100644 --- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.h +++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.h @@ -735,6 +735,16 @@ public: mlir::ConversionPatternRewriter &) const override; }; +class CIRToLLVMThrowOpLowering + : public mlir::OpConversionPattern<cir::ThrowOp> { +public: + using mlir::OpConversionPattern<cir::ThrowOp>::OpConversionPattern; + + mlir::LogicalResult + matchAndRewrite(cir::ThrowOp op, OpAdaptor, + mlir::ConversionPatternRewriter &) const override; +}; + class CIRToLLVMVAStartOpLowering : public mlir::OpConversionPattern<cir::VAStartOp> { public: diff --git a/clang/lib/Sema/SemaOpenACCClause.cpp b/clang/lib/Sema/SemaOpenACCClause.cpp index 43ae4f4d3011..e65526232a95 100644 --- a/clang/lib/Sema/SemaOpenACCClause.cpp +++ b/clang/lib/Sema/SemaOpenACCClause.cpp @@ -1968,7 +1968,8 @@ ExprResult SemaOpenACC::CheckReductionVar(OpenACCDirectiveKind DirectiveKind, } auto IsValidMemberOfComposite = [](QualType Ty) { - return Ty->isDependentType() || Ty->isScalarType(); + return Ty->isDependentType() || + (Ty->isScalarType() && !Ty->isPointerType()); }; auto EmitDiags = [&](SourceLocation Loc, PartialDiagnostic PD) { diff --git a/clang/test/AST/ast-print-openacc-combined-construct.cpp b/clang/test/AST/ast-print-openacc-combined-construct.cpp index b4e803348a2f..1f954cbf14b1 100644 --- a/clang/test/AST/ast-print-openacc-combined-construct.cpp +++ b/clang/test/AST/ast-print-openacc-combined-construct.cpp @@ -386,27 +386,18 @@ void foo() { #pragma acc serial loop vector for(int i = 0;i<5;++i); -//CHECK: #pragma acc parallel loop reduction(+: iPtr) -#pragma acc parallel loop reduction(+: iPtr) - for(int i = 0;i<5;++i); //CHECK: #pragma acc serial loop reduction(*: i) #pragma acc serial loop reduction(*: i) for(int i = 0;i<5;++i); //CHECK: #pragma acc kernels loop reduction(max: SomeB) #pragma acc kernels loop reduction(max: SomeB) for(int i = 0;i<5;++i); -//CHECK: #pragma acc parallel loop reduction(min: iPtr) -#pragma acc parallel loop reduction(min: iPtr) - for(int i = 0;i<5;++i); //CHECK: #pragma acc serial loop reduction(&: i) #pragma acc serial loop reduction(&: i) for(int i = 0;i<5;++i); //CHECK: #pragma acc kernels loop reduction(|: SomeB) #pragma acc kernels loop reduction(|: SomeB) for(int i = 0;i<5;++i); -//CHECK: #pragma acc parallel loop reduction(^: iPtr) -#pragma acc parallel loop reduction(^: iPtr) - for(int i = 0;i<5;++i); //CHECK: #pragma acc serial loop reduction(&&: i) #pragma acc serial loop reduction(&&: i) for(int i = 0;i<5;++i); diff --git a/clang/test/AST/ast-print-openacc-compute-construct.cpp b/clang/test/AST/ast-print-openacc-compute-construct.cpp index 7c3ac17ec1a2..d85682f0dac2 100644 --- a/clang/test/AST/ast-print-openacc-compute-construct.cpp +++ b/clang/test/AST/ast-print-openacc-compute-construct.cpp @@ -135,27 +135,18 @@ void foo() { #pragma acc parallel device_type (host) while(true); -//CHECK: #pragma acc parallel reduction(+: iPtr) -#pragma acc parallel reduction(+: iPtr) - while(true); //CHECK: #pragma acc parallel reduction(*: i) #pragma acc parallel reduction(*: i) while(true); //CHECK: #pragma acc parallel reduction(max: SomeB) #pragma acc parallel reduction(max: SomeB) while(true); -//CHECK: #pragma acc parallel reduction(min: iPtr) -#pragma acc parallel reduction(min: iPtr) - while(true); //CHECK: #pragma acc parallel reduction(&: i) #pragma acc parallel reduction(&: i) while(true); //CHECK: #pragma acc parallel reduction(|: SomeB) #pragma acc parallel reduction(|: SomeB) while(true); -//CHECK: #pragma acc parallel reduction(^: iPtr) -#pragma acc parallel reduction(^: iPtr) - while(true); //CHECK: #pragma acc parallel reduction(&&: i) #pragma acc parallel reduction(&&: i) while(true); diff --git a/clang/test/AST/ast-print-openacc-loop-construct.cpp b/clang/test/AST/ast-print-openacc-loop-construct.cpp index 6971089e5919..74c58894ee08 100644 --- a/clang/test/AST/ast-print-openacc-loop-construct.cpp +++ b/clang/test/AST/ast-print-openacc-loop-construct.cpp @@ -291,30 +291,20 @@ void foo() { #pragma acc loop vector for(int i = 0;i<5;++i); - int *iPtr; bool SomeB; -//CHECK: #pragma acc loop reduction(+: iPtr) -#pragma acc loop reduction(+: iPtr) - for(int i = 0;i<5;++i); //CHECK: #pragma acc loop reduction(*: i) #pragma acc loop reduction(*: i) for(int i = 0;i<5;++i); //CHECK: #pragma acc loop reduction(max: SomeB) #pragma acc loop reduction(max: SomeB) for(int i = 0;i<5;++i); -//CHECK: #pragma acc loop reduction(min: iPtr) -#pragma acc loop reduction(min: iPtr) - for(int i = 0;i<5;++i); //CHECK: #pragma acc loop reduction(&: i) #pragma acc loop reduction(&: i) for(int i = 0;i<5;++i); //CHECK: #pragma acc loop reduction(|: SomeB) #pragma acc loop reduction(|: SomeB) for(int i = 0;i<5;++i); -//CHECK: #pragma acc loop reduction(^: iPtr) -#pragma acc loop reduction(^: iPtr) - for(int i = 0;i<5;++i); //CHECK: #pragma acc loop reduction(&&: i) #pragma acc loop reduction(&&: i) for(int i = 0;i<5;++i); diff --git a/clang/test/CIR/CodeGen/complex-unary.cpp b/clang/test/CIR/CodeGen/complex-unary.cpp index 4cd81eb40597..e945d9b09f61 100644 --- a/clang/test/CIR/CodeGen/complex-unary.cpp +++ b/clang/test/CIR/CodeGen/complex-unary.cpp @@ -370,3 +370,138 @@ void foo8() { // OGCG: %[[B_IMAG_PTR:.*]] = getelementptr inbounds nuw { float, float }, ptr %[[B_ADDR]], i32 0, i32 1 // OGCG: store float %[[A_REAL_MINUS]], ptr %[[B_REAL_PTR]], align 4 // OGCG: store float %[[A_IMAG_MINUS]], ptr %[[B_IMAG_PTR]], align 4 + +void foo9() { + _Float16 _Complex a; + _Float16 _Complex b = +a; +} + + +// CIR-BEFORE: %[[A_ADDR:.*]] = cir.alloca !cir.complex<!cir.f16>, !cir.ptr<!cir.complex<!cir.f16>>, ["a"] +// CIR-BEFORE: %[[B_ADDR:.*]] = cir.alloca !cir.complex<!cir.f16>, !cir.ptr<!cir.complex<!cir.f16>>, ["b", init] +// CIR-BEFORE: %[[TMP_A:.*]] = cir.load{{.*}} %[[A_ADDR]] : !cir.ptr<!cir.complex<!cir.f16>>, !cir.complex<!cir.f16> +// CIR-BEFORE: %[[A_COMPLEX_F32:.*]] = cir.cast(float_complex, %[[TMP_A]] : !cir.complex<!cir.f16>), !cir.complex<!cir.float> +// CIR-BEFORE: %[[RESULT:.*]] = cir.unary(plus, %[[A_COMPLEX_F32]]) : !cir.complex<!cir.float>, !cir.complex<!cir.float> +// CIR-BEFORE: %[[A_COMPLEX_F16:.*]] = cir.cast(float_complex, %[[RESULT]] : !cir.complex<!cir.float>), !cir.complex<!cir.f16> +// CIR-BEFORE: cir.store{{.*}} %[[A_COMPLEX_F16]], %[[B_ADDR]] : !cir.complex<!cir.f16>, !cir.ptr<!cir.complex<!cir.f16>> + +// CIR-AFTER: %[[A_ADDR:.*]] = cir.alloca !cir.complex<!cir.f16>, !cir.ptr<!cir.complex<!cir.f16>>, ["a"] +// CIR-AFTER: %[[B_ADDR:.*]] = cir.alloca !cir.complex<!cir.f16>, !cir.ptr<!cir.complex<!cir.f16>>, ["b", init] +// CIR-AFTER: %[[TMP_A:.*]] = cir.load{{.*}} %[[A_ADDR]] : !cir.ptr<!cir.complex<!cir.f16>>, !cir.complex<!cir.f16> +// CIR-AFTER: %[[A_REAL:.*]] = cir.complex.real %[[TMP_A]] : !cir.complex<!cir.f16> -> !cir.f16 +// CIR-AFTER: %[[A_IMAG:.*]] = cir.complex.imag %[[TMP_A]] : !cir.complex<!cir.f16> -> !cir.f16 +// CIR-AFTER: %[[A_REAL_F32:.*]] = cir.cast(floating, %[[A_REAL]] : !cir.f16), !cir.float +// CIR-AFTER: %[[A_IMAG_F32:.*]] = cir.cast(floating, %[[A_IMAG]] : !cir.f16), !cir.float +// CIR-AFTER: %[[A_COMPLEX_F32:.*]] = cir.complex.create %[[A_REAL_F32]], %[[A_IMAG_F32]] : !cir.float -> !cir.complex<!cir.float> +// CIR-AFTER: %[[A_REAL_F32:.*]] = cir.complex.real %[[A_COMPLEX_F32]] : !cir.complex<!cir.float> -> !cir.float +// CIR-AFTER: %[[A_IMAG_F32:.*]] = cir.complex.imag %[[A_COMPLEX_F32]] : !cir.complex<!cir.float> -> !cir.float +// CIR-AFTER: %[[RESULT_REAL_F32:.*]] = cir.unary(plus, %[[A_REAL_F32]]) : !cir.float, !cir.float +// CIR-AFTER: %[[RESULT_IMAG_F32:.*]] = cir.unary(plus, %[[A_IMAG_F32]]) : !cir.float, !cir.float +// CIR-AFTER: %[[RESULT_COMPLEX_F32:.*]] = cir.complex.create %[[RESULT_REAL_F32]], %[[RESULT_IMAG_F32]] : !cir.float -> !cir.complex<!cir.float> +// CIR-AFTER: %[[RESULT_REAL_F32:.*]] = cir.complex.real %[[RESULT_COMPLEX_F32]] : !cir.complex<!cir.float> -> !cir.float +// CIR-AFTER: %[[RESULT_IMAG_F32:.*]] = cir.complex.imag %[[RESULT_COMPLEX_F32]] : !cir.complex<!cir.float> -> !cir.float +// CIR-AFTER: %[[RESULT_REAL_F16:.*]] = cir.cast(floating, %[[RESULT_REAL_F32]] : !cir.float), !cir.f16 +// CIR-AFTER: %[[RESULT_IMAG_F16:.*]] = cir.cast(floating, %[[RESULT_IMAG_F32]] : !cir.float), !cir.f16 +// CIR-AFTER: %[[RESULT_COMPLEX_F16:.*]] = cir.complex.create %[[RESULT_REAL_F16]], %[[RESULT_IMAG_F16]] : !cir.f16 -> !cir.complex<!cir.f16> +// CIR-AFTER: cir.store{{.*}} %[[RESULT_COMPLEX_F16]], %[[B_ADDR]] : !cir.complex<!cir.f16>, !cir.ptr<!cir.complex<!cir.f16>> + +// LLVM: %[[A_ADDR:.*]] = alloca { half, half }, i64 1, align 2 +// LLVM: %[[B_ADDR:.*]] = alloca { half, half }, i64 1, align 2 +// LLVM: %[[TMP_A:.*]] = load { half, half }, ptr %[[A_ADDR]], align 2 +// LLVM: %[[A_REAL:.*]] = extractvalue { half, half } %[[TMP_A]], 0 +// LLVM: %[[A_IMAG:.*]] = extractvalue { half, half } %[[TMP_A]], 1 +// LLVM: %[[A_REAL_F32:.*]] = fpext half %[[A_REAL]] to float +// LLVM: %[[A_IMAG_F32:.*]] = fpext half %[[A_IMAG]] to float +// LLVM: %[[TMP_A_COMPLEX_F32:.*]] = insertvalue { float, float } {{.*}}, float %[[A_REAL_F32]], 0 +// LLVM: %[[A_COMPLEX_F32:.*]] = insertvalue { float, float } %[[TMP_A_COMPLEX_F32]], float %[[A_IMAG_F32]], 1 +// LLVM: %[[TMP_A_COMPLEX_F32:.*]] = insertvalue { float, float } {{.*}}, float %[[A_REAL_F32]], 0 +// LLVM: %[[A_COMPLEX_F32:.*]] = insertvalue { float, float } %[[TMP_A_COMPLEX_F32]], float %[[A_IMAG_F32]], 1 +// LLVM: %[[A_REAL_F16:.*]] = fptrunc float %[[A_REAL_F32]] to half +// LLVM: %[[A_IMAG_F16:.*]] = fptrunc float %[[A_IMAG_F32]] to half +// LLVM: %[[TMP_RESULT_COMPLEX_F16:.*]] = insertvalue { half, half } {{.*}}, half %[[A_REAL_F16]], 0 +// LLVM: %[[RESULT_COMPLEX_F16:.*]] = insertvalue { half, half } %[[TMP_RESULT_COMPLEX_F16]], half %[[A_IMAG_F16]], 1 +// LLVM: store { half, half } %[[RESULT_COMPLEX_F16]], ptr %[[B_ADDR]], align 2 + +// OGCG: %[[A_ADDR:.*]] = alloca { half, half }, align 2 +// OGCG: %[[B_ADDR:.*]] = alloca { half, half }, align 2 +// OGCG: %[[A_REAL_PTR:.*]] = getelementptr inbounds nuw { half, half }, ptr %[[A_ADDR]], i32 0, i32 0 +// OGCG: %[[A_REAL:.*]] = load half, ptr %a.realp, align 2 +// OGCG: %[[A_IMAG_PTR:.*]] = getelementptr inbounds nuw { half, half }, ptr %[[A_ADDR]], i32 0, i32 1 +// OGCG: %[[A_IMAG:.*]] = load half, ptr %a.imagp, align 2 +// OGCG: %[[A_REAL_F32:.*]] = fpext half %[[A_REAL]] to float +// OGCG: %[[A_IMAG_F32:.*]] = fpext half %[[A_IMAG]] to float +// OGCG: %[[RESULT_REAL:.*]] = fptrunc float %[[A_REAL_F32]] to half +// OGCG: %[[RESULT_IMAG:.*]] = fptrunc float %[[A_IMAG_F32]] to half +// OGCG: %[[B_REAL_PTR:.*]] = getelementptr inbounds nuw { half, half }, ptr %[[B_ADDR]], i32 0, i32 0 +// OGCG: %[[B_IMAG_PTR:.*]] = getelementptr inbounds nuw { half, half }, ptr %[[B_ADDR]], i32 0, i32 1 +// OGCG: store half %[[RESULT_REAL]], ptr %[[B_REAL_PTR]], align 2 +// OGCG: store half %[[RESULT_IMAG]], ptr %[[B_IMAG_PTR]], align 2 + +void foo10() { + _Float16 _Complex a; + _Float16 _Complex b = -a; +} + +// CIR-BEFORE: %[[A_ADDR:.*]] = cir.alloca !cir.complex<!cir.f16>, !cir.ptr<!cir.complex<!cir.f16>>, ["a"] +// CIR-BEFORE: %[[B_ADDR:.*]] = cir.alloca !cir.complex<!cir.f16>, !cir.ptr<!cir.complex<!cir.f16>>, ["b", init] +// CIR-BEFORE: %[[TMP_A:.*]] = cir.load{{.*}} %[[A_ADDR]] : !cir.ptr<!cir.complex<!cir.f16>>, !cir.complex<!cir.f16> +// CIR-BEFORE: %[[A_COMPLEX_F32:.*]] = cir.cast(float_complex, %[[TMP_A]] : !cir.complex<!cir.f16>), !cir.complex<!cir.float> +// CIR-BEFORE: %[[RESULT:.*]] = cir.unary(minus, %[[A_COMPLEX_F32]]) : !cir.complex<!cir.float>, !cir.complex<!cir.float> +// CIR-BEFORE: %[[A_COMPLEX_F16:.*]] = cir.cast(float_complex, %[[RESULT]] : !cir.complex<!cir.float>), !cir.complex<!cir.f16> +// CIR-BEFORE: cir.store{{.*}} %[[A_COMPLEX_F16]], %[[B_ADDR]] : !cir.complex<!cir.f16>, !cir.ptr<!cir.complex<!cir.f16>> + +// CIR-AFTER: %[[A_ADDR:.*]] = cir.alloca !cir.complex<!cir.f16>, !cir.ptr<!cir.complex<!cir.f16>>, ["a"] +// CIR-AFTER: %[[B_ADDR:.*]] = cir.alloca !cir.complex<!cir.f16>, !cir.ptr<!cir.complex<!cir.f16>>, ["b", init] +// CIR-AFTER: %[[TMP_A:.*]] = cir.load{{.*}} %[[A_ADDR]] : !cir.ptr<!cir.complex<!cir.f16>>, !cir.complex<!cir.f16> +// CIR-AFTER: %[[A_REAL:.*]] = cir.complex.real %[[TMP_A]] : !cir.complex<!cir.f16> -> !cir.f16 +// CIR-AFTER: %[[A_IMAG:.*]] = cir.complex.imag %[[TMP_A]] : !cir.complex<!cir.f16> -> !cir.f16 +// CIR-AFTER: %[[A_REAL_F32:.*]] = cir.cast(floating, %[[A_REAL]] : !cir.f16), !cir.float +// CIR-AFTER: %[[A_IMAG_F32:.*]] = cir.cast(floating, %[[A_IMAG]] : !cir.f16), !cir.float +// CIR-AFTER: %[[A_COMPLEX_F32:.*]] = cir.complex.create %[[A_REAL_F32]], %[[A_IMAG_F32]] : !cir.float -> !cir.complex<!cir.float> +// CIR-AFTER: %[[A_REAL_F32:.*]] = cir.complex.real %[[A_COMPLEX_F32]] : !cir.complex<!cir.float> -> !cir.float +// CIR-AFTER: %[[A_IMAG_F32:.*]] = cir.complex.imag %[[A_COMPLEX_F32]] : !cir.complex<!cir.float> -> !cir.float +// CIR-AFTER: %[[RESULT_REAL_F32:.*]] = cir.unary(minus, %[[A_REAL_F32]]) : !cir.float, !cir.float +// CIR-AFTER: %[[RESULT_IMAG_F32:.*]] = cir.unary(minus, %[[A_IMAG_F32]]) : !cir.float, !cir.float +// CIR-AFTER: %[[RESULT_COMPLEX_F32:.*]] = cir.complex.create %[[RESULT_REAL_F32]], %[[RESULT_IMAG_F32]] : !cir.float -> !cir.complex<!cir.float> +// CIR-AFTER: %[[RESULT_REAL_F32:.*]] = cir.complex.real %[[RESULT_COMPLEX_F32]] : !cir.complex<!cir.float> -> !cir.float +// CIR-AFTER: %[[RESULT_IMAG_F32:.*]] = cir.complex.imag %[[RESULT_COMPLEX_F32]] : !cir.complex<!cir.float> -> !cir.float +// CIR-AFTER: %[[RESULT_REAL_F16:.*]] = cir.cast(floating, %[[RESULT_REAL_F32]] : !cir.float), !cir.f16 +// CIR-AFTER: %[[RESULT_IMAG_F16:.*]] = cir.cast(floating, %[[RESULT_IMAG_F32]] : !cir.float), !cir.f16 +// CIR-AFTER: %[[RESULT_COMPLEX_F16:.*]] = cir.complex.create %[[RESULT_REAL_F16]], %[[RESULT_IMAG_F16]] : !cir.f16 -> !cir.complex<!cir.f16> +// CIR-AFTER: cir.store{{.*}} %[[RESULT_COMPLEX_F16]], %[[B_ADDR]] : !cir.complex<!cir.f16>, !cir.ptr<!cir.complex<!cir.f16>> + +// LLVM: %[[A_ADDR:.*]] = alloca { half, half }, i64 1, align 2 +// LLVM: %[[B_ADDR:.*]] = alloca { half, half }, i64 1, align 2 +// LLVM: %[[TMP_A:.*]] = load { half, half }, ptr %[[A_ADDR]], align 2 +// LLVM: %[[A_REAL:.*]] = extractvalue { half, half } %[[TMP_A]], 0 +// LLVM: %[[A_IMAG:.*]] = extractvalue { half, half } %[[TMP_A]], 1 +// LLVM: %[[A_REAL_F32:.*]] = fpext half %[[A_REAL]] to float +// LLVM: %[[A_IMAG_F32:.*]] = fpext half %[[A_IMAG]] to float +// LLVM: %[[TMP_A_COMPLEX_F32:.*]] = insertvalue { float, float } {{.*}}, float %[[A_REAL_F32]], 0 +// LLVM: %[[A_COMPLEX_F32:.*]] = insertvalue { float, float } %[[TMP_A_COMPLEX_F32]], float %[[A_IMAG_F32]], 1 +// LLVM: %[[RESULT_REAL_F32:.*]] = fneg float %[[A_REAL_F32]] +// LLVM: %[[RESULT_IMAG_F32:.*]] = fneg float %[[A_IMAG_F32]] +// LLVM: %[[TMP_A_COMPLEX_F32:.*]] = insertvalue { float, float } {{.*}}, float %[[RESULT_REAL_F32]], 0 +// LLVM: %[[A_COMPLEX_F32:.*]] = insertvalue { float, float } %[[TMP_A_COMPLEX_F32]], float %[[RESULT_IMAG_F32]], 1 +// LLVM: %[[A_REAL_F16:.*]] = fptrunc float %[[RESULT_REAL_F32]] to half +// LLVM: %[[A_IMAG_F16:.*]] = fptrunc float %[[RESULT_IMAG_F32]] to half +// LLVM: %[[TMP_RESULT_COMPLEX_F16:.*]] = insertvalue { half, half } {{.*}}, half %[[A_REAL_F16]], 0 +// LLVM: %[[RESULT_COMPLEX_F16:.*]] = insertvalue { half, half } %[[TMP_RESULT_COMPLEX_F16]], half %[[A_IMAG_F16]], 1 +// LLVM: store { half, half } %[[RESULT_COMPLEX_F16]], ptr %[[B_ADDR]], align 2 + +// OGCG: %[[A_ADDR:.*]] = alloca { half, half }, align 2 +// OGCG: %[[B_ADDR:.*]] = alloca { half, half }, align 2 +// OGCG: %[[A_REAL_PTR:.*]] = getelementptr inbounds nuw { half, half }, ptr %[[A_ADDR]], i32 0, i32 0 +// OGCG: %[[A_REAL:.*]] = load half, ptr %a.realp, align 2 +// OGCG: %[[A_IMAG_PTR:.*]] = getelementptr inbounds nuw { half, half }, ptr %[[A_ADDR]], i32 0, i32 1 +// OGCG: %[[A_IMAG:.*]] = load half, ptr %a.imagp, align 2 +// OGCG: %[[A_REAL_F32:.*]] = fpext half %[[A_REAL]] to float +// OGCG: %[[A_IMAG_F32:.*]] = fpext half %[[A_IMAG]] to float +// OGCG: %[[RESULT_REAL_F32:.*]] = fneg float %[[A_REAL_F32]] +// OGCG: %[[RESULT_IMAG_F32:.*]] = fneg float %[[A_IMAG_F32]] +// OGCG: %[[RESULT_REAL:.*]] = fptrunc float %[[RESULT_REAL_F32]] to half +// OGCG: %[[RESULT_IMAG:.*]] = fptrunc float %[[RESULT_IMAG_F32]] to half +// OGCG: %[[B_REAL_PTR:.*]] = getelementptr inbounds nuw { half, half }, ptr %[[B_ADDR]], i32 0, i32 0 +// OGCG: %[[B_IMAG_PTR:.*]] = getelementptr inbounds nuw { half, half }, ptr %[[B_ADDR]], i32 0, i32 1 +// OGCG: store half %[[RESULT_REAL]], ptr %[[B_REAL_PTR]], align 2 +// OGCG: store half %[[RESULT_IMAG]], ptr %[[B_IMAG_PTR]], align 2 diff --git a/clang/test/CIR/CodeGen/throws.cpp b/clang/test/CIR/CodeGen/throws.cpp new file mode 100644 index 000000000000..0122f3088f0b --- /dev/null +++ b/clang/test/CIR/CodeGen/throws.cpp @@ -0,0 +1,85 @@ +// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-linux-gnu -fcxx-exceptions -fexceptions -fclangir -emit-cir %s -o %t.cir +// RUN: FileCheck --input-file=%t.cir %s -check-prefix=CIR +// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-linux-gnu -fcxx-exceptions -fexceptions -fclangir -emit-llvm %s -o %t-cir.ll +// RUN: FileCheck --input-file=%t-cir.ll %s -check-prefix=LLVM +// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-linux-gnu -fcxx-exceptions -fexceptions -emit-llvm %s -o %t.ll +// RUN: FileCheck --input-file=%t.ll %s -check-prefix=OGCG + +void foo() { + throw; +} + +// CIR: cir.throw +// CIR: cir.unreachable + +// LLVM: call void @__cxa_rethrow() +// LLVM: unreachable + +// OGCG: call void @__cxa_rethrow() +// OGCG: unreachable + +int foo1(int a, int b) { + if (b == 0) + throw; + return a / b; +} + +// CIR: %[[A_ADDR:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["a", init] +// CIR: %[[B_ADDR:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["b", init] +// CIR: %[[RES_ADDR:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["__retval"] +// CIR: cir.store %{{.*}}, %[[A_ADDR]] : !s32i, !cir.ptr<!s32i> +// CIR: cir.store %{{.*}}, %[[B_ADDR]] : !s32i, !cir.ptr<!s32i> +// CIR: cir.scope { +// CIR: %[[TMP_B:.*]] = cir.load{{.*}} %[[B_ADDR]] : !cir.ptr<!s32i>, !s32i +// CIR: %[[CONST_0:.*]] = cir.const #cir.int<0> : !s32i +// CIR: %[[IS_B_ZERO:.*]] = cir.cmp(eq, %[[TMP_B]], %[[CONST_0]]) : !s32i, !cir.bool +// CIR: cir.if %[[IS_B_ZERO]] { +// CIR: cir.throw +// CIR: cir.unreachable +// CIR: } +// CIR: } +// CIR: %[[TMP_A:.*]] = cir.load{{.*}} %[[A_ADDR]] : !cir.ptr<!s32i>, !s32i +// CIR: %[[TMP_B:.*]] = cir.load{{.*}} %[[B_ADDR]] : !cir.ptr<!s32i>, !s32i +// CIR: %[[DIV_A_B:.*]] = cir.binop(div, %[[TMP_A:.*]], %[[TMP_B:.*]]) : !s32i +// CIR: cir.store %[[DIV_A_B]], %[[RES_ADDR]] : !s32i, !cir.ptr<!s32i> +// CIR: %[[RESULT:.*]] = cir.load %[[RES_ADDR]] : !cir.ptr<!s32i>, !s32i +// CIR: cir.return %[[RESULT]] : !s32i + +// LLVM: %[[A_ADDR:.*]] = alloca i32, i64 1, align 4 +// LLVM: %[[B_ADDR:.*]] = alloca i32, i64 1, align 4 +// LLVM: %[[RES_ADDR:.*]] = alloca i32, i64 1, align 4 +// LLVM: store i32 %{{.*}}, ptr %[[A_ADDR]], align 4 +// LLVM: store i32 %{{.*}}, ptr %[[B_ADDR]], align 4 +// LLVM: br label %[[CHECK_COND:.*]] +// LLVM: [[CHECK_COND]]: +// LLVM: %[[TMP_B:.*]] = load i32, ptr %[[B_ADDR]], align 4 +// LLVM: %[[IS_B_ZERO:.*]] = icmp eq i32 %[[TMP_B]], 0 +// LLVM: br i1 %[[IS_B_ZERO]], label %[[IF_THEN:.*]], label %[[IF_ELSE:.*]] +// LLVM: [[IF_THEN]]: +// LLVM: call void @__cxa_rethrow() +// LLVM: unreachable +// LLVM: [[IF_ELSE]]: +// LLVM: br label %[[IF_END:.*]] +// LLVM: [[IF_END]]: +// LLVM: %[[TMP_A:.*]] = load i32, ptr %[[A_ADDR]], align 4 +// LLVM: %[[TMP_B:.*]] = load i32, ptr %[[B_ADDR]], align 4 +// LLVM: %[[DIV_A_B:.*]] = sdiv i32 %[[TMP_A]], %[[TMP_B]] +// LLVM: store i32 %[[DIV_A_B]], ptr %[[RES_ADDR]], align 4 +// LLVM: %[[RESULT:.*]] = load i32, ptr %[[RES_ADDR]], align 4 +// LLVM: ret i32 %[[RESULT]] + +// OGCG: %[[A_ADDR:.*]] = alloca i32, align 4 +// OGCG: %[[B_ADDR:.*]] = alloca i32, align 4 +// OGCG: store i32 %{{.*}}, ptr %[[A_ADDR]], align 4 +// OGCG: store i32 %{{.*}}, ptr %[[B_ADDR]], align 4 +// OGCG: %[[TMP_B:.*]] = load i32, ptr %[[B_ADDR]], align 4 +// OGCG: %[[IS_B_ZERO:.*]] = icmp eq i32 %[[TMP_B]], 0 +// OGCG: br i1 %[[IS_B_ZERO]], label %[[IF_THEN:.*]], label %[[IF_END:.*]] +// OGCG: [[IF_THEN]]: +// OGCG: call void @__cxa_rethrow() +// OGCG: unreachable +// OGCG: [[IF_END]]: +// OGCG: %[[TMP_A:.*]] = load i32, ptr %[[A_ADDR]], align 4 +// OGCG: %[[TMP_B:.*]] = load i32, ptr %[[B_ADDR]], align 4 +// OGCG: %[[DIV_A_B:.*]] = sdiv i32 %[[TMP_A]], %[[TMP_B]] +// OGCG: ret i32 %[[DIV_A_B]] diff --git a/clang/test/CIR/IR/invalid-throw.cir b/clang/test/CIR/IR/invalid-throw.cir new file mode 100644 index 000000000000..53582a11b285 --- /dev/null +++ b/clang/test/CIR/IR/invalid-throw.cir @@ -0,0 +1,16 @@ +// RUN: cir-opt %s -verify-diagnostics -split-input-file + +!s32i = !cir.int<s, 32> + +module { + +cir.func dso_local @throw_without_type_info() { + %0 = cir.alloca !s32i, !cir.ptr<!s32i>, ["a"] + // expected-error @below {{'cir.throw' op 'type_info' symbol attribute missing}} + cir.throw %0 : !cir.ptr<!s32i> + cir.unreachable + ^bb1: + cir.return +} + +} diff --git a/clang/test/CIR/IR/throw.cir b/clang/test/CIR/IR/throw.cir new file mode 100644 index 000000000000..8b24b481057b --- /dev/null +++ b/clang/test/CIR/IR/throw.cir @@ -0,0 +1,63 @@ +// RUN: cir-opt %s | FileCheck %s + +!s32i = !cir.int<s, 32> + +module { + +cir.func @throw_with_no_return() { + cir.throw + cir.unreachable +} + +// CHECK: cir.func @throw_with_no_return() { +// CHECK: cir.throw +// CHECK: cir.unreachable +// CHECK: } + +cir.func @throw_with_no_return_2(%arg0: !s32i, %arg1: !s32i) -> !s32i { + %0 = cir.alloca !s32i, !cir.ptr<!s32i>, ["a", init] + %1 = cir.alloca !s32i, !cir.ptr<!s32i>, ["b", init] + %2 = cir.alloca !s32i, !cir.ptr<!s32i>, ["__retval"] + cir.store %arg0, %0 : !s32i, !cir.ptr<!s32i> + cir.store %arg1, %1 : !s32i, !cir.ptr<!s32i> + cir.scope { + %7 = cir.load align(4) %1 : !cir.ptr<!s32i>, !s32i + %8 = cir.const #cir.int<0> : !s32i + %9 = cir.cmp(eq, %7, %8) : !s32i, !cir.bool + cir.if %9 { + cir.throw + cir.unreachable + } + } + %3 = cir.load align(4) %0 : !cir.ptr<!s32i>, !s32i + %4 = cir.load align(4) %1 : !cir.ptr<!s32i>, !s32i + %5 = cir.binop(div, %3, %4) : !s32i + cir.store %5, %2 : !s32i, !cir.ptr<!s32i> + %6 = cir.load %2 : !cir.ptr<!s32i>, !s32i + cir.return %6 : !s32i +} + +// CHECK: cir.func @throw_with_no_return_2(%[[ARG_0:.*]]: !s32i, %[[ARG_1:.*]]: !s32i) -> !s32i { +// CHECK: %[[A_ADDR:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["a", init] +// CHECK: %[[B_ADDR:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["b", init] +// CHECK: %[[RES_ADDR:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["__retval"] +// CHECK: cir.store %[[ARG_0]], %[[A_ADDR]] : !s32i, !cir.ptr<!s32i> +// CHECK: cir.store %[[ARG_1]], %[[B_ADDR]] : !s32i, !cir.ptr<!s32i> +// CHECK: cir.scope { +// CHECK: %[[TMP_B:.*]] = cir.load{{.*}} %[[B_ADDR]] : !cir.ptr<!s32i>, !s32i +// CHECK: %[[CONST_0:.*]] = cir.const #cir.int<0> : !s32i +// CHECK: %[[IS_B_ZERO:.*]] = cir.cmp(eq, %[[TMP_B]], %[[CONST_0]]) : !s32i, !cir.bool +// CHECK: cir.if %[[IS_B_ZERO]] { +// CHECK: cir.throw +// CHECK: cir.unreachable +// CHECK: } +// CHECK: } +// CHECK: %[[TMP_A:.*]] = cir.load{{.*}} %[[A_ADDR]] : !cir.ptr<!s32i>, !s32i +// CHECK: %[[TMP_B:.*]] = cir.load{{.*}} %[[B_ADDR]] : !cir.ptr<!s32i>, !s32i +// CHECK: %[[DIV_A_B:.*]] = cir.binop(div, %[[TMP_A:.*]], %[[TMP_B:.*]]) : !s32i +// CHECK: cir.store %[[DIV_A_B]], %[[RES_ADDR]] : !s32i, !cir.ptr<!s32i> +// CHECK: %[[RESULT:.*]] = cir.load %[[RES_ADDR]] : !cir.ptr<!s32i>, !s32i +// CHECK: cir.return %[[RESULT]] : !s32i +// CHECK: } + +} diff --git a/clang/test/ParserOpenACC/parse-clauses.c b/clang/test/ParserOpenACC/parse-clauses.c index a9ad7ab176cb..d3fd90331a83 100644 --- a/clang/test/ParserOpenACC/parse-clauses.c +++ b/clang/test/ParserOpenACC/parse-clauses.c @@ -723,7 +723,7 @@ void VarListClauses() { } void ReductionClauseParsing() { - char *Begin, *End; + char Begin, End; // expected-error@+1{{expected '('}} #pragma acc serial reduction for(int i = 0; i < 5;++i) {} diff --git a/clang/test/SemaOpenACC/compute-construct-reduction-clause.cpp b/clang/test/SemaOpenACC/compute-construct-reduction-clause.cpp index 924d19939d27..2e1f18009d84 100644 --- a/clang/test/SemaOpenACC/compute-construct-reduction-clause.cpp +++ b/clang/test/SemaOpenACC/compute-construct-reduction-clause.cpp @@ -112,6 +112,39 @@ void uses(unsigned Parm) { // expected-note@+1{{OpenACC 'reduction' variable reference must be a scalar variable or a composite of scalars, or an array, sub-array, or element of scalar types}} #pragma acc parallel reduction(+:CoCArr[1:1]) while (1); + + int *IPtr; + // expected-error@+2{{invalid type 'int *' used in OpenACC 'reduction' variable reference; type is not a scalar value, or array of scalars, or composite of scalars}} + // expected-note@+1{{OpenACC 'reduction' variable reference must be a scalar variable or a composite of scalars, or an array, sub-array, or element of scalar types}} +#pragma acc parallel reduction(+:IPtr) + while (1); +#pragma acc parallel reduction(+:IPtr[1]) + while (1); +#pragma acc parallel reduction(+:IPtr[1:1]) + while (1); + + int *IPtrArr[5]; + // expected-error@+3{{invalid type 'int *' used in OpenACC 'reduction' variable reference; type is not a scalar value, or array of scalars, or composite of scalars}} + // expected-note@+2{{used as element type of array type 'int *'}} + // expected-note@+1{{OpenACC 'reduction' variable reference must be a scalar variable or a composite of scalars, or an array, sub-array, or element of scalar types}} +#pragma acc parallel reduction(+:IPtrArr) + while (1); + + struct HasPtr { int *I; }; // #HASPTR + HasPtr HP; + // expected-error@+3{{invalid type 'int *' used in OpenACC 'reduction' variable reference; type is not a scalar value}} + // expected-note@#HASPTR{{used as field 'I' of composite 'HasPtr'}} + // expected-note@+1{{OpenACC 'reduction' variable reference must be a scalar variable or a composite of scalars, or an array, sub-array, or element of scalar types}} +#pragma acc parallel reduction(+:HP) + while (1); + + HasPtr HPArr[5]; + // expected-error@+4{{invalid type 'int *' used in OpenACC 'reduction' variable reference; type is not a scalar value}} + // expected-note@+3{{used as element type of array type 'HasPtr'}} + // expected-note@#HASPTR{{used as field 'I' of composite 'HasPtr'}} + // expected-note@+1{{OpenACC 'reduction' variable reference must be a scalar variable or a composite of scalars, or an array, sub-array, or element of scalar types}} +#pragma acc parallel reduction(+:HPArr) + while (1); } template<typename T, typename U, typename V> diff --git a/flang-rt/include/flang-rt/runtime/io-stmt.h b/flang-rt/include/flang-rt/runtime/io-stmt.h index adc8b742f837..b98422b8707f 100644 --- a/flang-rt/include/flang-rt/runtime/io-stmt.h +++ b/flang-rt/include/flang-rt/runtime/io-stmt.h @@ -395,7 +395,7 @@ public: RT_API_ATTRS void BadInquiryKeywordHashCrash(InquiryKeywordHash); - RT_API_ATTRS void ReportUnsupportedChildIo() const { + RT_API_ATTRS [[noreturn]] void ReportUnsupportedChildIo() const { Crash("not yet implemented: child IO"); } diff --git a/flang/lib/Parser/preprocessor.cpp b/flang/lib/Parser/preprocessor.cpp index ae14e2d46020..9176b4db3408 100644 --- a/flang/lib/Parser/preprocessor.cpp +++ b/flang/lib/Parser/preprocessor.cpp @@ -414,7 +414,7 @@ std::optional<TokenSequence> Preprocessor::MacroReplacement( const TokenSequence &input, Prescanner &prescanner, std::optional<std::size_t> *partialFunctionLikeMacro, bool inIfExpression) { // Do quick scan for any use of a defined name. - if (definitions_.empty()) { + if (!inIfExpression && definitions_.empty()) { return std::nullopt; } std::size_t tokens{input.SizeInTokens()}; diff --git a/flang/test/Preprocessing/no-pp-if.f90 b/flang/test/Preprocessing/no-pp-if.f90 new file mode 100644 index 000000000000..3e49df3deb25 --- /dev/null +++ b/flang/test/Preprocessing/no-pp-if.f90 @@ -0,0 +1,10 @@ +!RUN: %flang -fc1 -fdebug-unparse %s 2>&1 | FileCheck %s +!CHECK-NOT: ERROR STOP +!CHECK: CONTINUE +#if defined UNDEFINED +error stop +#endif +#if !defined UNDEFINED +continue +#endif +end diff --git a/llvm/include/llvm/Analysis/IR2Vec.h b/llvm/include/llvm/Analysis/IR2Vec.h index 15221c7f0791..caa816e2fd76 100644 --- a/llvm/include/llvm/Analysis/IR2Vec.h +++ b/llvm/include/llvm/Analysis/IR2Vec.h @@ -63,6 +63,7 @@ enum class IR2VecKind { Symbolic, FlowAware }; namespace ir2vec { +extern llvm::cl::OptionCategory IR2VecCategory; LLVM_ABI extern cl::opt<float> OpcWeight; LLVM_ABI extern cl::opt<float> TypeWeight; LLVM_ABI extern cl::opt<float> ArgWeight; diff --git a/llvm/include/llvm/Debuginfod/Debuginfod.h b/llvm/include/llvm/Debuginfod/Debuginfod.h index 99fe15ad8597..67121d08d256 100644 --- a/llvm/include/llvm/Debuginfod/Debuginfod.h +++ b/llvm/include/llvm/Debuginfod/Debuginfod.h @@ -152,11 +152,16 @@ public: Expected<std::string> findBinaryPath(object::BuildIDRef); }; -struct DebuginfodServer { +class DebuginfodServer { +public: HTTPServer Server; - DebuginfodLog &Log; - DebuginfodCollection &Collection; DebuginfodServer(DebuginfodLog &Log, DebuginfodCollection &Collection); + static Expected<DebuginfodServer> create(DebuginfodLog &Log, + DebuginfodCollection &Collection); + +private: + DebuginfodServer() = default; + Error init(DebuginfodLog &Log, DebuginfodCollection &Collection); }; } // end namespace llvm diff --git a/llvm/include/llvm/MC/DXContainerRootSignature.h b/llvm/include/llvm/MC/DXContainerRootSignature.h index 3cb631b0a887..14fcdfd76435 100644 --- a/llvm/include/llvm/MC/DXContainerRootSignature.h +++ b/llvm/include/llvm/MC/DXContainerRootSignature.h @@ -19,6 +19,18 @@ namespace llvm { class raw_ostream; namespace mcdxbc { +struct RootConstants { + uint32_t ShaderRegister; + uint32_t RegisterSpace; + uint32_t Num32BitValues; +}; + +struct RootDescriptor { + uint32_t ShaderRegister; + uint32_t RegisterSpace; + uint32_t Flags; +}; + struct RootParameterInfo { dxbc::RootParameterType Type; dxbc::ShaderVisibility Visibility; @@ -42,8 +54,8 @@ struct DescriptorTable { struct RootParametersContainer { SmallVector<RootParameterInfo> ParametersInfo; - SmallVector<dxbc::RTS0::v1::RootConstants> Constants; - SmallVector<dxbc::RTS0::v2::RootDescriptor> Descriptors; + SmallVector<RootConstants> Constants; + SmallVector<RootDescriptor> Descriptors; SmallVector<DescriptorTable> Tables; void addInfo(dxbc::RootParameterType Type, dxbc::ShaderVisibility Visibility, @@ -52,15 +64,14 @@ struct RootParametersContainer { } void addParameter(dxbc::RootParameterType Type, - dxbc::ShaderVisibility Visibility, - dxbc::RTS0::v1::RootConstants Constant) { + dxbc::ShaderVisibility Visibility, RootConstants Constant) { addInfo(Type, Visibility, Constants.size()); Constants.push_back(Constant); } void addParameter(dxbc::RootParameterType Type, dxbc::ShaderVisibility Visibility, - dxbc::RTS0::v2::RootDescriptor Descriptor) { + RootDescriptor Descriptor) { addInfo(Type, Visibility, Descriptors.size()); Descriptors.push_back(Descriptor); } @@ -76,11 +87,11 @@ struct RootParametersContainer { return Info; } - const dxbc::RTS0::v1::RootConstants &getConstant(size_t Index) const { + const RootConstants &getConstant(size_t Index) const { return Constants[Index]; } - const dxbc::RTS0::v2::RootDescriptor &getRootDescriptor(size_t Index) const { + const RootDescriptor &getRootDescriptor(size_t Index) const { return Descriptors[Index]; } diff --git a/llvm/lib/Analysis/DevelopmentModeInlineAdvisor.cpp b/llvm/lib/Analysis/DevelopmentModeInlineAdvisor.cpp index 790e00e1b3b0..ce2d8b654bf2 100644 --- a/llvm/lib/Analysis/DevelopmentModeInlineAdvisor.cpp +++ b/llvm/lib/Analysis/DevelopmentModeInlineAdvisor.cpp @@ -260,7 +260,7 @@ static const std::vector<TensorSpec> TrainingOnlyFeatures{ static const std::vector<TensorSpec> getInputFeatures() { std::vector<TensorSpec> InputSpecs; - for (const auto &Feature : FeatureMap) + for (const auto &Feature : getFeatureMap()) InputSpecs.push_back(TensorSpec(TFFeedPrefix + Feature.name(), Feature)); append_range(InputSpecs, TrainingOnlyFeatures); return InputSpecs; @@ -272,7 +272,7 @@ TrainingLogger::TrainingLogger(StringRef LogFileName, const ModelUnderTrainingRunner *MUTR) : LogFileName(LogFileName), MUTR(MUTR) { // The first output is the inlining decision. - std::vector<TensorSpec> FT(FeatureMap.begin(), FeatureMap.end()); + std::vector<TensorSpec> FT(getFeatureMap().begin(), getFeatureMap().end()); if (MUTR) append_range(FT, MUTR->extraOutputsForLoggingSpecs()); @@ -298,7 +298,7 @@ void TrainingLogger::logInlineEvent(const InlineEvent &Event, const MLModelRunner &ModelRunner) { L->startObservation(); size_t CurrentFeature = 0; - size_t FeatureMapSize = FeatureMap.size(); + size_t FeatureMapSize = getFeatureMap().size(); for (; CurrentFeature < FeatureMapSize; ++CurrentFeature) L->logTensorValue(CurrentFeature, reinterpret_cast<const char *>( diff --git a/llvm/lib/Analysis/IR2Vec.cpp b/llvm/lib/Analysis/IR2Vec.cpp index af6242d72e1c..eb54f90a7548 100644 --- a/llvm/lib/Analysis/IR2Vec.cpp +++ b/llvm/lib/Analysis/IR2Vec.cpp @@ -36,7 +36,7 @@ STATISTIC(VocabMissCounter, namespace llvm { namespace ir2vec { -static cl::OptionCategory IR2VecCategory("IR2Vec Options"); +cl::OptionCategory IR2VecCategory("IR2Vec Options"); // FIXME: Use a default vocab when not specified static cl::opt<std::string> diff --git a/llvm/lib/Debuginfod/Debuginfod.cpp b/llvm/lib/Debuginfod/Debuginfod.cpp index 12f817c9e4bf..77a8011ca82a 100644 --- a/llvm/lib/Debuginfod/Debuginfod.cpp +++ b/llvm/lib/Debuginfod/Debuginfod.cpp @@ -567,10 +567,10 @@ Expected<std::string> DebuginfodCollection::findDebugBinaryPath(BuildIDRef ID) { return getCachedOrDownloadDebuginfo(ID); } -DebuginfodServer::DebuginfodServer(DebuginfodLog &Log, - DebuginfodCollection &Collection) - : Log(Log), Collection(Collection) { - cantFail( +Error DebuginfodServer::init(DebuginfodLog &Log, + DebuginfodCollection &Collection) { + + Error Err = Server.get(R"(/buildid/(.*)/debuginfo)", [&](HTTPServerRequest Request) { Log.push("GET " + Request.UrlPath); std::string IDString; @@ -587,8 +587,11 @@ DebuginfodServer::DebuginfodServer(DebuginfodLog &Log, return; } streamFile(Request, *PathOrErr); - })); - cantFail( + }); + if (Err) + return Err; + + Err = Server.get(R"(/buildid/(.*)/executable)", [&](HTTPServerRequest Request) { Log.push("GET " + Request.UrlPath); std::string IDString; @@ -605,7 +608,18 @@ DebuginfodServer::DebuginfodServer(DebuginfodLog &Log, return; } streamFile(Request, *PathOrErr); - })); + }); + if (Err) + return Err; + return Error::success(); +} + +Expected<DebuginfodServer> +DebuginfodServer::create(DebuginfodLog &Log, DebuginfodCollection &Collection) { + DebuginfodServer Serverd; + if (llvm::Error Err = Serverd.init(Log, Collection)) + return std::move(Err); + return std::move(Serverd); } } // namespace llvm diff --git a/llvm/lib/Frontend/HLSL/RootSignatureMetadata.cpp b/llvm/lib/Frontend/HLSL/RootSignatureMetadata.cpp index 70f2646d66c5..a5a92cbd2d61 100644 --- a/llvm/lib/Frontend/HLSL/RootSignatureMetadata.cpp +++ b/llvm/lib/Frontend/HLSL/RootSignatureMetadata.cpp @@ -237,7 +237,7 @@ Error MetadataParser::parseRootConstants(mcdxbc::RootSignatureDesc &RSD, if (auto E = Visibility.takeError()) return Error(std::move(E)); - dxbc::RTS0::v1::RootConstants Constants; + mcdxbc::RootConstants Constants; if (std::optional<uint32_t> Val = extractMdIntValue(RootConstantNode, 2)) Constants.ShaderRegister = *Val; else @@ -291,7 +291,7 @@ Error MetadataParser::parseRootDescriptors( if (auto E = Visibility.takeError()) return Error(std::move(E)); - dxbc::RTS0::v2::RootDescriptor Descriptor; + mcdxbc::RootDescriptor Descriptor; if (std::optional<uint32_t> Val = extractMdIntValue(RootDescriptorNode, 2)) Descriptor.ShaderRegister = *Val; else @@ -541,7 +541,7 @@ Error MetadataParser::validateRootSignature( case dxbc::RootParameterType::CBV: case dxbc::RootParameterType::UAV: case dxbc::RootParameterType::SRV: { - const dxbc::RTS0::v2::RootDescriptor &Descriptor = + const mcdxbc::RootDescriptor &Descriptor = RSD.ParametersContainer.getRootDescriptor(Info.Location); if (!hlsl::rootsig::verifyRegisterValue(Descriptor.ShaderRegister)) DeferredErrs = diff --git a/llvm/lib/MC/DXContainerRootSignature.cpp b/llvm/lib/MC/DXContainerRootSignature.cpp index 4d5322b5b3cb..ce7d5c91bc7c 100644 --- a/llvm/lib/MC/DXContainerRootSignature.cpp +++ b/llvm/lib/MC/DXContainerRootSignature.cpp @@ -106,7 +106,7 @@ void RootSignatureDesc::write(raw_ostream &OS) const { const RootParameterInfo &Info = ParametersContainer.getInfo(I); switch (Info.Type) { case dxbc::RootParameterType::Constants32Bit: { - const dxbc::RTS0::v1::RootConstants &Constants = + const mcdxbc::RootConstants &Constants = ParametersContainer.getConstant(Info.Location); support::endian::write(BOS, Constants.ShaderRegister, llvm::endianness::little); @@ -119,7 +119,7 @@ void RootSignatureDesc::write(raw_ostream &OS) const { case dxbc::RootParameterType::CBV: case dxbc::RootParameterType::SRV: case dxbc::RootParameterType::UAV: { - const dxbc::RTS0::v2::RootDescriptor &Descriptor = + const mcdxbc::RootDescriptor &Descriptor = ParametersContainer.getRootDescriptor(Info.Location); support::endian::write(BOS, Descriptor.ShaderRegister, diff --git a/llvm/lib/ObjectYAML/DXContainerEmitter.cpp b/llvm/lib/ObjectYAML/DXContainerEmitter.cpp index 283749ec1297..fa3abd274480 100644 --- a/llvm/lib/ObjectYAML/DXContainerEmitter.cpp +++ b/llvm/lib/ObjectYAML/DXContainerEmitter.cpp @@ -286,7 +286,7 @@ Error DXContainerWriter::writeParts(raw_ostream &OS) { case dxbc::RootParameterType::Constants32Bit: { const DXContainerYAML::RootConstantsYaml &ConstantYaml = P.RootSignature->Parameters.getOrInsertConstants(L); - dxbc::RTS0::v1::RootConstants Constants; + mcdxbc::RootConstants Constants; Constants.Num32BitValues = ConstantYaml.Num32BitValues; Constants.RegisterSpace = ConstantYaml.RegisterSpace; @@ -300,7 +300,7 @@ Error DXContainerWriter::writeParts(raw_ostream &OS) { const DXContainerYAML::RootDescriptorYaml &DescriptorYaml = P.RootSignature->Parameters.getOrInsertDescriptor(L); - dxbc::RTS0::v2::RootDescriptor Descriptor; + mcdxbc::RootDescriptor Descriptor; Descriptor.RegisterSpace = DescriptorYaml.RegisterSpace; Descriptor.ShaderRegister = DescriptorYaml.ShaderRegister; if (RS.Version > 1) diff --git a/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp b/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp index e2bc9be191fb..a139167685ec 100644 --- a/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp +++ b/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp @@ -182,7 +182,7 @@ static void validateRootSignature(Module &M, dxbc::RootParameterType ParamType = dxbc::RootParameterType(ParamInfo.Type); switch (ParamType) { case dxbc::RootParameterType::Constants32Bit: { - dxbc::RTS0::v1::RootConstants Const = + mcdxbc::RootConstants Const = RSD.ParametersContainer.getConstant(ParamInfo.Location); Builder.trackBinding(dxil::ResourceClass::CBuffer, Const.RegisterSpace, Const.ShaderRegister, Const.ShaderRegister, @@ -193,7 +193,7 @@ static void validateRootSignature(Module &M, case dxbc::RootParameterType::SRV: case dxbc::RootParameterType::UAV: case dxbc::RootParameterType::CBV: { - dxbc::RTS0::v2::RootDescriptor Desc = + mcdxbc::RootDescriptor Desc = RSD.ParametersContainer.getRootDescriptor(ParamInfo.Location); Builder.trackBinding(toResourceClass(ParamInfo.Type), Desc.RegisterSpace, Desc.ShaderRegister, Desc.ShaderRegister, diff --git a/llvm/lib/Target/DirectX/DXILRootSignature.cpp b/llvm/lib/Target/DirectX/DXILRootSignature.cpp index 62037a8272e7..2436d3869464 100644 --- a/llvm/lib/Target/DirectX/DXILRootSignature.cpp +++ b/llvm/lib/Target/DirectX/DXILRootSignature.cpp @@ -182,7 +182,7 @@ PreservedAnalyses RootSignatureAnalysisPrinter::run(Module &M, << "\n"; switch (Info.Type) { case dxbc::RootParameterType::Constants32Bit: { - const dxbc::RTS0::v1::RootConstants &Constants = + const mcdxbc::RootConstants &Constants = RS.ParametersContainer.getConstant(Info.Location); OS << " Register Space: " << Constants.RegisterSpace << "\n" << " Shader Register: " << Constants.ShaderRegister << "\n" @@ -192,7 +192,7 @@ PreservedAnalyses RootSignatureAnalysisPrinter::run(Module &M, case dxbc::RootParameterType::CBV: case dxbc::RootParameterType::UAV: case dxbc::RootParameterType::SRV: { - const dxbc::RTS0::v2::RootDescriptor &Descriptor = + const mcdxbc::RootDescriptor &Descriptor = RS.ParametersContainer.getRootDescriptor(Info.Location); OS << " Register Space: " << Descriptor.RegisterSpace << "\n" << " Shader Register: " << Descriptor.ShaderRegister << "\n"; diff --git a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp index 1b1797ab30a3..fc0f3d5b6c2a 100644 --- a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp +++ b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp @@ -8717,7 +8717,7 @@ VPlanPtr LoopVectorizationPlanner::tryToBuildVPlanWithVPRecipes( // to remove the need to keep a map of masks beyond the predication // transform. RecipeBuilder.updateBlockMaskCache(Old2New); - for (const auto &[Old, _] : Old2New) + for (VPValue *Old : Old2New.keys()) Old->getDefiningRecipe()->eraseFromParent(); assert(isa<VPRegionBlock>(Plan->getVectorLoopRegion()) && @@ -10206,111 +10206,93 @@ bool LoopVectorizePass::processLoop(Loop *L) { bool DisableRuntimeUnroll = false; MDNode *OrigLoopID = L->getLoopID(); - { - using namespace ore; - if (!VectorizeLoop) { - assert(IC > 1 && "interleave count should not be 1 or 0"); - // If we decided that it is not legal to vectorize the loop, then - // interleave it. - VPlan &BestPlan = LVP.getPlanFor(VF.Width); - InnerLoopVectorizer Unroller(L, PSE, LI, DT, TTI, AC, - ElementCount::getFixed(1), IC, &CM, BFI, PSI, - Checks, BestPlan); - - // TODO: Move to general VPlan pipeline once epilogue loops are also - // supported. - VPlanTransforms::runPass( - VPlanTransforms::materializeConstantVectorTripCount, BestPlan, - VF.Width, IC, PSE); - LVP.addMinimumIterationCheck(BestPlan, VF.Width, IC, - VF.MinProfitableTripCount); - LVP.executePlan(VF.Width, IC, BestPlan, Unroller, DT, false); + // If we decided that it is *legal* to interleave or vectorize the loop, then + // do it. - ORE->emit([&]() { - return OptimizationRemark(LV_NAME, "Interleaved", L->getStartLoc(), - L->getHeader()) - << "interleaved loop (interleaved count: " - << NV("InterleaveCount", IC) << ")"; - }); - } else { - // If we decided that it is *legal* to vectorize the loop, then do it. - - VPlan &BestPlan = LVP.getPlanFor(VF.Width); - // Consider vectorizing the epilogue too if it's profitable. - VectorizationFactor EpilogueVF = - LVP.selectEpilogueVectorizationFactor(VF.Width, IC); - if (EpilogueVF.Width.isVector()) { - std::unique_ptr<VPlan> BestMainPlan(BestPlan.duplicate()); - - // The first pass vectorizes the main loop and creates a scalar epilogue - // to be vectorized by executing the plan (potentially with a different - // factor) again shortly afterwards. - VPlan &BestEpiPlan = LVP.getPlanFor(EpilogueVF.Width); - BestEpiPlan.getMiddleBlock()->setName("vec.epilog.middle.block"); - preparePlanForMainVectorLoop(*BestMainPlan, BestEpiPlan); - EpilogueLoopVectorizationInfo EPI(VF.Width, IC, EpilogueVF.Width, 1, - BestEpiPlan); - EpilogueVectorizerMainLoop MainILV(L, PSE, LI, DT, TTI, AC, EPI, &CM, - BFI, PSI, Checks, *BestMainPlan); - auto ExpandedSCEVs = LVP.executePlan(EPI.MainLoopVF, EPI.MainLoopUF, - *BestMainPlan, MainILV, DT, false); - ++LoopsVectorized; - - // Second pass vectorizes the epilogue and adjusts the control flow - // edges from the first pass. - EpilogueVectorizerEpilogueLoop EpilogILV( - L, PSE, LI, DT, TTI, AC, EPI, &CM, BFI, PSI, Checks, BestEpiPlan); - EpilogILV.setTripCount(MainILV.getTripCount()); - preparePlanForEpilogueVectorLoop(BestEpiPlan, L, ExpandedSCEVs, EPI); - - LVP.executePlan(EPI.EpilogueVF, EPI.EpilogueUF, BestEpiPlan, EpilogILV, - DT, true); - - // Fix induction resume values from the additional bypass block. - BasicBlock *BypassBlock = EpilogILV.getAdditionalBypassBlock(); - IRBuilder<> BypassBuilder(BypassBlock, - BypassBlock->getFirstInsertionPt()); - BasicBlock *PH = L->getLoopPreheader(); - for (const auto &[IVPhi, II] : LVL.getInductionVars()) { - auto *Inc = cast<PHINode>(IVPhi->getIncomingValueForBlock(PH)); - Value *V = createInductionAdditionalBypassValues( - IVPhi, II, BypassBuilder, ExpandedSCEVs, EPI.VectorTripCount, - LVL.getPrimaryInduction()); - // TODO: Directly add as extra operand to the VPResumePHI recipe. - Inc->setIncomingValueForBlock(BypassBlock, V); - } - ++LoopsEpilogueVectorized; + VPlan &BestPlan = LVP.getPlanFor(VF.Width); + // Consider vectorizing the epilogue too if it's profitable. + VectorizationFactor EpilogueVF = + LVP.selectEpilogueVectorizationFactor(VF.Width, IC); + if (EpilogueVF.Width.isVector()) { + std::unique_ptr<VPlan> BestMainPlan(BestPlan.duplicate()); + + // The first pass vectorizes the main loop and creates a scalar epilogue + // to be vectorized by executing the plan (potentially with a different + // factor) again shortly afterwards. + VPlan &BestEpiPlan = LVP.getPlanFor(EpilogueVF.Width); + BestEpiPlan.getMiddleBlock()->setName("vec.epilog.middle.block"); + preparePlanForMainVectorLoop(*BestMainPlan, BestEpiPlan); + EpilogueLoopVectorizationInfo EPI(VF.Width, IC, EpilogueVF.Width, 1, + BestEpiPlan); + EpilogueVectorizerMainLoop MainILV(L, PSE, LI, DT, TTI, AC, EPI, &CM, BFI, + PSI, Checks, *BestMainPlan); + auto ExpandedSCEVs = LVP.executePlan(EPI.MainLoopVF, EPI.MainLoopUF, + *BestMainPlan, MainILV, DT, false); + ++LoopsVectorized; + + // Second pass vectorizes the epilogue and adjusts the control flow + // edges from the first pass. + EpilogueVectorizerEpilogueLoop EpilogILV(L, PSE, LI, DT, TTI, AC, EPI, &CM, + BFI, PSI, Checks, BestEpiPlan); + EpilogILV.setTripCount(MainILV.getTripCount()); + preparePlanForEpilogueVectorLoop(BestEpiPlan, L, ExpandedSCEVs, EPI); + + LVP.executePlan(EPI.EpilogueVF, EPI.EpilogueUF, BestEpiPlan, EpilogILV, DT, + true); + + // Fix induction resume values from the additional bypass block. + BasicBlock *BypassBlock = EpilogILV.getAdditionalBypassBlock(); + IRBuilder<> BypassBuilder(BypassBlock, BypassBlock->getFirstInsertionPt()); + BasicBlock *PH = L->getLoopPreheader(); + for (const auto &[IVPhi, II] : LVL.getInductionVars()) { + auto *Inc = cast<PHINode>(IVPhi->getIncomingValueForBlock(PH)); + Value *V = createInductionAdditionalBypassValues( + IVPhi, II, BypassBuilder, ExpandedSCEVs, EPI.VectorTripCount, + LVL.getPrimaryInduction()); + // TODO: Directly add as extra operand to the VPResumePHI recipe. + Inc->setIncomingValueForBlock(BypassBlock, V); + } + ++LoopsEpilogueVectorized; + + if (!Checks.hasChecks()) + DisableRuntimeUnroll = true; + } else { + InnerLoopVectorizer LB(L, PSE, LI, DT, TTI, AC, VF.Width, IC, &CM, BFI, PSI, + Checks, BestPlan); + // TODO: Move to general VPlan pipeline once epilogue loops are also + // supported. + VPlanTransforms::runPass( + VPlanTransforms::materializeConstantVectorTripCount, BestPlan, VF.Width, + IC, PSE); + LVP.addMinimumIterationCheck(BestPlan, VF.Width, IC, + VF.MinProfitableTripCount); - if (!Checks.hasChecks()) - DisableRuntimeUnroll = true; - } else { - InnerLoopVectorizer LB(L, PSE, LI, DT, TTI, AC, VF.Width, IC, &CM, BFI, - PSI, Checks, BestPlan); - // TODO: Move to general VPlan pipeline once epilogue loops are also - // supported. - VPlanTransforms::runPass( - VPlanTransforms::materializeConstantVectorTripCount, BestPlan, - VF.Width, IC, PSE); - LVP.addMinimumIterationCheck(BestPlan, VF.Width, IC, - VF.MinProfitableTripCount); - - LVP.executePlan(VF.Width, IC, BestPlan, LB, DT, false); - ++LoopsVectorized; - - // Add metadata to disable runtime unrolling a scalar loop when there - // are no runtime checks about strides and memory. A scalar loop that is - // rarely used is not worth unrolling. - if (!Checks.hasChecks()) - DisableRuntimeUnroll = true; - } - // Report the vectorization decision. - reportVectorization(ORE, L, VF, IC); - } + LVP.executePlan(VF.Width, IC, BestPlan, LB, DT, false); + ++LoopsVectorized; - if (ORE->allowExtraAnalysis(LV_NAME)) - checkMixedPrecision(L, ORE); + // Add metadata to disable runtime unrolling a scalar loop when there + // are no runtime checks about strides and memory. A scalar loop that is + // rarely used is not worth unrolling. + if (!Checks.hasChecks() && !VF.Width.isScalar()) + DisableRuntimeUnroll = true; + } + if (VF.Width.isScalar()) { + using namespace ore; + assert(IC > 1); + ORE->emit([&]() { + return OptimizationRemark(LV_NAME, "Interleaved", L->getStartLoc(), + L->getHeader()) + << "interleaved loop (interleaved count: " + << NV("InterleaveCount", IC) << ")"; + }); + } else { + // Report the vectorization decision. + reportVectorization(ORE, L, VF, IC); } + if (ORE->allowExtraAnalysis(LV_NAME)) + checkMixedPrecision(L, ORE); + assert(DT->verify(DominatorTree::VerificationLevel::Fast) && "DT not preserved correctly"); diff --git a/llvm/tools/llvm-debuginfod/llvm-debuginfod.cpp b/llvm/tools/llvm-debuginfod/llvm-debuginfod.cpp index 7b85166c1b4a..901bf489ea9f 100644 --- a/llvm/tools/llvm-debuginfod/llvm-debuginfod.cpp +++ b/llvm/tools/llvm-debuginfod/llvm-debuginfod.cpp @@ -131,8 +131,8 @@ int llvm_debuginfod_main(int argc, char **argv, const llvm::ToolContext &) { DefaultThreadPool Pool(hardware_concurrency(MaxConcurrency)); DebuginfodLog Log; DebuginfodCollection Collection(Paths, Log, Pool, MinInterval); - DebuginfodServer Server(Log, Collection); - + DebuginfodServer Server = + ExitOnErr(DebuginfodServer::create(Log, Collection)); if (!Port) Port = ExitOnErr(Server.Server.bind(HostInterface.c_str())); else diff --git a/llvm/tools/llvm-ir2vec/llvm-ir2vec.cpp b/llvm/tools/llvm-ir2vec/llvm-ir2vec.cpp index 8f8b4e2f2bda..c065aaeedd39 100644 --- a/llvm/tools/llvm-ir2vec/llvm-ir2vec.cpp +++ b/llvm/tools/llvm-ir2vec/llvm-ir2vec.cpp @@ -55,8 +55,6 @@ namespace llvm { namespace ir2vec { -static cl::OptionCategory IR2VecToolCategory("IR2Vec Tool Options"); - // Subcommands static cl::SubCommand TripletsSubCmd("triplets", "Generate triplets for vocabulary training"); @@ -72,18 +70,18 @@ static cl::opt<std::string> InputFilename(cl::Positional, cl::desc("<input bitcode file or '-' for stdin>"), cl::init("-"), cl::sub(TripletsSubCmd), - cl::sub(EmbeddingsSubCmd), cl::cat(IR2VecToolCategory)); + cl::sub(EmbeddingsSubCmd), cl::cat(ir2vec::IR2VecCategory)); static cl::opt<std::string> OutputFilename("o", cl::desc("Output filename"), cl::value_desc("filename"), cl::init("-"), - cl::cat(IR2VecToolCategory)); + cl::cat(ir2vec::IR2VecCategory)); // Embedding-specific options static cl::opt<std::string> FunctionName("function", cl::desc("Process specific function only"), cl::value_desc("name"), cl::Optional, cl::init(""), - cl::sub(EmbeddingsSubCmd), cl::cat(IR2VecToolCategory)); + cl::sub(EmbeddingsSubCmd), cl::cat(ir2vec::IR2VecCategory)); enum EmbeddingLevel { InstructionLevel, // Generate instruction-level embeddings @@ -100,7 +98,7 @@ static cl::opt<EmbeddingLevel> clEnumValN(FunctionLevel, "func", "Generate function-level embeddings")), cl::init(FunctionLevel), cl::sub(EmbeddingsSubCmd), - cl::cat(IR2VecToolCategory)); + cl::cat(ir2vec::IR2VecCategory)); namespace { @@ -325,7 +323,7 @@ int main(int argc, char **argv) { using namespace llvm::ir2vec; InitLLVM X(argc, argv); - cl::HideUnrelatedOptions(IR2VecToolCategory); + cl::HideUnrelatedOptions(ir2vec::IR2VecCategory); cl::ParseCommandLineOptions( argc, argv, "IR2Vec - Embedding Generation Tool\n" diff --git a/llvm/utils/TableGen/DecoderEmitter.cpp b/llvm/utils/TableGen/DecoderEmitter.cpp index 6eab90f50179..f1db0368d098 100644 --- a/llvm/utils/TableGen/DecoderEmitter.cpp +++ b/llvm/utils/TableGen/DecoderEmitter.cpp @@ -157,6 +157,9 @@ class InstructionEncoding { /// The name of this encoding (for debugging purposes). std::string Name; + /// The namespace in which this encoding exists. + StringRef DecoderNamespace; + /// Known bits of this encoding. This is the value of the `Inst` field /// with any variable references replaced with '?'. KnownBits InstBits; @@ -190,6 +193,9 @@ public: /// Returns the name of this encoding, for debugging purposes. StringRef getName() const { return Name; } + /// Returns the namespace in which this encoding exists. + StringRef getDecoderNamespace() const { return DecoderNamespace; } + /// Returns the size of this encoding, in bits. unsigned getBitWidth() const { return InstBits.getBitWidth(); } @@ -2054,6 +2060,7 @@ InstructionEncoding::InstructionEncoding(const Record *EncodingDef, Name = (EncodingDef->getName() + Twine(':')).str(); Name.append(InstDef->getName()); + DecoderNamespace = EncodingDef->getValueAsString("DecoderNamespace"); DecoderMethod = EncodingDef->getValueAsString("DecoderMethod"); if (!DecoderMethod.empty()) HasCompleteDecoder = EncodingDef->getValueAsBit("hasCompleteDecoder"); @@ -2339,8 +2346,7 @@ void DecoderEmitter::handleHwModesUnrelatedEncodings( break; } case SUPPRESSION_LEVEL1: { - const Record *InstDef = Encodings[EncodingID].getInstruction()->TheDef; - StringRef DecoderNamespace = InstDef->getValueAsString("DecoderNamespace"); + StringRef DecoderNamespace = Encodings[EncodingID].getDecoderNamespace(); auto It = NamespacesWithHwModes.find(DecoderNamespace); if (It != NamespacesWithHwModes.end()) { for (unsigned HwModeID : It->second) @@ -2513,8 +2519,7 @@ namespace { const InstructionEncoding &Encoding = Encodings[EncodingID]; const Record *EncodingDef = Encoding.getRecord(); unsigned Size = EncodingDef->getValueAsInt("Size"); - StringRef DecoderNamespace = - EncodingDef->getValueAsString("DecoderNamespace"); + StringRef DecoderNamespace = Encoding.getDecoderNamespace(); EncMap[{DecoderNamespace, HwModeID, Size}].push_back(EncodingID); } } |
