[llvm-branch-commits] [clang] release/21.x: [clang] Fix catching pointers by reference on mingw targets (#162546) (PR #163714)
llvmbot wrote: @efriedma-quic What do you think about merging this PR to the release branch? https://github.com/llvm/llvm-project/pull/163714 ___ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [Hexagon] Support lowering of setuo & seto for vector types in Hexago… (PR #163212)
github-actions[bot] wrote: @fhossein-quic (or anyone else). If you would like to add a note about this fix in the release notes (completely optional). Please reply to this comment with a one or two sentence description of the fix. When you are done, please add the release:note label to this PR. https://github.com/llvm/llvm-project/pull/163212 ___ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [BOLT] Extend Inliner to work on functions with Pointer Autentication (PR #162458)
https://github.com/bgergely0 updated
https://github.com/llvm/llvm-project/pull/162458
From c3da2b1f78c092c26a56e06f4b9d635e8d45a14b Mon Sep 17 00:00:00 2001
From: Gergely Balint
Date: Wed, 8 Oct 2025 11:17:31 +
Subject: [PATCH] [BOLT] Extend Inliner to work on functions with Pointer
Autentication
The inliner uses DirectSP to check if a function has instructions that
modify the SP. Exceptions are stack Push and Pop instructions.
We can also allow pointer signing and authentication instructions.
The inliner removes the Return instructions from the inlined functions.
If it is a fused pointer-authentication-and-return (e.g. RETAA), we have
to generate a new authentication instruction in place of the Return.
---
bolt/include/bolt/Core/MCPlusBuilder.h| 6 +++
bolt/lib/Passes/Inliner.cpp | 18
.../Target/AArch64/AArch64MCPlusBuilder.cpp | 29
bolt/test/AArch64/inline-armv8.3-returns.s| 45 +++
4 files changed, 98 insertions(+)
create mode 100644 bolt/test/AArch64/inline-armv8.3-returns.s
diff --git a/bolt/include/bolt/Core/MCPlusBuilder.h
b/bolt/include/bolt/Core/MCPlusBuilder.h
index 2772de73081d1..ba28016a234fb 100644
--- a/bolt/include/bolt/Core/MCPlusBuilder.h
+++ b/bolt/include/bolt/Core/MCPlusBuilder.h
@@ -632,6 +632,12 @@ class MCPlusBuilder {
return false;
}
+ /// Generate the matching pointer authentication instruction from a fused
+ /// pauth-and-return instruction.
+ virtual void createMatchingAuth(const MCInst &AuthAndRet, MCInst &Auth) {
+llvm_unreachable("not implemented");
+ }
+
/// Returns the register used as a return address. Returns std::nullopt if
/// not applicable, such as reading the return address from a system register
/// or from the stack.
diff --git a/bolt/lib/Passes/Inliner.cpp b/bolt/lib/Passes/Inliner.cpp
index 9b28c7efde5bf..913ff3d554a5b 100644
--- a/bolt/lib/Passes/Inliner.cpp
+++ b/bolt/lib/Passes/Inliner.cpp
@@ -195,6 +195,13 @@ InliningInfo getInliningInfo(const BinaryFunction &BF) {
if (BC.MIB->isPush(Inst) || BC.MIB->isPop(Inst))
continue;
+// Pointer signing and authenticatin instructions are used around
+// Push and Pop. These are also straightforward to handle.
+if (BC.isAArch64() &&
+(BC.MIB->isPSignOnLR(Inst) || BC.MIB->isPAuthOnLR(Inst) ||
+ BC.MIB->isPAuthAndRet(Inst)))
+ continue;
+
DirectSP |= BC.MIB->hasDefOfPhysReg(Inst, SPReg) ||
BC.MIB->hasUseOfPhysReg(Inst, SPReg);
}
@@ -338,6 +345,17 @@ Inliner::inlineCall(BinaryBasicBlock &CallerBB,
BC.Ctx.get());
}
+ // Handling fused authentication and return instructions (Armv8.3-A):
+ // if the Return here is RETA(A|B), we have to keep the authentication
+ // part.
+ // RETAA -> AUTIASP + RET
+ // RETAB -> AUTIBSP + RET
+ if (BC.isAArch64() && BC.MIB->isPAuthAndRet(Inst)) {
+MCInst Auth;
+BC.MIB->createMatchingAuth(Inst, Auth);
+InsertII =
+std::next(InlinedBB->insertInstruction(InsertII, std::move(Auth)));
+ }
if (CSIsTailCall || (!MIB.isCall(Inst) && !MIB.isReturn(Inst))) {
InsertII =
std::next(InlinedBB->insertInstruction(InsertII, std::move(Inst)));
diff --git a/bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp
b/bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp
index df4f42128605e..5fb1d7458a4bc 100644
--- a/bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp
+++ b/bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp
@@ -266,6 +266,35 @@ class AArch64MCPlusBuilder : public MCPlusBuilder {
Inst.getOpcode() == AArch64::RETABSPPCr;
}
+ void createMatchingAuth(const MCInst &AuthAndRet, MCInst &Auth) override {
+assert(isPAuthAndRet(AuthAndRet) &&
+ "Not a fused pauth-and-return instruction");
+
+Auth.clear();
+switch (AuthAndRet.getOpcode()) {
+case AArch64::RETAA:
+ Auth.setOpcode(AArch64::AUTIASP);
+ break;
+case AArch64::RETAB:
+ Auth.setOpcode(AArch64::AUTIBSP);
+ break;
+case AArch64::RETAASPPCi:
+ Auth.setOpcode(AArch64::AUTIASPPCi);
+ break;
+case AArch64::RETABSPPCi:
+ Auth.setOpcode(AArch64::AUTIBSPPCi);
+ break;
+case AArch64::RETAASPPCr:
+ Auth.setOpcode(AArch64::AUTIASPPCr);
+ break;
+case AArch64::RETABSPPCr:
+ Auth.setOpcode(AArch64::AUTIBSPPCr);
+ break;
+default:
+ llvm_unreachable("Unhandled fused pauth-and-return instruction");
+}
+ }
+
std::optional getSignedReg(const MCInst &Inst) const override {
switch (Inst.getOpcode()) {
case AArch64::PACIA:
diff --git a/bolt/test/AArch64/inline-armv8.3-returns.s
b/bolt/test/AArch64/inline-armv8.3-returns.s
new file mode 100644
index 0..055b589476caf
--- /dev/null
+++ b/bolt/test/AArch64/inline-armv8.3-returns.s
@@ -0,0 +1,45 @@
+# This test chec
[llvm-branch-commits] [clang] [llvm] [HLSL] GetDimensions methods for buffer resources (PR #161929)
@@ -421,13 +444,32 @@ BuiltinTypeMethodBuilder::addParam(StringRef Name,
QualType Ty,
void BuiltinTypeMethodBuilder::createDecl() {
assert(Method == nullptr && "Method or constructor is already created");
- // create method or constructor type
+ // create function prototype
ASTContext &AST = DeclBuilder.SemaRef.getASTContext();
SmallVector ParamTypes;
- for (Param &MP : Params)
-ParamTypes.emplace_back(MP.Ty);
+ SmallVector ParamExtInfos(Params.size());
+ uint32_t ArgIndex = 0;
+ bool IsTemplate = DeclBuilder.Template != nullptr;
+ bool UseParamExtInfo = false;
+ for (Param &MP : Params) {
+QualType Ty = MP.Ty;
+if (MP.Modifier != HLSLParamModifierAttr::Keyword_in) {
+ UseParamExtInfo = true;
+ ParamExtInfos[ArgIndex].withABI(
+ convertParamModifierToParamABI(MP.Modifier));
+ // Only update types on inout and out parameters for non-templated
+ // methods. Templated types will have their inout/out parameters
+ // converted to references during template instantiation.
+ if (!IsTemplate)
+Ty = getInoutParameterType(AST, Ty);
+}
+ParamTypes.emplace_back(Ty);
+++ArgIndex;
+ }
hekota wrote:
I tried different combinations of the `out` attribute, ABI param and when to
add `restrict &` on the function prototype or the method decl - this is the
variation that works and does not have to 'coerce' the arguments. However, I
did some testing now and found a bug in with `out` parameters and templates:
https://godbolt.org/z/dKn1r4v4E
I'll file an issue. We'll need to fix this bug first before revisiting this.
https://github.com/llvm/llvm-project/pull/161929
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [mlir] [mlir][linalg] Update vectorizatio of linalg.pack (PR #163539)
https://github.com/banach-space updated
https://github.com/llvm/llvm-project/pull/163539
From e2ec90e47522345b2c920134fe8ca45ad514806f Mon Sep 17 00:00:00 2001
From: Andrzej Warzynski
Date: Mon, 13 Oct 2025 14:49:00 +
Subject: [PATCH] [mlir][linalg] Update vectorizatio of linalg.pack
This patch changes `vectorizeAsTensorPackOp` to require users to specify
all write-side vector sizes for `linalg.pack` (not just the outer
dimensions). This makes `linalg.pack` vectorization consistent with
`linalg.unpack` (see #149293 for a similar change).
Conceptually, `linalg.pack` consists of these high-level steps:
* **Read** from the source tensor using `vector.transfer_read`.
* **Re-associate** dimensions of the transposed value, as specified by
the op (via `vector.shape_cast`)
* **Transpose** the re-associated value according to the permutation
in the `linalg.pack` op (via `vector.transpose`).
* **Write** the result into the destination tensor via
`vector.transfer_write`.
Previously, the vector sizes provided by the user were interpreted as
write-vector-sizes for PackOp _outer_ dims (i.e. the final step above).
These were used to:
* Infer read-vector-sizes using the `inner_tiles` attribute of PackOp.
* Deduce vector sizes for the transpose and shape cast operations.
* Ultimately determine the vector shape for the read.
However, this logic breaks when one or more tile sizes are dynamic (*).
In such cases, `vectorizePackOpPrecondition` would currently fail (see
`@pack_with_dynamic_dims_and_dynamic_inner_tile` added in this PR -
without this change it will crash).
This patch updates the contract: users now directly specify _all_ the
"write-vector-sizes", which inherently encode all inner tile sizes - including
dynamic ones. It becomes the user's responsibility to provide valid sizes.
In practice, since `linalg.pack` is typically constructed, tiled, and
vectorized by the same transformation pipeline, the necessary
"write-vector-sizes" should be recoverable.
Notes for reviewers:
* See test updates for user-facing impact.
* Review `vectorizeAsTensorPackOp` as a new implementation rather than
a diff.
* Comments and variable names were updated to align with
`vectorizeAsTensorUnPackOp`.
(*) As a concrete example, "scalable" tile sizes are represent as
dynamic values. Note, support for "scalable" vectorisation will be added
in a separate PR.
---
.../include/mlir/Dialect/Linalg/Utils/Utils.h | 3 +-
.../Dialect/Linalg/Transforms/Transforms.cpp | 3 +-
.../Linalg/Transforms/Vectorization.cpp | 217 +-
mlir/lib/Dialect/Linalg/Utils/Utils.cpp | 8 +-
.../linalg-ops-with-patterns.mlir | 2 +
.../Linalg/vectorization/linalg-ops.mlir | 98 +++-
6 files changed, 216 insertions(+), 115 deletions(-)
diff --git a/mlir/include/mlir/Dialect/Linalg/Utils/Utils.h
b/mlir/include/mlir/Dialect/Linalg/Utils/Utils.h
index 48978eb7663d5..49c75f4b00280 100644
--- a/mlir/include/mlir/Dialect/Linalg/Utils/Utils.h
+++ b/mlir/include/mlir/Dialect/Linalg/Utils/Utils.h
@@ -37,7 +37,8 @@ namespace linalg {
/// This function uses the helper function `computePackUnPackPerm` to get
/// the permutation vector. Only major difference between UnPack and Pack is
/// that packOp uses destination rank whereas unpack Uses source rank.
-SmallVector getPackInverseDestPerm(linalg::PackOp packOp);
+SmallVector getPackInverseDestPerm(linalg::PackOp packOp,
+PackingMetadata &metadatap);
/// Shell function to compute the Source Permutation of unPackOp.
/// This function, like the getPackInverseDestPerm uses the helper function
diff --git a/mlir/lib/Dialect/Linalg/Transforms/Transforms.cpp
b/mlir/lib/Dialect/Linalg/Transforms/Transforms.cpp
index eb2d825e17e44..12b6da774701c 100644
--- a/mlir/lib/Dialect/Linalg/Transforms/Transforms.cpp
+++ b/mlir/lib/Dialect/Linalg/Transforms/Transforms.cpp
@@ -234,8 +234,9 @@ FailureOr linalg::lowerPack(RewriterBase
&rewriter,
// before any outer or inner permutations have been applied.
PackingMetadata packingMetadata = computePackingMetadata(
packedTensorType.getRank(), packOp.getInnerDimsPos());
+ PackingMetadata packMetadata;
SmallVector packedToStripMinedShapePerm =
- getPackInverseDestPerm(packOp);
+ getPackInverseDestPerm(packOp, packMetadata);
// 3. Compute the stripMinedShape: this is the packed shape before any outer
// or inner permutations have been applied.
diff --git a/mlir/lib/Dialect/Linalg/Transforms/Vectorization.cpp
b/mlir/lib/Dialect/Linalg/Transforms/Vectorization.cpp
index 9d62491214018..890d1d5a7216d 100644
--- a/mlir/lib/Dialect/Linalg/Transforms/Vectorization.cpp
+++ b/mlir/lib/Dialect/Linalg/Transforms/Vectorization.cpp
@@ -1564,13 +1564,6 @@ vectorizeAsLinalgGeneric(RewriterBase &rewriter,
VectorizationState &state,
return success();
}
-/// Given a linalg::PackOp, return the `dest` shape before any packi
[llvm-branch-commits] [flang] [llvm] [flang][OpenMP] Add optional argument to requirement clauses (PR #163557)
llvmbot wrote:
@llvm/pr-subscribers-flang-openmp
Author: Krzysztof Parzyszek (kparzysz)
Changes
OpenMP 6.0 added an optional logical parameter to the requirement clauses
(except ATOMIC_DEFAULT_MEM_ORDER) to indicate whether the clause should take
effect or not. The parameter defaults to true if not specified.
The parameter value is a compile-time constant expression, but it may require
folding to get the final value. Since name resolution happens before folding,
the argument expression needs to be analyzed by hand. The determination of the
value needs to happen during name resolution because the requirement directives
need to be available through module files (and the module reader doesn't to
semantic checks beyond name resolution).
---
Patch is 25.45 KiB, truncated to 20.00 KiB below, full version:
https://github.com/llvm/llvm-project/pull/163557.diff
11 Files Affected:
- (modified) flang/include/flang/Lower/OpenMP/Clauses.h (+1)
- (modified) flang/include/flang/Parser/dump-parse-tree.h (+5)
- (modified) flang/include/flang/Parser/parse-tree.h (+48-1)
- (modified) flang/lib/Lower/OpenMP/Clauses.cpp (+59-9)
- (modified) flang/lib/Parser/openmp-parsers.cpp (+10-4)
- (modified) flang/lib/Semantics/check-omp-structure.cpp (+32-9)
- (modified) flang/lib/Semantics/resolve-directives.cpp (+21-3)
- (modified) flang/test/Parser/OpenMP/requires.f90 (+14)
- (added) flang/test/Semantics/OpenMP/requires10.f90 (+13)
- (modified) llvm/include/llvm/Frontend/OpenMP/ClauseT.h (+34-23)
- (modified) llvm/include/llvm/Frontend/OpenMP/OMP.td (+10)
``diff
diff --git a/flang/include/flang/Lower/OpenMP/Clauses.h
b/flang/include/flang/Lower/OpenMP/Clauses.h
index 5cd196a7869a2..273e61166fd9d 100644
--- a/flang/include/flang/Lower/OpenMP/Clauses.h
+++ b/flang/include/flang/Lower/OpenMP/Clauses.h
@@ -282,6 +282,7 @@ using Replayable = tomp::clause::ReplayableT;
using ReverseOffload = tomp::clause::ReverseOffloadT;
using Safelen = tomp::clause::SafelenT;
using Schedule = tomp::clause::ScheduleT;
+using SelfMaps = tomp::clause::SelfMapsT;
using SeqCst = tomp::clause::SeqCstT;
using Severity = tomp::clause::SeverityT;
using Shared = tomp::clause::SharedT;
diff --git a/flang/include/flang/Parser/dump-parse-tree.h
b/flang/include/flang/Parser/dump-parse-tree.h
index 14885293fd5eb..8854dc2267c8e 100644
--- a/flang/include/flang/Parser/dump-parse-tree.h
+++ b/flang/include/flang/Parser/dump-parse-tree.h
@@ -566,6 +566,7 @@ class ParseTreeDumper {
NODE(OmpDoacross, Sink)
NODE(OmpDoacross, Source)
NODE(parser, OmpDoacrossClause)
+ NODE(parser, OmpDynamicAllocatorsClause)
NODE(parser, OmpDynGroupprivateClause)
NODE(OmpDynGroupprivateClause, Modifier)
NODE(parser, OmpEndDirective)
@@ -659,9 +660,11 @@ class ParseTreeDumper {
NODE(parser, OmpRefModifier)
NODE_ENUM(OmpRefModifier, Value)
NODE(parser, OmpReplayableClause)
+ NODE(parser, OmpReverseOffloadClause)
NODE(parser, OmpScheduleClause)
NODE(OmpScheduleClause, Modifier)
NODE_ENUM(OmpScheduleClause, Kind)
+ NODE(parser, OmpSelfMapsClause)
NODE(parser, OmpSelfModifier)
NODE_ENUM(OmpSelfModifier, Value)
NODE(parser, OmpSeverityClause)
@@ -689,6 +692,8 @@ class ParseTreeDumper {
NODE(parser, OmpTransparentClause)
NODE(parser, OmpTypeNameList)
NODE(parser, OmpTypeSpecifier)
+ NODE(parser, OmpUnifiedAddressClause)
+ NODE(parser, OmpUnifiedSharedMemoryClause)
NODE(parser, OmpUpdateClause)
NODE(parser, OmpUseClause)
NODE(parser, OmpVariableCategory)
diff --git a/flang/include/flang/Parser/parse-tree.h
b/flang/include/flang/Parser/parse-tree.h
index d919b777d7487..18b583669421a 100644
--- a/flang/include/flang/Parser/parse-tree.h
+++ b/flang/include/flang/Parser/parse-tree.h
@@ -337,6 +337,7 @@ using IntConstantExpr = Integer; // R1031
using ScalarLogicalExpr = Scalar;
using ScalarIntExpr = Scalar;
using ScalarIntConstantExpr = Scalar;
+using ScalarLogicalConstantExpr = Scalar>;
using ScalarDefaultCharExpr = Scalar;
// R1030 default-char-constant-expr is used in the Standard only as part of
// scalar-default-char-constant-expr.
@@ -4414,6 +4415,16 @@ struct OmpDeviceTypeClause {
WRAPPER_CLASS_BOILERPLATE(OmpDeviceTypeClause, DeviceTypeDescription);
};
+// Ref: [5.0:60-63], [5.1:83-86], [5.2:212-213], [6.0:356-362]
+//
+// dynamic-allocators-clause ->
+//DYNAMIC_ALLOCATORS// since 5.0
+//[(scalar-logical-const-expr)] // since 6.0
+struct OmpDynamicAllocatorsClause {
+ WRAPPER_CLASS_BOILERPLATE(
+ OmpDynamicAllocatorsClause, ScalarLogicalConstantExpr);
+};
+
struct OmpDynGroupprivateClause {
TUPLE_CLASS_BOILERPLATE(OmpDynGroupprivateClause);
MODIFIER_BOILERPLATE(OmpAccessGroup, OmpPrescriptiveness);
@@ -4690,7 +4701,16 @@ struct OmpReductionClause {
// replayable-clause ->
//REPLAYABLE[(replayable-expression)] // since 6.0
struct OmpReplayableClause {
- WRAPPER_CLASS_BOILERPLATE(OmpReplaya
[llvm-branch-commits] [llvm] [MIR2Vec] Handle Operands (PR #163281)
https://github.com/mtrofin deleted https://github.com/llvm/llvm-project/pull/163281 ___ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [llvm] [FlowSensitive] [StatusOr] [2/N] Add minimal model (PR #162932)
@@ -0,0 +1,2539 @@
+//===- UncheckedStatusOrAccessModelTestFixture.cpp
===//
+//
+// 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
+//
+//===--===//
+
+#include "UncheckedStatusOrAccessModelTestFixture.h"
+#include "MockHeaders.h"
+#include "llvm/Support/ErrorHandling.h"
+
+#include
+#include
+#include
+
+#include "gtest/gtest.h"
+
+namespace clang::dataflow::statusor_model {
+namespace {
+
+TEST_P(UncheckedStatusOrAccessModelTest, NoStatusOrMention) {
+ ExpectDiagnosticsFor(R"cc(
+void target() { "nop"; }
+ )cc");
+}
+
+TEST_P(UncheckedStatusOrAccessModelTest,
+ UnwrapWithoutCheck_Lvalue_CallToValue) {
+ ExpectDiagnosticsFor(R"cc(
+#include "unchecked_statusor_use_test_defs.h"
+
+void target(STATUSOR_INT sor) {
+ sor.value(); // [[unsafe]]
+}
+ )cc");
+}
+
+TEST_P(UncheckedStatusOrAccessModelTest, NonExplicitInitialization) {
+ ExpectDiagnosticsFor(R"cc(
+#include "unchecked_statusor_use_test_defs.h"
+STATUSOR_INT target() {
+ STATUSOR_INT x = Make();
+ return x.value(); // [[unsafe]]
+}
+ )cc");
+}
+
+TEST_P(UncheckedStatusOrAccessModelTest,
+ UnwrapWithoutCheck_Lvalue_CallToValue_NewLine) {
+ ExpectDiagnosticsFor(R"cc(
+#include "unchecked_statusor_use_test_defs.h"
+
+void target(STATUSOR_INT sor) {
+ sor.value(); // [[unsafe]]
+}
+ )cc");
+}
+
+TEST_P(UncheckedStatusOrAccessModelTest,
+ UnwrapWithoutCheck_Rvalue_CallToValue) {
+ ExpectDiagnosticsFor(R"cc(
+#include "unchecked_statusor_use_test_defs.h"
+
+void target(STATUSOR_INT sor) {
+ std::move(sor).value(); // [[unsafe]]
+}
+ )cc");
+}
+
+TEST_P(UncheckedStatusOrAccessModelTest,
+ UnwrapWithoutCheck_Lvalue_CallToValueOrDie) {
+ ExpectDiagnosticsFor(R"cc(
+#include "unchecked_statusor_use_test_defs.h"
+
+void target(STATUSOR_INT sor) {
+ sor.ValueOrDie(); // [[unsafe]]
+}
+ )cc");
+}
+
+TEST_P(UncheckedStatusOrAccessModelTest,
+ UnwrapWithoutCheck_Rvalue_CallToValueOrDie) {
+ ExpectDiagnosticsFor(R"cc(
+#include "unchecked_statusor_use_test_defs.h"
+
+void target(STATUSOR_INT sor) {
+ std::move(sor).ValueOrDie(); // [[unsafe]]
+}
+ )cc");
+}
+
+TEST_P(UncheckedStatusOrAccessModelTest,
+ UnwrapWithoutCheck_Lvalue_CallToOperatorStar) {
+ ExpectDiagnosticsFor(R"cc(
+#include "unchecked_statusor_use_test_defs.h"
+
+void target(STATUSOR_INT sor) {
+ *sor; // [[unsafe]]
+}
+ )cc");
+}
+
+TEST_P(UncheckedStatusOrAccessModelTest,
+ UnwrapWithoutCheck_Lvalue_CallToOperatorStarSeparateLine) {
+ ExpectDiagnosticsFor(R"cc(
+#include "unchecked_statusor_use_test_defs.h"
+
+void target(STATUSOR_INT sor) {
+ * // [[unsafe]]
+ sor;
+}
+ )cc");
+}
+
+TEST_P(UncheckedStatusOrAccessModelTest,
+ UnwrapWithoutCheck_Rvalue_CallToOperatorStar) {
+ ExpectDiagnosticsFor(R"cc(
+#include "unchecked_statusor_use_test_defs.h"
+
+void target(STATUSOR_INT sor) {
+ *std::move(sor); // [[unsafe]]
+}
+ )cc");
+}
+
+TEST_P(UncheckedStatusOrAccessModelTest,
+ UnwrapWithoutCheck_Lvalue_CallToOperatorArrow) {
+ ExpectDiagnosticsFor(R"cc(
+#include "unchecked_statusor_use_test_defs.h"
+
+struct Foo {
+ void foo();
+};
+
+void target(absl::StatusOr sor) {
+ sor->foo(); // [[unsafe]]
+}
+ )cc");
+}
+
+TEST_P(UncheckedStatusOrAccessModelTest,
+ UnwrapWithoutCheck_Rvalue_CallToOperatorArrow) {
+ ExpectDiagnosticsFor(R"cc(
+#include "unchecked_statusor_use_test_defs.h"
+
+struct Foo {
+ void foo();
+};
+
+void target(absl::StatusOr sor) {
+ std::move(sor)->foo(); // [[unsafe]]
+}
+ )cc");
+}
+
+TEST_P(UncheckedStatusOrAccessModelTest, UnwrapRvalueWithCheck) {
+ ExpectDiagnosticsFor(R"cc(
+#include "unchecked_statusor_use_test_defs.h"
+
+void target(STATUSOR_INT sor) {
+ if (sor.ok()) std::move(sor).value();
+}
+ )cc");
+}
+
+TEST_P(UncheckedStatusOrAccessModelTest, ParensInDeclInitExpr) {
+ ExpectDiagnosticsFor(R"cc(
+#include "unchecked_statusor_use_test_defs.h"
+
+void target() {
+ auto sor = (Make());
+ if (sor.ok()) sor.value();
+}
+ )cc");
+}
+
+TEST_P(UncheckedStatusOrAccessModelTest, ReferenceInDeclInitExpr) {
+ ExpectDiagnosticsFor(R"cc(
+#include "unchecked_statusor_use_test_defs.h"
+
+struct Foo {
+ const STATUSOR_INT& GetStatusOrInt() const;
+};
+
+void target(Foo foo) {
+ auto sor = foo.GetStatusOrInt();
+ if (sor.ok()) sor.value();
+}
+ )cc");
+ ExpectDiagnosticsFor(R"cc(
+#include "unchecked_statusor_use_test_defs.h"
+
+struct Foo {
+ STATUSOR_INT& GetStatusOrInt();
+};
+
+void target(Foo foo) {
+ auto sor = foo.GetStatusOrInt();
+ if (sor.ok()
[llvm-branch-commits] [clang] [llvm] [FlowSensitive] [StatusOr] [2/N] Add minimal model (PR #162932)
@@ -0,0 +1,2539 @@
+//===- UncheckedStatusOrAccessModelTestFixture.cpp
===//
+//
+// 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
+//
+//===--===//
+
+#include "UncheckedStatusOrAccessModelTestFixture.h"
+#include "MockHeaders.h"
+#include "llvm/Support/ErrorHandling.h"
+
+#include
+#include
+#include
+
+#include "gtest/gtest.h"
+
+namespace clang::dataflow::statusor_model {
+namespace {
+
+TEST_P(UncheckedStatusOrAccessModelTest, NoStatusOrMention) {
+ ExpectDiagnosticsFor(R"cc(
+void target() { "nop"; }
+ )cc");
+}
+
+TEST_P(UncheckedStatusOrAccessModelTest,
+ UnwrapWithoutCheck_Lvalue_CallToValue) {
+ ExpectDiagnosticsFor(R"cc(
+#include "unchecked_statusor_use_test_defs.h"
+
+void target(STATUSOR_INT sor) {
+ sor.value(); // [[unsafe]]
+}
+ )cc");
+}
+
+TEST_P(UncheckedStatusOrAccessModelTest, NonExplicitInitialization) {
+ ExpectDiagnosticsFor(R"cc(
+#include "unchecked_statusor_use_test_defs.h"
+STATUSOR_INT target() {
+ STATUSOR_INT x = Make();
+ return x.value(); // [[unsafe]]
+}
+ )cc");
+}
+
+TEST_P(UncheckedStatusOrAccessModelTest,
+ UnwrapWithoutCheck_Lvalue_CallToValue_NewLine) {
+ ExpectDiagnosticsFor(R"cc(
+#include "unchecked_statusor_use_test_defs.h"
+
+void target(STATUSOR_INT sor) {
+ sor.value(); // [[unsafe]]
+}
+ )cc");
+}
+
+TEST_P(UncheckedStatusOrAccessModelTest,
+ UnwrapWithoutCheck_Rvalue_CallToValue) {
+ ExpectDiagnosticsFor(R"cc(
+#include "unchecked_statusor_use_test_defs.h"
+
+void target(STATUSOR_INT sor) {
+ std::move(sor).value(); // [[unsafe]]
+}
+ )cc");
+}
+
+TEST_P(UncheckedStatusOrAccessModelTest,
+ UnwrapWithoutCheck_Lvalue_CallToValueOrDie) {
+ ExpectDiagnosticsFor(R"cc(
+#include "unchecked_statusor_use_test_defs.h"
+
+void target(STATUSOR_INT sor) {
+ sor.ValueOrDie(); // [[unsafe]]
+}
+ )cc");
+}
+
+TEST_P(UncheckedStatusOrAccessModelTest,
+ UnwrapWithoutCheck_Rvalue_CallToValueOrDie) {
+ ExpectDiagnosticsFor(R"cc(
+#include "unchecked_statusor_use_test_defs.h"
+
+void target(STATUSOR_INT sor) {
+ std::move(sor).ValueOrDie(); // [[unsafe]]
+}
+ )cc");
+}
+
+TEST_P(UncheckedStatusOrAccessModelTest,
+ UnwrapWithoutCheck_Lvalue_CallToOperatorStar) {
+ ExpectDiagnosticsFor(R"cc(
+#include "unchecked_statusor_use_test_defs.h"
+
+void target(STATUSOR_INT sor) {
+ *sor; // [[unsafe]]
+}
+ )cc");
+}
+
+TEST_P(UncheckedStatusOrAccessModelTest,
+ UnwrapWithoutCheck_Lvalue_CallToOperatorStarSeparateLine) {
+ ExpectDiagnosticsFor(R"cc(
+#include "unchecked_statusor_use_test_defs.h"
+
+void target(STATUSOR_INT sor) {
+ * // [[unsafe]]
+ sor;
+}
+ )cc");
+}
+
+TEST_P(UncheckedStatusOrAccessModelTest,
+ UnwrapWithoutCheck_Rvalue_CallToOperatorStar) {
+ ExpectDiagnosticsFor(R"cc(
+#include "unchecked_statusor_use_test_defs.h"
+
+void target(STATUSOR_INT sor) {
+ *std::move(sor); // [[unsafe]]
+}
+ )cc");
+}
+
+TEST_P(UncheckedStatusOrAccessModelTest,
+ UnwrapWithoutCheck_Lvalue_CallToOperatorArrow) {
+ ExpectDiagnosticsFor(R"cc(
+#include "unchecked_statusor_use_test_defs.h"
+
+struct Foo {
+ void foo();
+};
+
+void target(absl::StatusOr sor) {
+ sor->foo(); // [[unsafe]]
+}
+ )cc");
+}
+
+TEST_P(UncheckedStatusOrAccessModelTest,
+ UnwrapWithoutCheck_Rvalue_CallToOperatorArrow) {
+ ExpectDiagnosticsFor(R"cc(
+#include "unchecked_statusor_use_test_defs.h"
+
+struct Foo {
+ void foo();
+};
+
+void target(absl::StatusOr sor) {
+ std::move(sor)->foo(); // [[unsafe]]
+}
+ )cc");
+}
+
+TEST_P(UncheckedStatusOrAccessModelTest, UnwrapRvalueWithCheck) {
+ ExpectDiagnosticsFor(R"cc(
+#include "unchecked_statusor_use_test_defs.h"
+
+void target(STATUSOR_INT sor) {
+ if (sor.ok()) std::move(sor).value();
+}
+ )cc");
+}
+
+TEST_P(UncheckedStatusOrAccessModelTest, ParensInDeclInitExpr) {
+ ExpectDiagnosticsFor(R"cc(
+#include "unchecked_statusor_use_test_defs.h"
+
+void target() {
+ auto sor = (Make());
+ if (sor.ok()) sor.value();
+}
+ )cc");
+}
+
+TEST_P(UncheckedStatusOrAccessModelTest, ReferenceInDeclInitExpr) {
+ ExpectDiagnosticsFor(R"cc(
+#include "unchecked_statusor_use_test_defs.h"
+
+struct Foo {
+ const STATUSOR_INT& GetStatusOrInt() const;
+};
+
+void target(Foo foo) {
+ auto sor = foo.GetStatusOrInt();
+ if (sor.ok()) sor.value();
+}
+ )cc");
+ ExpectDiagnosticsFor(R"cc(
+#include "unchecked_statusor_use_test_defs.h"
+
+struct Foo {
+ STATUSOR_INT& GetStatusOrInt();
+};
+
+void target(Foo foo) {
+ auto sor = foo.GetStatusOrInt();
+ if (sor.ok()
[llvm-branch-commits] [llvm] [MIR2Vec] Handle Operands (PR #163281)
@@ -74,31 +76,114 @@ class MIRVocabulary {
friend class llvm::MIR2VecVocabLegacyAnalysis;
using VocabMap = std::map;
-private:
- // Define vocabulary layout - adapted for MIR
+ // MIRVocabulary Layout:
+ //
+---+-+
+ // | Entity Type | Description
|
+ //
+---+-+
+ // | 1. Opcodes| Target specific opcodes derived from TII, grouped
|
+ // | | by instruction semantics.
|
+ // | 2. Common Operands| All common operand types, except register operands,
|
+ // | | defined by MachineOperand::MachineOperandType enum.
|
+ // | 3. Physical | Register classes defined by the target, specialized
|
+ // |Registers | by physical registers.
|
+ // | 4. Virtual| Register classes defined by the target, specialized
|
+ // |Registers | by virtual and physical registers.
|
+ //
+---+-+
+
+ /// Layout information for the MIR vocabulary. Defines the starting index
+ /// and size of each section in the vocabulary.
struct {
size_t OpcodeBase = 0;
-size_t OperandBase = 0;
+size_t CommonOperandBase = 0;
+size_t PhyRegBase = 0;
+size_t VirtRegBase = 0;
size_t TotalEntries = 0;
} Layout;
- enum class Section : unsigned { Opcodes = 0, MaxSections };
+ enum class Section : unsigned {
+Opcodes = 0,
+CommonOperands = 1,
+PhyRegisters = 2,
+VirtRegisters = 3,
+MaxSections
+ };
ir2vec::VocabStorage Storage;
mutable std::set UniqueBaseOpcodeNames;
+ mutable SmallVector RegisterOperandNames;
+
+ // Some instructions have optional register operands that may be NoRegister.
+ // We return a zero vector in such cases.
+ mutable Embedding ZeroEmbedding;
mtrofin wrote:
This sounds like a `const`, not a `mutable`?
https://github.com/llvm/llvm-project/pull/163281
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [MIR2Vec] Handle Operands (PR #163281)
@@ -74,31 +76,114 @@ class MIRVocabulary {
friend class llvm::MIR2VecVocabLegacyAnalysis;
using VocabMap = std::map;
-private:
- // Define vocabulary layout - adapted for MIR
+ // MIRVocabulary Layout:
+ //
+---+-+
+ // | Entity Type | Description
|
+ //
+---+-+
+ // | 1. Opcodes| Target specific opcodes derived from TII, grouped
|
+ // | | by instruction semantics.
|
+ // | 2. Common Operands| All common operand types, except register operands,
|
+ // | | defined by MachineOperand::MachineOperandType enum.
|
+ // | 3. Physical | Register classes defined by the target, specialized
|
mtrofin wrote:
add "classes " for 3 and 4 in the left column. I know the right column says
"classes", but this would make it immediately more clear.
https://github.com/llvm/llvm-project/pull/163281
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [SelectionDAG] Widen <2 x T> vector types for atomic load (PR #148897)
https://github.com/jofrn updated
https://github.com/llvm/llvm-project/pull/148897
>From b382b4a24e516aa150e1c4ad1e9c6f2c328cf064 Mon Sep 17 00:00:00 2001
From: jofrn
Date: Tue, 15 Jul 2025 12:59:37 -0400
Subject: [PATCH] [SelectionDAG] Widen <2 x T> vector types for atomic load
Vector types of 2 elements must be widened. This change does this
for vector types of atomic load in SelectionDAG
so that it can translate aligned vectors of >1 size.
---
llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h | 1 +
.../SelectionDAG/LegalizeVectorTypes.cpp | 97 --
llvm/test/CodeGen/X86/atomic-load-store.ll| 286 ++
3 files changed, 361 insertions(+), 23 deletions(-)
diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h
b/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h
index 9656a30321efa..ed2c30be7d71d 100644
--- a/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h
+++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h
@@ -1084,6 +1084,7 @@ class LLVM_LIBRARY_VISIBILITY DAGTypeLegalizer {
SDValue WidenVecRes_EXTRACT_SUBVECTOR(SDNode* N);
SDValue WidenVecRes_INSERT_SUBVECTOR(SDNode *N);
SDValue WidenVecRes_INSERT_VECTOR_ELT(SDNode* N);
+ SDValue WidenVecRes_ATOMIC_LOAD(AtomicSDNode *N);
SDValue WidenVecRes_LOAD(SDNode* N);
SDValue WidenVecRes_VP_LOAD(VPLoadSDNode *N);
SDValue WidenVecRes_VP_LOAD_FF(VPLoadFFSDNode *N);
diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
b/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
index e12bedd8b09d3..d991af5fdedfd 100644
--- a/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
@@ -4859,6 +4859,9 @@ void DAGTypeLegalizer::WidenVectorResult(SDNode *N,
unsigned ResNo) {
break;
case ISD::EXTRACT_SUBVECTOR: Res = WidenVecRes_EXTRACT_SUBVECTOR(N); break;
case ISD::INSERT_VECTOR_ELT: Res = WidenVecRes_INSERT_VECTOR_ELT(N); break;
+ case ISD::ATOMIC_LOAD:
+Res = WidenVecRes_ATOMIC_LOAD(cast(N));
+break;
case ISD::LOAD: Res = WidenVecRes_LOAD(N); break;
case ISD::STEP_VECTOR:
case ISD::SPLAT_VECTOR:
@@ -6248,6 +6251,74 @@ SDValue
DAGTypeLegalizer::WidenVecRes_INSERT_VECTOR_ELT(SDNode *N) {
N->getOperand(1), N->getOperand(2));
}
+/// Either return the same load or provide appropriate casts
+/// from the load and return that.
+static SDValue coerceLoadedValue(SDValue LdOp, EVT FirstVT, EVT WidenVT,
+ TypeSize LdWidth, TypeSize FirstVTWidth,
+ SDLoc dl, SelectionDAG &DAG) {
+ assert(TypeSize::isKnownLE(LdWidth, FirstVTWidth));
+ TypeSize WidenWidth = WidenVT.getSizeInBits();
+ if (!FirstVT.isVector()) {
+unsigned NumElts =
+WidenWidth.getFixedValue() / FirstVTWidth.getFixedValue();
+EVT NewVecVT = EVT::getVectorVT(*DAG.getContext(), FirstVT, NumElts);
+SDValue VecOp = DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, NewVecVT, LdOp);
+return DAG.getNode(ISD::BITCAST, dl, WidenVT, VecOp);
+ }
+ assert(FirstVT == WidenVT);
+ return LdOp;
+}
+
+static std::optional findMemType(SelectionDAG &DAG,
+ const TargetLowering &TLI, unsigned
Width,
+ EVT WidenVT, unsigned Align,
+ unsigned WidenEx);
+
+SDValue DAGTypeLegalizer::WidenVecRes_ATOMIC_LOAD(AtomicSDNode *LD) {
+ EVT WidenVT =
+ TLI.getTypeToTransformTo(*DAG.getContext(), LD->getValueType(0));
+ EVT LdVT = LD->getMemoryVT();
+ SDLoc dl(LD);
+ assert(LdVT.isVector() && WidenVT.isVector() && "Expected vectors");
+ assert(LdVT.isScalableVector() == WidenVT.isScalableVector() &&
+ "Must be scalable");
+ assert(LdVT.getVectorElementType() == WidenVT.getVectorElementType() &&
+ "Expected equivalent element types");
+
+ // Load information
+ SDValue Chain = LD->getChain();
+ SDValue BasePtr = LD->getBasePtr();
+ MachineMemOperand::Flags MMOFlags = LD->getMemOperand()->getFlags();
+ AAMDNodes AAInfo = LD->getAAInfo();
+
+ TypeSize LdWidth = LdVT.getSizeInBits();
+ TypeSize WidenWidth = WidenVT.getSizeInBits();
+ TypeSize WidthDiff = WidenWidth - LdWidth;
+
+ // Find the vector type that can load from.
+ std::optional FirstVT =
+ findMemType(DAG, TLI, LdWidth.getKnownMinValue(), WidenVT, /*LdAlign=*/0,
+ WidthDiff.getKnownMinValue());
+
+ if (!FirstVT)
+return SDValue();
+
+ SmallVector MemVTs;
+ TypeSize FirstVTWidth = FirstVT->getSizeInBits();
+
+ SDValue LdOp = DAG.getAtomicLoad(ISD::NON_EXTLOAD, dl, *FirstVT, *FirstVT,
+ Chain, BasePtr, LD->getMemOperand());
+
+ // Load the element with one instruction.
+ SDValue Result = coerceLoadedValue(LdOp, *FirstVT, WidenVT, LdWidth,
+ FirstVTWidth, dl, DAG);
+
+ // Modified the chain - switch anything that used the old chain to use
+ // the new one.
+ ReplaceValueWith(SDValue(LD,
[llvm-branch-commits] [llvm] [X86] Remove extra MOV after widening atomic load (PR #148898)
https://github.com/jofrn updated
https://github.com/llvm/llvm-project/pull/148898
>From aab7a4e376abe3bf7cf52b3e28d658d384c13635 Mon Sep 17 00:00:00 2001
From: jofrn
Date: Tue, 15 Jul 2025 13:01:24 -0400
Subject: [PATCH] [X86] Remove extra MOV after widening atomic load
This change adds patterns to optimize out an extra MOV
present after widening the atomic load.
---
llvm/lib/Target/X86/X86InstrCompiler.td| 7 +
llvm/test/CodeGen/X86/atomic-load-store.ll | 192 +++--
2 files changed, 35 insertions(+), 164 deletions(-)
diff --git a/llvm/lib/Target/X86/X86InstrCompiler.td
b/llvm/lib/Target/X86/X86InstrCompiler.td
index ec31675731b79..85db6762dbaf3 100644
--- a/llvm/lib/Target/X86/X86InstrCompiler.td
+++ b/llvm/lib/Target/X86/X86InstrCompiler.td
@@ -1204,6 +1204,13 @@ def : Pat<(i16 (atomic_load_nonext_16 addr:$src)),
(MOV16rm addr:$src)>;
def : Pat<(i32 (atomic_load_nonext_32 addr:$src)), (MOV32rm addr:$src)>;
def : Pat<(i64 (atomic_load_nonext_64 addr:$src)), (MOV64rm addr:$src)>;
+def : Pat<(v4i32 (scalar_to_vector (i32 (zext (i16 (atomic_load_16
addr:$src)),
+ (MOVDI2PDIrm addr:$src)>; // load atomic <2 x i8>
+def : Pat<(v4i32 (scalar_to_vector (i32 (atomic_load_32 addr:$src,
+ (MOVDI2PDIrm addr:$src)>; // load atomic <2 x i16>
+def : Pat<(v2i64 (scalar_to_vector (i64 (atomic_load_64 addr:$src,
+ (MOV64toPQIrm addr:$src)>; // load atomic <2 x i32,float>
+
// Floating point loads/stores.
def : Pat<(atomic_store_32 (i32 (bitconvert (f32 FR32:$src))), addr:$dst),
(MOVSSmr addr:$dst, FR32:$src)>, Requires<[UseSSE1]>;
diff --git a/llvm/test/CodeGen/X86/atomic-load-store.ll
b/llvm/test/CodeGen/X86/atomic-load-store.ll
index ff5391f44bbe3..4b818b6cfa57e 100644
--- a/llvm/test/CodeGen/X86/atomic-load-store.ll
+++ b/llvm/test/CodeGen/X86/atomic-load-store.ll
@@ -319,159 +319,60 @@ define <2 x i8> @atomic_vec2_i8(ptr %x) {
define <2 x i16> @atomic_vec2_i16(ptr %x) {
; CHECK-O3-LABEL: atomic_vec2_i16:
; CHECK-O3: # %bb.0:
-; CHECK-O3-NEXT:movl (%rdi), %eax
-; CHECK-O3-NEXT:movd %eax, %xmm0
+; CHECK-O3-NEXT:movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
; CHECK-O3-NEXT:retq
;
; CHECK-SSE-O3-LABEL: atomic_vec2_i16:
; CHECK-SSE-O3: # %bb.0:
-; CHECK-SSE-O3-NEXT:movl (%rdi), %eax
-; CHECK-SSE-O3-NEXT:movd %eax, %xmm0
+; CHECK-SSE-O3-NEXT:movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
; CHECK-SSE-O3-NEXT:retq
;
; CHECK-AVX-O3-LABEL: atomic_vec2_i16:
; CHECK-AVX-O3: # %bb.0:
-; CHECK-AVX-O3-NEXT:movl (%rdi), %eax
-; CHECK-AVX-O3-NEXT:vmovd %eax, %xmm0
+; CHECK-AVX-O3-NEXT:movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
; CHECK-AVX-O3-NEXT:retq
;
; CHECK-O0-LABEL: atomic_vec2_i16:
; CHECK-O0: # %bb.0:
-; CHECK-O0-NEXT:movl (%rdi), %eax
-; CHECK-O0-NEXT:movd %eax, %xmm0
+; CHECK-O0-NEXT:movd {{.*#+}} xmm0 = mem[0],zero,zero,zero
; CHECK-O0-NEXT:retq
;
; CHECK-SSE-O0-LABEL: atomic_vec2_i16:
; CHECK-SSE-O0: # %bb.0:
-; CHECK-SSE-O0-NEXT:movl (%rdi), %eax
-; CHECK-SSE-O0-NEXT:movd %eax, %xmm0
+; CHECK-SSE-O0-NEXT:movd {{.*#+}} xmm0 = mem[0],zero,zero,zero
; CHECK-SSE-O0-NEXT:retq
;
; CHECK-AVX-O0-LABEL: atomic_vec2_i16:
; CHECK-AVX-O0: # %bb.0:
-; CHECK-AVX-O0-NEXT:movl (%rdi), %eax
-; CHECK-AVX-O0-NEXT:vmovd %eax, %xmm0
+; CHECK-AVX-O0-NEXT:movd {{.*#+}} xmm0 = mem[0],zero,zero,zero
; CHECK-AVX-O0-NEXT:retq
%ret = load atomic <2 x i16>, ptr %x acquire, align 4
ret <2 x i16> %ret
}
define <2 x ptr addrspace(270)> @atomic_vec2_ptr270(ptr %x) {
-; CHECK-O3-LABEL: atomic_vec2_ptr270:
-; CHECK-O3: # %bb.0:
-; CHECK-O3-NEXT:movq (%rdi), %rax
-; CHECK-O3-NEXT:movq %rax, %xmm0
-; CHECK-O3-NEXT:retq
-;
-; CHECK-SSE-O3-LABEL: atomic_vec2_ptr270:
-; CHECK-SSE-O3: # %bb.0:
-; CHECK-SSE-O3-NEXT:movq (%rdi), %rax
-; CHECK-SSE-O3-NEXT:movq %rax, %xmm0
-; CHECK-SSE-O3-NEXT:retq
-;
-; CHECK-AVX-O3-LABEL: atomic_vec2_ptr270:
-; CHECK-AVX-O3: # %bb.0:
-; CHECK-AVX-O3-NEXT:movq (%rdi), %rax
-; CHECK-AVX-O3-NEXT:vmovq %rax, %xmm0
-; CHECK-AVX-O3-NEXT:retq
-;
-; CHECK-O0-LABEL: atomic_vec2_ptr270:
-; CHECK-O0: # %bb.0:
-; CHECK-O0-NEXT:movq (%rdi), %rax
-; CHECK-O0-NEXT:movq %rax, %xmm0
-; CHECK-O0-NEXT:retq
-;
-; CHECK-SSE-O0-LABEL: atomic_vec2_ptr270:
-; CHECK-SSE-O0: # %bb.0:
-; CHECK-SSE-O0-NEXT:movq (%rdi), %rax
-; CHECK-SSE-O0-NEXT:movq %rax, %xmm0
-; CHECK-SSE-O0-NEXT:retq
-;
-; CHECK-AVX-O0-LABEL: atomic_vec2_ptr270:
-; CHECK-AVX-O0: # %bb.0:
-; CHECK-AVX-O0-NEXT:movq (%rdi), %rax
-; CHECK-AVX-O0-NEXT:vmovq %rax, %xmm0
-; CHECK-AVX-O0-NEXT:retq
+; CHECK-LABEL: atomic_vec2_ptr270:
+; CHECK: # %bb.0:
+; CHECK-NEXT:movq (%rdi), %xmm0
+; CHECK-NEXT:retq
%ret = load atomic <2 x ptr addrspace(270)>, ptr %x acquire, align 8
ret <2 x ptr addrspace(270)> %ret
}
define <2
[llvm-branch-commits] [clang] [llvm] [FlowSensitive] [StatusOr] [2/N] Add minimal model (PR #162932)
https://github.com/fmayer edited https://github.com/llvm/llvm-project/pull/162932 ___ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [llvm] [FlowSensitive] [StatusOr] [2/N] Add minimal model (PR #162932)
https://github.com/jvoung commented: Exciting to see! (but whew it is a bunch of tests...) https://github.com/llvm/llvm-project/pull/162932 ___ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang][Driver] Support Outline Flags on RISC-V and X86 (PR #163494)
https://github.com/lenary updated
https://github.com/llvm/llvm-project/pull/163494
>From 86e0964dcae26bb04b4d8dc8ddeb15eb66fe0f42 Mon Sep 17 00:00:00 2001
From: Sam Elliott
Date: Tue, 14 Oct 2025 21:46:45 -0700
Subject: [PATCH] [clang][Driver] Support Outline Flags on RISC-V and X86
These two targets both also support the machine outliner, so these flags
should probably be cross-target. This updates the docs for these flags
as well.
---
clang/include/clang/Driver/Options.td | 16 ++--
clang/lib/Driver/ToolChains/CommonArgs.cpp | 12
clang/test/Driver/aarch64-outliner.c | 3 ---
clang/test/Driver/riscv-outliner.c | 7 +++
clang/test/Driver/unsupported-outliner.c | 3 +++
clang/test/Driver/x86-outliner.c | 7 +++
6 files changed, 35 insertions(+), 13 deletions(-)
create mode 100644 clang/test/Driver/riscv-outliner.c
create mode 100644 clang/test/Driver/unsupported-outliner.c
create mode 100644 clang/test/Driver/x86-outliner.c
diff --git a/clang/include/clang/Driver/Options.td
b/clang/include/clang/Driver/Options.td
index 611b68e5281f0..d62b771f463ea 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -5127,12 +5127,16 @@ def mms_bitfields : Flag<["-"], "mms-bitfields">,
Group,
Visibility<[ClangOption, CC1Option]>,
HelpText<"Set the default structure layout to be compatible with the
Microsoft compiler standard">,
MarshallingInfoFlag>;
-def moutline : Flag<["-"], "moutline">, Group,
- Visibility<[ClangOption, CC1Option]>,
-HelpText<"Enable function outlining (AArch64 only)">;
-def mno_outline : Flag<["-"], "mno-outline">, Group,
- Visibility<[ClangOption, CC1Option]>,
-HelpText<"Disable function outlining (AArch64 only)">;
+def moutline
+: Flag<["-"], "moutline">,
+ Group,
+ Visibility<[ClangOption, CC1Option]>,
+ HelpText<"Enable function outlining (AArch64,Arm,RISC-V,X86 only)">;
+def mno_outline
+: Flag<["-"], "mno-outline">,
+ Group,
+ Visibility<[ClangOption, CC1Option]>,
+ HelpText<"Disable function outlining (AArch64,Arm,RISC-V,X86 only)">;
def mno_ms_bitfields : Flag<["-"], "mno-ms-bitfields">, Group,
HelpText<"Do not set the default structure layout to be compatible with the
Microsoft compiler standard">;
def mskip_rax_setup : Flag<["-"], "mskip-rax-setup">, Group,
diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp
b/clang/lib/Driver/ToolChains/CommonArgs.cpp
index 99400ac701fbe..24b12fbf88f6f 100644
--- a/clang/lib/Driver/ToolChains/CommonArgs.cpp
+++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp
@@ -2916,12 +2916,16 @@ void tools::addMachineOutlinerArgs(const Driver &D,
if (Arg *A = Args.getLastArg(options::OPT_moutline,
options::OPT_mno_outline)) {
if (A->getOption().matches(options::OPT_moutline)) {
- // We only support -moutline in AArch64 and ARM targets right now. If
- // we're not compiling for these, emit a warning and ignore the flag.
- // Otherwise, add the proper mllvm flags.
- if (!(Triple.isARM() || Triple.isThumb() || Triple.isAArch64())) {
+ // We only support -moutline in AArch64, ARM, RISC-V and X86 targets
right
+ // now. If we're not compiling for these, emit a warning and ignore the
+ // flag. Otherwise, add the proper mllvm flags.
+ if (!(Triple.isARM() || Triple.isThumb() || Triple.isAArch64() ||
+Triple.isRISCV() || Triple.isX86())) {
D.Diag(diag::warn_drv_moutline_unsupported_opt) <<
Triple.getArchName();
} else {
+// FIXME: This should probably use the `nooutline` attribute rather
than
+// tweaking Pipeline Pass flags, so `-mno-outline` and `-moutline`
+// objects can be combined correctly during LTO.
addArg(Twine("-enable-machine-outliner"));
}
} else {
diff --git a/clang/test/Driver/aarch64-outliner.c
b/clang/test/Driver/aarch64-outliner.c
index c5d28d121513f..5ed822f122fc4 100644
--- a/clang/test/Driver/aarch64-outliner.c
+++ b/clang/test/Driver/aarch64-outliner.c
@@ -4,6 +4,3 @@
// RUN: %clang --target=aarch64 -moutline -mno-outline -S %s -### 2>&1 |
FileCheck %s -check-prefix=OFF
// RUN: %clang --target=aarch64_be -moutline -mno-outline -S %s -### 2>&1 |
FileCheck %s -check-prefix=OFF
// OFF: "-mllvm" "-enable-machine-outliner=never"
-// RUN: %clang --target=x86_64 -moutline -S %s -### 2>&1 | FileCheck %s
-check-prefix=WARN
-// WARN: warning: 'x86_64' does not support '-moutline'; flag ignored
[-Woption-ignored]
-// WARN-NOT: "-mllvm" "-enable-machine-outliner"
diff --git a/clang/test/Driver/riscv-outliner.c
b/clang/test/Driver/riscv-outliner.c
new file mode 100644
index 0..9e9905ab4fd8a
--- /dev/null
+++ b/clang/test/Driver/riscv-outliner.c
@@ -0,0 +1,7 @@
+// RUN: %clang --target=riscv32 -moutline -S %s -### 2>&1 | FileCheck %s
-check-prefix=ON
+// RUN: %clang --target=riscv64 -moutline -S %s -### 2>&1
[llvm-branch-commits] [Clang] Implement constexpr evaluation for __builtin_infer_alloc_token() (PR #163639)
https://github.com/melver edited https://github.com/llvm/llvm-project/pull/163639 ___ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [llvm] [Clang][CodeGen] Implement code generation for __builtin_infer_alloc_token() (PR #156842)
https://github.com/melver edited https://github.com/llvm/llvm-project/pull/156842 ___ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [Clang] Move AllocToken frontend options to LangOptions (PR #163635)
llvmbot wrote:
@llvm/pr-subscribers-clang-codegen
Author: Marco Elver (melver)
Changes
Move the `AllocTokenMax` from `CodeGenOptions` and introduces a new
`AllocTokenMode` to `LangOptions`. Note, `-falloc-token-mode=`
deliberately remains an internal experimental option.
This refactoring is necessary because these options influence frontend
behavior, specifically constexpr evaluation of `__builtin_infer_alloc_token`.
Placing them in `LangOptions` makes them accessible during semantic analysis
frontend, which occurs before codegen.
---
This change is part of the following series:
1. https://github.com/llvm/llvm-project/pull/163632
2. https://github.com/llvm/llvm-project/pull/163633
3. https://github.com/llvm/llvm-project/pull/163634
4. https://github.com/llvm/llvm-project/pull/163635
5. https://github.com/llvm/llvm-project/pull/163636
6. https://github.com/llvm/llvm-project/pull/163638
7. https://github.com/llvm/llvm-project/pull/163639
8. https://github.com/llvm/llvm-project/pull/156842
---
Full diff: https://github.com/llvm/llvm-project/pull/163635.diff
7 Files Affected:
- (modified) clang/docs/AllocToken.rst (+2-2)
- (modified) clang/include/clang/Basic/CodeGenOptions.h (-4)
- (modified) clang/include/clang/Basic/LangOptions.h (+8)
- (modified) clang/include/clang/Driver/Options.td (+4)
- (modified) clang/lib/CodeGen/BackendUtil.cpp (+6-3)
- (modified) clang/lib/Frontend/CompilerInvocation.cpp (+47-13)
- (modified) clang/test/Driver/fsanitize-alloc-token.c (+11)
``diff
diff --git a/clang/docs/AllocToken.rst b/clang/docs/AllocToken.rst
index bda84669456ce..b65e18ccfa967 100644
--- a/clang/docs/AllocToken.rst
+++ b/clang/docs/AllocToken.rst
@@ -37,8 +37,8 @@ The default mode to calculate tokens is:
pointers.
Other token ID assignment modes are supported, but they may be subject to
-change or removal. These may (experimentally) be selected with ``-mllvm
--alloc-token-mode=``:
+change or removal. These may (experimentally) be selected with ``-Xclang
+-falloc-token-mode=``:
* ``typehash``: This mode assigns a token ID based on the hash of the allocated
type's name.
diff --git a/clang/include/clang/Basic/CodeGenOptions.h
b/clang/include/clang/Basic/CodeGenOptions.h
index cae06c3c9495a..5d5cf250b56b9 100644
--- a/clang/include/clang/Basic/CodeGenOptions.h
+++ b/clang/include/clang/Basic/CodeGenOptions.h
@@ -447,10 +447,6 @@ class CodeGenOptions : public CodeGenOptionsBase {
std::optional AllowRuntimeCheckSkipHotCutoff;
- /// Maximum number of allocation tokens (0 = no max), nullopt if none set
(use
- /// pass default).
- std::optional AllocTokenMax;
-
/// List of backend command-line options for -fembed-bitcode.
std::vector CmdArgs;
diff --git a/clang/include/clang/Basic/LangOptions.h
b/clang/include/clang/Basic/LangOptions.h
index 41595ec2a060d..83becb73076f9 100644
--- a/clang/include/clang/Basic/LangOptions.h
+++ b/clang/include/clang/Basic/LangOptions.h
@@ -25,6 +25,7 @@
#include "llvm/ADT/FloatingPointMode.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/BinaryFormat/DXContainer.h"
+#include "llvm/Support/AllocToken.h"
#include "llvm/TargetParser/Triple.h"
#include
#include
@@ -565,6 +566,13 @@ class LangOptions : public LangOptionsBase {
bool AtomicFineGrainedMemory = false;
bool AtomicIgnoreDenormalMode = false;
+ /// Maximum number of allocation tokens (0 = no max), nullopt if none set
(use
+ /// target default).
+ std::optional AllocTokenMax;
+
+ /// The allocation token mode.
+ std::optional AllocTokenMode;
+
LangOptions();
/// Set language defaults for the given input language and
diff --git a/clang/include/clang/Driver/Options.td
b/clang/include/clang/Driver/Options.td
index 611b68e5281f0..370fedd545fec 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -2751,6 +2751,10 @@ def falloc_token_max_EQ : Joined<["-"],
"falloc-token-max=">,
MetaVarName<"">,
HelpText<"Limit to maximum N allocation tokens (0 = no max)">;
+def falloc_token_mode_EQ : Joined<["-"], "falloc-token-mode=">,
+ Group, Visibility<[CC1Option]>,
+ HelpText<"Set the allocation token mode (experimental)">;
+
def fallow_runtime_check_skip_hot_cutoff_EQ
: Joined<["-"], "fallow-runtime-check-skip-hot-cutoff=">,
Group,
diff --git a/clang/lib/CodeGen/BackendUtil.cpp
b/clang/lib/CodeGen/BackendUtil.cpp
index f8e8086afc36f..23ad11ac9f792 100644
--- a/clang/lib/CodeGen/BackendUtil.cpp
+++ b/clang/lib/CodeGen/BackendUtil.cpp
@@ -234,9 +234,12 @@ class EmitAssemblyHelper {
};
} // namespace
-static AllocTokenOptions getAllocTokenOptions(const CodeGenOptions &CGOpts) {
+static AllocTokenOptions getAllocTokenOptions(const LangOptions &LangOpts,
+ const CodeGenOptions &CGOpts) {
AllocTokenOptions Opts;
- Opts.MaxTokens = CGOpts.AllocTokenMax;
+ if (LangOpts.AllocTokenMode)
+Opts.Mode = *LangOpts.AllocTokenMode;
+ Opts.MaxTok
[llvm-branch-commits] [Clang] Implement constexpr evaluation for __builtin_infer_alloc_token() (PR #163639)
https://github.com/melver ready_for_review https://github.com/llvm/llvm-project/pull/163639 ___ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [NFC][Asan] Make GetTLSFakeStack static (PR #163669)
llvmbot wrote:
@llvm/pr-subscribers-compiler-rt-sanitizer
Author: Vitaly Buka (vitalybuka)
Changes
---
Full diff: https://github.com/llvm/llvm-project/pull/163669.diff
2 Files Affected:
- (modified) compiler-rt/lib/asan/asan_fake_stack.cpp (+2-2)
- (modified) compiler-rt/lib/asan/asan_fake_stack.h (-1)
``diff
diff --git a/compiler-rt/lib/asan/asan_fake_stack.cpp
b/compiler-rt/lib/asan/asan_fake_stack.cpp
index f2f6769520ae8..5034ea2a0e459 100644
--- a/compiler-rt/lib/asan/asan_fake_stack.cpp
+++ b/compiler-rt/lib/asan/asan_fake_stack.cpp
@@ -216,10 +216,10 @@ void FakeStack::ForEachFakeFrame(RangeIteratorCallback
callback, void* arg) {
#if (SANITIZER_LINUX && !SANITIZER_ANDROID) || SANITIZER_FUCHSIA
static THREADLOCAL FakeStack* fake_stack_tls;
-FakeStack* GetTLSFakeStack() { return fake_stack_tls; }
+static FakeStack* GetTLSFakeStack() { return fake_stack_tls; }
void SetTLSFakeStack(FakeStack* fs) { fake_stack_tls = fs; }
#else
-FakeStack* GetTLSFakeStack() { return 0; }
+static FakeStack* GetTLSFakeStack() { return nullptr; }
void SetTLSFakeStack(FakeStack* fs) {}
#endif // (SANITIZER_LINUX && !SANITIZER_ANDROID) || SANITIZER_FUCHSIA
diff --git a/compiler-rt/lib/asan/asan_fake_stack.h
b/compiler-rt/lib/asan/asan_fake_stack.h
index 50706e6e5876c..ec772c3299f00 100644
--- a/compiler-rt/lib/asan/asan_fake_stack.h
+++ b/compiler-rt/lib/asan/asan_fake_stack.h
@@ -195,7 +195,6 @@ class FakeStack {
void *true_start;
};
-FakeStack *GetTLSFakeStack();
void SetTLSFakeStack(FakeStack *fs);
} // namespace __asan
``
https://github.com/llvm/llvm-project/pull/163669
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [NFC][Asan] Make GetTLSFakeStack static (PR #163669)
https://github.com/vitalybuka created https://github.com/llvm/llvm-project/pull/163669 None ___ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [asan] Hide SetTLSFakeStack as static function of cpp (PR #163674)
https://github.com/vitalybuka edited https://github.com/llvm/llvm-project/pull/163674 ___ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [lld] bd9bc53 - [LLD] [COFF] Fix aarch64 delayimport of sret arguments (#163096)
Author: Martin Storsjö
Date: 2025-10-15T09:31:19Z
New Revision: bd9bc536b4ac7147142d1fc21915c4e6868f7d15
URL:
https://github.com/llvm/llvm-project/commit/bd9bc536b4ac7147142d1fc21915c4e6868f7d15
DIFF:
https://github.com/llvm/llvm-project/commit/bd9bc536b4ac7147142d1fc21915c4e6868f7d15.diff
LOG: [LLD] [COFF] Fix aarch64 delayimport of sret arguments (#163096)
For sret arguments on aarch64, the x8 register is used as input
parameter to functions, even though x8 normally isn't an input parameter
register.
When delayloading a DLL, the first call of a delayloaded function ends
up calling a helper which resolves the function. Therefore, any input
arguments to the actual function to be called need to be backed up and
restored - this also includes x8.
This matches how MS link.exe also changed its delayloading trampoline,
between MSVC 2019 16.7 and 16.8 (between link.exe 14.27.29110.0 and
14.28.29333.0).
This fixes running LLDB on aarch64 mingw, after
ec28b95b7491bc2fbb6ec66cdbfd939e71255c42 and
93d326038959fd87fb666a8bf97d774d0abb3591. Those commits make LLDB load
liblldb.dll with delayloading, and the first function to be called,
SBDebugger::InitializeWithErrorHandling(), returns an SBError, which in
the itanium C++ ABI is returned as an sret via a pointer in x8.
(cherry picked from commit 7e690517bceea62a6b9c7e05622fb48bb6316efc)
Added:
Modified:
lld/COFF/DLL.cpp
lld/test/COFF/arm64-delayimport.yaml
lld/test/COFF/arm64x-delayimport.test
Removed:
Unicorn! · GitHub
body {
background-color: #f6f8fa;
color: #24292e;
font-family: -apple-system,BlinkMacSystemFont,Segoe
UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol;
font-size: 14px;
line-height: 1.5;
margin: 0;
}
.container { margin: 50px auto; max-width: 600px; text-align: center;
padding: 0 24px; }
a { color: #4183c4; text-decoration: none; }
a:hover { text-decoration: underline; }
h1 { letter-spacing: -1px; line-height: 60px; font-size: 60px;
font-weight: 100; margin: 0px; text-shadow: 0 1px 0 #fff; }
p { color: rgba(0, 0, 0, 0.5); margin: 10px 0 10px; font-size: 18px;
font-weight: 200; line-height: 1.6em;}
ul { list-style: none; margin: 25px 0; padding: 0; }
li { display: table-cell; font-weight: bold; width: 1%; }
.logo { display: inline-block; margin-top: 35px; }
.logo-img-2x { display: none; }
@media
only screen and (-webkit-min-device-pixel-ratio: 2),
only screen and ( min--moz-device-pixel-ratio: 2),
only screen and ( -o-min-device-pixel-ratio: 2/1),
only screen and (min-device-pixel-ratio: 2),
only screen and (min-resolution: 192dpi),
only screen and (min-resolution: 2dppx) {
.logo-img-1x { display: none; }
.logo-img-2x { display: inline-block; }
}
#suggestions {
margin-top: 35px;
color: #ccc;
}
#suggestions a {
color: #66;
font-weight: 200;
font-size: 14px;
margin: 0 10px;
}
We're having a really bad day.
The Unicorns have taken over. We're doing our best to get them under
control and get GitHub back up and running.
https://support.github.com/contact";>Contact Support —
https://githubstatus.com";>GitHub Status —
https://twitter.com/githubstatus";>@githubstatus
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Ensure -mno-outline adds attributes (PR #163692)
llvmbot wrote:
@llvm/pr-subscribers-clang-driver
Author: Sam Elliott (lenary)
Changes
Before this change, `-mno-outline` and `-moutline` only controlled the
pass pipelines for the invoked compiler/linker.
The drawback of this implementation is that, when using LTO, only the
flag provided to the linker invocation is honoured (and any files which
individually use `-mno-outline` will have that flag ignored).
This change serialises the `-mno-outline` flag into each function's
IR/Bitcode, so that we can correctly disable outlining from functions in
files which disabled outlining, without affecting outlining choices for
functions from other files. This matches how other optimisation flags
are handled so the IR/Bitcode can be correctly merged during LTO.
---
Full diff: https://github.com/llvm/llvm-project/pull/163692.diff
9 Files Affected:
- (modified) clang/include/clang/Basic/CodeGenOptions.def (+3)
- (modified) clang/include/clang/Driver/Options.td (+7-10)
- (modified) clang/lib/CodeGen/CodeGenModule.cpp (+3-1)
- (modified) clang/lib/Driver/ToolChains/CommonArgs.cpp (+7-4)
- (modified) clang/test/CodeGen/attr-nooutline.c (+7-3)
- (modified) clang/test/Driver/aarch64-outliner.c (+1-1)
- (modified) clang/test/Driver/arm-machine-outliner.c (+1-1)
- (modified) clang/test/Driver/riscv-outliner.c (+1-1)
- (modified) clang/test/Driver/x86-outliner.c (+1-1)
``diff
diff --git a/clang/include/clang/Basic/CodeGenOptions.def
b/clang/include/clang/Basic/CodeGenOptions.def
index 90e1f8d1eb5e9..4ccb75ebf904b 100644
--- a/clang/include/clang/Basic/CodeGenOptions.def
+++ b/clang/include/clang/Basic/CodeGenOptions.def
@@ -489,6 +489,9 @@ CODEGENOPT(ResMayAlias, 1, 0, Benign)
ENUM_CODEGENOPT(WinX64EHUnwindV2, WinX64EHUnwindV2Mode,
2, WinX64EHUnwindV2Mode::Disabled, Benign)
+/// Adds attributes that prevent outlining (`-mno-outline`)
+CODEGENOPT(DisableOutlining, 1, 0, Benign)
+
/// FIXME: Make DebugOptions its own top-level .def file.
#include "DebugOptions.def"
diff --git a/clang/include/clang/Driver/Options.td
b/clang/include/clang/Driver/Options.td
index d62b771f463ea..729be4f09c034 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -5127,16 +5127,13 @@ def mms_bitfields : Flag<["-"], "mms-bitfields">,
Group,
Visibility<[ClangOption, CC1Option]>,
HelpText<"Set the default structure layout to be compatible with the
Microsoft compiler standard">,
MarshallingInfoFlag>;
-def moutline
-: Flag<["-"], "moutline">,
- Group,
- Visibility<[ClangOption, CC1Option]>,
- HelpText<"Enable function outlining (AArch64,Arm,RISC-V,X86 only)">;
-def mno_outline
-: Flag<["-"], "mno-outline">,
- Group,
- Visibility<[ClangOption, CC1Option]>,
- HelpText<"Disable function outlining (AArch64,Arm,RISC-V,X86 only)">;
+defm outline
+: BoolMOption<
+ "outline", CodeGenOpts<"DisableOutlining">, DefaultFalse,
+ NegFlag,
+ PosFlag>;
def mno_ms_bitfields : Flag<["-"], "mno-ms-bitfields">, Group,
HelpText<"Do not set the default structure layout to be compatible with the
Microsoft compiler standard">;
def mskip_rax_setup : Flag<["-"], "mskip-rax-setup">, Group,
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp
b/clang/lib/CodeGen/CodeGenModule.cpp
index ab267236ed579..ca3ef780d2853 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -2820,7 +2820,9 @@ void
CodeGenModule::SetLLVMFunctionAttributesForDefinition(const Decl *D,
B.addAttribute(llvm::Attribute::MinSize);
}
- if (D->hasAttr())
+ // Add `nooutline` if Outlining is disabled with a command-line flag or a
+ // function attribute.
+ if (CodeGenOpts.DisableOutlining || D->hasAttr())
B.addAttribute(llvm::Attribute::NoOutline);
F->addFnAttrs(B);
diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp
b/clang/lib/Driver/ToolChains/CommonArgs.cpp
index 24b12fbf88f6f..a03b34ffb5d50 100644
--- a/clang/lib/Driver/ToolChains/CommonArgs.cpp
+++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp
@@ -2923,13 +2923,16 @@ void tools::addMachineOutlinerArgs(const Driver &D,
Triple.isRISCV() || Triple.isX86())) {
D.Diag(diag::warn_drv_moutline_unsupported_opt) <<
Triple.getArchName();
} else {
-// FIXME: This should probably use the `nooutline` attribute rather
than
-// tweaking Pipeline Pass flags, so `-mno-outline` and `-moutline`
-// objects can be combined correctly during LTO.
+// Enable Pass in pipeline
addArg(Twine("-enable-machine-outliner"));
}
} else {
- // Disable all outlining behaviour.
+ if (!IsLTO)
+// Disable all outlining behaviour using `nooutline` option, in case
+// Linker Invocation lacks `-mno-outline`.
+CmdArgs.push_back("-mno-outline");
+
+ // Disable Pass in Pipeline
addArg(Twine("-enable-machine-outliner=never"));
