[llvm-branch-commits] [llvm] dde78a2 - Revert "Revert "[X86] combineBROADCAST_LOAD - merge across chains" (#128380)"

2025-02-22 Thread via llvm-branch-commits

Author: Vitaly Buka
Date: 2025-02-22T16:15:48-08:00
New Revision: dde78a2e84edc0fe987266a7fcae774dd36532c3

URL: 
https://github.com/llvm/llvm-project/commit/dde78a2e84edc0fe987266a7fcae774dd36532c3
DIFF: 
https://github.com/llvm/llvm-project/commit/dde78a2e84edc0fe987266a7fcae774dd36532c3.diff

LOG: Revert "Revert "[X86] combineBROADCAST_LOAD - merge across chains" 
(#128380)"

This reverts commit 50b0669e8468279518ae0be27c8b6a134c4d95d1.

Added: 


Modified: 
llvm/lib/Target/X86/X86ISelLowering.cpp
llvm/test/CodeGen/X86/any_extend_vector_inreg_of_broadcast_from_memory.ll
llvm/test/CodeGen/X86/zero_extend_vector_inreg_of_broadcast_from_memory.ll

Removed: 




diff  --git a/llvm/lib/Target/X86/X86ISelLowering.cpp 
b/llvm/lib/Target/X86/X86ISelLowering.cpp
index 2bc76d3814792..a4357197e2843 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -59360,21 +59360,14 @@ static SDValue combineFP_EXTEND(SDNode *N, 
SelectionDAG &DAG,
   return DAG.getNode(ISD::FP_EXTEND, dl, VT, Cvt);
 }
 
-// Try to find a larger VBROADCAST_LOAD/SUBV_BROADCAST_LOAD that we can extract
-// from. Limit this to cases where the loads have the same input chain and the
-// output chains are unused. This avoids any memory ordering issues.
+// Try to find a larger VBROADCAST_LOAD/SUBV_BROADCAST_LOAD that we can 
extract.
 static SDValue combineBROADCAST_LOAD(SDNode *N, SelectionDAG &DAG,
  TargetLowering::DAGCombinerInfo &DCI) {
   assert((N->getOpcode() == X86ISD::VBROADCAST_LOAD ||
   N->getOpcode() == X86ISD::SUBV_BROADCAST_LOAD) &&
  "Unknown broadcast load type");
 
-  // Only do this if the chain result is unused.
-  if (N->hasAnyUseOfValue(1))
-return SDValue();
-
   auto *MemIntrin = cast(N);
-
   SDValue Ptr = MemIntrin->getBasePtr();
   SDValue Chain = MemIntrin->getChain();
   EVT VT = N->getSimpleValueType(0);
@@ -59388,12 +59381,15 @@ static SDValue combineBROADCAST_LOAD(SDNode *N, 
SelectionDAG &DAG,
 cast(User)->getChain() == Chain &&
 cast(User)->getMemoryVT().getSizeInBits() ==
 MemVT.getSizeInBits() &&
-!User->hasAnyUseOfValue(1) &&
 User->getValueSizeInBits(0).getFixedValue() > VT.getFixedSizeInBits()) 
{
+  assert(cast(User)->isSimple() &&
+ MemIntrin->isSimple() && "Illegal broadcast load type");
   SDValue Extract = extractSubVector(SDValue(User, 0), 0, DAG, SDLoc(N),
  VT.getSizeInBits());
   Extract = DAG.getBitcast(VT, Extract);
-  return DCI.CombineTo(N, Extract, SDValue(User, 1));
+  Extract = DCI.CombineTo(N, Extract, SDValue(User, 1));
+  DAG.makeEquivalentMemoryOrdering(SDValue(N, 1), Extract.getValue(1));
+  return Extract;
 }
 
   return SDValue();

diff  --git 
a/llvm/test/CodeGen/X86/any_extend_vector_inreg_of_broadcast_from_memory.ll 
b/llvm/test/CodeGen/X86/any_extend_vector_inreg_of_broadcast_from_memory.ll
index d617cfb6aedee..ca589e63b671a 100644
--- a/llvm/test/CodeGen/X86/any_extend_vector_inreg_of_broadcast_from_memory.ll
+++ b/llvm/test/CodeGen/X86/any_extend_vector_inreg_of_broadcast_from_memory.ll
@@ -1888,15 +1888,14 @@ define void 
@vec384_i8_widen_to_i16_factor2_broadcast_to_v24i16_factor24(ptr %in
 ;
 ; AVX2-LABEL: vec384_i8_widen_to_i16_factor2_broadcast_to_v24i16_factor24:
 ; AVX2:   # %bb.0:
-; AVX2-NEXT:vpbroadcastb (%rdi), %xmm0
-; AVX2-NEXT:vmovdqa 48(%rdi), %xmm1
-; AVX2-NEXT:vpshufb {{.*#+}} xmm1 = 
xmm1[1,3,5,7,9,11,13,15,u,u,u,u,u,u,u,u]
-; AVX2-NEXT:vpbroadcastb (%rdi), %ymm2
-; AVX2-NEXT:vpunpcklbw {{.*#+}} ymm1 = 
ymm2[0],ymm1[0],ymm2[1],ymm1[1],ymm2[2],ymm1[2],ymm2[3],ymm1[3],ymm2[4],ymm1[4],ymm2[5],ymm1[5],ymm2[6],ymm1[6],ymm2[7],ymm1[7],ymm2[16],ymm1[16],ymm2[17],ymm1[17],ymm2[18],ymm1[18],ymm2[19],ymm1[19],ymm2[20],ymm1[20],ymm2[21],ymm1[21],ymm2[22],ymm1[22],ymm2[23],ymm1[23]
-; AVX2-NEXT:vpaddb (%rsi), %ymm1, %ymm1
-; AVX2-NEXT:vpaddb 32(%rsi), %ymm0, %ymm0
-; AVX2-NEXT:vmovdqa %ymm0, 32(%rdx)
-; AVX2-NEXT:vmovdqa %ymm1, (%rdx)
+; AVX2-NEXT:vmovdqa 48(%rdi), %xmm0
+; AVX2-NEXT:vpshufb {{.*#+}} xmm0 = 
xmm0[1,3,5,7,9,11,13,15,u,u,u,u,u,u,u,u]
+; AVX2-NEXT:vpbroadcastb (%rdi), %ymm1
+; AVX2-NEXT:vpunpcklbw {{.*#+}} ymm0 = 
ymm1[0],ymm0[0],ymm1[1],ymm0[1],ymm1[2],ymm0[2],ymm1[3],ymm0[3],ymm1[4],ymm0[4],ymm1[5],ymm0[5],ymm1[6],ymm0[6],ymm1[7],ymm0[7],ymm1[16],ymm0[16],ymm1[17],ymm0[17],ymm1[18],ymm0[18],ymm1[19],ymm0[19],ymm1[20],ymm0[20],ymm1[21],ymm0[21],ymm1[22],ymm0[22],ymm1[23],ymm0[23]
+; AVX2-NEXT:vpaddb (%rsi), %ymm0, %ymm0
+; AVX2-NEXT:vpaddb 32(%rsi), %ymm1, %ymm1
+; AVX2-NEXT:vmovdqa %ymm1, 32(%rdx)
+; AVX2-NEXT:vmovdqa %ymm0, (%rdx)
 ; AVX2-NEXT:vzeroupper
 ; AVX2-NEXT:retq
 ;
@@ -2112,15 +2111,14 @@ define void 
@vec384_i8_widen_to_i32_factor4_broadcast_t

[llvm-branch-commits] [llvm] 1aacd31 - Revert "[X86] combineBROADCAST_LOAD - merge across chains (#128209)"

2025-02-22 Thread via llvm-branch-commits

Author: Vitaly Buka
Date: 2025-02-22T16:02:11-08:00
New Revision: 1aacd3108d3fb66c1f2483e973b52a97006eba9b

URL: 
https://github.com/llvm/llvm-project/commit/1aacd3108d3fb66c1f2483e973b52a97006eba9b
DIFF: 
https://github.com/llvm/llvm-project/commit/1aacd3108d3fb66c1f2483e973b52a97006eba9b.diff

LOG: Revert "[X86] combineBROADCAST_LOAD - merge across chains (#128209)"

This reverts commit e21a1737f3523488a04169096fa27d0914a142a7.

Added: 


Modified: 
llvm/lib/Target/X86/X86ISelLowering.cpp
llvm/test/CodeGen/X86/any_extend_vector_inreg_of_broadcast_from_memory.ll
llvm/test/CodeGen/X86/zero_extend_vector_inreg_of_broadcast_from_memory.ll

Removed: 




diff  --git a/llvm/lib/Target/X86/X86ISelLowering.cpp 
b/llvm/lib/Target/X86/X86ISelLowering.cpp
index a4357197e2843..2bc76d3814792 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -59360,14 +59360,21 @@ static SDValue combineFP_EXTEND(SDNode *N, 
SelectionDAG &DAG,
   return DAG.getNode(ISD::FP_EXTEND, dl, VT, Cvt);
 }
 
-// Try to find a larger VBROADCAST_LOAD/SUBV_BROADCAST_LOAD that we can 
extract.
+// Try to find a larger VBROADCAST_LOAD/SUBV_BROADCAST_LOAD that we can extract
+// from. Limit this to cases where the loads have the same input chain and the
+// output chains are unused. This avoids any memory ordering issues.
 static SDValue combineBROADCAST_LOAD(SDNode *N, SelectionDAG &DAG,
  TargetLowering::DAGCombinerInfo &DCI) {
   assert((N->getOpcode() == X86ISD::VBROADCAST_LOAD ||
   N->getOpcode() == X86ISD::SUBV_BROADCAST_LOAD) &&
  "Unknown broadcast load type");
 
+  // Only do this if the chain result is unused.
+  if (N->hasAnyUseOfValue(1))
+return SDValue();
+
   auto *MemIntrin = cast(N);
+
   SDValue Ptr = MemIntrin->getBasePtr();
   SDValue Chain = MemIntrin->getChain();
   EVT VT = N->getSimpleValueType(0);
@@ -59381,15 +59388,12 @@ static SDValue combineBROADCAST_LOAD(SDNode *N, 
SelectionDAG &DAG,
 cast(User)->getChain() == Chain &&
 cast(User)->getMemoryVT().getSizeInBits() ==
 MemVT.getSizeInBits() &&
+!User->hasAnyUseOfValue(1) &&
 User->getValueSizeInBits(0).getFixedValue() > VT.getFixedSizeInBits()) 
{
-  assert(cast(User)->isSimple() &&
- MemIntrin->isSimple() && "Illegal broadcast load type");
   SDValue Extract = extractSubVector(SDValue(User, 0), 0, DAG, SDLoc(N),
  VT.getSizeInBits());
   Extract = DAG.getBitcast(VT, Extract);
-  Extract = DCI.CombineTo(N, Extract, SDValue(User, 1));
-  DAG.makeEquivalentMemoryOrdering(SDValue(N, 1), Extract.getValue(1));
-  return Extract;
+  return DCI.CombineTo(N, Extract, SDValue(User, 1));
 }
 
   return SDValue();

diff  --git 
a/llvm/test/CodeGen/X86/any_extend_vector_inreg_of_broadcast_from_memory.ll 
b/llvm/test/CodeGen/X86/any_extend_vector_inreg_of_broadcast_from_memory.ll
index ca589e63b671a..d617cfb6aedee 100644
--- a/llvm/test/CodeGen/X86/any_extend_vector_inreg_of_broadcast_from_memory.ll
+++ b/llvm/test/CodeGen/X86/any_extend_vector_inreg_of_broadcast_from_memory.ll
@@ -1888,14 +1888,15 @@ define void 
@vec384_i8_widen_to_i16_factor2_broadcast_to_v24i16_factor24(ptr %in
 ;
 ; AVX2-LABEL: vec384_i8_widen_to_i16_factor2_broadcast_to_v24i16_factor24:
 ; AVX2:   # %bb.0:
-; AVX2-NEXT:vmovdqa 48(%rdi), %xmm0
-; AVX2-NEXT:vpshufb {{.*#+}} xmm0 = 
xmm0[1,3,5,7,9,11,13,15,u,u,u,u,u,u,u,u]
-; AVX2-NEXT:vpbroadcastb (%rdi), %ymm1
-; AVX2-NEXT:vpunpcklbw {{.*#+}} ymm0 = 
ymm1[0],ymm0[0],ymm1[1],ymm0[1],ymm1[2],ymm0[2],ymm1[3],ymm0[3],ymm1[4],ymm0[4],ymm1[5],ymm0[5],ymm1[6],ymm0[6],ymm1[7],ymm0[7],ymm1[16],ymm0[16],ymm1[17],ymm0[17],ymm1[18],ymm0[18],ymm1[19],ymm0[19],ymm1[20],ymm0[20],ymm1[21],ymm0[21],ymm1[22],ymm0[22],ymm1[23],ymm0[23]
-; AVX2-NEXT:vpaddb (%rsi), %ymm0, %ymm0
-; AVX2-NEXT:vpaddb 32(%rsi), %ymm1, %ymm1
-; AVX2-NEXT:vmovdqa %ymm1, 32(%rdx)
-; AVX2-NEXT:vmovdqa %ymm0, (%rdx)
+; AVX2-NEXT:vpbroadcastb (%rdi), %xmm0
+; AVX2-NEXT:vmovdqa 48(%rdi), %xmm1
+; AVX2-NEXT:vpshufb {{.*#+}} xmm1 = 
xmm1[1,3,5,7,9,11,13,15,u,u,u,u,u,u,u,u]
+; AVX2-NEXT:vpbroadcastb (%rdi), %ymm2
+; AVX2-NEXT:vpunpcklbw {{.*#+}} ymm1 = 
ymm2[0],ymm1[0],ymm2[1],ymm1[1],ymm2[2],ymm1[2],ymm2[3],ymm1[3],ymm2[4],ymm1[4],ymm2[5],ymm1[5],ymm2[6],ymm1[6],ymm2[7],ymm1[7],ymm2[16],ymm1[16],ymm2[17],ymm1[17],ymm2[18],ymm1[18],ymm2[19],ymm1[19],ymm2[20],ymm1[20],ymm2[21],ymm1[21],ymm2[22],ymm1[22],ymm2[23],ymm1[23]
+; AVX2-NEXT:vpaddb (%rsi), %ymm1, %ymm1
+; AVX2-NEXT:vpaddb 32(%rsi), %ymm0, %ymm0
+; AVX2-NEXT:vmovdqa %ymm0, 32(%rdx)
+; AVX2-NEXT:vmovdqa %ymm1, (%rdx)
 ; AVX2-NEXT:vzeroupper
 ; AVX2-NEXT:retq
 ;
@@ -2111,14 +2112,15 @@ define void 
@vec384_i8_widen_to_i32_factor4_broadcast_to_v12i32_f

[llvm-branch-commits] [clang] [clang][NFC] Remove CXXRecordDecl::lookupDependentName() and its helpers (PR #128392)

2025-02-22 Thread Nathan Ridge via llvm-branch-commits

https://github.com/HighCommander4 created 
https://github.com/llvm/llvm-project/pull/128392

This function has been superseded by HeuristicResolver::lookupDependentName(), 
which implements the same heuristics and more.

Porting note for any out-of-tree callers:

```
RD->lookupDependentName(Name, Filter);
```

can be replaced with:

```
HeuristicResolver(RD->getASTContext())->lookupDependentName(Name, Filter);
```

>From 4bb5f832edc9370e3d782427db8cd51b8ffdc835 Mon Sep 17 00:00:00 2001
From: Nathan Ridge 
Date: Sat, 22 Feb 2025 22:48:03 -0500
Subject: [PATCH] [clang][NFC] Remove CXXRecordDecl::lookupDependentName() and
 its helpers

This function has been superseded by HeuristicResolver::lookupDependentName(),
which implements the same heuristics and more.

Porting note for any out-of-tree callers:

```
RD->lookupDependentName(Name, Filter);
```

can be replaced with:

```
HeuristicResolver(RD->getASTContext())->lookupDependentName(Name, Filter);
```
---
 clang/include/clang/AST/DeclCXX.h |  8 -
 clang/lib/AST/CXXInheritance.cpp  | 53 ---
 2 files changed, 61 deletions(-)

diff --git a/clang/include/clang/AST/DeclCXX.h 
b/clang/include/clang/AST/DeclCXX.h
index 266b93a64a390..dbd02ef7f8011 100644
--- a/clang/include/clang/AST/DeclCXX.h
+++ b/clang/include/clang/AST/DeclCXX.h
@@ -1720,14 +1720,6 @@ class CXXRecordDecl : public RecordDecl {
   /// static analysis, or similar.
   bool hasMemberName(DeclarationName N) const;
 
-  /// Performs an imprecise lookup of a dependent name in this class.
-  ///
-  /// This function does not follow strict semantic rules and should be used
-  /// only when lookup rules can be relaxed, e.g. indexing.
-  std::vector
-  lookupDependentName(DeclarationName Name,
-  llvm::function_ref Filter);
-
   /// Renders and displays an inheritance diagram
   /// for this C++ class and all of its base classes (transitively) using
   /// GraphViz.
diff --git a/clang/lib/AST/CXXInheritance.cpp b/clang/lib/AST/CXXInheritance.cpp
index ee5775837d535..ab862d57eae89 100644
--- a/clang/lib/AST/CXXInheritance.cpp
+++ b/clang/lib/AST/CXXInheritance.cpp
@@ -411,59 +411,6 @@ bool CXXRecordDecl::hasMemberName(DeclarationName Name) 
const {
   Paths);
 }
 
-static bool
-findOrdinaryMemberInDependentClasses(const CXXBaseSpecifier *Specifier,
- CXXBasePath &Path, DeclarationName Name) {
-  const TemplateSpecializationType *TST =
-  Specifier->getType()->getAs();
-  if (!TST) {
-auto *RT = Specifier->getType()->getAs();
-if (!RT)
-  return false;
-return findOrdinaryMember(cast(RT->getDecl()), Path, Name);
-  }
-  TemplateName TN = TST->getTemplateName();
-  const auto *TD = dyn_cast_or_null(TN.getAsTemplateDecl());
-  if (!TD)
-return false;
-  CXXRecordDecl *RD = TD->getTemplatedDecl();
-  if (!RD)
-return false;
-  return findOrdinaryMember(RD, Path, Name);
-}
-
-std::vector CXXRecordDecl::lookupDependentName(
-DeclarationName Name,
-llvm::function_ref Filter) {
-  std::vector Results;
-  // Lookup in the class.
-  bool AnyOrdinaryMembers = false;
-  for (const NamedDecl *ND : lookup(Name)) {
-if (isOrdinaryMember(ND))
-  AnyOrdinaryMembers = true;
-if (Filter(ND))
-  Results.push_back(ND);
-  }
-  if (AnyOrdinaryMembers)
-return Results;
-
-  // Perform lookup into our base classes.
-  CXXBasePaths Paths;
-  Paths.setOrigin(this);
-  if (!lookupInBases(
-  [&](const CXXBaseSpecifier *Specifier, CXXBasePath &Path) {
-return findOrdinaryMemberInDependentClasses(Specifier, Path, Name);
-  },
-  Paths, /*LookupInDependent=*/true))
-return Results;
-  for (DeclContext::lookup_iterator I = Paths.front().Decls, E = I.end();
-   I != E; ++I) {
-if (isOrdinaryMember(*I) && Filter(*I))
-  Results.push_back(*I);
-  }
-  return Results;
-}
-
 void OverridingMethods::add(unsigned OverriddenSubobject,
 UniqueVirtualMethod Overriding) {
   SmallVectorImpl &SubobjectOverrides

___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [clang] [clang][NFC] Remove CXXRecordDecl::lookupDependentName() and its helpers (PR #128392)

2025-02-22 Thread via llvm-branch-commits

llvmbot wrote:




@llvm/pr-subscribers-clang

Author: Nathan Ridge (HighCommander4)


Changes

This function has been superseded by HeuristicResolver::lookupDependentName(), 
which implements the same heuristics and more.

Porting note for any out-of-tree callers:

```
RD->lookupDependentName(Name, Filter);
```

can be replaced with:

```
HeuristicResolver(RD->getASTContext())->lookupDependentName(Name, Filter);
```

---
Full diff: https://github.com/llvm/llvm-project/pull/128392.diff


2 Files Affected:

- (modified) clang/include/clang/AST/DeclCXX.h (-8) 
- (modified) clang/lib/AST/CXXInheritance.cpp (-53) 


``diff
diff --git a/clang/include/clang/AST/DeclCXX.h 
b/clang/include/clang/AST/DeclCXX.h
index 266b93a64a390..dbd02ef7f8011 100644
--- a/clang/include/clang/AST/DeclCXX.h
+++ b/clang/include/clang/AST/DeclCXX.h
@@ -1720,14 +1720,6 @@ class CXXRecordDecl : public RecordDecl {
   /// static analysis, or similar.
   bool hasMemberName(DeclarationName N) const;
 
-  /// Performs an imprecise lookup of a dependent name in this class.
-  ///
-  /// This function does not follow strict semantic rules and should be used
-  /// only when lookup rules can be relaxed, e.g. indexing.
-  std::vector
-  lookupDependentName(DeclarationName Name,
-  llvm::function_ref Filter);
-
   /// Renders and displays an inheritance diagram
   /// for this C++ class and all of its base classes (transitively) using
   /// GraphViz.
diff --git a/clang/lib/AST/CXXInheritance.cpp b/clang/lib/AST/CXXInheritance.cpp
index ee5775837d535..ab862d57eae89 100644
--- a/clang/lib/AST/CXXInheritance.cpp
+++ b/clang/lib/AST/CXXInheritance.cpp
@@ -411,59 +411,6 @@ bool CXXRecordDecl::hasMemberName(DeclarationName Name) 
const {
   Paths);
 }
 
-static bool
-findOrdinaryMemberInDependentClasses(const CXXBaseSpecifier *Specifier,
- CXXBasePath &Path, DeclarationName Name) {
-  const TemplateSpecializationType *TST =
-  Specifier->getType()->getAs();
-  if (!TST) {
-auto *RT = Specifier->getType()->getAs();
-if (!RT)
-  return false;
-return findOrdinaryMember(cast(RT->getDecl()), Path, Name);
-  }
-  TemplateName TN = TST->getTemplateName();
-  const auto *TD = dyn_cast_or_null(TN.getAsTemplateDecl());
-  if (!TD)
-return false;
-  CXXRecordDecl *RD = TD->getTemplatedDecl();
-  if (!RD)
-return false;
-  return findOrdinaryMember(RD, Path, Name);
-}
-
-std::vector CXXRecordDecl::lookupDependentName(
-DeclarationName Name,
-llvm::function_ref Filter) {
-  std::vector Results;
-  // Lookup in the class.
-  bool AnyOrdinaryMembers = false;
-  for (const NamedDecl *ND : lookup(Name)) {
-if (isOrdinaryMember(ND))
-  AnyOrdinaryMembers = true;
-if (Filter(ND))
-  Results.push_back(ND);
-  }
-  if (AnyOrdinaryMembers)
-return Results;
-
-  // Perform lookup into our base classes.
-  CXXBasePaths Paths;
-  Paths.setOrigin(this);
-  if (!lookupInBases(
-  [&](const CXXBaseSpecifier *Specifier, CXXBasePath &Path) {
-return findOrdinaryMemberInDependentClasses(Specifier, Path, Name);
-  },
-  Paths, /*LookupInDependent=*/true))
-return Results;
-  for (DeclContext::lookup_iterator I = Paths.front().Decls, E = I.end();
-   I != E; ++I) {
-if (isOrdinaryMember(*I) && Filter(*I))
-  Results.push_back(*I);
-  }
-  return Results;
-}
-
 void OverridingMethods::add(unsigned OverriddenSubobject,
 UniqueVirtualMethod Overriding) {
   SmallVectorImpl &SubobjectOverrides

``




https://github.com/llvm/llvm-project/pull/128392
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [clang] [clang][NFC] Remove CXXRecordDecl::lookupDependentName() and its helpers (PR #128392)

2025-02-22 Thread Nathan Ridge via llvm-branch-commits

HighCommander4 wrote:

For reference, the callers of `CXXRecordDecl::lookupDependentName()` have been 
ported over to `HeuristicResolver` over the following series of patches:

https://github.com/llvm/llvm-project/pull/124888
https://github.com/llvm/llvm-project/pull/125153
https://github.com/llvm/llvm-project/pull/128106
https://github.com/llvm/llvm-project/pull/128391

https://github.com/llvm/llvm-project/pull/128392
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [flang] [flang][draft] update fir.coordinate_of to carry the fields (PR #127231)

2025-02-22 Thread Razvan Lupusoru via llvm-branch-commits

razvanlupusoru wrote:

Nice work!

https://github.com/llvm/llvm-project/pull/127231
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] release/20.x: [SLP] Check for PHI nodes (potentially cycles!) when checking dependencies (PR #127294)

2025-02-22 Thread Nikita Popov via llvm-branch-commits

https://github.com/nikic closed https://github.com/llvm/llvm-project/pull/127294
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] RegAllocFast: Fix verifier errors after assigning to reserved registers (PR #128281)

2025-02-22 Thread Matt Arsenault via llvm-branch-commits

https://github.com/arsenm updated 
https://github.com/llvm/llvm-project/pull/128281

>From d93b45487feba452868706b31e6e59e0bb1a5d19 Mon Sep 17 00:00:00 2001
From: Matt Arsenault 
Date: Thu, 12 Dec 2024 10:53:41 +0900
Subject: [PATCH] RegAllocFast: Fix verifier errors after assigning to reserved
 registers

---
 llvm/lib/CodeGen/RegAllocFast.cpp | 41 ---
 ...ut-of-registers-error-all-regs-reserved.ll |  3 +-
 2 files changed, 28 insertions(+), 16 deletions(-)

diff --git a/llvm/lib/CodeGen/RegAllocFast.cpp 
b/llvm/lib/CodeGen/RegAllocFast.cpp
index 14128dafbe4ee..9f92c11826cce 100644
--- a/llvm/lib/CodeGen/RegAllocFast.cpp
+++ b/llvm/lib/CodeGen/RegAllocFast.cpp
@@ -206,6 +206,7 @@ class RegAllocFastImpl {
 bool Error = false;  ///< Could not allocate.
 
 explicit LiveReg(Register VirtReg) : VirtReg(VirtReg) {}
+explicit LiveReg() {}
 
 unsigned getSparseSetIndex() const { return VirtReg.virtRegIndex(); }
   };
@@ -216,7 +217,7 @@ class RegAllocFastImpl {
   LiveRegMap LiveVirtRegs;
 
   /// Stores assigned virtual registers present in the bundle MI.
-  DenseMap BundleVirtRegsMap;
+  DenseMap BundleVirtRegsMap;
 
   DenseMap> LiveDbgValueMap;
   /// List of DBG_VALUE that we encountered without the vreg being assigned
@@ -374,7 +375,8 @@ class RegAllocFastImpl {
 SmallSet &PrologLiveIns) const;
 
   void reloadAtBegin(MachineBasicBlock &MBB);
-  bool setPhysReg(MachineInstr &MI, MachineOperand &MO, MCPhysReg PhysReg);
+  bool setPhysReg(MachineInstr &MI, MachineOperand &MO,
+  const LiveReg &Assignment);
 
   Register traceCopies(Register VirtReg) const;
   Register traceCopyChain(Register Reg) const;
@@ -1005,7 +1007,8 @@ void RegAllocFastImpl::allocVirtRegUndef(MachineOperand 
&MO) {
 MO.setSubReg(0);
   }
   MO.setReg(PhysReg);
-  MO.setIsRenamable(true);
+  if (!LRI->Error)
+MO.setIsRenamable(true);
 }
 
 /// Variation of defineVirtReg() with special handling for livethrough regs
@@ -1109,10 +1112,10 @@ bool RegAllocFastImpl::defineVirtReg(MachineInstr &MI, 
unsigned OpNum,
 LRI->Reloaded = false;
   }
   if (MI.getOpcode() == TargetOpcode::BUNDLE) {
-BundleVirtRegsMap[VirtReg] = PhysReg;
+BundleVirtRegsMap[VirtReg] = *LRI;
   }
   markRegUsedInInstr(PhysReg);
-  return setPhysReg(MI, MO, PhysReg);
+  return setPhysReg(MI, MO, *LRI);
 }
 
 /// Allocates a register for a VirtReg use.
@@ -1158,10 +1161,10 @@ bool RegAllocFastImpl::useVirtReg(MachineInstr &MI, 
MachineOperand &MO,
   LRI->LastUse = &MI;
 
   if (MI.getOpcode() == TargetOpcode::BUNDLE) {
-BundleVirtRegsMap[VirtReg] = LRI->PhysReg;
+BundleVirtRegsMap[VirtReg] = *LRI;
   }
   markRegUsedInInstr(LRI->PhysReg);
-  return setPhysReg(MI, MO, LRI->PhysReg);
+  return setPhysReg(MI, MO, *LRI);
 }
 
 /// Query a physical register to use as a filler in contexts where the
@@ -1215,16 +1218,27 @@ MCPhysReg RegAllocFastImpl::getErrorAssignment(const 
LiveReg &LR,
 /// Changes operand OpNum in MI the refer the PhysReg, considering subregs.
 /// \return true if MI's MachineOperands were re-arranged/invalidated.
 bool RegAllocFastImpl::setPhysReg(MachineInstr &MI, MachineOperand &MO,
-  MCPhysReg PhysReg) {
+  const LiveReg &Assignment) {
+  MCPhysReg PhysReg = Assignment.PhysReg;
+  assert(PhysReg && "assignments should always be to a valid physreg");
+
+  if (LLVM_UNLIKELY(Assignment.Error)) {
+// Make sure we don't set renamable in error scenarios, as we may have
+// assigned to a reserved register.
+if (MO.isUse())
+  MO.setIsUndef(true);
+  }
+
   if (!MO.getSubReg()) {
 MO.setReg(PhysReg);
-MO.setIsRenamable(true);
+MO.setIsRenamable(!Assignment.Error);
 return false;
   }
 
   // Handle subregister index.
-  MO.setReg(PhysReg ? TRI->getSubReg(PhysReg, MO.getSubReg()) : MCRegister());
-  MO.setIsRenamable(true);
+  MO.setReg(TRI->getSubReg(PhysReg, MO.getSubReg()));
+  MO.setIsRenamable(!Assignment.Error);
+
   // Note: We leave the subreg number around a little longer in case of defs.
   // This is so that the register freeing logic in allocateInstruction can 
still
   // recognize this as subregister defs. The code there will clear the number.
@@ -1706,7 +1720,7 @@ void RegAllocFastImpl::handleDebugValue(MachineInstr &MI) 
{
 if (LRI != LiveVirtRegs.end() && LRI->PhysReg) {
   // Update every use of Reg within MI.
   for (auto &RegMO : DbgOps)
-setPhysReg(MI, *RegMO, LRI->PhysReg);
+setPhysReg(MI, *RegMO, *LRI);
 } else {
   DanglingDbgValues[Reg].push_back(&MI);
 }
@@ -1729,8 +1743,7 @@ void RegAllocFastImpl::handleBundle(MachineInstr &MI) {
   if (!Reg.isVirtual() || !shouldAllocateRegister(Reg))
 continue;
 
-  DenseMap::iterator DI;
-  DI = BundleVirtRegsMap.find(Reg);
+  DenseMap::iterator DI = BundleVirtRegsMap.find(Reg);
   assert(DI != BundleVirtRegsMap

[llvm-branch-commits] [llvm] Reapply "RegAlloc: Fix verifier error after failed allocation (#119690)" (PR #128400)

2025-02-22 Thread Matt Arsenault via llvm-branch-commits

https://github.com/arsenm created 
https://github.com/llvm/llvm-project/pull/128400

Reapply "RegAlloc: Fix verifier error after failed allocation (#119690)"

This reverts commit 0c50054820799578be8f62b6fd2cc3fbc751c01e.

Reapply with more fixes to avoid expensive_checks failures. Make sure to
call splitSeparateComponents after shrinkToUses, and update the VirtRegMap
with the split registers. Also set undef on all physical register aliases to
the assigned register.

Move physreg handling. Not sure if necessary

Remove intervals from regunits. Not sure if necessary

>From c8e70d9b94b799014f41264f67c3dd298c0e42e5 Mon Sep 17 00:00:00 2001
From: Matt Arsenault 
Date: Sat, 22 Feb 2025 10:02:04 +0700
Subject: [PATCH 1/3] Reapply "RegAlloc: Fix verifier error after failed
 allocation (#119690)"

This reverts commit 0c50054820799578be8f62b6fd2cc3fbc751c01e.

Reapply with more fixes to avoid expensive_checks failures. Make sure to
call splitSeparateComponents after shrinkToUses, and update the VirtRegMap
with the split registers. Also set undef on all physical register aliases to
the assigned register.
---
 llvm/lib/CodeGen/RegAllocBase.cpp | 55 +
 llvm/lib/CodeGen/RegAllocBase.h   |  6 ++
 llvm/lib/CodeGen/RegAllocBasic.cpp|  1 +
 llvm/lib/CodeGen/RegAllocGreedy.cpp   |  1 +
 .../AMDGPU/illegal-eviction-assert.mir|  6 +-
 ...-reg-class-snippet-copy-use-after-free.mir | 16 ++---
 llvm/test/CodeGen/AMDGPU/issue48473.mir   |  2 +-
 ...ster-killed-error-after-alloc-failure0.mir | 59 +++
 ...ister-killed-error-after-alloc-failure1.ll | 30 ++
 .../remaining-virtual-register-operands.ll|  2 +-
 10 files changed, 165 insertions(+), 13 deletions(-)
 create mode 100644 
llvm/test/CodeGen/AMDGPU/register-killed-error-after-alloc-failure0.mir
 create mode 100644 
llvm/test/CodeGen/AMDGPU/register-killed-error-after-alloc-failure1.ll

diff --git a/llvm/lib/CodeGen/RegAllocBase.cpp 
b/llvm/lib/CodeGen/RegAllocBase.cpp
index 50addcbcca065..d17e92da0d2c5 100644
--- a/llvm/lib/CodeGen/RegAllocBase.cpp
+++ b/llvm/lib/CodeGen/RegAllocBase.cpp
@@ -65,6 +65,7 @@ void RegAllocBase::init(VirtRegMap &vrm, LiveIntervals &lis,
   Matrix = &mat;
   MRI->freezeReservedRegs();
   RegClassInfo.runOnMachineFunction(vrm.getMachineFunction());
+  FailedVRegs.clear();
 }
 
 // Visit all the live registers. If they are already assigned to a physical
@@ -128,6 +129,7 @@ void RegAllocBase::allocatePhysRegs() {
 
   // Keep going after reporting the error.
   VRM->assignVirt2Phys(VirtReg->reg(), AvailablePhysReg);
+  FailedVRegs.insert(VirtReg->reg());
 } else if (AvailablePhysReg)
   Matrix->assign(*VirtReg, AvailablePhysReg);
 
@@ -161,6 +163,59 @@ void RegAllocBase::postOptimization() {
   DeadRemats.clear();
 }
 
+void RegAllocBase::cleanupFailedVRegs() {
+  SmallSet JunkRegs;
+
+  for (Register FailedReg : FailedVRegs) {
+JunkRegs.insert(FailedReg);
+
+MCRegister PhysReg = VRM->getPhys(FailedReg);
+LiveInterval &FailedInterval = LIS->getInterval(FailedReg);
+
+// The liveness information for the failed register and anything 
interfering
+// with the physical register we arbitrarily chose is junk and needs to be
+// deleted.
+for (MCRegUnitIterator Units(PhysReg, TRI); Units.isValid(); ++Units) {
+  LiveIntervalUnion::Query &Q = Matrix->query(FailedInterval, *Units);
+  for (const LiveInterval *InterferingReg : Q.interferingVRegs())
+JunkRegs.insert(InterferingReg->reg());
+}
+
+// The liveness of the assigned physical register is also now unreliable.
+for (MCRegAliasIterator Aliases(PhysReg, TRI, true); Aliases.isValid();
+ ++Aliases) {
+  for (MachineOperand &MO : MRI->reg_operands(*Aliases)) {
+if (MO.readsReg())
+  MO.setIsUndef(true);
+  }
+}
+  }
+
+  for (Register JunkReg : JunkRegs) {
+MCRegister PhysReg = VRM->getPhys(JunkReg);
+// We still should produce valid IR. Kill all the uses and reduce the live
+// ranges so that we don't think it's possible to introduce kill flags
+// later which will fail the verifier.
+for (MachineOperand &MO : MRI->reg_operands(JunkReg)) {
+  if (MO.readsReg())
+MO.setIsUndef(true);
+}
+
+LiveInterval &JunkLI = LIS->getInterval(JunkReg);
+if (LIS->shrinkToUses(&JunkLI)) {
+  SmallVector SplitLIs;
+  LIS->splitSeparateComponents(JunkLI, SplitLIs);
+
+  VRM->grow();
+  Register Original = VRM->getOriginal(JunkReg);
+  for (LiveInterval *SplitLI : SplitLIs) {
+VRM->setIsSplitFromReg(SplitLI->reg(), Original);
+VRM->assignVirt2Phys(SplitLI->reg(), PhysReg);
+  }
+}
+  }
+}
+
 void RegAllocBase::enqueue(const LiveInterval *LI) {
   const Register Reg = LI->reg();
 
diff --git a/llvm/lib/CodeGen/RegAllocBase.h b/llvm/lib/CodeGen/RegAllocBase.h
index 5bd52da61f2dc..1fdbab694bb0e 100644
--- a/llvm/lib/CodeGen/RegAllocBase.

[llvm-branch-commits] [llvm] Reapply "RegAlloc: Fix verifier error after failed allocation (#119690)" (PR #128400)

2025-02-22 Thread via llvm-branch-commits

llvmbot wrote:




@llvm/pr-subscribers-backend-amdgpu

Author: Matt Arsenault (arsenm)


Changes

Reapply "RegAlloc: Fix verifier error after failed allocation (#119690)"

This reverts commit 0c50054820799578be8f62b6fd2cc3fbc751c01e.

Reapply with more fixes to avoid expensive_checks failures. Make sure to
call splitSeparateComponents after shrinkToUses, and update the VirtRegMap
with the split registers. Also set undef on all physical register aliases to
the assigned register.

Move physreg handling. Not sure if necessary

Remove intervals from regunits. Not sure if necessary

---
Full diff: https://github.com/llvm/llvm-project/pull/128400.diff


10 Files Affected:

- (modified) llvm/lib/CodeGen/RegAllocBase.cpp (+56) 
- (modified) llvm/lib/CodeGen/RegAllocBase.h (+6) 
- (modified) llvm/lib/CodeGen/RegAllocBasic.cpp (+1) 
- (modified) llvm/lib/CodeGen/RegAllocGreedy.cpp (+1) 
- (modified) llvm/test/CodeGen/AMDGPU/illegal-eviction-assert.mir (+3-3) 
- (modified) 
llvm/test/CodeGen/AMDGPU/inflated-reg-class-snippet-copy-use-after-free.mir 
(+8-8) 
- (modified) llvm/test/CodeGen/AMDGPU/issue48473.mir (+1-1) 
- (added) 
llvm/test/CodeGen/AMDGPU/register-killed-error-after-alloc-failure0.mir (+59) 
- (added) 
llvm/test/CodeGen/AMDGPU/register-killed-error-after-alloc-failure1.ll (+30) 
- (modified) llvm/test/CodeGen/AMDGPU/remaining-virtual-register-operands.ll 
(+1-1) 


``diff
diff --git a/llvm/lib/CodeGen/RegAllocBase.cpp 
b/llvm/lib/CodeGen/RegAllocBase.cpp
index 50addcbcca065..d66d396a15018 100644
--- a/llvm/lib/CodeGen/RegAllocBase.cpp
+++ b/llvm/lib/CodeGen/RegAllocBase.cpp
@@ -65,6 +65,7 @@ void RegAllocBase::init(VirtRegMap &vrm, LiveIntervals &lis,
   Matrix = &mat;
   MRI->freezeReservedRegs();
   RegClassInfo.runOnMachineFunction(vrm.getMachineFunction());
+  FailedVRegs.clear();
 }
 
 // Visit all the live registers. If they are already assigned to a physical
@@ -128,6 +129,7 @@ void RegAllocBase::allocatePhysRegs() {
 
   // Keep going after reporting the error.
   VRM->assignVirt2Phys(VirtReg->reg(), AvailablePhysReg);
+  FailedVRegs.insert(VirtReg->reg());
 } else if (AvailablePhysReg)
   Matrix->assign(*VirtReg, AvailablePhysReg);
 
@@ -161,6 +163,60 @@ void RegAllocBase::postOptimization() {
   DeadRemats.clear();
 }
 
+void RegAllocBase::cleanupFailedVRegs() {
+  SmallSet JunkRegs;
+
+  for (Register FailedReg : FailedVRegs) {
+JunkRegs.insert(FailedReg);
+
+MCRegister PhysReg = VRM->getPhys(FailedReg);
+LiveInterval &FailedInterval = LIS->getInterval(FailedReg);
+
+// The liveness information for the failed register and anything 
interfering
+// with the physical register we arbitrarily chose is junk and needs to be
+// deleted.
+for (MCRegUnitIterator Units(PhysReg, TRI); Units.isValid(); ++Units) {
+  LiveIntervalUnion::Query &Q = Matrix->query(FailedInterval, *Units);
+  for (const LiveInterval *InterferingReg : Q.interferingVRegs())
+JunkRegs.insert(InterferingReg->reg());
+  LIS->removeRegUnit(*Units);
+}
+  }
+
+  for (Register JunkReg : JunkRegs) {
+MCRegister PhysReg = VRM->getPhys(JunkReg);
+// We still should produce valid IR. Kill all the uses and reduce the live
+// ranges so that we don't think it's possible to introduce kill flags
+// later which will fail the verifier.
+for (MachineOperand &MO : MRI->reg_operands(JunkReg)) {
+  if (MO.readsReg())
+MO.setIsUndef(true);
+}
+
+// The liveness of the assigned physical register is also now unreliable.
+for (MCRegAliasIterator Aliases(PhysReg, TRI, true); Aliases.isValid();
+ ++Aliases) {
+  for (MachineOperand &MO : MRI->reg_operands(*Aliases)) {
+if (MO.readsReg())
+  MO.setIsUndef(true);
+  }
+}
+
+LiveInterval &JunkLI = LIS->getInterval(JunkReg);
+if (LIS->shrinkToUses(&JunkLI)) {
+  SmallVector SplitLIs;
+  LIS->splitSeparateComponents(JunkLI, SplitLIs);
+
+  VRM->grow();
+  Register Original = VRM->getOriginal(JunkReg);
+  for (LiveInterval *SplitLI : SplitLIs) {
+VRM->setIsSplitFromReg(SplitLI->reg(), Original);
+VRM->assignVirt2Phys(SplitLI->reg(), PhysReg);
+  }
+}
+  }
+}
+
 void RegAllocBase::enqueue(const LiveInterval *LI) {
   const Register Reg = LI->reg();
 
diff --git a/llvm/lib/CodeGen/RegAllocBase.h b/llvm/lib/CodeGen/RegAllocBase.h
index 5bd52da61f2dc..1fdbab694bb0e 100644
--- a/llvm/lib/CodeGen/RegAllocBase.h
+++ b/llvm/lib/CodeGen/RegAllocBase.h
@@ -37,6 +37,7 @@
 #define LLVM_LIB_CODEGEN_REGALLOCBASE_H
 
 #include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallSet.h"
 #include "llvm/CodeGen/MachineRegisterInfo.h"
 #include "llvm/CodeGen/RegAllocCommon.h"
 #include "llvm/CodeGen/RegisterClassInfo.h"
@@ -81,6 +82,7 @@ class RegAllocBase {
   /// always available for the remat of all the siblings of the original reg.
   SmallPtrSet DeadRemats;
 
+  SmallSet FailedVRegs;
   RegAllocBase(const RegAlloc

[llvm-branch-commits] [llvm] Reapply "RegAlloc: Fix verifier error after failed allocation (#119690)" (PR #128400)

2025-02-22 Thread Matt Arsenault via llvm-branch-commits

arsenm wrote:

> [!WARNING]
> This pull request is not mergeable via GitHub because a downstack PR is 
> open. Once all requirements are satisfied, merge this PR as a stack  href="https://app.graphite.dev/github/pr/llvm/llvm-project/128400?utm_source=stack-comment-downstack-mergeability-warning";
>  >on Graphite.
> https://graphite.dev/docs/merge-pull-requests";>Learn more

* **#128400** https://app.graphite.dev/github/pr/llvm/llvm-project/128400?utm_source=stack-comment-icon";
 target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" 
width="10px" height="10px"/> 👈 https://app.graphite.dev/github/pr/llvm/llvm-project/128400?utm_source=stack-comment-view-in-graphite";
 target="_blank">(View in Graphite)
* **#128281** https://app.graphite.dev/github/pr/llvm/llvm-project/128281?utm_source=stack-comment-icon";
 target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" 
width="10px" height="10px"/>
* **#128280** https://app.graphite.dev/github/pr/llvm/llvm-project/128280?utm_source=stack-comment-icon";
 target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" 
width="10px" height="10px"/>
* `main`




This stack of pull requests is managed by https://graphite.dev?utm-source=stack-comment";>Graphite. Learn 
more about https://stacking.dev/?utm_source=stack-comment";>stacking.


https://github.com/llvm/llvm-project/pull/128400
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] Reapply "RegAlloc: Fix verifier error after failed allocation (#119690)" (PR #128400)

2025-02-22 Thread Matt Arsenault via llvm-branch-commits

https://github.com/arsenm ready_for_review 
https://github.com/llvm/llvm-project/pull/128400
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] Reapply "RegAlloc: Fix verifier error after failed allocation (#119690)" (PR #128400)

2025-02-22 Thread via llvm-branch-commits

github-actions[bot] wrote:




:warning: undef deprecator found issues in your code. :warning:



You can test this locally with the following command:


``bash
git diff -U0 --pickaxe-regex -S 
'([^a-zA-Z0-9#_-]undef[^a-zA-Z0-9_-]|UndefValue::get)' 
d93b45487feba452868706b31e6e59e0bb1a5d19 
a8b8cafcb1c5e252e23a1626a44eed4e4ef89316 
llvm/test/CodeGen/AMDGPU/register-killed-error-after-alloc-failure1.ll 
llvm/lib/CodeGen/RegAllocBase.cpp llvm/lib/CodeGen/RegAllocBase.h 
llvm/lib/CodeGen/RegAllocBasic.cpp llvm/lib/CodeGen/RegAllocGreedy.cpp 
llvm/test/CodeGen/AMDGPU/remaining-virtual-register-operands.ll
``




The following files introduce new uses of undef:
 - llvm/test/CodeGen/AMDGPU/register-killed-error-after-alloc-failure1.ll

[Undef](https://llvm.org/docs/LangRef.html#undefined-values) is now deprecated 
and should only be used in the rare cases where no replacement is possible. For 
example, a load of uninitialized memory yields `undef`. You should use `poison` 
values for placeholders instead.

In tests, avoid using `undef` and having tests that trigger undefined behavior. 
If you need an operand with some unimportant value, you can add a new argument 
to the function and use that instead.

For example, this is considered a bad practice:
```llvm
define void @fn() {
  ...
  br i1 undef, ...
}
```

Please use the following instead:
```llvm
define void @fn(i1 %cond) {
  ...
  br i1 %cond, ...
}
```

Please refer to the [Undefined Behavior 
Manual](https://llvm.org/docs/UndefinedBehavior.html) for more information.



https://github.com/llvm/llvm-project/pull/128400
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] release/20.x: Reland "[LV]: Teach LV to recursively (de)interleave." (#125094) (PR #128389)

2025-02-22 Thread via llvm-branch-commits

llvmbot wrote:

@fhahn What do you think about merging this PR to the release branch?

https://github.com/llvm/llvm-project/pull/128389
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] release/20.x: Reland "[LV]: Teach LV to recursively (de)interleave." (#125094) (PR #128389)

2025-02-22 Thread via llvm-branch-commits

https://github.com/llvmbot milestoned 
https://github.com/llvm/llvm-project/pull/128389
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] release/20.x: Reland "[LV]: Teach LV to recursively (de)interleave." (#125094) (PR #128389)

2025-02-22 Thread via llvm-branch-commits

llvmbot wrote:




@llvm/pr-subscribers-vectorizers

Author: None (llvmbot)


Changes

Backport e9a20f77ee2117b4a6eb40826b7280e29ad29e1e

Requested by: @hassnaaHamdi

---

Patch is 194.18 KiB, truncated to 20.00 KiB below, full version: 
https://github.com/llvm/llvm-project/pull/128389.diff


6 Files Affected:

- (modified) llvm/lib/Transforms/Vectorize/LoopVectorize.cpp (+7-7) 
- (modified) llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp (+56-23) 
- (modified) 
llvm/test/Transforms/LoopVectorize/AArch64/sve-interleaved-accesses.ll (+259-1) 
- (modified) 
llvm/test/Transforms/LoopVectorize/AArch64/sve-interleaved-masked-accesses.ll 
(+252) 
- (modified) llvm/test/Transforms/LoopVectorize/RISCV/interleaved-accesses.ll 
(+678-640) 
- (added) 
llvm/test/Transforms/PhaseOrdering/AArch64/sve-interleave-vectorization.ll 
(+135) 


``diff
diff --git a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp 
b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
index 0ceeec48487f6..2ac58feaf39bb 100644
--- a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
+++ b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
@@ -3390,10 +3390,10 @@ bool 
LoopVectorizationCostModel::interleavedAccessCanBeWidened(
   if (hasIrregularType(ScalarTy, DL))
 return false;
 
-  // We currently only know how to emit interleave/deinterleave with
-  // Factor=2 for scalable vectors. This is purely an implementation
-  // limit.
-  if (VF.isScalable() && InterleaveFactor != 2)
+  // For scalable vectors, the only interleave factor currently supported
+  // must be power of 2 since we require the (de)interleave2 intrinsics
+  // instead of shufflevectors.
+  if (VF.isScalable() && !isPowerOf2_32(InterleaveFactor))
 return false;
 
   // If the group involves a non-integral pointer, we may not be able to
@@ -9259,9 +9259,9 @@ 
LoopVectorizationPlanner::tryToBuildVPlanWithVPRecipes(VFRange &Range) {
  CM.getWideningDecision(IG->getInsertPos(), VF) ==
  LoopVectorizationCostModel::CM_Interleave);
   // For scalable vectors, the only interleave factor currently supported
-  // is 2 since we require the (de)interleave2 intrinsics instead of
-  // shufflevectors.
-  assert((!Result || !VF.isScalable() || IG->getFactor() == 2) &&
+  // must be power of 2 since we require the (de)interleave2 intrinsics
+  // instead of shufflevectors.
+  assert((!Result || !VF.isScalable() || isPowerOf2_32(IG->getFactor())) &&
  "Unsupported interleave factor for scalable vectors");
   return Result;
 };
diff --git a/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp 
b/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp
index 97be2da24fc37..4f13116382796 100644
--- a/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp
+++ b/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp
@@ -2892,10 +2892,21 @@ static Value *interleaveVectors(IRBuilderBase &Builder, 
ArrayRef Vals,
   // Scalable vectors cannot use arbitrary shufflevectors (only splats), so
   // must use intrinsics to interleave.
   if (VecTy->isScalableTy()) {
-VectorType *WideVecTy = VectorType::getDoubleElementsVectorType(VecTy);
-return Builder.CreateIntrinsic(WideVecTy, Intrinsic::vector_interleave2,
-   Vals,
-   /*FMFSource=*/nullptr, Name);
+assert(isPowerOf2_32(Factor) && "Unsupported interleave factor for "
+"scalable vectors, must be power of 2");
+SmallVector InterleavingValues(Vals);
+// When interleaving, the number of values will be shrunk until we have the
+// single final interleaved value.
+auto *InterleaveTy = cast(InterleavingValues[0]->getType());
+for (unsigned Midpoint = Factor / 2; Midpoint > 0; Midpoint /= 2) {
+  InterleaveTy = VectorType::getDoubleElementsVectorType(InterleaveTy);
+  for (unsigned I = 0; I < Midpoint; ++I)
+InterleavingValues[I] = Builder.CreateIntrinsic(
+InterleaveTy, Intrinsic::vector_interleave2,
+{InterleavingValues[I], InterleavingValues[Midpoint + I]},
+/*FMFSource=*/nullptr, Name);
+}
+return InterleavingValues[0];
   }
 
   // Fixed length. Start by concatenating all vectors into a wide vector.
@@ -2981,15 +2992,11 @@ void VPInterleaveRecipe::execute(VPTransformState 
&State) {
   &InterleaveFactor](Value *MaskForGaps) -> Value * {
 if (State.VF.isScalable()) {
   assert(!MaskForGaps && "Interleaved groups with gaps are not 
supported.");
-  assert(InterleaveFactor == 2 &&
+  assert(isPowerOf2_32(InterleaveFactor) &&
  "Unsupported deinterleave factor for scalable vectors");
   auto *ResBlockInMask = State.get(BlockInMask);
-  SmallVector Ops = {ResBlockInMask, ResBlockInMask};
-  auto *MaskTy = VectorType::get(State.Builder.getInt1Ty(),
- State.VF.getKnownMinValue() * 2, true);
-  return State

[llvm-branch-commits] [llvm] release/20.x: Reland "[LV]: Teach LV to recursively (de)interleave." (#125094) (PR #128389)

2025-02-22 Thread via llvm-branch-commits

llvmbot wrote:




@llvm/pr-subscribers-llvm-transforms

Author: None (llvmbot)


Changes

Backport e9a20f77ee2117b4a6eb40826b7280e29ad29e1e

Requested by: @hassnaaHamdi

---

Patch is 194.18 KiB, truncated to 20.00 KiB below, full version: 
https://github.com/llvm/llvm-project/pull/128389.diff


6 Files Affected:

- (modified) llvm/lib/Transforms/Vectorize/LoopVectorize.cpp (+7-7) 
- (modified) llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp (+56-23) 
- (modified) 
llvm/test/Transforms/LoopVectorize/AArch64/sve-interleaved-accesses.ll (+259-1) 
- (modified) 
llvm/test/Transforms/LoopVectorize/AArch64/sve-interleaved-masked-accesses.ll 
(+252) 
- (modified) llvm/test/Transforms/LoopVectorize/RISCV/interleaved-accesses.ll 
(+678-640) 
- (added) 
llvm/test/Transforms/PhaseOrdering/AArch64/sve-interleave-vectorization.ll 
(+135) 


``diff
diff --git a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp 
b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
index 0ceeec48487f6..2ac58feaf39bb 100644
--- a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
+++ b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
@@ -3390,10 +3390,10 @@ bool 
LoopVectorizationCostModel::interleavedAccessCanBeWidened(
   if (hasIrregularType(ScalarTy, DL))
 return false;
 
-  // We currently only know how to emit interleave/deinterleave with
-  // Factor=2 for scalable vectors. This is purely an implementation
-  // limit.
-  if (VF.isScalable() && InterleaveFactor != 2)
+  // For scalable vectors, the only interleave factor currently supported
+  // must be power of 2 since we require the (de)interleave2 intrinsics
+  // instead of shufflevectors.
+  if (VF.isScalable() && !isPowerOf2_32(InterleaveFactor))
 return false;
 
   // If the group involves a non-integral pointer, we may not be able to
@@ -9259,9 +9259,9 @@ 
LoopVectorizationPlanner::tryToBuildVPlanWithVPRecipes(VFRange &Range) {
  CM.getWideningDecision(IG->getInsertPos(), VF) ==
  LoopVectorizationCostModel::CM_Interleave);
   // For scalable vectors, the only interleave factor currently supported
-  // is 2 since we require the (de)interleave2 intrinsics instead of
-  // shufflevectors.
-  assert((!Result || !VF.isScalable() || IG->getFactor() == 2) &&
+  // must be power of 2 since we require the (de)interleave2 intrinsics
+  // instead of shufflevectors.
+  assert((!Result || !VF.isScalable() || isPowerOf2_32(IG->getFactor())) &&
  "Unsupported interleave factor for scalable vectors");
   return Result;
 };
diff --git a/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp 
b/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp
index 97be2da24fc37..4f13116382796 100644
--- a/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp
+++ b/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp
@@ -2892,10 +2892,21 @@ static Value *interleaveVectors(IRBuilderBase &Builder, 
ArrayRef Vals,
   // Scalable vectors cannot use arbitrary shufflevectors (only splats), so
   // must use intrinsics to interleave.
   if (VecTy->isScalableTy()) {
-VectorType *WideVecTy = VectorType::getDoubleElementsVectorType(VecTy);
-return Builder.CreateIntrinsic(WideVecTy, Intrinsic::vector_interleave2,
-   Vals,
-   /*FMFSource=*/nullptr, Name);
+assert(isPowerOf2_32(Factor) && "Unsupported interleave factor for "
+"scalable vectors, must be power of 2");
+SmallVector InterleavingValues(Vals);
+// When interleaving, the number of values will be shrunk until we have the
+// single final interleaved value.
+auto *InterleaveTy = cast(InterleavingValues[0]->getType());
+for (unsigned Midpoint = Factor / 2; Midpoint > 0; Midpoint /= 2) {
+  InterleaveTy = VectorType::getDoubleElementsVectorType(InterleaveTy);
+  for (unsigned I = 0; I < Midpoint; ++I)
+InterleavingValues[I] = Builder.CreateIntrinsic(
+InterleaveTy, Intrinsic::vector_interleave2,
+{InterleavingValues[I], InterleavingValues[Midpoint + I]},
+/*FMFSource=*/nullptr, Name);
+}
+return InterleavingValues[0];
   }
 
   // Fixed length. Start by concatenating all vectors into a wide vector.
@@ -2981,15 +2992,11 @@ void VPInterleaveRecipe::execute(VPTransformState 
&State) {
   &InterleaveFactor](Value *MaskForGaps) -> Value * {
 if (State.VF.isScalable()) {
   assert(!MaskForGaps && "Interleaved groups with gaps are not 
supported.");
-  assert(InterleaveFactor == 2 &&
+  assert(isPowerOf2_32(InterleaveFactor) &&
  "Unsupported deinterleave factor for scalable vectors");
   auto *ResBlockInMask = State.get(BlockInMask);
-  SmallVector Ops = {ResBlockInMask, ResBlockInMask};
-  auto *MaskTy = VectorType::get(State.Builder.getInt1Ty(),
- State.VF.getKnownMinValue() * 2, true);
-  return S

[llvm-branch-commits] [llvm] release/20.x: [SLP] Check for PHI nodes (potentially cycles!) when checking dependencies (PR #127294)

2025-02-22 Thread via llvm-branch-commits

Zentrik wrote:

@alexey-bataev Am I correct in thinking that the 
`Transforms/SLPVectorizer/X86/perfect-matched-reused-bv.ll` test just needs to 
be updated to reflect that vectorization fails. It looks like the test is there 
to make sure there's no crash when compiling.

https://github.com/llvm/llvm-project/pull/127294
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] release/20.x: [SLP] Check for PHI nodes (potentially cycles!) when checking dependencies (PR #127294)

2025-02-22 Thread Alexey Bataev via llvm-branch-commits

alexey-bataev wrote:

Yes, updating should be enough

https://github.com/llvm/llvm-project/pull/127294
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] release/20.x: [SLP] Check for PHI nodes (potentially cycles!) when checking dependencies (PR #127294)

2025-02-22 Thread Nikita Popov via llvm-branch-commits

nikic wrote:

Closing in favor of https://github.com/llvm/llvm-project/pull/128371.

https://github.com/llvm/llvm-project/pull/127294
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] release/20.x: [SLP] Check for PHI nodes (potentially cycles!) when checking dependencies: Backport Attempt 3 (PR #128371)

2025-02-22 Thread Alexey Bataev via llvm-branch-commits

https://github.com/alexey-bataev approved this pull request.

LG

https://github.com/llvm/llvm-project/pull/128371
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] release/20.x: [SLP] Check for PHI nodes (potentially cycles!) when checking dependencies: Backport Attempt 3 (PR #128371)

2025-02-22 Thread Nikita Popov via llvm-branch-commits

https://github.com/nikic milestoned 
https://github.com/llvm/llvm-project/pull/128371
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] release/20.x: [SLP] Check for PHI nodes (potentially cycles!) when checking dependencies: Backport Attempt 3 (PR #128371)

2025-02-22 Thread via llvm-branch-commits

https://github.com/Zentrik updated 
https://github.com/llvm/llvm-project/pull/128371

>From 976a97097c645a4d861e4a36c142b30c33a5e575 Mon Sep 17 00:00:00 2001
From: Alexey Bataev 
Date: Thu, 13 Feb 2025 14:19:51 -0800
Subject: [PATCH 1/2] [SLP] Check for PHI nodes (potentially cycles!) when
 checking dependencies

When checking for dependecies for gather nodes with users with the same
last instruction, cannot rely on the index order, if there is (even
potential!) cycle in the graph, which may cause order not work correctly
and cause compiler crash.

Fixes #127128

(cherry picked from commit ac217ee389d63124432e5e6890851a678f7a676b)
---
 .../Transforms/Vectorize/SLPVectorizer.cpp| 10 +++-
 .../X86/delayed-gather-emission.ll|  2 +-
 .../X86/matching-gather-nodes-phi-users.ll|  2 +-
 .../SLPVectorizer/X86/phi-node-with-cycle.ll  | 59 +++
 4 files changed, 70 insertions(+), 3 deletions(-)
 create mode 100644 
llvm/test/Transforms/SLPVectorizer/X86/phi-node-with-cycle.ll

diff --git a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp 
b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
index 19963e780ebd3..7b20eda550095 100644
--- a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
+++ b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
@@ -13181,8 +13181,16 @@ BoUpSLP::isGatherShuffledSingleRegisterEntry(
   continue;
 // If the user instruction is used for some reason in different
 // vectorized nodes - make it depend on index.
+// If any vector node is PHI node, this dependency might not work
+// because of cycle dependencies, so disable it.
 if (TEUseEI.UserTE != UseEI.UserTE &&
-TEUseEI.UserTE->Idx < UseEI.UserTE->Idx)
+(TEUseEI.UserTE->Idx < UseEI.UserTE->Idx ||
+ any_of(
+ VectorizableTree,
+ [](const std::unique_ptr &TE) {
+   return TE->State == TreeEntry::Vectorize &&
+  TE->getOpcode() == Instruction::PHI;
+ })))
   continue;
   }
 
diff --git a/llvm/test/Transforms/SLPVectorizer/X86/delayed-gather-emission.ll 
b/llvm/test/Transforms/SLPVectorizer/X86/delayed-gather-emission.ll
index 5562291dbb6be..bf3f0c4df74e4 100644
--- a/llvm/test/Transforms/SLPVectorizer/X86/delayed-gather-emission.ll
+++ b/llvm/test/Transforms/SLPVectorizer/X86/delayed-gather-emission.ll
@@ -31,7 +31,7 @@ define void @test() {
 ; CHECK-NEXT:[[TOBOOL:%.*]] = fcmp une float [[I2]], 0.00e+00
 ; CHECK-NEXT:[[TMP8:%.*]] = shufflevector <2 x float> [[TMP5]], <2 x 
float> poison, <2 x i32> 
 ; CHECK-NEXT:[[TMP9]] = insertelement <2 x float> [[TMP8]], float [[I2]], 
i32 0
-; CHECK-NEXT:[[TMP10]] = shufflevector <2 x float> [[TMP9]], <2 x float> 
[[TMP2]], <2 x i32> 
+; CHECK-NEXT:[[TMP10]] = insertelement <2 x float> [[TMP2]], float [[I2]], 
i32 0
 ; CHECK-NEXT:br i1 [[TOBOOL]], label [[BB1]], label [[BB2]]
 ;
 entry:
diff --git 
a/llvm/test/Transforms/SLPVectorizer/X86/matching-gather-nodes-phi-users.ll 
b/llvm/test/Transforms/SLPVectorizer/X86/matching-gather-nodes-phi-users.ll
index 166c819098c8c..d649465c9ff12 100644
--- a/llvm/test/Transforms/SLPVectorizer/X86/matching-gather-nodes-phi-users.ll
+++ b/llvm/test/Transforms/SLPVectorizer/X86/matching-gather-nodes-phi-users.ll
@@ -8,7 +8,7 @@
 ; YAML: Function:test
 ; YAML: Args:
 ; YAML:   - String:  'Stores SLP vectorized with cost '
-; YAML:   - Cost:'-6'
+; YAML:   - Cost:'-3'
 ; YAML:   - String:  ' and with tree size '
 ; YAML:   - TreeSize:'14'
 ; YAML: ...
diff --git a/llvm/test/Transforms/SLPVectorizer/X86/phi-node-with-cycle.ll 
b/llvm/test/Transforms/SLPVectorizer/X86/phi-node-with-cycle.ll
new file mode 100644
index 0..22e7e6a8e6624
--- /dev/null
+++ b/llvm/test/Transforms/SLPVectorizer/X86/phi-node-with-cycle.ll
@@ -0,0 +1,59 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 
UTC_ARGS: --version 5
+; RUN: opt -S --passes=slp-vectorizer -mtriple=x86_64-unknown-linux-gnu 
-mcpu=haswell < %s | FileCheck %s
+
+define void @test(float %0) {
+; CHECK-LABEL: define void @test(
+; CHECK-SAME: float [[TMP0:%.*]]) #[[ATTR0:[0-9]+]] {
+; CHECK-NEXT:[[TMP2:%.*]] = insertelement <2 x float> , float [[TMP0]], i32 1
+; CHECK-NEXT:[[TMP3:%.*]] = fdiv <2 x float> [[TMP2]], zeroinitializer
+; CHECK-NEXT:[[TMP4:%.*]] = insertelement <2 x float> , float [[TMP0]], i32 0
+; CHECK-NEXT:[[TMP5:%.*]] = fdiv <2 x float> [[TMP4]], zeroinitializer
+; CHECK-NEXT:br label %[[BB6:.*]]
+; CHECK:   [[BB6]]:
+; CHECK-NEXT:[[TMP7:%.*]] = fmul <2 x float> [[TMP5]], zeroinitializer
+; CHECK-NEXT:[[TMP8:%.*]] = fsub <2 x float> zeroinitializer, [[TMP7]]
+; CHECK-NEXT:br label %[[BB10:.*]]
+; CHECK:   [[BB9:.*]]:
+; CHECK-NEXT:br label %[[BB10]]
+; CHECK:   [[BB10]]:
+; CHECK-NEXT:[[TMP11:%.*]] = phi <2 x float> [ [[TMP8]], %[[BB

[llvm-branch-commits] [llvm] release/20.x: [SLP] Check for PHI nodes (potentially cycles!) when checking dependencies: Backport Attempt 3 (PR #128371)

2025-02-22 Thread via llvm-branch-commits

llvmbot wrote:




@llvm/pr-subscribers-vectorizers

Author: None (Zentrik)


Changes

Backport 
https://github.com/llvm/llvm-project/commit/ac217ee389d63124432e5e6890851a678f7a676b

This fixes https://github.com/llvm/llvm-project/pull/127294 by updating the 
test at `llvm/test/Transforms/SLPVectorizer/X86/perfect-matched-reused-bv.ll`


---
Full diff: https://github.com/llvm/llvm-project/pull/128371.diff


5 Files Affected:

- (modified) llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp (+9-1) 
- (modified) llvm/test/Transforms/SLPVectorizer/X86/delayed-gather-emission.ll 
(+1-1) 
- (modified) 
llvm/test/Transforms/SLPVectorizer/X86/matching-gather-nodes-phi-users.ll 
(+1-1) 
- (modified) 
llvm/test/Transforms/SLPVectorizer/X86/perfect-matched-reused-bv.ll (+7-6) 
- (added) llvm/test/Transforms/SLPVectorizer/X86/phi-node-with-cycle.ll (+59) 


``diff
diff --git a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp 
b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
index 19963e780ebd3..7b20eda550095 100644
--- a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
+++ b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
@@ -13181,8 +13181,16 @@ BoUpSLP::isGatherShuffledSingleRegisterEntry(
   continue;
 // If the user instruction is used for some reason in different
 // vectorized nodes - make it depend on index.
+// If any vector node is PHI node, this dependency might not work
+// because of cycle dependencies, so disable it.
 if (TEUseEI.UserTE != UseEI.UserTE &&
-TEUseEI.UserTE->Idx < UseEI.UserTE->Idx)
+(TEUseEI.UserTE->Idx < UseEI.UserTE->Idx ||
+ any_of(
+ VectorizableTree,
+ [](const std::unique_ptr &TE) {
+   return TE->State == TreeEntry::Vectorize &&
+  TE->getOpcode() == Instruction::PHI;
+ })))
   continue;
   }
 
diff --git a/llvm/test/Transforms/SLPVectorizer/X86/delayed-gather-emission.ll 
b/llvm/test/Transforms/SLPVectorizer/X86/delayed-gather-emission.ll
index 5562291dbb6be..bf3f0c4df74e4 100644
--- a/llvm/test/Transforms/SLPVectorizer/X86/delayed-gather-emission.ll
+++ b/llvm/test/Transforms/SLPVectorizer/X86/delayed-gather-emission.ll
@@ -31,7 +31,7 @@ define void @test() {
 ; CHECK-NEXT:[[TOBOOL:%.*]] = fcmp une float [[I2]], 0.00e+00
 ; CHECK-NEXT:[[TMP8:%.*]] = shufflevector <2 x float> [[TMP5]], <2 x 
float> poison, <2 x i32> 
 ; CHECK-NEXT:[[TMP9]] = insertelement <2 x float> [[TMP8]], float [[I2]], 
i32 0
-; CHECK-NEXT:[[TMP10]] = shufflevector <2 x float> [[TMP9]], <2 x float> 
[[TMP2]], <2 x i32> 
+; CHECK-NEXT:[[TMP10]] = insertelement <2 x float> [[TMP2]], float [[I2]], 
i32 0
 ; CHECK-NEXT:br i1 [[TOBOOL]], label [[BB1]], label [[BB2]]
 ;
 entry:
diff --git 
a/llvm/test/Transforms/SLPVectorizer/X86/matching-gather-nodes-phi-users.ll 
b/llvm/test/Transforms/SLPVectorizer/X86/matching-gather-nodes-phi-users.ll
index 166c819098c8c..d649465c9ff12 100644
--- a/llvm/test/Transforms/SLPVectorizer/X86/matching-gather-nodes-phi-users.ll
+++ b/llvm/test/Transforms/SLPVectorizer/X86/matching-gather-nodes-phi-users.ll
@@ -8,7 +8,7 @@
 ; YAML: Function:test
 ; YAML: Args:
 ; YAML:   - String:  'Stores SLP vectorized with cost '
-; YAML:   - Cost:'-6'
+; YAML:   - Cost:'-3'
 ; YAML:   - String:  ' and with tree size '
 ; YAML:   - TreeSize:'14'
 ; YAML: ...
diff --git 
a/llvm/test/Transforms/SLPVectorizer/X86/perfect-matched-reused-bv.ll 
b/llvm/test/Transforms/SLPVectorizer/X86/perfect-matched-reused-bv.ll
index 1053e0fc10669..c4a49242a5583 100644
--- a/llvm/test/Transforms/SLPVectorizer/X86/perfect-matched-reused-bv.ll
+++ b/llvm/test/Transforms/SLPVectorizer/X86/perfect-matched-reused-bv.ll
@@ -7,16 +7,17 @@ define void @test() {
 ; CHECK-NEXT:  [[BB:.*]]:
 ; CHECK-NEXT:br label %[[BB1:.*]]
 ; CHECK:   [[BB1]]:
-; CHECK-NEXT:[[TMP0:%.*]] = phi <2 x i32> [ zeroinitializer, %[[BB]] ], [ 
[[TMP4:%.*]], %[[BB4:.*]] ]
-; CHECK-NEXT:[[TMP1:%.*]] = or <2 x i32> [[TMP0]], zeroinitializer
+; CHECK-NEXT:[[PHI:%.*]] = phi i32 [ 0, %[[BB]] ], [ [[ADD6:%.*]], 
%[[BB4:.*]] ]
+; CHECK-NEXT:[[PHI2:%.*]] = phi i32 [ 0, %[[BB]] ], [ 0, %[[BB4]] ]
+; CHECK-NEXT:[[OR:%.*]] = or i32 [[PHI2]], 0
+; CHECK-NEXT:[[OR3:%.*]] = or i32 [[PHI]], 0
 ; CHECK-NEXT:br i1 false, label %[[BB7:.*]], label %[[BB4]]
 ; CHECK:   [[BB4]]:
-; CHECK-NEXT:[[TMP2:%.*]] = shufflevector <2 x i32> [[TMP0]], <2 x i32> 
, <2 x i32> 
-; CHECK-NEXT:[[TMP3:%.*]] = add <2 x i32> zeroinitializer, [[TMP2]]
-; CHECK-NEXT:[[TMP4]] = add <2 x i32> zeroinitializer, [[TMP2]]
+; CHECK-NEXT:[[ADD6]] = add i32 [[PHI]], 0
 ; CHECK-NEXT:br i1 false, label %[[BB7]], label %[[BB1]]
 ; CHECK:   [[BB7]]:
-; CHECK-NEXT:[[TMP5:%.*]] = phi <2 x i32> [ [[TMP1]], %[[BB1]] ], [ 
[[TMP3]], %[[BB4]] ]
+; CHECK-NEXT:[[PHI8:%.*]] = phi

[llvm-branch-commits] [llvm] release/20.x: [SLP] Check for PHI nodes (potentially cycles!) when checking dependencies (PR #128371)

2025-02-22 Thread via llvm-branch-commits

https://github.com/Zentrik created 
https://github.com/llvm/llvm-project/pull/128371

Backport 
https://github.com/llvm/llvm-project/commit/ac217ee389d63124432e5e6890851a678f7a676b

This fixes https://github.com/llvm/llvm-project/pull/127294 by updating the 
test at `llvm/test/Transforms/SLPVectorizer/X86/perfect-matched-reused-bv.ll`


>From a426b578f8c51dc1f645a901dc6eedb33462fa22 Mon Sep 17 00:00:00 2001
From: Alexey Bataev 
Date: Thu, 13 Feb 2025 14:19:51 -0800
Subject: [PATCH 1/2] [SLP] Check for PHI nodes (potentially cycles!) when
 checking dependencies

When checking for dependecies for gather nodes with users with the same
last instruction, cannot rely on the index order, if there is (even
potential!) cycle in the graph, which may cause order not work correctly
and cause compiler crash.

Fixes #127128

(cherry picked from commit ac217ee389d63124432e5e6890851a678f7a676b)
---
 .../Transforms/Vectorize/SLPVectorizer.cpp| 10 +++-
 .../X86/delayed-gather-emission.ll|  2 +-
 .../X86/matching-gather-nodes-phi-users.ll|  2 +-
 .../SLPVectorizer/X86/phi-node-with-cycle.ll  | 59 +++
 4 files changed, 70 insertions(+), 3 deletions(-)
 create mode 100644 
llvm/test/Transforms/SLPVectorizer/X86/phi-node-with-cycle.ll

diff --git a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp 
b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
index 19963e780ebd3..7b20eda550095 100644
--- a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
+++ b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
@@ -13181,8 +13181,16 @@ BoUpSLP::isGatherShuffledSingleRegisterEntry(
   continue;
 // If the user instruction is used for some reason in different
 // vectorized nodes - make it depend on index.
+// If any vector node is PHI node, this dependency might not work
+// because of cycle dependencies, so disable it.
 if (TEUseEI.UserTE != UseEI.UserTE &&
-TEUseEI.UserTE->Idx < UseEI.UserTE->Idx)
+(TEUseEI.UserTE->Idx < UseEI.UserTE->Idx ||
+ any_of(
+ VectorizableTree,
+ [](const std::unique_ptr &TE) {
+   return TE->State == TreeEntry::Vectorize &&
+  TE->getOpcode() == Instruction::PHI;
+ })))
   continue;
   }
 
diff --git a/llvm/test/Transforms/SLPVectorizer/X86/delayed-gather-emission.ll 
b/llvm/test/Transforms/SLPVectorizer/X86/delayed-gather-emission.ll
index 5562291dbb6be..bf3f0c4df74e4 100644
--- a/llvm/test/Transforms/SLPVectorizer/X86/delayed-gather-emission.ll
+++ b/llvm/test/Transforms/SLPVectorizer/X86/delayed-gather-emission.ll
@@ -31,7 +31,7 @@ define void @test() {
 ; CHECK-NEXT:[[TOBOOL:%.*]] = fcmp une float [[I2]], 0.00e+00
 ; CHECK-NEXT:[[TMP8:%.*]] = shufflevector <2 x float> [[TMP5]], <2 x 
float> poison, <2 x i32> 
 ; CHECK-NEXT:[[TMP9]] = insertelement <2 x float> [[TMP8]], float [[I2]], 
i32 0
-; CHECK-NEXT:[[TMP10]] = shufflevector <2 x float> [[TMP9]], <2 x float> 
[[TMP2]], <2 x i32> 
+; CHECK-NEXT:[[TMP10]] = insertelement <2 x float> [[TMP2]], float [[I2]], 
i32 0
 ; CHECK-NEXT:br i1 [[TOBOOL]], label [[BB1]], label [[BB2]]
 ;
 entry:
diff --git 
a/llvm/test/Transforms/SLPVectorizer/X86/matching-gather-nodes-phi-users.ll 
b/llvm/test/Transforms/SLPVectorizer/X86/matching-gather-nodes-phi-users.ll
index 166c819098c8c..d649465c9ff12 100644
--- a/llvm/test/Transforms/SLPVectorizer/X86/matching-gather-nodes-phi-users.ll
+++ b/llvm/test/Transforms/SLPVectorizer/X86/matching-gather-nodes-phi-users.ll
@@ -8,7 +8,7 @@
 ; YAML: Function:test
 ; YAML: Args:
 ; YAML:   - String:  'Stores SLP vectorized with cost '
-; YAML:   - Cost:'-6'
+; YAML:   - Cost:'-3'
 ; YAML:   - String:  ' and with tree size '
 ; YAML:   - TreeSize:'14'
 ; YAML: ...
diff --git a/llvm/test/Transforms/SLPVectorizer/X86/phi-node-with-cycle.ll 
b/llvm/test/Transforms/SLPVectorizer/X86/phi-node-with-cycle.ll
new file mode 100644
index 0..22e7e6a8e6624
--- /dev/null
+++ b/llvm/test/Transforms/SLPVectorizer/X86/phi-node-with-cycle.ll
@@ -0,0 +1,59 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 
UTC_ARGS: --version 5
+; RUN: opt -S --passes=slp-vectorizer -mtriple=x86_64-unknown-linux-gnu 
-mcpu=haswell < %s | FileCheck %s
+
+define void @test(float %0) {
+; CHECK-LABEL: define void @test(
+; CHECK-SAME: float [[TMP0:%.*]]) #[[ATTR0:[0-9]+]] {
+; CHECK-NEXT:[[TMP2:%.*]] = insertelement <2 x float> , float [[TMP0]], i32 1
+; CHECK-NEXT:[[TMP3:%.*]] = fdiv <2 x float> [[TMP2]], zeroinitializer
+; CHECK-NEXT:[[TMP4:%.*]] = insertelement <2 x float> , float [[TMP0]], i32 0
+; CHECK-NEXT:[[TMP5:%.*]] = fdiv <2 x float> [[TMP4]], zeroinitializer
+; CHECK-NEXT:br label %[[BB6:.*]]
+; CHECK:   [[BB6]]:
+; CHECK-NEXT:[[TMP7:%.*]] = fmul <2 x float> [[TMP5]], zeroinitializer
+; CHECK-NEXT:[[T

[llvm-branch-commits] [llvm] release/20.x: [SLP] Check for PHI nodes (potentially cycles!) when checking dependencies: Backport Attempt 3 (PR #128371)

2025-02-22 Thread via llvm-branch-commits

llvmbot wrote:




@llvm/pr-subscribers-llvm-transforms

Author: None (Zentrik)


Changes

Backport 
https://github.com/llvm/llvm-project/commit/ac217ee389d63124432e5e6890851a678f7a676b

This fixes https://github.com/llvm/llvm-project/pull/127294 by updating the 
test at `llvm/test/Transforms/SLPVectorizer/X86/perfect-matched-reused-bv.ll`


---
Full diff: https://github.com/llvm/llvm-project/pull/128371.diff


5 Files Affected:

- (modified) llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp (+9-1) 
- (modified) llvm/test/Transforms/SLPVectorizer/X86/delayed-gather-emission.ll 
(+1-1) 
- (modified) 
llvm/test/Transforms/SLPVectorizer/X86/matching-gather-nodes-phi-users.ll 
(+1-1) 
- (modified) 
llvm/test/Transforms/SLPVectorizer/X86/perfect-matched-reused-bv.ll (+7-6) 
- (added) llvm/test/Transforms/SLPVectorizer/X86/phi-node-with-cycle.ll (+59) 


``diff
diff --git a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp 
b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
index 19963e780ebd3..7b20eda550095 100644
--- a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
+++ b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
@@ -13181,8 +13181,16 @@ BoUpSLP::isGatherShuffledSingleRegisterEntry(
   continue;
 // If the user instruction is used for some reason in different
 // vectorized nodes - make it depend on index.
+// If any vector node is PHI node, this dependency might not work
+// because of cycle dependencies, so disable it.
 if (TEUseEI.UserTE != UseEI.UserTE &&
-TEUseEI.UserTE->Idx < UseEI.UserTE->Idx)
+(TEUseEI.UserTE->Idx < UseEI.UserTE->Idx ||
+ any_of(
+ VectorizableTree,
+ [](const std::unique_ptr &TE) {
+   return TE->State == TreeEntry::Vectorize &&
+  TE->getOpcode() == Instruction::PHI;
+ })))
   continue;
   }
 
diff --git a/llvm/test/Transforms/SLPVectorizer/X86/delayed-gather-emission.ll 
b/llvm/test/Transforms/SLPVectorizer/X86/delayed-gather-emission.ll
index 5562291dbb6be..bf3f0c4df74e4 100644
--- a/llvm/test/Transforms/SLPVectorizer/X86/delayed-gather-emission.ll
+++ b/llvm/test/Transforms/SLPVectorizer/X86/delayed-gather-emission.ll
@@ -31,7 +31,7 @@ define void @test() {
 ; CHECK-NEXT:[[TOBOOL:%.*]] = fcmp une float [[I2]], 0.00e+00
 ; CHECK-NEXT:[[TMP8:%.*]] = shufflevector <2 x float> [[TMP5]], <2 x 
float> poison, <2 x i32> 
 ; CHECK-NEXT:[[TMP9]] = insertelement <2 x float> [[TMP8]], float [[I2]], 
i32 0
-; CHECK-NEXT:[[TMP10]] = shufflevector <2 x float> [[TMP9]], <2 x float> 
[[TMP2]], <2 x i32> 
+; CHECK-NEXT:[[TMP10]] = insertelement <2 x float> [[TMP2]], float [[I2]], 
i32 0
 ; CHECK-NEXT:br i1 [[TOBOOL]], label [[BB1]], label [[BB2]]
 ;
 entry:
diff --git 
a/llvm/test/Transforms/SLPVectorizer/X86/matching-gather-nodes-phi-users.ll 
b/llvm/test/Transforms/SLPVectorizer/X86/matching-gather-nodes-phi-users.ll
index 166c819098c8c..d649465c9ff12 100644
--- a/llvm/test/Transforms/SLPVectorizer/X86/matching-gather-nodes-phi-users.ll
+++ b/llvm/test/Transforms/SLPVectorizer/X86/matching-gather-nodes-phi-users.ll
@@ -8,7 +8,7 @@
 ; YAML: Function:test
 ; YAML: Args:
 ; YAML:   - String:  'Stores SLP vectorized with cost '
-; YAML:   - Cost:'-6'
+; YAML:   - Cost:'-3'
 ; YAML:   - String:  ' and with tree size '
 ; YAML:   - TreeSize:'14'
 ; YAML: ...
diff --git 
a/llvm/test/Transforms/SLPVectorizer/X86/perfect-matched-reused-bv.ll 
b/llvm/test/Transforms/SLPVectorizer/X86/perfect-matched-reused-bv.ll
index 1053e0fc10669..c4a49242a5583 100644
--- a/llvm/test/Transforms/SLPVectorizer/X86/perfect-matched-reused-bv.ll
+++ b/llvm/test/Transforms/SLPVectorizer/X86/perfect-matched-reused-bv.ll
@@ -7,16 +7,17 @@ define void @test() {
 ; CHECK-NEXT:  [[BB:.*]]:
 ; CHECK-NEXT:br label %[[BB1:.*]]
 ; CHECK:   [[BB1]]:
-; CHECK-NEXT:[[TMP0:%.*]] = phi <2 x i32> [ zeroinitializer, %[[BB]] ], [ 
[[TMP4:%.*]], %[[BB4:.*]] ]
-; CHECK-NEXT:[[TMP1:%.*]] = or <2 x i32> [[TMP0]], zeroinitializer
+; CHECK-NEXT:[[PHI:%.*]] = phi i32 [ 0, %[[BB]] ], [ [[ADD6:%.*]], 
%[[BB4:.*]] ]
+; CHECK-NEXT:[[PHI2:%.*]] = phi i32 [ 0, %[[BB]] ], [ 0, %[[BB4]] ]
+; CHECK-NEXT:[[OR:%.*]] = or i32 [[PHI2]], 0
+; CHECK-NEXT:[[OR3:%.*]] = or i32 [[PHI]], 0
 ; CHECK-NEXT:br i1 false, label %[[BB7:.*]], label %[[BB4]]
 ; CHECK:   [[BB4]]:
-; CHECK-NEXT:[[TMP2:%.*]] = shufflevector <2 x i32> [[TMP0]], <2 x i32> 
, <2 x i32> 
-; CHECK-NEXT:[[TMP3:%.*]] = add <2 x i32> zeroinitializer, [[TMP2]]
-; CHECK-NEXT:[[TMP4]] = add <2 x i32> zeroinitializer, [[TMP2]]
+; CHECK-NEXT:[[ADD6]] = add i32 [[PHI]], 0
 ; CHECK-NEXT:br i1 false, label %[[BB7]], label %[[BB1]]
 ; CHECK:   [[BB7]]:
-; CHECK-NEXT:[[TMP5:%.*]] = phi <2 x i32> [ [[TMP1]], %[[BB1]] ], [ 
[[TMP3]], %[[BB4]] ]
+; CHECK-NEXT:[[PHI8:%.*]] =

[llvm-branch-commits] [llvm] release/20.x: [SLP] Check for PHI nodes (potentially cycles!) when checking dependencies: Backport Attempt 3 (PR #128371)

2025-02-22 Thread via llvm-branch-commits

https://github.com/Zentrik edited 
https://github.com/llvm/llvm-project/pull/128371
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] release/20.x: [SLP] Check for PHI nodes (potentially cycles!) when checking dependencies: Backport Attempt 3 (PR #128371)

2025-02-22 Thread via llvm-branch-commits

Zentrik wrote:

I suspect I don't have permissions to add this to the milestone.

https://github.com/llvm/llvm-project/pull/128371
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] release/20.x: [DAGCombiner] visitFREEZE: Early exit when N is deleted (#128161) (PR #128283)

2025-02-22 Thread Simon Pilgrim via llvm-branch-commits

https://github.com/RKSimon approved this pull request.

LGTM 

https://github.com/llvm/llvm-project/pull/128283
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] RegAllocFast: Fix verifier errors after assigning to reserved registers (PR #128281)

2025-02-22 Thread Matt Arsenault via llvm-branch-commits

https://github.com/arsenm updated 
https://github.com/llvm/llvm-project/pull/128281

>From 8d9b1ee1f1e67bd5f946a9e88e14fc7e0a34248f Mon Sep 17 00:00:00 2001
From: Matt Arsenault 
Date: Thu, 12 Dec 2024 10:53:41 +0900
Subject: [PATCH] RegAllocFast: Fix verifier errors after assigning to reserved
 registers

---
 llvm/lib/CodeGen/RegAllocFast.cpp | 41 ---
 ...ut-of-registers-error-all-regs-reserved.ll |  3 +-
 2 files changed, 28 insertions(+), 16 deletions(-)

diff --git a/llvm/lib/CodeGen/RegAllocFast.cpp 
b/llvm/lib/CodeGen/RegAllocFast.cpp
index 14128dafbe4ee..9f92c11826cce 100644
--- a/llvm/lib/CodeGen/RegAllocFast.cpp
+++ b/llvm/lib/CodeGen/RegAllocFast.cpp
@@ -206,6 +206,7 @@ class RegAllocFastImpl {
 bool Error = false;  ///< Could not allocate.
 
 explicit LiveReg(Register VirtReg) : VirtReg(VirtReg) {}
+explicit LiveReg() {}
 
 unsigned getSparseSetIndex() const { return VirtReg.virtRegIndex(); }
   };
@@ -216,7 +217,7 @@ class RegAllocFastImpl {
   LiveRegMap LiveVirtRegs;
 
   /// Stores assigned virtual registers present in the bundle MI.
-  DenseMap BundleVirtRegsMap;
+  DenseMap BundleVirtRegsMap;
 
   DenseMap> LiveDbgValueMap;
   /// List of DBG_VALUE that we encountered without the vreg being assigned
@@ -374,7 +375,8 @@ class RegAllocFastImpl {
 SmallSet &PrologLiveIns) const;
 
   void reloadAtBegin(MachineBasicBlock &MBB);
-  bool setPhysReg(MachineInstr &MI, MachineOperand &MO, MCPhysReg PhysReg);
+  bool setPhysReg(MachineInstr &MI, MachineOperand &MO,
+  const LiveReg &Assignment);
 
   Register traceCopies(Register VirtReg) const;
   Register traceCopyChain(Register Reg) const;
@@ -1005,7 +1007,8 @@ void RegAllocFastImpl::allocVirtRegUndef(MachineOperand 
&MO) {
 MO.setSubReg(0);
   }
   MO.setReg(PhysReg);
-  MO.setIsRenamable(true);
+  if (!LRI->Error)
+MO.setIsRenamable(true);
 }
 
 /// Variation of defineVirtReg() with special handling for livethrough regs
@@ -1109,10 +1112,10 @@ bool RegAllocFastImpl::defineVirtReg(MachineInstr &MI, 
unsigned OpNum,
 LRI->Reloaded = false;
   }
   if (MI.getOpcode() == TargetOpcode::BUNDLE) {
-BundleVirtRegsMap[VirtReg] = PhysReg;
+BundleVirtRegsMap[VirtReg] = *LRI;
   }
   markRegUsedInInstr(PhysReg);
-  return setPhysReg(MI, MO, PhysReg);
+  return setPhysReg(MI, MO, *LRI);
 }
 
 /// Allocates a register for a VirtReg use.
@@ -1158,10 +1161,10 @@ bool RegAllocFastImpl::useVirtReg(MachineInstr &MI, 
MachineOperand &MO,
   LRI->LastUse = &MI;
 
   if (MI.getOpcode() == TargetOpcode::BUNDLE) {
-BundleVirtRegsMap[VirtReg] = LRI->PhysReg;
+BundleVirtRegsMap[VirtReg] = *LRI;
   }
   markRegUsedInInstr(LRI->PhysReg);
-  return setPhysReg(MI, MO, LRI->PhysReg);
+  return setPhysReg(MI, MO, *LRI);
 }
 
 /// Query a physical register to use as a filler in contexts where the
@@ -1215,16 +1218,27 @@ MCPhysReg RegAllocFastImpl::getErrorAssignment(const 
LiveReg &LR,
 /// Changes operand OpNum in MI the refer the PhysReg, considering subregs.
 /// \return true if MI's MachineOperands were re-arranged/invalidated.
 bool RegAllocFastImpl::setPhysReg(MachineInstr &MI, MachineOperand &MO,
-  MCPhysReg PhysReg) {
+  const LiveReg &Assignment) {
+  MCPhysReg PhysReg = Assignment.PhysReg;
+  assert(PhysReg && "assignments should always be to a valid physreg");
+
+  if (LLVM_UNLIKELY(Assignment.Error)) {
+// Make sure we don't set renamable in error scenarios, as we may have
+// assigned to a reserved register.
+if (MO.isUse())
+  MO.setIsUndef(true);
+  }
+
   if (!MO.getSubReg()) {
 MO.setReg(PhysReg);
-MO.setIsRenamable(true);
+MO.setIsRenamable(!Assignment.Error);
 return false;
   }
 
   // Handle subregister index.
-  MO.setReg(PhysReg ? TRI->getSubReg(PhysReg, MO.getSubReg()) : MCRegister());
-  MO.setIsRenamable(true);
+  MO.setReg(TRI->getSubReg(PhysReg, MO.getSubReg()));
+  MO.setIsRenamable(!Assignment.Error);
+
   // Note: We leave the subreg number around a little longer in case of defs.
   // This is so that the register freeing logic in allocateInstruction can 
still
   // recognize this as subregister defs. The code there will clear the number.
@@ -1706,7 +1720,7 @@ void RegAllocFastImpl::handleDebugValue(MachineInstr &MI) 
{
 if (LRI != LiveVirtRegs.end() && LRI->PhysReg) {
   // Update every use of Reg within MI.
   for (auto &RegMO : DbgOps)
-setPhysReg(MI, *RegMO, LRI->PhysReg);
+setPhysReg(MI, *RegMO, *LRI);
 } else {
   DanglingDbgValues[Reg].push_back(&MI);
 }
@@ -1729,8 +1743,7 @@ void RegAllocFastImpl::handleBundle(MachineInstr &MI) {
   if (!Reg.isVirtual() || !shouldAllocateRegister(Reg))
 continue;
 
-  DenseMap::iterator DI;
-  DI = BundleVirtRegsMap.find(Reg);
+  DenseMap::iterator DI = BundleVirtRegsMap.find(Reg);
   assert(DI != BundleVirtRegsMap

[llvm-branch-commits] [llvm] RegAllocFast: Fix verifier errors after assigning to reserved registers (PR #128281)

2025-02-22 Thread Matt Arsenault via llvm-branch-commits

https://github.com/arsenm updated 
https://github.com/llvm/llvm-project/pull/128281

>From 8d9b1ee1f1e67bd5f946a9e88e14fc7e0a34248f Mon Sep 17 00:00:00 2001
From: Matt Arsenault 
Date: Thu, 12 Dec 2024 10:53:41 +0900
Subject: [PATCH] RegAllocFast: Fix verifier errors after assigning to reserved
 registers

---
 llvm/lib/CodeGen/RegAllocFast.cpp | 41 ---
 ...ut-of-registers-error-all-regs-reserved.ll |  3 +-
 2 files changed, 28 insertions(+), 16 deletions(-)

diff --git a/llvm/lib/CodeGen/RegAllocFast.cpp 
b/llvm/lib/CodeGen/RegAllocFast.cpp
index 14128dafbe4ee..9f92c11826cce 100644
--- a/llvm/lib/CodeGen/RegAllocFast.cpp
+++ b/llvm/lib/CodeGen/RegAllocFast.cpp
@@ -206,6 +206,7 @@ class RegAllocFastImpl {
 bool Error = false;  ///< Could not allocate.
 
 explicit LiveReg(Register VirtReg) : VirtReg(VirtReg) {}
+explicit LiveReg() {}
 
 unsigned getSparseSetIndex() const { return VirtReg.virtRegIndex(); }
   };
@@ -216,7 +217,7 @@ class RegAllocFastImpl {
   LiveRegMap LiveVirtRegs;
 
   /// Stores assigned virtual registers present in the bundle MI.
-  DenseMap BundleVirtRegsMap;
+  DenseMap BundleVirtRegsMap;
 
   DenseMap> LiveDbgValueMap;
   /// List of DBG_VALUE that we encountered without the vreg being assigned
@@ -374,7 +375,8 @@ class RegAllocFastImpl {
 SmallSet &PrologLiveIns) const;
 
   void reloadAtBegin(MachineBasicBlock &MBB);
-  bool setPhysReg(MachineInstr &MI, MachineOperand &MO, MCPhysReg PhysReg);
+  bool setPhysReg(MachineInstr &MI, MachineOperand &MO,
+  const LiveReg &Assignment);
 
   Register traceCopies(Register VirtReg) const;
   Register traceCopyChain(Register Reg) const;
@@ -1005,7 +1007,8 @@ void RegAllocFastImpl::allocVirtRegUndef(MachineOperand 
&MO) {
 MO.setSubReg(0);
   }
   MO.setReg(PhysReg);
-  MO.setIsRenamable(true);
+  if (!LRI->Error)
+MO.setIsRenamable(true);
 }
 
 /// Variation of defineVirtReg() with special handling for livethrough regs
@@ -1109,10 +1112,10 @@ bool RegAllocFastImpl::defineVirtReg(MachineInstr &MI, 
unsigned OpNum,
 LRI->Reloaded = false;
   }
   if (MI.getOpcode() == TargetOpcode::BUNDLE) {
-BundleVirtRegsMap[VirtReg] = PhysReg;
+BundleVirtRegsMap[VirtReg] = *LRI;
   }
   markRegUsedInInstr(PhysReg);
-  return setPhysReg(MI, MO, PhysReg);
+  return setPhysReg(MI, MO, *LRI);
 }
 
 /// Allocates a register for a VirtReg use.
@@ -1158,10 +1161,10 @@ bool RegAllocFastImpl::useVirtReg(MachineInstr &MI, 
MachineOperand &MO,
   LRI->LastUse = &MI;
 
   if (MI.getOpcode() == TargetOpcode::BUNDLE) {
-BundleVirtRegsMap[VirtReg] = LRI->PhysReg;
+BundleVirtRegsMap[VirtReg] = *LRI;
   }
   markRegUsedInInstr(LRI->PhysReg);
-  return setPhysReg(MI, MO, LRI->PhysReg);
+  return setPhysReg(MI, MO, *LRI);
 }
 
 /// Query a physical register to use as a filler in contexts where the
@@ -1215,16 +1218,27 @@ MCPhysReg RegAllocFastImpl::getErrorAssignment(const 
LiveReg &LR,
 /// Changes operand OpNum in MI the refer the PhysReg, considering subregs.
 /// \return true if MI's MachineOperands were re-arranged/invalidated.
 bool RegAllocFastImpl::setPhysReg(MachineInstr &MI, MachineOperand &MO,
-  MCPhysReg PhysReg) {
+  const LiveReg &Assignment) {
+  MCPhysReg PhysReg = Assignment.PhysReg;
+  assert(PhysReg && "assignments should always be to a valid physreg");
+
+  if (LLVM_UNLIKELY(Assignment.Error)) {
+// Make sure we don't set renamable in error scenarios, as we may have
+// assigned to a reserved register.
+if (MO.isUse())
+  MO.setIsUndef(true);
+  }
+
   if (!MO.getSubReg()) {
 MO.setReg(PhysReg);
-MO.setIsRenamable(true);
+MO.setIsRenamable(!Assignment.Error);
 return false;
   }
 
   // Handle subregister index.
-  MO.setReg(PhysReg ? TRI->getSubReg(PhysReg, MO.getSubReg()) : MCRegister());
-  MO.setIsRenamable(true);
+  MO.setReg(TRI->getSubReg(PhysReg, MO.getSubReg()));
+  MO.setIsRenamable(!Assignment.Error);
+
   // Note: We leave the subreg number around a little longer in case of defs.
   // This is so that the register freeing logic in allocateInstruction can 
still
   // recognize this as subregister defs. The code there will clear the number.
@@ -1706,7 +1720,7 @@ void RegAllocFastImpl::handleDebugValue(MachineInstr &MI) 
{
 if (LRI != LiveVirtRegs.end() && LRI->PhysReg) {
   // Update every use of Reg within MI.
   for (auto &RegMO : DbgOps)
-setPhysReg(MI, *RegMO, LRI->PhysReg);
+setPhysReg(MI, *RegMO, *LRI);
 } else {
   DanglingDbgValues[Reg].push_back(&MI);
 }
@@ -1729,8 +1743,7 @@ void RegAllocFastImpl::handleBundle(MachineInstr &MI) {
   if (!Reg.isVirtual() || !shouldAllocateRegister(Reg))
 continue;
 
-  DenseMap::iterator DI;
-  DI = BundleVirtRegsMap.find(Reg);
+  DenseMap::iterator DI = BundleVirtRegsMap.find(Reg);
   assert(DI != BundleVirtRegsMap

[llvm-branch-commits] [llvm] RegAllocFast: Fix verifier errors after assigning to reserved registers (PR #128281)

2025-02-22 Thread Christudasan Devadasan via llvm-branch-commits


@@ -1005,7 +1007,8 @@ void RegAllocFastImpl::allocVirtRegUndef(MachineOperand 
&MO) {
 MO.setSubReg(0);
   }
   MO.setReg(PhysReg);
-  MO.setIsRenamable(true);
+  if (!LRI->Error)
+MO.setIsRenamable(true);

cdevadas wrote:

```suggestion
  MO.setIsRenamable(!LRI->Error);
```

https://github.com/llvm/llvm-project/pull/128281
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [clang] c47780a - Revert "[analyzer] Delay the checker constructions after parsing (#127409)"

2025-02-22 Thread via llvm-branch-commits

Author: Balazs Benics
Date: 2025-02-22T11:42:41+01:00
New Revision: c47780aa45385a617e9beeb032896beebb2f3411

URL: 
https://github.com/llvm/llvm-project/commit/c47780aa45385a617e9beeb032896beebb2f3411
DIFF: 
https://github.com/llvm/llvm-project/commit/c47780aa45385a617e9beeb032896beebb2f3411.diff

LOG: Revert "[analyzer] Delay the checker constructions after parsing (#127409)"

This reverts commit f0088ee87cecfb442921251b4a70f96cf3474a15.

Added: 


Modified: 
clang/lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp
clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp

Removed: 




diff  --git a/clang/lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp 
b/clang/lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp
index 10dfa73cc522d..da2d16ca9b5dd 100644
--- a/clang/lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp
@@ -40,28 +40,17 @@ enum class OpenVariant {
   OpenAt
 };
 
-static std::optional getCreateFlagValue(const ASTContext &Ctx,
- const Preprocessor &PP) {
-  std::optional MacroVal = tryExpandAsInteger("O_CREAT", PP);
-  if (MacroVal.has_value())
-return MacroVal;
-
-  // If we failed, fall-back to known values.
-  if (Ctx.getTargetInfo().getTriple().getVendor() == llvm::Triple::Apple)
-return {0x0200};
-  return MacroVal;
-}
-
 namespace {
 
-class UnixAPIMisuseChecker : public Checker {
+class UnixAPIMisuseChecker
+: public Checker> {
   const BugType BT_open{this, "Improper use of 'open'", categories::UnixAPI};
   const BugType BT_getline{this, "Improper use of getdelim",
categories::UnixAPI};
   const BugType BT_pthreadOnce{this, "Improper use of 'pthread_once'",
categories::UnixAPI};
   const BugType BT_ArgumentNull{this, "NULL pointer", categories::UnixAPI};
-  const std::optional Val_O_CREAT;
+  mutable std::optional Val_O_CREAT;
 
   ProgramStateRef
   EnsurePtrNotNull(SVal PtrVal, const Expr *PtrExpr, CheckerContext &C,
@@ -74,9 +63,6 @@ class UnixAPIMisuseChecker : public Checker {
   const Expr *SizePtrExpr, CheckerContext &C, ProgramStateRef State) const;
 
 public:
-  UnixAPIMisuseChecker(const ASTContext &Ctx, const Preprocessor &PP)
-  : Val_O_CREAT(getCreateFlagValue(Ctx, PP)) {}
-
   void checkASTDecl(const TranslationUnitDecl *TU, AnalysisManager &Mgr,
 BugReporter &BR) const;
 
@@ -148,6 +134,20 @@ ProgramStateRef UnixAPIMisuseChecker::EnsurePtrNotNull(
   return PtrNotNull;
 }
 
+void UnixAPIMisuseChecker::checkASTDecl(const TranslationUnitDecl *TU,
+AnalysisManager &Mgr,
+BugReporter &) const {
+  // The definition of O_CREAT is platform specific.
+  // Try to get the macro value from the preprocessor.
+  Val_O_CREAT = tryExpandAsInteger("O_CREAT", Mgr.getPreprocessor());
+  // If we failed, fall-back to known values.
+  if (!Val_O_CREAT) {
+if (TU->getASTContext().getTargetInfo().getTriple().getVendor() ==
+llvm::Triple::Apple)
+  Val_O_CREAT = 0x0200;
+  }
+}
+
 
//===--===//
 // "open" (man 2 open)
 //===--===/
@@ -262,7 +262,7 @@ void UnixAPIMisuseChecker::CheckOpenVariant(CheckerContext 
&C,
 return;
   }
 
-  if (!Val_O_CREAT.has_value()) {
+  if (!Val_O_CREAT) {
 return;
   }
 
@@ -276,7 +276,7 @@ void UnixAPIMisuseChecker::CheckOpenVariant(CheckerContext 
&C,
   }
   NonLoc oflags = V.castAs();
   NonLoc ocreateFlag = C.getSValBuilder()
-   .makeIntVal(Val_O_CREAT.value(), 
oflagsEx->getType())
+   .makeIntVal(*Val_O_CREAT, oflagsEx->getType())
.castAs();
   SVal maskedFlagsUC = C.getSValBuilder().evalBinOpNN(state, BO_And,
   oflags, ocreateFlag,
@@ -621,17 +621,14 @@ void UnixAPIPortabilityChecker::checkPreStmt(const 
CallExpr *CE,
 // Registration.
 
//===--===//
 
-void ento::registerUnixAPIMisuseChecker(CheckerManager &Mgr) {
-  Mgr.registerChecker(Mgr.getASTContext(),
-Mgr.getPreprocessor());
-}
-bool ento::shouldRegisterUnixAPIMisuseChecker(const CheckerManager &Mgr) {
-  return true;
-}
+#define REGISTER_CHECKER(CHECKERNAME)  
\
+  void ento::register##CHECKERNAME(CheckerManager &mgr) {  
\
+mgr.registerChecker();
\
+  }
\
+   
\
+  bool ento::shouldRegister##

[llvm-branch-commits] [libcxx] [NFC][libc++] Guard agains operator& hijacking. (PR #128351)

2025-02-22 Thread Mark de Wever via llvm-branch-commits

https://github.com/mordante created 
https://github.com/llvm/llvm-project/pull/128351

This set usage of operator& instead of std::addressof seems not be easy to 
"abuse". Some seem easy to misuse, like basic_ostream::operator<<, trying to do 
that results in compilation errors since the `widen` function is not 
specialized for the hijacking character type. Hence there are no tests.

>From 6614bf3ed9221cf47baeede6d06f2c9f2455dfe1 Mon Sep 17 00:00:00 2001
From: Mark de Wever 
Date: Sun, 16 Feb 2025 13:25:15 +0100
Subject: [PATCH] [NFC][libc++] Guard agains operator& hijacking.

This set usage of operator& instead of std::addressof seems not be easy to
"abuse". Some seem easy to misuse, like basic_ostream::operator<<, trying
to do that results in compilation errors since the `widen` function is not
specialized for the hijacking character type. Hence there are no tests.
---
 libcxx/include/__atomic/atomic.h  |  2 +-
 libcxx/include/__atomic/atomic_ref.h  |  2 +-
 libcxx/include/__charconv/traits.h|  3 +-
 libcxx/include/__filesystem/path.h|  3 +-
 libcxx/include/__functional/hash.h| 11 ++--
 libcxx/include/__iterator/aliasing_iterator.h |  2 +-
 libcxx/include/__locale   |  3 +-
 libcxx/include/__mdspan/layout_left.h |  2 +-
 libcxx/include/__mdspan/layout_right.h|  2 +-
 libcxx/include/__mdspan/layout_stride.h   |  7 +--
 libcxx/include/__mdspan/mdspan.h  |  2 +-
 libcxx/include/__memory/shared_count.h|  5 +-
 libcxx/include/__ostream/basic_ostream.h  |  9 ++--
 libcxx/include/__split_buffer |  6 +--
 .../__stop_token/intrusive_shared_ptr.h   |  3 +-
 .../include/__string/constexpr_c_functions.h  |  2 +-
 libcxx/include/__thread/thread.h  |  3 +-
 libcxx/include/cwchar |  3 +-
 libcxx/include/fstream| 10 ++--
 libcxx/include/future | 14 ++---
 libcxx/include/locale |  5 +-
 libcxx/include/regex  | 51 ++-
 libcxx/include/string |  4 +-
 23 files changed, 83 insertions(+), 71 deletions(-)

diff --git a/libcxx/include/__atomic/atomic.h b/libcxx/include/__atomic/atomic.h
index 975a479e20400..8a0996a478e2f 100644
--- a/libcxx/include/__atomic/atomic.h
+++ b/libcxx/include/__atomic/atomic.h
@@ -361,7 +361,7 @@ struct atomic<_Tp> : __atomic_base<_Tp> {
   // https://github.com/llvm/llvm-project/issues/47978
   // clang bug: __old is not updated on failure for atomic::compare_exchange_weak
   // Note __old = __self.load(memory_order_relaxed) will not work
-  std::__cxx_atomic_load_inplace(std::addressof(__self.__a_), &__old, 
memory_order_relaxed);
+  std::__cxx_atomic_load_inplace(std::addressof(__self.__a_), 
std::addressof(__old), memory_order_relaxed);
 }
 #  endif
 __new = __operation(__old, __operand);
diff --git a/libcxx/include/__atomic/atomic_ref.h 
b/libcxx/include/__atomic/atomic_ref.h
index 177ea646b6cd0..b5493662c518e 100644
--- a/libcxx/include/__atomic/atomic_ref.h
+++ b/libcxx/include/__atomic/atomic_ref.h
@@ -119,7 +119,7 @@ struct __atomic_ref_base {
   // that the pointer is going to be aligned properly at runtime because that 
is a (checked) precondition
   // of atomic_ref's constructor.
   static constexpr bool is_always_lock_free =
-  __atomic_always_lock_free(sizeof(_Tp), 
&__get_aligner_instance::__instance);
+  __atomic_always_lock_free(sizeof(_Tp), 
std::addressof(__get_aligner_instance::__instance));
 
   _LIBCPP_HIDE_FROM_ABI bool is_lock_free() const noexcept { return 
__atomic_is_lock_free(sizeof(_Tp), __ptr_); }
 
diff --git a/libcxx/include/__charconv/traits.h 
b/libcxx/include/__charconv/traits.h
index 2cb37c8cfb023..dd1fa2354436a 100644
--- a/libcxx/include/__charconv/traits.h
+++ b/libcxx/include/__charconv/traits.h
@@ -15,6 +15,7 @@
 #include <__charconv/tables.h>
 #include <__charconv/to_chars_base_10.h>
 #include <__config>
+#include <__memory/addressof.h>
 #include <__type_traits/enable_if.h>
 #include <__type_traits/is_unsigned.h>
 #include 
@@ -142,7 +143,7 @@ __mul_overflowed(unsigned short __a, _Tp __b, unsigned 
short& __r) {
 template 
 inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool 
__mul_overflowed(_Tp __a, _Tp __b, _Tp& __r) {
   static_assert(is_unsigned<_Tp>::value, "");
-  return __builtin_mul_overflow(__a, __b, &__r);
+  return __builtin_mul_overflow(__a, __b, std::addressof(__r));
 }
 
 template 
diff --git a/libcxx/include/__filesystem/path.h 
b/libcxx/include/__filesystem/path.h
index 698ae209ae1f8..a2c28bfd79bb9 100644
--- a/libcxx/include/__filesystem/path.h
+++ b/libcxx/include/__filesystem/path.h
@@ -17,6 +17,7 @@
 #include <__fwd/functional.h>
 #include <__iterator/back_insert_iterator.h>
 #include <__iterator/iterator_traits.h>
+#include <__memory/addressof.h>
 #includ

[llvm-branch-commits] [libcxx] [NFC][libc++] Guard agains operator& hijacking. (PR #128351)

2025-02-22 Thread Mark de Wever via llvm-branch-commits

https://github.com/mordante updated 
https://github.com/llvm/llvm-project/pull/128351

>From 921a76f2275b2bde219a9f0a7a434da1f22294f9 Mon Sep 17 00:00:00 2001
From: Mark de Wever 
Date: Sun, 16 Feb 2025 13:25:15 +0100
Subject: [PATCH] [NFC][libc++] Guard agains operator& hijacking.

This set usage of operator& instead of std::addressof seems not be easy to
"abuse". Some seem easy to misuse, like basic_ostream::operator<<, trying
to do that results in compilation errors since the `widen` function is not
specialized for the hijacking character type. Hence there are no tests.
---
 libcxx/include/__atomic/atomic.h  |  2 +-
 libcxx/include/__atomic/atomic_ref.h  |  2 +-
 libcxx/include/__charconv/traits.h|  3 +-
 libcxx/include/__filesystem/path.h|  3 +-
 libcxx/include/__functional/hash.h| 11 ++--
 libcxx/include/__iterator/aliasing_iterator.h |  2 +-
 libcxx/include/__locale   |  3 +-
 libcxx/include/__mdspan/layout_left.h |  2 +-
 libcxx/include/__mdspan/layout_right.h|  2 +-
 libcxx/include/__mdspan/layout_stride.h   |  7 +--
 libcxx/include/__mdspan/mdspan.h  |  2 +-
 libcxx/include/__memory/shared_count.h|  5 +-
 libcxx/include/__ostream/basic_ostream.h  |  9 ++--
 libcxx/include/__split_buffer |  6 +--
 .../__stop_token/intrusive_shared_ptr.h   |  3 +-
 .../include/__string/constexpr_c_functions.h  |  2 +-
 libcxx/include/__thread/thread.h  |  3 +-
 libcxx/include/cwchar |  3 +-
 libcxx/include/fstream| 10 ++--
 libcxx/include/future | 14 ++---
 libcxx/include/locale |  5 +-
 libcxx/include/regex  | 51 ++-
 libcxx/include/string |  4 +-
 23 files changed, 83 insertions(+), 71 deletions(-)

diff --git a/libcxx/include/__atomic/atomic.h b/libcxx/include/__atomic/atomic.h
index 975a479e20400..8a0996a478e2f 100644
--- a/libcxx/include/__atomic/atomic.h
+++ b/libcxx/include/__atomic/atomic.h
@@ -361,7 +361,7 @@ struct atomic<_Tp> : __atomic_base<_Tp> {
   // https://github.com/llvm/llvm-project/issues/47978
   // clang bug: __old is not updated on failure for atomic::compare_exchange_weak
   // Note __old = __self.load(memory_order_relaxed) will not work
-  std::__cxx_atomic_load_inplace(std::addressof(__self.__a_), &__old, 
memory_order_relaxed);
+  std::__cxx_atomic_load_inplace(std::addressof(__self.__a_), 
std::addressof(__old), memory_order_relaxed);
 }
 #  endif
 __new = __operation(__old, __operand);
diff --git a/libcxx/include/__atomic/atomic_ref.h 
b/libcxx/include/__atomic/atomic_ref.h
index 177ea646b6cd0..b5493662c518e 100644
--- a/libcxx/include/__atomic/atomic_ref.h
+++ b/libcxx/include/__atomic/atomic_ref.h
@@ -119,7 +119,7 @@ struct __atomic_ref_base {
   // that the pointer is going to be aligned properly at runtime because that 
is a (checked) precondition
   // of atomic_ref's constructor.
   static constexpr bool is_always_lock_free =
-  __atomic_always_lock_free(sizeof(_Tp), 
&__get_aligner_instance::__instance);
+  __atomic_always_lock_free(sizeof(_Tp), 
std::addressof(__get_aligner_instance::__instance));
 
   _LIBCPP_HIDE_FROM_ABI bool is_lock_free() const noexcept { return 
__atomic_is_lock_free(sizeof(_Tp), __ptr_); }
 
diff --git a/libcxx/include/__charconv/traits.h 
b/libcxx/include/__charconv/traits.h
index 2cb37c8cfb023..dd1fa2354436a 100644
--- a/libcxx/include/__charconv/traits.h
+++ b/libcxx/include/__charconv/traits.h
@@ -15,6 +15,7 @@
 #include <__charconv/tables.h>
 #include <__charconv/to_chars_base_10.h>
 #include <__config>
+#include <__memory/addressof.h>
 #include <__type_traits/enable_if.h>
 #include <__type_traits/is_unsigned.h>
 #include 
@@ -142,7 +143,7 @@ __mul_overflowed(unsigned short __a, _Tp __b, unsigned 
short& __r) {
 template 
 inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool 
__mul_overflowed(_Tp __a, _Tp __b, _Tp& __r) {
   static_assert(is_unsigned<_Tp>::value, "");
-  return __builtin_mul_overflow(__a, __b, &__r);
+  return __builtin_mul_overflow(__a, __b, std::addressof(__r));
 }
 
 template 
diff --git a/libcxx/include/__filesystem/path.h 
b/libcxx/include/__filesystem/path.h
index 698ae209ae1f8..a2c28bfd79bb9 100644
--- a/libcxx/include/__filesystem/path.h
+++ b/libcxx/include/__filesystem/path.h
@@ -17,6 +17,7 @@
 #include <__fwd/functional.h>
 #include <__iterator/back_insert_iterator.h>
 #include <__iterator/iterator_traits.h>
+#include <__memory/addressof.h>
 #include <__type_traits/decay.h>
 #include <__type_traits/enable_if.h>
 #include <__type_traits/is_pointer.h>
@@ -584,7 +585,7 @@ class _LIBCPP_EXPORTED_FROM_ABI path {
 
   template ::value, 
int> = 0>
   _LIBCPP_HIDE_FROM_ABI path& operator+=(_ECharT __x) {
-_PathCVT<_ECharT>::__append_source(__pn_, 

[llvm-branch-commits] [libcxx] [NFC][libc++] Guard agains operator& hijacking. (PR #128351)

2025-02-22 Thread Mark de Wever via llvm-branch-commits

https://github.com/mordante updated 
https://github.com/llvm/llvm-project/pull/128351

>From 05c33c80b15e9f1cd27206f31ff69add583f72af Mon Sep 17 00:00:00 2001
From: Mark de Wever 
Date: Sun, 16 Feb 2025 13:25:15 +0100
Subject: [PATCH] [NFC][libc++] Guard agains operator& hijacking.

This set usage of operator& instead of std::addressof seems not be easy to
"abuse". Some seem easy to misuse, like basic_ostream::operator<<, trying
to do that results in compilation errors since the `widen` function is not
specialized for the hijacking character type. Hence there are no tests.
---
 libcxx/include/__atomic/atomic.h  |  2 +-
 libcxx/include/__atomic/atomic_ref.h  |  2 +-
 libcxx/include/__charconv/traits.h|  3 +-
 libcxx/include/__filesystem/path.h|  3 +-
 libcxx/include/__functional/hash.h| 11 ++--
 libcxx/include/__iterator/aliasing_iterator.h |  3 +-
 libcxx/include/__locale   |  3 +-
 libcxx/include/__mdspan/layout_left.h |  3 +-
 libcxx/include/__mdspan/layout_right.h|  3 +-
 libcxx/include/__mdspan/layout_stride.h   | 10 ++--
 libcxx/include/__mdspan/mdspan.h  |  3 +-
 libcxx/include/__memory/shared_count.h|  5 +-
 libcxx/include/__ostream/basic_ostream.h  |  9 ++--
 libcxx/include/__split_buffer |  6 +--
 .../__stop_token/intrusive_shared_ptr.h   |  3 +-
 .../include/__string/constexpr_c_functions.h  |  2 +-
 libcxx/include/__thread/thread.h  |  3 +-
 libcxx/include/cwchar |  3 +-
 libcxx/include/fstream| 10 ++--
 libcxx/include/future | 10 ++--
 libcxx/include/locale |  5 +-
 libcxx/include/regex  | 51 ++-
 libcxx/include/string |  4 +-
 23 files changed, 87 insertions(+), 70 deletions(-)

diff --git a/libcxx/include/__atomic/atomic.h b/libcxx/include/__atomic/atomic.h
index 975a479e20400..8a0996a478e2f 100644
--- a/libcxx/include/__atomic/atomic.h
+++ b/libcxx/include/__atomic/atomic.h
@@ -361,7 +361,7 @@ struct atomic<_Tp> : __atomic_base<_Tp> {
   // https://github.com/llvm/llvm-project/issues/47978
   // clang bug: __old is not updated on failure for atomic::compare_exchange_weak
   // Note __old = __self.load(memory_order_relaxed) will not work
-  std::__cxx_atomic_load_inplace(std::addressof(__self.__a_), &__old, 
memory_order_relaxed);
+  std::__cxx_atomic_load_inplace(std::addressof(__self.__a_), 
std::addressof(__old), memory_order_relaxed);
 }
 #  endif
 __new = __operation(__old, __operand);
diff --git a/libcxx/include/__atomic/atomic_ref.h 
b/libcxx/include/__atomic/atomic_ref.h
index 177ea646b6cd0..b5493662c518e 100644
--- a/libcxx/include/__atomic/atomic_ref.h
+++ b/libcxx/include/__atomic/atomic_ref.h
@@ -119,7 +119,7 @@ struct __atomic_ref_base {
   // that the pointer is going to be aligned properly at runtime because that 
is a (checked) precondition
   // of atomic_ref's constructor.
   static constexpr bool is_always_lock_free =
-  __atomic_always_lock_free(sizeof(_Tp), 
&__get_aligner_instance::__instance);
+  __atomic_always_lock_free(sizeof(_Tp), 
std::addressof(__get_aligner_instance::__instance));
 
   _LIBCPP_HIDE_FROM_ABI bool is_lock_free() const noexcept { return 
__atomic_is_lock_free(sizeof(_Tp), __ptr_); }
 
diff --git a/libcxx/include/__charconv/traits.h 
b/libcxx/include/__charconv/traits.h
index 2cb37c8cfb023..dd1fa2354436a 100644
--- a/libcxx/include/__charconv/traits.h
+++ b/libcxx/include/__charconv/traits.h
@@ -15,6 +15,7 @@
 #include <__charconv/tables.h>
 #include <__charconv/to_chars_base_10.h>
 #include <__config>
+#include <__memory/addressof.h>
 #include <__type_traits/enable_if.h>
 #include <__type_traits/is_unsigned.h>
 #include 
@@ -142,7 +143,7 @@ __mul_overflowed(unsigned short __a, _Tp __b, unsigned 
short& __r) {
 template 
 inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool 
__mul_overflowed(_Tp __a, _Tp __b, _Tp& __r) {
   static_assert(is_unsigned<_Tp>::value, "");
-  return __builtin_mul_overflow(__a, __b, &__r);
+  return __builtin_mul_overflow(__a, __b, std::addressof(__r));
 }
 
 template 
diff --git a/libcxx/include/__filesystem/path.h 
b/libcxx/include/__filesystem/path.h
index 698ae209ae1f8..a2c28bfd79bb9 100644
--- a/libcxx/include/__filesystem/path.h
+++ b/libcxx/include/__filesystem/path.h
@@ -17,6 +17,7 @@
 #include <__fwd/functional.h>
 #include <__iterator/back_insert_iterator.h>
 #include <__iterator/iterator_traits.h>
+#include <__memory/addressof.h>
 #include <__type_traits/decay.h>
 #include <__type_traits/enable_if.h>
 #include <__type_traits/is_pointer.h>
@@ -584,7 +585,7 @@ class _LIBCPP_EXPORTED_FROM_ABI path {
 
   template ::value, 
int> = 0>
   _LIBCPP_HIDE_FROM_ABI path& operator+=(_ECharT __x) {
-_PathCVT<_ECharT>::__append_source(__pn_, 

[llvm-branch-commits] [llvm] [AMDGPU][Attributor] Rework update of `AAAMDWavesPerEU` (PR #123995)

2025-02-22 Thread Jan Patrick Lehr via llvm-branch-commits

jplehr wrote:

Out of curiosity: I believe this is case three, why would we not want to use 
the user-provided values?

https://github.com/llvm/llvm-project/pull/123995
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [libcxx] [libc++] Clang-tidy operator& hijacker. (PR #128366)

2025-02-22 Thread Mark de Wever via llvm-branch-commits

https://github.com/mordante updated 
https://github.com/llvm/llvm-project/pull/128366

>From ab09f9dfbc3ee01af586b8a5285ac72b4f35e2f9 Mon Sep 17 00:00:00 2001
From: Mark de Wever 
Date: Sun, 16 Feb 2025 12:07:44 +0100
Subject: [PATCH] [libc++] Clang-tidy operator& hijacker.

Guards against introducing new places where operator& depends on a
template type.
---
 .../tools/clang_tidy_checks/CMakeLists.txt|  1 +
 .../tools/clang_tidy_checks/libcpp_module.cpp |  3 ++
 .../robust_against_operator_ampersand.cpp | 47 +++
 .../robust_against_operator_ampersand.hpp | 24 ++
 4 files changed, 75 insertions(+)
 create mode 100644 
libcxx/test/tools/clang_tidy_checks/robust_against_operator_ampersand.cpp
 create mode 100644 
libcxx/test/tools/clang_tidy_checks/robust_against_operator_ampersand.hpp

diff --git a/libcxx/test/tools/clang_tidy_checks/CMakeLists.txt 
b/libcxx/test/tools/clang_tidy_checks/CMakeLists.txt
index 0f8f0e8864d0f..e8e62c3f4ba40 100644
--- a/libcxx/test/tools/clang_tidy_checks/CMakeLists.txt
+++ b/libcxx/test/tools/clang_tidy_checks/CMakeLists.txt
@@ -96,6 +96,7 @@ set(SOURCES
 proper_version_checks.cpp
 qualify_declval.cpp
 robust_against_adl.cpp
+robust_against_operator_ampersand.cpp
 uglify_attributes.cpp
 
 libcpp_module.cpp
diff --git a/libcxx/test/tools/clang_tidy_checks/libcpp_module.cpp 
b/libcxx/test/tools/clang_tidy_checks/libcpp_module.cpp
index bc7c8ce7ec443..a52e25f2cf08f 100644
--- a/libcxx/test/tools/clang_tidy_checks/libcpp_module.cpp
+++ b/libcxx/test/tools/clang_tidy_checks/libcpp_module.cpp
@@ -17,6 +17,7 @@
 #include "proper_version_checks.hpp"
 #include "qualify_declval.hpp"
 #include "robust_against_adl.hpp"
+#include "robust_against_operator_ampersand.hpp"
 #include "uglify_attributes.hpp"
 
 namespace {
@@ -30,6 +31,8 @@ class LibcxxTestModule : public clang::tidy::ClangTidyModule {
 
check_factories.registerCheck("libcpp-nodebug-on-aliases");
 
check_factories.registerCheck("libcpp-cpp-version-check");
 
check_factories.registerCheck("libcpp-robust-against-adl");
+check_factories.registerCheck(
+"libcpp-robust-against-operator-ampersand");
 
check_factories.registerCheck("libcpp-uglify-attributes");
 
check_factories.registerCheck("libcpp-qualify-declval");
   }
diff --git 
a/libcxx/test/tools/clang_tidy_checks/robust_against_operator_ampersand.cpp 
b/libcxx/test/tools/clang_tidy_checks/robust_against_operator_ampersand.cpp
new file mode 100644
index 0..3d3e7d516be9a
--- /dev/null
+++ b/libcxx/test/tools/clang_tidy_checks/robust_against_operator_ampersand.cpp
@@ -0,0 +1,47 @@
+//===--===//
+//
+// 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 "clang-tidy/ClangTidyCheck.h"
+#include "clang-tidy/ClangTidyModuleRegistry.h"
+#include "clang/Tooling/FixIt.h"
+
+#include "robust_against_operator_ampersand.hpp"
+
+// This clang-tidy check ensures that we don't use operator& on dependant
+// types. If the type is user supplied it may call the type's operator&.
+// Instead use std::addressof.
+
+namespace libcpp {
+robust_against_operator_ampersand::robust_against_operator_ampersand(
+llvm::StringRef name, clang::tidy::ClangTidyContext* context)
+: clang::tidy::ClangTidyCheck(name, context), 
disabled_(!context->getLangOpts().CPlusPlus11) {}
+
+void 
robust_against_operator_ampersand::registerMatchers(clang::ast_matchers::MatchFinder*
 finder) {
+  if (disabled_)
+return;
+
+  using namespace clang::ast_matchers;
+  finder->addMatcher(
+  cxxOperatorCallExpr(allOf(hasOperatorName("&"), argumentCountIs(1), 
isTypeDependent()),
+  unless(hasUnaryOperand(dependentScopeDeclRefExpr(
+  .bind("match"),
+  this);
+}
+
+void robust_against_operator_ampersand::check(const 
clang::ast_matchers::MatchFinder::MatchResult& result) {
+  if (const auto* call = result.Nodes.getNodeAs< clang::CXXOperatorCallExpr 
>("match"); call != nullptr) {
+diag(call->getBeginLoc(), "Guard against user provided operator& for 
dependent types.")
+<< clang::FixItHint::CreateReplacement(
+   call->getSourceRange(),
+   (llvm::Twine(
+"std::addressof(" + 
clang::tooling::fixit::getText(*call->getArg(0), *result.Context) + ")"))
+   .str());
+  }
+}
+
+} // namespace libcpp
diff --git 
a/libcxx/test/tools/clang_tidy_checks/robust_against_operator_ampersand.hpp 
b/libcxx/test/tools/clang_tidy_checks/robust_against_operator_ampersand.hpp
new file mode 100644
index 0..e7010de02685c
--- /dev/null
+++ b/libcxx/test/tools/clang_tidy_checks/robust_against_operator_ampers

[llvm-branch-commits] [libcxx] [libc++] Clang-tidy operator& hijacker. (PR #128366)

2025-02-22 Thread via llvm-branch-commits

llvmbot wrote:




@llvm/pr-subscribers-libcxx

Author: Mark de Wever (mordante)


Changes

Guards against introducing new places where operator& depends on a template 
type.

---
Full diff: https://github.com/llvm/llvm-project/pull/128366.diff


4 Files Affected:

- (modified) libcxx/test/tools/clang_tidy_checks/CMakeLists.txt (+1) 
- (modified) libcxx/test/tools/clang_tidy_checks/libcpp_module.cpp (+3) 
- (added) 
libcxx/test/tools/clang_tidy_checks/robust_against_operator_ampersand.cpp (+44) 
- (added) 
libcxx/test/tools/clang_tidy_checks/robust_against_operator_ampersand.hpp (+18) 


``diff
diff --git a/libcxx/test/tools/clang_tidy_checks/CMakeLists.txt 
b/libcxx/test/tools/clang_tidy_checks/CMakeLists.txt
index 0f8f0e8864d0f..e8e62c3f4ba40 100644
--- a/libcxx/test/tools/clang_tidy_checks/CMakeLists.txt
+++ b/libcxx/test/tools/clang_tidy_checks/CMakeLists.txt
@@ -96,6 +96,7 @@ set(SOURCES
 proper_version_checks.cpp
 qualify_declval.cpp
 robust_against_adl.cpp
+robust_against_operator_ampersand.cpp
 uglify_attributes.cpp
 
 libcpp_module.cpp
diff --git a/libcxx/test/tools/clang_tidy_checks/libcpp_module.cpp 
b/libcxx/test/tools/clang_tidy_checks/libcpp_module.cpp
index bc7c8ce7ec443..a52e25f2cf08f 100644
--- a/libcxx/test/tools/clang_tidy_checks/libcpp_module.cpp
+++ b/libcxx/test/tools/clang_tidy_checks/libcpp_module.cpp
@@ -17,6 +17,7 @@
 #include "proper_version_checks.hpp"
 #include "qualify_declval.hpp"
 #include "robust_against_adl.hpp"
+#include "robust_against_operator_ampersand.hpp"
 #include "uglify_attributes.hpp"
 
 namespace {
@@ -30,6 +31,8 @@ class LibcxxTestModule : public clang::tidy::ClangTidyModule {
 
check_factories.registerCheck("libcpp-nodebug-on-aliases");
 
check_factories.registerCheck("libcpp-cpp-version-check");
 
check_factories.registerCheck("libcpp-robust-against-adl");
+check_factories.registerCheck(
+"libcpp-robust-against-operator-ampersand");
 
check_factories.registerCheck("libcpp-uglify-attributes");
 
check_factories.registerCheck("libcpp-qualify-declval");
   }
diff --git 
a/libcxx/test/tools/clang_tidy_checks/robust_against_operator_ampersand.cpp 
b/libcxx/test/tools/clang_tidy_checks/robust_against_operator_ampersand.cpp
new file mode 100644
index 0..8361e0c3eee88
--- /dev/null
+++ b/libcxx/test/tools/clang_tidy_checks/robust_against_operator_ampersand.cpp
@@ -0,0 +1,44 @@
+//===--===//
+//
+// 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 "clang-tidy/ClangTidyCheck.h"
+#include "clang-tidy/ClangTidyModuleRegistry.h"
+#include "clang/Tooling/FixIt.h"
+
+#include "robust_against_operator_ampersand.hpp"
+
+// This clang-tidy check ensures that we don't use operator& on dependant
+// types. If the type is user supplied it may call the type's operator&.
+// Instead use std::addressof.
+
+namespace libcpp {
+robust_against_operator_ampersand::robust_against_operator_ampersand(
+llvm::StringRef name, clang::tidy::ClangTidyContext* context)
+: clang::tidy::ClangTidyCheck(name, context) {}
+
+void 
robust_against_operator_ampersand::registerMatchers(clang::ast_matchers::MatchFinder*
 finder) {
+  using namespace clang::ast_matchers;
+  finder->addMatcher(
+  cxxOperatorCallExpr(allOf(hasOperatorName("&"), argumentCountIs(1), 
isTypeDependent()),
+  unless(hasUnaryOperand(dependentScopeDeclRefExpr(
+  .bind("match"),
+  this);
+}
+
+void robust_against_operator_ampersand::check(const 
clang::ast_matchers::MatchFinder::MatchResult& result) {
+  if (const auto* call = result.Nodes.getNodeAs< clang::CXXOperatorCallExpr 
>("match"); call != nullptr) {
+diag(call->getBeginLoc(), "Guard against user provided operator& for 
dependent types.")
+<< clang::FixItHint::CreateReplacement(
+   call->getSourceRange(),
+   (llvm::Twine(
+"std::addressof(" + 
clang::tooling::fixit::getText(*call->getArg(0), *result.Context) + ")"))
+   .str());
+  }
+}
+
+} // namespace libcpp
diff --git 
a/libcxx/test/tools/clang_tidy_checks/robust_against_operator_ampersand.hpp 
b/libcxx/test/tools/clang_tidy_checks/robust_against_operator_ampersand.hpp
new file mode 100644
index 0..5cdc0baca5c23
--- /dev/null
+++ b/libcxx/test/tools/clang_tidy_checks/robust_against_operator_ampersand.hpp
@@ -0,0 +1,18 @@
+//===--===//
+//
+// 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 LLV

[llvm-branch-commits] [libcxx] [libc++] Clang-tidy operator& hijacker. (PR #128366)

2025-02-22 Thread Mark de Wever via llvm-branch-commits

https://github.com/mordante created 
https://github.com/llvm/llvm-project/pull/128366

Guards against introducing new places where operator& depends on a template 
type.

>From 5a96aadb54b757812dc48f07e753477164d8062a Mon Sep 17 00:00:00 2001
From: Mark de Wever 
Date: Sun, 16 Feb 2025 12:07:44 +0100
Subject: [PATCH] [libc++] Clang-tidy operator& hijacker.

Guards against introducing new places where operator& depends on a
template type.
---
 .../tools/clang_tidy_checks/CMakeLists.txt|  1 +
 .../tools/clang_tidy_checks/libcpp_module.cpp |  3 ++
 .../robust_against_operator_ampersand.cpp | 44 +++
 .../robust_against_operator_ampersand.hpp | 18 
 4 files changed, 66 insertions(+)
 create mode 100644 
libcxx/test/tools/clang_tidy_checks/robust_against_operator_ampersand.cpp
 create mode 100644 
libcxx/test/tools/clang_tidy_checks/robust_against_operator_ampersand.hpp

diff --git a/libcxx/test/tools/clang_tidy_checks/CMakeLists.txt 
b/libcxx/test/tools/clang_tidy_checks/CMakeLists.txt
index 0f8f0e8864d0f..e8e62c3f4ba40 100644
--- a/libcxx/test/tools/clang_tidy_checks/CMakeLists.txt
+++ b/libcxx/test/tools/clang_tidy_checks/CMakeLists.txt
@@ -96,6 +96,7 @@ set(SOURCES
 proper_version_checks.cpp
 qualify_declval.cpp
 robust_against_adl.cpp
+robust_against_operator_ampersand.cpp
 uglify_attributes.cpp
 
 libcpp_module.cpp
diff --git a/libcxx/test/tools/clang_tidy_checks/libcpp_module.cpp 
b/libcxx/test/tools/clang_tidy_checks/libcpp_module.cpp
index bc7c8ce7ec443..a52e25f2cf08f 100644
--- a/libcxx/test/tools/clang_tidy_checks/libcpp_module.cpp
+++ b/libcxx/test/tools/clang_tidy_checks/libcpp_module.cpp
@@ -17,6 +17,7 @@
 #include "proper_version_checks.hpp"
 #include "qualify_declval.hpp"
 #include "robust_against_adl.hpp"
+#include "robust_against_operator_ampersand.hpp"
 #include "uglify_attributes.hpp"
 
 namespace {
@@ -30,6 +31,8 @@ class LibcxxTestModule : public clang::tidy::ClangTidyModule {
 
check_factories.registerCheck("libcpp-nodebug-on-aliases");
 
check_factories.registerCheck("libcpp-cpp-version-check");
 
check_factories.registerCheck("libcpp-robust-against-adl");
+check_factories.registerCheck(
+"libcpp-robust-against-operator-ampersand");
 
check_factories.registerCheck("libcpp-uglify-attributes");
 
check_factories.registerCheck("libcpp-qualify-declval");
   }
diff --git 
a/libcxx/test/tools/clang_tidy_checks/robust_against_operator_ampersand.cpp 
b/libcxx/test/tools/clang_tidy_checks/robust_against_operator_ampersand.cpp
new file mode 100644
index 0..8361e0c3eee88
--- /dev/null
+++ b/libcxx/test/tools/clang_tidy_checks/robust_against_operator_ampersand.cpp
@@ -0,0 +1,44 @@
+//===--===//
+//
+// 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 "clang-tidy/ClangTidyCheck.h"
+#include "clang-tidy/ClangTidyModuleRegistry.h"
+#include "clang/Tooling/FixIt.h"
+
+#include "robust_against_operator_ampersand.hpp"
+
+// This clang-tidy check ensures that we don't use operator& on dependant
+// types. If the type is user supplied it may call the type's operator&.
+// Instead use std::addressof.
+
+namespace libcpp {
+robust_against_operator_ampersand::robust_against_operator_ampersand(
+llvm::StringRef name, clang::tidy::ClangTidyContext* context)
+: clang::tidy::ClangTidyCheck(name, context) {}
+
+void 
robust_against_operator_ampersand::registerMatchers(clang::ast_matchers::MatchFinder*
 finder) {
+  using namespace clang::ast_matchers;
+  finder->addMatcher(
+  cxxOperatorCallExpr(allOf(hasOperatorName("&"), argumentCountIs(1), 
isTypeDependent()),
+  unless(hasUnaryOperand(dependentScopeDeclRefExpr(
+  .bind("match"),
+  this);
+}
+
+void robust_against_operator_ampersand::check(const 
clang::ast_matchers::MatchFinder::MatchResult& result) {
+  if (const auto* call = result.Nodes.getNodeAs< clang::CXXOperatorCallExpr 
>("match"); call != nullptr) {
+diag(call->getBeginLoc(), "Guard against user provided operator& for 
dependent types.")
+<< clang::FixItHint::CreateReplacement(
+   call->getSourceRange(),
+   (llvm::Twine(
+"std::addressof(" + 
clang::tooling::fixit::getText(*call->getArg(0), *result.Context) + ")"))
+   .str());
+  }
+}
+
+} // namespace libcpp
diff --git 
a/libcxx/test/tools/clang_tidy_checks/robust_against_operator_ampersand.hpp 
b/libcxx/test/tools/clang_tidy_checks/robust_against_operator_ampersand.hpp
new file mode 100644
index 0..5cdc0baca5c23
--- /dev/null
+++ b/libcxx/test/tools/clang_tidy_checks/robust_against_operator_ampers

[llvm-branch-commits] [libcxx] [NFC][libc++] Guard agains operator& hijacking. (PR #128351)

2025-02-22 Thread via llvm-branch-commits

llvmbot wrote:




@llvm/pr-subscribers-libcxx

Author: Mark de Wever (mordante)


Changes

This set usage of operator& instead of std::addressof seems not be easy to 
"abuse". Some seem easy to misuse, like basic_ostream::operator<<, trying 
to do that results in compilation errors since the `widen` function is not 
specialized for the hijacking character type. Hence there are no tests.

---

Patch is 34.49 KiB, truncated to 20.00 KiB below, full version: 
https://github.com/llvm/llvm-project/pull/128351.diff


23 Files Affected:

- (modified) libcxx/include/__atomic/atomic.h (+1-1) 
- (modified) libcxx/include/__atomic/atomic_ref.h (+1-1) 
- (modified) libcxx/include/__charconv/traits.h (+2-1) 
- (modified) libcxx/include/__filesystem/path.h (+2-1) 
- (modified) libcxx/include/__functional/hash.h (+6-5) 
- (modified) libcxx/include/__iterator/aliasing_iterator.h (+1-1) 
- (modified) libcxx/include/__locale (+2-1) 
- (modified) libcxx/include/__mdspan/layout_left.h (+1-1) 
- (modified) libcxx/include/__mdspan/layout_right.h (+1-1) 
- (modified) libcxx/include/__mdspan/layout_stride.h (+4-3) 
- (modified) libcxx/include/__mdspan/mdspan.h (+1-1) 
- (modified) libcxx/include/__memory/shared_count.h (+3-2) 
- (modified) libcxx/include/__ostream/basic_ostream.h (+5-4) 
- (modified) libcxx/include/__split_buffer (+3-3) 
- (modified) libcxx/include/__stop_token/intrusive_shared_ptr.h (+2-1) 
- (modified) libcxx/include/__string/constexpr_c_functions.h (+1-1) 
- (modified) libcxx/include/__thread/thread.h (+2-1) 
- (modified) libcxx/include/cwchar (+2-1) 
- (modified) libcxx/include/fstream (+5-5) 
- (modified) libcxx/include/future (+7-7) 
- (modified) libcxx/include/locale (+3-2) 
- (modified) libcxx/include/regex (+26-25) 
- (modified) libcxx/include/string (+2-2) 


``diff
diff --git a/libcxx/include/__atomic/atomic.h b/libcxx/include/__atomic/atomic.h
index 975a479e20400..8a0996a478e2f 100644
--- a/libcxx/include/__atomic/atomic.h
+++ b/libcxx/include/__atomic/atomic.h
@@ -361,7 +361,7 @@ struct atomic<_Tp> : __atomic_base<_Tp> {
   // https://github.com/llvm/llvm-project/issues/47978
   // clang bug: __old is not updated on failure for atomic::compare_exchange_weak
   // Note __old = __self.load(memory_order_relaxed) will not work
-  std::__cxx_atomic_load_inplace(std::addressof(__self.__a_), &__old, 
memory_order_relaxed);
+  std::__cxx_atomic_load_inplace(std::addressof(__self.__a_), 
std::addressof(__old), memory_order_relaxed);
 }
 #  endif
 __new = __operation(__old, __operand);
diff --git a/libcxx/include/__atomic/atomic_ref.h 
b/libcxx/include/__atomic/atomic_ref.h
index 177ea646b6cd0..b5493662c518e 100644
--- a/libcxx/include/__atomic/atomic_ref.h
+++ b/libcxx/include/__atomic/atomic_ref.h
@@ -119,7 +119,7 @@ struct __atomic_ref_base {
   // that the pointer is going to be aligned properly at runtime because that 
is a (checked) precondition
   // of atomic_ref's constructor.
   static constexpr bool is_always_lock_free =
-  __atomic_always_lock_free(sizeof(_Tp), 
&__get_aligner_instance::__instance);
+  __atomic_always_lock_free(sizeof(_Tp), 
std::addressof(__get_aligner_instance::__instance));
 
   _LIBCPP_HIDE_FROM_ABI bool is_lock_free() const noexcept { return 
__atomic_is_lock_free(sizeof(_Tp), __ptr_); }
 
diff --git a/libcxx/include/__charconv/traits.h 
b/libcxx/include/__charconv/traits.h
index 2cb37c8cfb023..dd1fa2354436a 100644
--- a/libcxx/include/__charconv/traits.h
+++ b/libcxx/include/__charconv/traits.h
@@ -15,6 +15,7 @@
 #include <__charconv/tables.h>
 #include <__charconv/to_chars_base_10.h>
 #include <__config>
+#include <__memory/addressof.h>
 #include <__type_traits/enable_if.h>
 #include <__type_traits/is_unsigned.h>
 #include 
@@ -142,7 +143,7 @@ __mul_overflowed(unsigned short __a, _Tp __b, unsigned 
short& __r) {
 template 
 inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool 
__mul_overflowed(_Tp __a, _Tp __b, _Tp& __r) {
   static_assert(is_unsigned<_Tp>::value, "");
-  return __builtin_mul_overflow(__a, __b, &__r);
+  return __builtin_mul_overflow(__a, __b, std::addressof(__r));
 }
 
 template 
diff --git a/libcxx/include/__filesystem/path.h 
b/libcxx/include/__filesystem/path.h
index 698ae209ae1f8..a2c28bfd79bb9 100644
--- a/libcxx/include/__filesystem/path.h
+++ b/libcxx/include/__filesystem/path.h
@@ -17,6 +17,7 @@
 #include <__fwd/functional.h>
 #include <__iterator/back_insert_iterator.h>
 #include <__iterator/iterator_traits.h>
+#include <__memory/addressof.h>
 #include <__type_traits/decay.h>
 #include <__type_traits/enable_if.h>
 #include <__type_traits/is_pointer.h>
@@ -584,7 +585,7 @@ class _LIBCPP_EXPORTED_FROM_ABI path {
 
   template ::value, 
int> = 0>
   _LIBCPP_HIDE_FROM_ABI path& operator+=(_ECharT __x) {
-_PathCVT<_ECharT>::__append_source(__pn_, basic_string_view<_ECharT>(&__x, 
1));
+_PathCVT<_ECharT>::__append_source(__pn_, 
basic_string_view<_ECharT>(std::add

[llvm-branch-commits] [libcxx] [NFC][libc++] Guard agains operator& hijacking. (PR #128351)

2025-02-22 Thread via llvm-branch-commits

github-actions[bot] wrote:




:warning: C/C++ code formatter, clang-format found issues in your code. 
:warning:



You can test this locally with the following command:


``bash
git-clang-format --diff 0e79268c4ac3b91dd5742bc04d8d5658bf587b0e 
6614bf3ed9221cf47baeede6d06f2c9f2455dfe1 --extensions ,h -- 
libcxx/include/__atomic/atomic.h libcxx/include/__atomic/atomic_ref.h 
libcxx/include/__charconv/traits.h libcxx/include/__filesystem/path.h 
libcxx/include/__functional/hash.h 
libcxx/include/__iterator/aliasing_iterator.h libcxx/include/__locale 
libcxx/include/__mdspan/layout_left.h libcxx/include/__mdspan/layout_right.h 
libcxx/include/__mdspan/layout_stride.h libcxx/include/__mdspan/mdspan.h 
libcxx/include/__memory/shared_count.h libcxx/include/__ostream/basic_ostream.h 
libcxx/include/__split_buffer 
libcxx/include/__stop_token/intrusive_shared_ptr.h 
libcxx/include/__string/constexpr_c_functions.h 
libcxx/include/__thread/thread.h libcxx/include/cwchar libcxx/include/fstream 
libcxx/include/future libcxx/include/locale libcxx/include/regex 
libcxx/include/string
``





View the diff from clang-format here.


``diff
diff --git a/libcxx/include/regex b/libcxx/include/regex
index 617431efca..c04cbc316d 100644
--- a/libcxx/include/regex
+++ b/libcxx/include/regex
@@ -2177,7 +2177,8 @@ void __bracket_expression<_CharT, 
_Traits>::__exec(__state& __s) const {
 }
   }
   if (!__equivalences_.empty()) {
-string_type __s2 = 
__traits_.transform_primary(std::addressof(__ch2.first), 
std::addressof(__ch2.first) + 2);
+string_type __s2 =
+__traits_.transform_primary(std::addressof(__ch2.first), 
std::addressof(__ch2.first) + 2);
 for (size_t __i = 0; __i < __equivalences_.size(); ++__i) {
   if (__s2 == __equivalences_[__i]) {
 __found = true;
@@ -2225,7 +2226,8 @@ void __bracket_expression<_CharT, 
_Traits>::__exec(__state& __s) const {
   }
 }
 if (!__ranges_.empty()) {
-  string_type __s2 = __collate_ ? 
__traits_.transform(std::addressof(__ch), std::addressof(__ch) + 1) : 
string_type(1, __ch);
+  string_type __s2 =
+  __collate_ ? __traits_.transform(std::addressof(__ch), 
std::addressof(__ch) + 1) : string_type(1, __ch);
   for (size_t __i = 0; __i < __ranges_.size(); ++__i) {
 if (__ranges_[__i].first <= __s2 && __s2 <= __ranges_[__i].second) {
   __found = true;
@@ -5678,7 +5680,8 @@ template 
 bool regex_token_iterator<_BidirectionalIterator, _CharT, 
_Traits>::operator==(const regex_token_iterator& __x) const {
   if (__result_ == nullptr && __x.__result_ == nullptr)
 return true;
-  if (__result_ == std::addressof(__suffix_) && __x.__result_ == 
std::addressof(__x.__suffix_) && __suffix_ == __x.__suffix_)
+  if (__result_ == std::addressof(__suffix_) && __x.__result_ == 
std::addressof(__x.__suffix_) &&
+  __suffix_ == __x.__suffix_)
 return true;
   if (__result_ == nullptr || __x.__result_ == nullptr)
 return false;

``




https://github.com/llvm/llvm-project/pull/128351
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [libcxx] [NFC][libc++] Guard against operator& hijacking. (PR #128351)

2025-02-22 Thread Mark de Wever via llvm-branch-commits

https://github.com/mordante edited 
https://github.com/llvm/llvm-project/pull/128351
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] [AMDGPU][Attributor] Rework update of `AAAMDWavesPerEU` (PR #123995)

2025-02-22 Thread Matt Arsenault via llvm-branch-commits

arsenm wrote:

> Out of curiosity: I believe this is case three, why would we not want to use 
> the user-provided values?

A library use does not have the usage context. It may have specified a bounds 
to avoid negatively impacting occupancy of some unknown calling kernel. If we 
know the bounds of the concrete calling kernels, the function should specialize 
for its bound 

https://github.com/llvm/llvm-project/pull/123995
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [flang] [flang][draft] update fir.coordinate_of to carry the fields (PR #127231)

2025-02-22 Thread Valentin Clement バレンタイン クレメン via llvm-branch-commits

https://github.com/clementval approved this pull request.


https://github.com/llvm/llvm-project/pull/127231
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] RegAllocFast: Fix verifier errors after assigning to reserved registers (PR #128281)

2025-02-22 Thread Matt Arsenault via llvm-branch-commits

https://github.com/arsenm updated 
https://github.com/llvm/llvm-project/pull/128281

>From d93b45487feba452868706b31e6e59e0bb1a5d19 Mon Sep 17 00:00:00 2001
From: Matt Arsenault 
Date: Thu, 12 Dec 2024 10:53:41 +0900
Subject: [PATCH] RegAllocFast: Fix verifier errors after assigning to reserved
 registers

---
 llvm/lib/CodeGen/RegAllocFast.cpp | 41 ---
 ...ut-of-registers-error-all-regs-reserved.ll |  3 +-
 2 files changed, 28 insertions(+), 16 deletions(-)

diff --git a/llvm/lib/CodeGen/RegAllocFast.cpp 
b/llvm/lib/CodeGen/RegAllocFast.cpp
index 14128dafbe4ee..9f92c11826cce 100644
--- a/llvm/lib/CodeGen/RegAllocFast.cpp
+++ b/llvm/lib/CodeGen/RegAllocFast.cpp
@@ -206,6 +206,7 @@ class RegAllocFastImpl {
 bool Error = false;  ///< Could not allocate.
 
 explicit LiveReg(Register VirtReg) : VirtReg(VirtReg) {}
+explicit LiveReg() {}
 
 unsigned getSparseSetIndex() const { return VirtReg.virtRegIndex(); }
   };
@@ -216,7 +217,7 @@ class RegAllocFastImpl {
   LiveRegMap LiveVirtRegs;
 
   /// Stores assigned virtual registers present in the bundle MI.
-  DenseMap BundleVirtRegsMap;
+  DenseMap BundleVirtRegsMap;
 
   DenseMap> LiveDbgValueMap;
   /// List of DBG_VALUE that we encountered without the vreg being assigned
@@ -374,7 +375,8 @@ class RegAllocFastImpl {
 SmallSet &PrologLiveIns) const;
 
   void reloadAtBegin(MachineBasicBlock &MBB);
-  bool setPhysReg(MachineInstr &MI, MachineOperand &MO, MCPhysReg PhysReg);
+  bool setPhysReg(MachineInstr &MI, MachineOperand &MO,
+  const LiveReg &Assignment);
 
   Register traceCopies(Register VirtReg) const;
   Register traceCopyChain(Register Reg) const;
@@ -1005,7 +1007,8 @@ void RegAllocFastImpl::allocVirtRegUndef(MachineOperand 
&MO) {
 MO.setSubReg(0);
   }
   MO.setReg(PhysReg);
-  MO.setIsRenamable(true);
+  if (!LRI->Error)
+MO.setIsRenamable(true);
 }
 
 /// Variation of defineVirtReg() with special handling for livethrough regs
@@ -1109,10 +1112,10 @@ bool RegAllocFastImpl::defineVirtReg(MachineInstr &MI, 
unsigned OpNum,
 LRI->Reloaded = false;
   }
   if (MI.getOpcode() == TargetOpcode::BUNDLE) {
-BundleVirtRegsMap[VirtReg] = PhysReg;
+BundleVirtRegsMap[VirtReg] = *LRI;
   }
   markRegUsedInInstr(PhysReg);
-  return setPhysReg(MI, MO, PhysReg);
+  return setPhysReg(MI, MO, *LRI);
 }
 
 /// Allocates a register for a VirtReg use.
@@ -1158,10 +1161,10 @@ bool RegAllocFastImpl::useVirtReg(MachineInstr &MI, 
MachineOperand &MO,
   LRI->LastUse = &MI;
 
   if (MI.getOpcode() == TargetOpcode::BUNDLE) {
-BundleVirtRegsMap[VirtReg] = LRI->PhysReg;
+BundleVirtRegsMap[VirtReg] = *LRI;
   }
   markRegUsedInInstr(LRI->PhysReg);
-  return setPhysReg(MI, MO, LRI->PhysReg);
+  return setPhysReg(MI, MO, *LRI);
 }
 
 /// Query a physical register to use as a filler in contexts where the
@@ -1215,16 +1218,27 @@ MCPhysReg RegAllocFastImpl::getErrorAssignment(const 
LiveReg &LR,
 /// Changes operand OpNum in MI the refer the PhysReg, considering subregs.
 /// \return true if MI's MachineOperands were re-arranged/invalidated.
 bool RegAllocFastImpl::setPhysReg(MachineInstr &MI, MachineOperand &MO,
-  MCPhysReg PhysReg) {
+  const LiveReg &Assignment) {
+  MCPhysReg PhysReg = Assignment.PhysReg;
+  assert(PhysReg && "assignments should always be to a valid physreg");
+
+  if (LLVM_UNLIKELY(Assignment.Error)) {
+// Make sure we don't set renamable in error scenarios, as we may have
+// assigned to a reserved register.
+if (MO.isUse())
+  MO.setIsUndef(true);
+  }
+
   if (!MO.getSubReg()) {
 MO.setReg(PhysReg);
-MO.setIsRenamable(true);
+MO.setIsRenamable(!Assignment.Error);
 return false;
   }
 
   // Handle subregister index.
-  MO.setReg(PhysReg ? TRI->getSubReg(PhysReg, MO.getSubReg()) : MCRegister());
-  MO.setIsRenamable(true);
+  MO.setReg(TRI->getSubReg(PhysReg, MO.getSubReg()));
+  MO.setIsRenamable(!Assignment.Error);
+
   // Note: We leave the subreg number around a little longer in case of defs.
   // This is so that the register freeing logic in allocateInstruction can 
still
   // recognize this as subregister defs. The code there will clear the number.
@@ -1706,7 +1720,7 @@ void RegAllocFastImpl::handleDebugValue(MachineInstr &MI) 
{
 if (LRI != LiveVirtRegs.end() && LRI->PhysReg) {
   // Update every use of Reg within MI.
   for (auto &RegMO : DbgOps)
-setPhysReg(MI, *RegMO, LRI->PhysReg);
+setPhysReg(MI, *RegMO, *LRI);
 } else {
   DanglingDbgValues[Reg].push_back(&MI);
 }
@@ -1729,8 +1743,7 @@ void RegAllocFastImpl::handleBundle(MachineInstr &MI) {
   if (!Reg.isVirtual() || !shouldAllocateRegister(Reg))
 continue;
 
-  DenseMap::iterator DI;
-  DI = BundleVirtRegsMap.find(Reg);
+  DenseMap::iterator DI = BundleVirtRegsMap.find(Reg);
   assert(DI != BundleVirtRegsMap