summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAiden Grossman <aidengrossman@google.com>2025-08-29 19:51:31 +0000
committerAiden Grossman <aidengrossman@google.com>2025-08-29 19:51:31 +0000
commitf1c66003a3be0e5296de0aaaab1cb1b804e8cbe7 (patch)
tree4b5fbe67499bfe3fa1568c336aad08082f2480be
parent328a8372b5362b8de7bc2c33fb75c7e046a00673 (diff)
parent80c21797901b9c5a787774fdb94046ea285c1b83 (diff)
[𝘀𝗽𝗿] changes introduced through rebaseusers/boomanaiden154/main.bolt-enable-lit-internal-shell-by-default
Created using spr 1.3.6 [skip ci]
-rw-r--r--.ci/compute_projects.py9
-rw-r--r--.ci/compute_projects_test.py16
-rw-r--r--clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h20
-rw-r--r--clang/include/clang/CIR/Dialect/IR/CIROps.td59
-rw-r--r--clang/include/clang/CIR/MissingFeatures.h1
-rw-r--r--clang/lib/CIR/CodeGen/CIRGenCXXABI.h4
-rw-r--r--clang/lib/CIR/CodeGen/CIRGenException.cpp41
-rw-r--r--clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp12
-rw-r--r--clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp5
-rw-r--r--clang/lib/CIR/CodeGen/CIRGenFunction.h2
-rw-r--r--clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp40
-rw-r--r--clang/lib/CIR/CodeGen/CMakeLists.txt1
-rw-r--r--clang/lib/CIR/Dialect/IR/CIRDialect.cpp18
-rw-r--r--clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp45
-rw-r--r--clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.h10
-rw-r--r--clang/lib/Sema/SemaOpenACCClause.cpp3
-rw-r--r--clang/test/AST/ast-print-openacc-combined-construct.cpp9
-rw-r--r--clang/test/AST/ast-print-openacc-compute-construct.cpp9
-rw-r--r--clang/test/AST/ast-print-openacc-loop-construct.cpp10
-rw-r--r--clang/test/CIR/CodeGen/complex-unary.cpp135
-rw-r--r--clang/test/CIR/CodeGen/throws.cpp85
-rw-r--r--clang/test/CIR/IR/invalid-throw.cir16
-rw-r--r--clang/test/CIR/IR/throw.cir63
-rw-r--r--clang/test/ParserOpenACC/parse-clauses.c2
-rw-r--r--clang/test/SemaOpenACC/compute-construct-reduction-clause.cpp33
-rw-r--r--flang-rt/include/flang-rt/runtime/io-stmt.h2
-rw-r--r--flang/lib/Parser/preprocessor.cpp2
-rw-r--r--flang/test/Preprocessing/no-pp-if.f9010
-rw-r--r--llvm/include/llvm/Analysis/IR2Vec.h1
-rw-r--r--llvm/include/llvm/Debuginfod/Debuginfod.h11
-rw-r--r--llvm/include/llvm/MC/DXContainerRootSignature.h25
-rw-r--r--llvm/lib/Analysis/DevelopmentModeInlineAdvisor.cpp6
-rw-r--r--llvm/lib/Analysis/IR2Vec.cpp2
-rw-r--r--llvm/lib/Debuginfod/Debuginfod.cpp28
-rw-r--r--llvm/lib/Frontend/HLSL/RootSignatureMetadata.cpp6
-rw-r--r--llvm/lib/MC/DXContainerRootSignature.cpp4
-rw-r--r--llvm/lib/ObjectYAML/DXContainerEmitter.cpp4
-rw-r--r--llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp4
-rw-r--r--llvm/lib/Target/DirectX/DXILRootSignature.cpp4
-rw-r--r--llvm/lib/Transforms/Vectorize/LoopVectorize.cpp184
-rw-r--r--llvm/tools/llvm-debuginfod/llvm-debuginfod.cpp4
-rw-r--r--llvm/tools/llvm-ir2vec/llvm-ir2vec.cpp12
-rw-r--r--llvm/utils/TableGen/DecoderEmitter.cpp13
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);
}
}