[llvm-branch-commits] [clang] release/21.x: [clang] Fix catching pointers by reference on mingw targets (#162546) (PR #163714)

2025-10-15 Thread via llvm-branch-commits

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)

2025-10-15 Thread via llvm-branch-commits

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)

2025-10-15 Thread Gergely Bálint via llvm-branch-commits

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)

2025-10-15 Thread Helena Kotas via llvm-branch-commits


@@ -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)

2025-10-15 Thread Andrzej Warzyński via llvm-branch-commits

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)

2025-10-15 Thread via llvm-branch-commits

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)

2025-10-15 Thread Mircea Trofin via llvm-branch-commits

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)

2025-10-15 Thread Jan Voung via llvm-branch-commits


@@ -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)

2025-10-15 Thread Jan Voung via llvm-branch-commits


@@ -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)

2025-10-15 Thread Mircea Trofin via llvm-branch-commits


@@ -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)

2025-10-15 Thread Mircea Trofin via llvm-branch-commits


@@ -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)

2025-10-15 Thread via llvm-branch-commits

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)

2025-10-15 Thread via llvm-branch-commits

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)

2025-10-15 Thread Florian Mayer via llvm-branch-commits

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)

2025-10-15 Thread Jan Voung via llvm-branch-commits

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)

2025-10-15 Thread Sam Elliott via llvm-branch-commits

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)

2025-10-15 Thread Marco Elver via llvm-branch-commits

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)

2025-10-15 Thread Marco Elver via llvm-branch-commits

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)

2025-10-15 Thread via llvm-branch-commits

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)

2025-10-15 Thread Marco Elver via llvm-branch-commits

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)

2025-10-15 Thread via llvm-branch-commits

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)

2025-10-15 Thread Vitaly Buka via llvm-branch-commits

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)

2025-10-15 Thread Vitaly Buka via llvm-branch-commits

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)

2025-10-15 Thread Cullen Rhodes via llvm-branch-commits

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)

2025-10-15 Thread via llvm-branch-commits

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"));