[llvm-branch-commits] [clang] [llvm] [llvm] Introduce type id operand bundle (PR #87573)

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

https://github.com/nikic requested changes to this pull request.

Missing LangRef specification.

More generally, a lot of context seems to be missing here. I see you link two 
RFCs from 2021, neither of which appear to have received a response, and 
neither of which actually describe the proposed IR level changes. A key 
question for me would be why this is an operand bundle rather than metadata. At 
least from a cursory look, the use of an operand bundle doesn't seem 
appropriate. Would I be correct in assuming that dropping the operand bundle 
would *not* result in a correctness issue?

https://github.com/llvm/llvm-project/pull/87573
___
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] [MC/DC] Handle __builtin_expect as if parenthses (PR #125405)

2025-02-02 Thread NAKAMURA Takumi via llvm-branch-commits

https://github.com/chapuni created 
https://github.com/llvm/llvm-project/pull/125405

Fixes #124565

>From f70a6c8686617963c55854c2d8c6fa8607ca0806 Mon Sep 17 00:00:00 2001
From: NAKAMURA Takumi 
Date: Sun, 2 Feb 2025 22:10:25 +0900
Subject: [PATCH] [MC/DC] Handle __builtin_expect as if parenthses

Fixes #124565
---
 clang/include/clang/AST/IgnoreExpr.h|  9 +
 clang/lib/CodeGen/CodeGenFunction.cpp   | 13 -
 clang/lib/CodeGen/CodeGenPGO.cpp|  8 +---
 clang/test/CoverageMapping/mcdc-nested-expr.cpp |  5 -
 4 files changed, 26 insertions(+), 9 deletions(-)

diff --git a/clang/include/clang/AST/IgnoreExpr.h 
b/clang/include/clang/AST/IgnoreExpr.h
index 917bada61fa6fdd..c366aa176674815 100644
--- a/clang/include/clang/AST/IgnoreExpr.h
+++ b/clang/include/clang/AST/IgnoreExpr.h
@@ -134,6 +134,15 @@ inline Expr 
*IgnoreElidableImplicitConstructorSingleStep(Expr *E) {
   return E;
 }
 
+inline Expr *IgnoreBuiltinExpectSingleStep(Expr *E) {
+  if (auto *CE = dyn_cast(E)) {
+if (const FunctionDecl *FD = CE->getDirectCallee())
+  if (FD->getBuiltinID() == Builtin::BI__builtin_expect)
+return CE->getArg(0);
+  }
+  return E;
+}
+
 inline Expr *IgnoreImplicitAsWrittenSingleStep(Expr *E) {
   if (auto *ICE = dyn_cast(E))
 return ICE->getSubExprAsWritten();
diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp 
b/clang/lib/CodeGen/CodeGenFunction.cpp
index bbef277a524480b..05766aa7693d2e1 100644
--- a/clang/lib/CodeGen/CodeGenFunction.cpp
+++ b/clang/lib/CodeGen/CodeGenFunction.cpp
@@ -27,6 +27,7 @@
 #include "clang/AST/Decl.h"
 #include "clang/AST/DeclCXX.h"
 #include "clang/AST/Expr.h"
+#include "clang/AST/IgnoreExpr.h"
 #include "clang/AST/StmtCXX.h"
 #include "clang/AST/StmtObjC.h"
 #include "clang/Basic/Builtins.h"
@@ -1748,12 +1749,14 @@ bool 
CodeGenFunction::ConstantFoldsToSimpleInteger(const Expr *Cond,
 
 /// Strip parentheses and simplistic logical-NOT operators.
 const Expr *CodeGenFunction::stripCond(const Expr *C) {
-  while (const UnaryOperator *Op = dyn_cast(C->IgnoreParens())) 
{
-if (Op->getOpcode() != UO_LNot)
-  break;
-C = Op->getSubExpr();
+  while (true) {
+const Expr *SC = IgnoreExprNodes(C, IgnoreParensSingleStep,
+ IgnoreBuiltinExpectSingleStep,
+ IgnoreImplicitCastsSingleStep);
+if (C == SC)
+  return SC;
+C = SC;
   }
-  return C->IgnoreParens();
 }
 
 /// Determine whether the given condition is an instrumentable condition
diff --git a/clang/lib/CodeGen/CodeGenPGO.cpp b/clang/lib/CodeGen/CodeGenPGO.cpp
index 792373839107f0a..0fd49b880bba305 100644
--- a/clang/lib/CodeGen/CodeGenPGO.cpp
+++ b/clang/lib/CodeGen/CodeGenPGO.cpp
@@ -247,8 +247,9 @@ struct MapRegionCounters : public 
RecursiveASTVisitor {
 }
 
 if (const Expr *E = dyn_cast(S)) {
-  const BinaryOperator *BinOp = 
dyn_cast(E->IgnoreParens());
-  if (BinOp && BinOp->isLogicalOp()) {
+  if (const auto *BinOp =
+  dyn_cast(CodeGenFunction::stripCond(E));
+  BinOp && BinOp->isLogicalOp()) {
 /// Check for "split-nested" logical operators. This happens when a new
 /// boolean expression logical-op nest is encountered within an 
existing
 /// boolean expression, separated by a non-logical operator.  For
@@ -280,7 +281,8 @@ struct MapRegionCounters : public 
RecursiveASTVisitor {
   return true;
 
 if (const Expr *E = dyn_cast(S)) {
-  const BinaryOperator *BinOp = 
dyn_cast(E->IgnoreParens());
+  const BinaryOperator *BinOp =
+  dyn_cast(CodeGenFunction::stripCond(E));
   if (BinOp && BinOp->isLogicalOp()) {
 assert(LogOpStack.back() == BinOp);
 LogOpStack.pop_back();
diff --git a/clang/test/CoverageMapping/mcdc-nested-expr.cpp 
b/clang/test/CoverageMapping/mcdc-nested-expr.cpp
index bb82873e3b600d0..0614a2b7ab8c101 100644
--- a/clang/test/CoverageMapping/mcdc-nested-expr.cpp
+++ b/clang/test/CoverageMapping/mcdc-nested-expr.cpp
@@ -21,8 +21,11 @@ bool func_condop(bool a, bool b, bool c) {
 // Treated as parentheses.
 // CHECK: func_expect{{.*}}:
 bool func_expect(bool a, bool b, bool c) {
-  // WARN: :[[@LINE+1]]:10: warning: unsupported MC/DC boolean expression; 
contains an operation with a nested boolean expression.
   return a || __builtin_expect(b && c, true);
+  // CHECK:  Decision,File 0, [[@LINE-1]]:10 -> [[#L:@LINE-1]]:45 = M:4, C:3
+  // CHECK:  Branch,File 0, [[#L]]:10 -> [[#L]]:11 = (#0 - #1), #1 [1,0,2]
+  // CHECK:  Branch,File 0, [[#L]]:32 -> [[#L]]:33 = #2, (#1 - #2) [2,3,0]
+  // CHECK:  Branch,File 0, [[#L]]:37 -> [[#L]]:38 = #3, (#2 - #3) [3,0,0]
 }
 
 // LNot among BinOp(s)

___
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] [MC/DC] Handle __builtin_expect as if parenthses (PR #125405)

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

llvmbot wrote:




@llvm/pr-subscribers-clang-codegen

Author: NAKAMURA Takumi (chapuni)


Changes

Fixes #124565

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


4 Files Affected:

- (modified) clang/include/clang/AST/IgnoreExpr.h (+9) 
- (modified) clang/lib/CodeGen/CodeGenFunction.cpp (+8-5) 
- (modified) clang/lib/CodeGen/CodeGenPGO.cpp (+5-3) 
- (modified) clang/test/CoverageMapping/mcdc-nested-expr.cpp (+4-1) 


``diff
diff --git a/clang/include/clang/AST/IgnoreExpr.h 
b/clang/include/clang/AST/IgnoreExpr.h
index 917bada61fa6fd..c366aa17667481 100644
--- a/clang/include/clang/AST/IgnoreExpr.h
+++ b/clang/include/clang/AST/IgnoreExpr.h
@@ -134,6 +134,15 @@ inline Expr 
*IgnoreElidableImplicitConstructorSingleStep(Expr *E) {
   return E;
 }
 
+inline Expr *IgnoreBuiltinExpectSingleStep(Expr *E) {
+  if (auto *CE = dyn_cast(E)) {
+if (const FunctionDecl *FD = CE->getDirectCallee())
+  if (FD->getBuiltinID() == Builtin::BI__builtin_expect)
+return CE->getArg(0);
+  }
+  return E;
+}
+
 inline Expr *IgnoreImplicitAsWrittenSingleStep(Expr *E) {
   if (auto *ICE = dyn_cast(E))
 return ICE->getSubExprAsWritten();
diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp 
b/clang/lib/CodeGen/CodeGenFunction.cpp
index bbef277a524480..05766aa7693d2e 100644
--- a/clang/lib/CodeGen/CodeGenFunction.cpp
+++ b/clang/lib/CodeGen/CodeGenFunction.cpp
@@ -27,6 +27,7 @@
 #include "clang/AST/Decl.h"
 #include "clang/AST/DeclCXX.h"
 #include "clang/AST/Expr.h"
+#include "clang/AST/IgnoreExpr.h"
 #include "clang/AST/StmtCXX.h"
 #include "clang/AST/StmtObjC.h"
 #include "clang/Basic/Builtins.h"
@@ -1748,12 +1749,14 @@ bool 
CodeGenFunction::ConstantFoldsToSimpleInteger(const Expr *Cond,
 
 /// Strip parentheses and simplistic logical-NOT operators.
 const Expr *CodeGenFunction::stripCond(const Expr *C) {
-  while (const UnaryOperator *Op = dyn_cast(C->IgnoreParens())) 
{
-if (Op->getOpcode() != UO_LNot)
-  break;
-C = Op->getSubExpr();
+  while (true) {
+const Expr *SC = IgnoreExprNodes(C, IgnoreParensSingleStep,
+ IgnoreBuiltinExpectSingleStep,
+ IgnoreImplicitCastsSingleStep);
+if (C == SC)
+  return SC;
+C = SC;
   }
-  return C->IgnoreParens();
 }
 
 /// Determine whether the given condition is an instrumentable condition
diff --git a/clang/lib/CodeGen/CodeGenPGO.cpp b/clang/lib/CodeGen/CodeGenPGO.cpp
index 792373839107f0..0fd49b880bba30 100644
--- a/clang/lib/CodeGen/CodeGenPGO.cpp
+++ b/clang/lib/CodeGen/CodeGenPGO.cpp
@@ -247,8 +247,9 @@ struct MapRegionCounters : public 
RecursiveASTVisitor {
 }
 
 if (const Expr *E = dyn_cast(S)) {
-  const BinaryOperator *BinOp = 
dyn_cast(E->IgnoreParens());
-  if (BinOp && BinOp->isLogicalOp()) {
+  if (const auto *BinOp =
+  dyn_cast(CodeGenFunction::stripCond(E));
+  BinOp && BinOp->isLogicalOp()) {
 /// Check for "split-nested" logical operators. This happens when a new
 /// boolean expression logical-op nest is encountered within an 
existing
 /// boolean expression, separated by a non-logical operator.  For
@@ -280,7 +281,8 @@ struct MapRegionCounters : public 
RecursiveASTVisitor {
   return true;
 
 if (const Expr *E = dyn_cast(S)) {
-  const BinaryOperator *BinOp = 
dyn_cast(E->IgnoreParens());
+  const BinaryOperator *BinOp =
+  dyn_cast(CodeGenFunction::stripCond(E));
   if (BinOp && BinOp->isLogicalOp()) {
 assert(LogOpStack.back() == BinOp);
 LogOpStack.pop_back();
diff --git a/clang/test/CoverageMapping/mcdc-nested-expr.cpp 
b/clang/test/CoverageMapping/mcdc-nested-expr.cpp
index bb82873e3b600d..0614a2b7ab8c10 100644
--- a/clang/test/CoverageMapping/mcdc-nested-expr.cpp
+++ b/clang/test/CoverageMapping/mcdc-nested-expr.cpp
@@ -21,8 +21,11 @@ bool func_condop(bool a, bool b, bool c) {
 // Treated as parentheses.
 // CHECK: func_expect{{.*}}:
 bool func_expect(bool a, bool b, bool c) {
-  // WARN: :[[@LINE+1]]:10: warning: unsupported MC/DC boolean expression; 
contains an operation with a nested boolean expression.
   return a || __builtin_expect(b && c, true);
+  // CHECK:  Decision,File 0, [[@LINE-1]]:10 -> [[#L:@LINE-1]]:45 = M:4, C:3
+  // CHECK:  Branch,File 0, [[#L]]:10 -> [[#L]]:11 = (#0 - #1), #1 [1,0,2]
+  // CHECK:  Branch,File 0, [[#L]]:32 -> [[#L]]:33 = #2, (#1 - #2) [2,3,0]
+  // CHECK:  Branch,File 0, [[#L]]:37 -> [[#L]]:38 = #3, (#2 - #3) [3,0,0]
 }
 
 // LNot among BinOp(s)

``




https://github.com/llvm/llvm-project/pull/125405
___
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] [MC/DC] Handle __builtin_expect as if parenthses (PR #125405)

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

llvmbot wrote:




@llvm/pr-subscribers-clang

Author: NAKAMURA Takumi (chapuni)


Changes

Fixes #124565

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


4 Files Affected:

- (modified) clang/include/clang/AST/IgnoreExpr.h (+9) 
- (modified) clang/lib/CodeGen/CodeGenFunction.cpp (+8-5) 
- (modified) clang/lib/CodeGen/CodeGenPGO.cpp (+5-3) 
- (modified) clang/test/CoverageMapping/mcdc-nested-expr.cpp (+4-1) 


``diff
diff --git a/clang/include/clang/AST/IgnoreExpr.h 
b/clang/include/clang/AST/IgnoreExpr.h
index 917bada61fa6fd..c366aa17667481 100644
--- a/clang/include/clang/AST/IgnoreExpr.h
+++ b/clang/include/clang/AST/IgnoreExpr.h
@@ -134,6 +134,15 @@ inline Expr 
*IgnoreElidableImplicitConstructorSingleStep(Expr *E) {
   return E;
 }
 
+inline Expr *IgnoreBuiltinExpectSingleStep(Expr *E) {
+  if (auto *CE = dyn_cast(E)) {
+if (const FunctionDecl *FD = CE->getDirectCallee())
+  if (FD->getBuiltinID() == Builtin::BI__builtin_expect)
+return CE->getArg(0);
+  }
+  return E;
+}
+
 inline Expr *IgnoreImplicitAsWrittenSingleStep(Expr *E) {
   if (auto *ICE = dyn_cast(E))
 return ICE->getSubExprAsWritten();
diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp 
b/clang/lib/CodeGen/CodeGenFunction.cpp
index bbef277a524480..05766aa7693d2e 100644
--- a/clang/lib/CodeGen/CodeGenFunction.cpp
+++ b/clang/lib/CodeGen/CodeGenFunction.cpp
@@ -27,6 +27,7 @@
 #include "clang/AST/Decl.h"
 #include "clang/AST/DeclCXX.h"
 #include "clang/AST/Expr.h"
+#include "clang/AST/IgnoreExpr.h"
 #include "clang/AST/StmtCXX.h"
 #include "clang/AST/StmtObjC.h"
 #include "clang/Basic/Builtins.h"
@@ -1748,12 +1749,14 @@ bool 
CodeGenFunction::ConstantFoldsToSimpleInteger(const Expr *Cond,
 
 /// Strip parentheses and simplistic logical-NOT operators.
 const Expr *CodeGenFunction::stripCond(const Expr *C) {
-  while (const UnaryOperator *Op = dyn_cast(C->IgnoreParens())) 
{
-if (Op->getOpcode() != UO_LNot)
-  break;
-C = Op->getSubExpr();
+  while (true) {
+const Expr *SC = IgnoreExprNodes(C, IgnoreParensSingleStep,
+ IgnoreBuiltinExpectSingleStep,
+ IgnoreImplicitCastsSingleStep);
+if (C == SC)
+  return SC;
+C = SC;
   }
-  return C->IgnoreParens();
 }
 
 /// Determine whether the given condition is an instrumentable condition
diff --git a/clang/lib/CodeGen/CodeGenPGO.cpp b/clang/lib/CodeGen/CodeGenPGO.cpp
index 792373839107f0..0fd49b880bba30 100644
--- a/clang/lib/CodeGen/CodeGenPGO.cpp
+++ b/clang/lib/CodeGen/CodeGenPGO.cpp
@@ -247,8 +247,9 @@ struct MapRegionCounters : public 
RecursiveASTVisitor {
 }
 
 if (const Expr *E = dyn_cast(S)) {
-  const BinaryOperator *BinOp = 
dyn_cast(E->IgnoreParens());
-  if (BinOp && BinOp->isLogicalOp()) {
+  if (const auto *BinOp =
+  dyn_cast(CodeGenFunction::stripCond(E));
+  BinOp && BinOp->isLogicalOp()) {
 /// Check for "split-nested" logical operators. This happens when a new
 /// boolean expression logical-op nest is encountered within an 
existing
 /// boolean expression, separated by a non-logical operator.  For
@@ -280,7 +281,8 @@ struct MapRegionCounters : public 
RecursiveASTVisitor {
   return true;
 
 if (const Expr *E = dyn_cast(S)) {
-  const BinaryOperator *BinOp = 
dyn_cast(E->IgnoreParens());
+  const BinaryOperator *BinOp =
+  dyn_cast(CodeGenFunction::stripCond(E));
   if (BinOp && BinOp->isLogicalOp()) {
 assert(LogOpStack.back() == BinOp);
 LogOpStack.pop_back();
diff --git a/clang/test/CoverageMapping/mcdc-nested-expr.cpp 
b/clang/test/CoverageMapping/mcdc-nested-expr.cpp
index bb82873e3b600d..0614a2b7ab8c10 100644
--- a/clang/test/CoverageMapping/mcdc-nested-expr.cpp
+++ b/clang/test/CoverageMapping/mcdc-nested-expr.cpp
@@ -21,8 +21,11 @@ bool func_condop(bool a, bool b, bool c) {
 // Treated as parentheses.
 // CHECK: func_expect{{.*}}:
 bool func_expect(bool a, bool b, bool c) {
-  // WARN: :[[@LINE+1]]:10: warning: unsupported MC/DC boolean expression; 
contains an operation with a nested boolean expression.
   return a || __builtin_expect(b && c, true);
+  // CHECK:  Decision,File 0, [[@LINE-1]]:10 -> [[#L:@LINE-1]]:45 = M:4, C:3
+  // CHECK:  Branch,File 0, [[#L]]:10 -> [[#L]]:11 = (#0 - #1), #1 [1,0,2]
+  // CHECK:  Branch,File 0, [[#L]]:32 -> [[#L]]:33 = #2, (#1 - #2) [2,3,0]
+  // CHECK:  Branch,File 0, [[#L]]:37 -> [[#L]]:38 = #3, (#2 - #3) [3,0,0]
 }
 
 // LNot among BinOp(s)

``




https://github.com/llvm/llvm-project/pull/125405
___
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] [MC/DC] Enable usage of `!` among `&&` and `||` (PR #125406)

2025-02-02 Thread NAKAMURA Takumi via llvm-branch-commits

https://github.com/chapuni created 
https://github.com/llvm/llvm-project/pull/125406

In the current implementation, `!(a || b) && c` was not treated as one Decision 
with three terms.

Fixes #124563

>From f2cf50e10b59d7d461967baef4d589c9282d0f6d Mon Sep 17 00:00:00 2001
From: NAKAMURA Takumi 
Date: Sun, 2 Feb 2025 22:11:51 +0900
Subject: [PATCH] [MC/DC] Enable usage of `!` among `&&` and `||`

In the current implementation, `!(a || b) && c` was not treated as one
Decision with three terms.

Fixes #124563
---
 clang/include/clang/AST/IgnoreExpr.h  |  8 ++
 clang/lib/CodeGen/CodeGenFunction.cpp | 12 ++-
 clang/lib/CodeGen/CodeGenPGO.cpp  |  8 +-
 clang/lib/CodeGen/CoverageMappingGen.cpp  | 12 +++
 .../test/CoverageMapping/mcdc-nested-expr.cpp |  6 +-
 clang/test/Profile/c-mcdc-not.c   | 95 +++
 6 files changed, 132 insertions(+), 9 deletions(-)

diff --git a/clang/include/clang/AST/IgnoreExpr.h 
b/clang/include/clang/AST/IgnoreExpr.h
index 917bada61fa6fd..c48c0c0daf8151 100644
--- a/clang/include/clang/AST/IgnoreExpr.h
+++ b/clang/include/clang/AST/IgnoreExpr.h
@@ -134,6 +134,14 @@ inline Expr 
*IgnoreElidableImplicitConstructorSingleStep(Expr *E) {
   return E;
 }
 
+inline Expr *IgnoreUOpLNotSingleStep(Expr *E) {
+  if (auto *UO = dyn_cast(E)) {
+if (UO->getOpcode() == UO_LNot)
+  return UO->getSubExpr();
+  }
+  return E;
+}
+
 inline Expr *IgnoreImplicitAsWrittenSingleStep(Expr *E) {
   if (auto *ICE = dyn_cast(E))
 return ICE->getSubExprAsWritten();
diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp 
b/clang/lib/CodeGen/CodeGenFunction.cpp
index bbef277a524480..2c380ac926b1e7 100644
--- a/clang/lib/CodeGen/CodeGenFunction.cpp
+++ b/clang/lib/CodeGen/CodeGenFunction.cpp
@@ -27,6 +27,7 @@
 #include "clang/AST/Decl.h"
 #include "clang/AST/DeclCXX.h"
 #include "clang/AST/Expr.h"
+#include "clang/AST/IgnoreExpr.h"
 #include "clang/AST/StmtCXX.h"
 #include "clang/AST/StmtObjC.h"
 #include "clang/Basic/Builtins.h"
@@ -1748,12 +1749,13 @@ bool 
CodeGenFunction::ConstantFoldsToSimpleInteger(const Expr *Cond,
 
 /// Strip parentheses and simplistic logical-NOT operators.
 const Expr *CodeGenFunction::stripCond(const Expr *C) {
-  while (const UnaryOperator *Op = dyn_cast(C->IgnoreParens())) 
{
-if (Op->getOpcode() != UO_LNot)
-  break;
-C = Op->getSubExpr();
+  while (true) {
+const Expr *SC =
+IgnoreExprNodes(C, IgnoreParensSingleStep, IgnoreUOpLNotSingleStep);
+if (C == SC)
+  return SC;
+C = SC;
   }
-  return C->IgnoreParens();
 }
 
 /// Determine whether the given condition is an instrumentable condition
diff --git a/clang/lib/CodeGen/CodeGenPGO.cpp b/clang/lib/CodeGen/CodeGenPGO.cpp
index 792373839107f0..0fd49b880bba30 100644
--- a/clang/lib/CodeGen/CodeGenPGO.cpp
+++ b/clang/lib/CodeGen/CodeGenPGO.cpp
@@ -247,8 +247,9 @@ struct MapRegionCounters : public 
RecursiveASTVisitor {
 }
 
 if (const Expr *E = dyn_cast(S)) {
-  const BinaryOperator *BinOp = 
dyn_cast(E->IgnoreParens());
-  if (BinOp && BinOp->isLogicalOp()) {
+  if (const auto *BinOp =
+  dyn_cast(CodeGenFunction::stripCond(E));
+  BinOp && BinOp->isLogicalOp()) {
 /// Check for "split-nested" logical operators. This happens when a new
 /// boolean expression logical-op nest is encountered within an 
existing
 /// boolean expression, separated by a non-logical operator.  For
@@ -280,7 +281,8 @@ struct MapRegionCounters : public 
RecursiveASTVisitor {
   return true;
 
 if (const Expr *E = dyn_cast(S)) {
-  const BinaryOperator *BinOp = 
dyn_cast(E->IgnoreParens());
+  const BinaryOperator *BinOp =
+  dyn_cast(CodeGenFunction::stripCond(E));
   if (BinOp && BinOp->isLogicalOp()) {
 assert(LogOpStack.back() == BinOp);
 LogOpStack.pop_back();
diff --git a/clang/lib/CodeGen/CoverageMappingGen.cpp 
b/clang/lib/CodeGen/CoverageMappingGen.cpp
index f09157771d2b5c..9bf73cf27a5fa9 100644
--- a/clang/lib/CodeGen/CoverageMappingGen.cpp
+++ b/clang/lib/CodeGen/CoverageMappingGen.cpp
@@ -799,6 +799,12 @@ struct MCDCCoverageBuilder {
   /// Return the LHS Decision ([0,0] if not set).
   const mcdc::ConditionIDs &back() const { return DecisionStack.back(); }
 
+  void swapConds() {
+if (DecisionStack.empty())
+  return;
+
+std::swap(DecisionStack.back()[false], DecisionStack.back()[true]);
+  }
   /// Push the binary operator statement to track the nest level and assign IDs
   /// to the operator's LHS and RHS.  The RHS may be a larger subtree that is
   /// broken up on successive levels.
@@ -2241,6 +2247,12 @@ struct CounterCoverageMappingBuilder
 SM.isInSystemHeader(SM.getSpellingLoc(E->getEndLoc(;
   }
 
+  void VisitUnaryLNot(const UnaryOperator *E) {
+MCDCBuilder.swapConds();
+Visit(E->getSubExpr());
+MCDCBuilder.swapConds();
+  }
+
   void VisitBinLAnd(const BinaryOperator *E) {
 if (isExprInSyste

[llvm-branch-commits] [clang] [MC/DC] Enable usage of `!` among `&&` and `||` (PR #125406)

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

llvmbot wrote:




@llvm/pr-subscribers-clang

Author: NAKAMURA Takumi (chapuni)


Changes

In the current implementation, `!(a || b) && c` was not treated as one 
Decision with three terms.

Fixes #124563

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


6 Files Affected:

- (modified) clang/include/clang/AST/IgnoreExpr.h (+8) 
- (modified) clang/lib/CodeGen/CodeGenFunction.cpp (+7-5) 
- (modified) clang/lib/CodeGen/CodeGenPGO.cpp (+5-3) 
- (modified) clang/lib/CodeGen/CoverageMappingGen.cpp (+12) 
- (modified) clang/test/CoverageMapping/mcdc-nested-expr.cpp (+5-1) 
- (modified) clang/test/Profile/c-mcdc-not.c (+95) 


``diff
diff --git a/clang/include/clang/AST/IgnoreExpr.h 
b/clang/include/clang/AST/IgnoreExpr.h
index 917bada61fa6fdd..c48c0c0daf81517 100644
--- a/clang/include/clang/AST/IgnoreExpr.h
+++ b/clang/include/clang/AST/IgnoreExpr.h
@@ -134,6 +134,14 @@ inline Expr 
*IgnoreElidableImplicitConstructorSingleStep(Expr *E) {
   return E;
 }
 
+inline Expr *IgnoreUOpLNotSingleStep(Expr *E) {
+  if (auto *UO = dyn_cast(E)) {
+if (UO->getOpcode() == UO_LNot)
+  return UO->getSubExpr();
+  }
+  return E;
+}
+
 inline Expr *IgnoreImplicitAsWrittenSingleStep(Expr *E) {
   if (auto *ICE = dyn_cast(E))
 return ICE->getSubExprAsWritten();
diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp 
b/clang/lib/CodeGen/CodeGenFunction.cpp
index bbef277a524480b..2c380ac926b1e70 100644
--- a/clang/lib/CodeGen/CodeGenFunction.cpp
+++ b/clang/lib/CodeGen/CodeGenFunction.cpp
@@ -27,6 +27,7 @@
 #include "clang/AST/Decl.h"
 #include "clang/AST/DeclCXX.h"
 #include "clang/AST/Expr.h"
+#include "clang/AST/IgnoreExpr.h"
 #include "clang/AST/StmtCXX.h"
 #include "clang/AST/StmtObjC.h"
 #include "clang/Basic/Builtins.h"
@@ -1748,12 +1749,13 @@ bool 
CodeGenFunction::ConstantFoldsToSimpleInteger(const Expr *Cond,
 
 /// Strip parentheses and simplistic logical-NOT operators.
 const Expr *CodeGenFunction::stripCond(const Expr *C) {
-  while (const UnaryOperator *Op = dyn_cast(C->IgnoreParens())) 
{
-if (Op->getOpcode() != UO_LNot)
-  break;
-C = Op->getSubExpr();
+  while (true) {
+const Expr *SC =
+IgnoreExprNodes(C, IgnoreParensSingleStep, IgnoreUOpLNotSingleStep);
+if (C == SC)
+  return SC;
+C = SC;
   }
-  return C->IgnoreParens();
 }
 
 /// Determine whether the given condition is an instrumentable condition
diff --git a/clang/lib/CodeGen/CodeGenPGO.cpp b/clang/lib/CodeGen/CodeGenPGO.cpp
index 792373839107f0a..0fd49b880bba305 100644
--- a/clang/lib/CodeGen/CodeGenPGO.cpp
+++ b/clang/lib/CodeGen/CodeGenPGO.cpp
@@ -247,8 +247,9 @@ struct MapRegionCounters : public 
RecursiveASTVisitor {
 }
 
 if (const Expr *E = dyn_cast(S)) {
-  const BinaryOperator *BinOp = 
dyn_cast(E->IgnoreParens());
-  if (BinOp && BinOp->isLogicalOp()) {
+  if (const auto *BinOp =
+  dyn_cast(CodeGenFunction::stripCond(E));
+  BinOp && BinOp->isLogicalOp()) {
 /// Check for "split-nested" logical operators. This happens when a new
 /// boolean expression logical-op nest is encountered within an 
existing
 /// boolean expression, separated by a non-logical operator.  For
@@ -280,7 +281,8 @@ struct MapRegionCounters : public 
RecursiveASTVisitor {
   return true;
 
 if (const Expr *E = dyn_cast(S)) {
-  const BinaryOperator *BinOp = 
dyn_cast(E->IgnoreParens());
+  const BinaryOperator *BinOp =
+  dyn_cast(CodeGenFunction::stripCond(E));
   if (BinOp && BinOp->isLogicalOp()) {
 assert(LogOpStack.back() == BinOp);
 LogOpStack.pop_back();
diff --git a/clang/lib/CodeGen/CoverageMappingGen.cpp 
b/clang/lib/CodeGen/CoverageMappingGen.cpp
index f09157771d2b5c0..9bf73cf27a5fa9a 100644
--- a/clang/lib/CodeGen/CoverageMappingGen.cpp
+++ b/clang/lib/CodeGen/CoverageMappingGen.cpp
@@ -799,6 +799,12 @@ struct MCDCCoverageBuilder {
   /// Return the LHS Decision ([0,0] if not set).
   const mcdc::ConditionIDs &back() const { return DecisionStack.back(); }
 
+  void swapConds() {
+if (DecisionStack.empty())
+  return;
+
+std::swap(DecisionStack.back()[false], DecisionStack.back()[true]);
+  }
   /// Push the binary operator statement to track the nest level and assign IDs
   /// to the operator's LHS and RHS.  The RHS may be a larger subtree that is
   /// broken up on successive levels.
@@ -2241,6 +2247,12 @@ struct CounterCoverageMappingBuilder
 SM.isInSystemHeader(SM.getSpellingLoc(E->getEndLoc(;
   }
 
+  void VisitUnaryLNot(const UnaryOperator *E) {
+MCDCBuilder.swapConds();
+Visit(E->getSubExpr());
+MCDCBuilder.swapConds();
+  }
+
   void VisitBinLAnd(const BinaryOperator *E) {
 if (isExprInSystemHeader(E)) {
   LeafExprSet.insert(E);
diff --git a/clang/test/CoverageMapping/mcdc-nested-expr.cpp 
b/clang/test/CoverageMapping/mcdc-nested-expr.cpp
index bb82873e3b600d0..a49dad0b336126f 100644
--- a/clang/test/CoverageMapping/mcdc-neste

[llvm-branch-commits] [clang] [MC/DC] Refactor MCDCCoverageBuilder. NFC. (PR #125409)

2025-02-02 Thread NAKAMURA Takumi via llvm-branch-commits

https://github.com/chapuni created 
https://github.com/llvm/llvm-project/pull/125409

- Get rid of the old `DecisionStack` and dissolve it into push/pop `CurCondIDs` 
in `VisitBin`, since `VisitBin` is recursive.

- Introduce the new `DecisionStack` with `DecisionState` to handle the current 
`Decision` in nested `Decision`s.
  - The stack has the sentinel that has `DecisionExpr = nullptr`.
  - Split out `checkDecisionRootOrPush` from `pushAndAssignIDs` for non-BinOp. 
It assigns `CondID` to `E` (instead of assignment LHS in `pushAndAssignIDs`).
  - The stack is manupilated at the top Decision operator in `VisitBin`.
- The stack grows at the entrance of the Decision with the initial state.
- In the same level in `VisitBin`, the stack is popped and the `Decision` 
record is emitted.
- Introduce `DecisionEndToSince` to sweep `MCDCBranch`es partially in 
`cancelDecision`.

>From 2b37ea400809fd57f2b71b997d5dca622113a422 Mon Sep 17 00:00:00 2001
From: NAKAMURA Takumi 
Date: Sun, 2 Feb 2025 22:00:22 +0900
Subject: [PATCH] [MC/DC] Refactor MCDCCoverageBuilder. NFC.

- Get rid of the old `DecisionStack` and dissolve it into push/pop
  `CurCondIDs` in `VisitBin`, since `VisitBin` is recursive.

- Introduce the new `DecisionStack` with `DecisionState` to handle the
  current `Decision` in nested `Decision`s.
  - The stack has the sentinel that has `DecisionExpr = nullptr`.
  - Split out `checkDecisionRootOrPush` from `pushAndAssignIDs` for
non-BinOp. It assigns `CondID` to `E` (instead of assignment LHS
in `pushAndAssignIDs`).
  - The stack is manupilated at the top Decision operator in `VisitBin`.
- The stack grows at the entrance of the Decision with the initial
  state.
- In the same level in `VisitBin`, the stack is popped and the
  `Decision` record is emitted.
- Introduce `DecisionEndToSince` to sweep `MCDCBranch`es partially in
  `cancelDecision`.
---
 clang/lib/CodeGen/CoverageMappingGen.cpp | 309 ++-
 1 file changed, 187 insertions(+), 122 deletions(-)

diff --git a/clang/lib/CodeGen/CoverageMappingGen.cpp 
b/clang/lib/CodeGen/CoverageMappingGen.cpp
index 4dbc0c70e34d60..3a281fd39b4bcb 100644
--- a/clang/lib/CodeGen/CoverageMappingGen.cpp
+++ b/clang/lib/CodeGen/CoverageMappingGen.cpp
@@ -750,41 +750,48 @@ struct MCDCCoverageBuilder {
 
 private:
   CodeGenModule &CGM;
-
-  llvm::SmallVector DecisionStack;
   MCDC::State &MCDCState;
-  const Stmt *DecisionStmt = nullptr;
-  mcdc::ConditionID NextID = 0;
-  bool NotMapped = false;
 
-  /// Represent a sentinel value as a pair of final decisions for the bottom
-  // of DecisionStack.
-  static constexpr mcdc::ConditionIDs DecisionStackSentinel{-1, -1};
+  struct DecisionState {
+/// The root Decision
+const Expr *DecisionExpr = nullptr;
 
-  /// Is this a logical-AND operation?
-  bool isLAnd(const BinaryOperator *E) const {
-return E->getOpcode() == BO_LAnd;
-  }
+/// Pair of Destination conditions [false, true]
+/// -1, the final decision at the initial state.
+/// Modify before/after the traversal of BinOp LHS.
+mcdc::ConditionIDs CurCondIDs = {-1, -1};
+
+/// The ID to be assigned, and total number of conditions.
+mcdc::ConditionID NextID = 0;
+
+/// false if the Decision is recognized but should be ignored.
+bool Active = false;
+
+DecisionState() = default;
+DecisionState(const Expr *DecisionExpr, bool Valid)
+: DecisionExpr(DecisionExpr), Active(Valid) {}
+  };
+
+  /// The bottom [0] is the sentinel.
+  /// - DecisionExpr = nullptr, doesn't match to any Expr(s).
+  /// - Active = false
+  llvm::SmallVector DecisionStack;
+
+  /// , on SourceRegions.
+  /// Used for restoring MCDCBranch=>Branch.
+  llvm::DenseMap DecisionEndToSince;
 
 public:
   MCDCCoverageBuilder(CodeGenModule &CGM, MCDC::State &MCDCState)
-  : CGM(CGM), DecisionStack(1, DecisionStackSentinel),
-MCDCState(MCDCState) {}
-
-  /// Return whether the build of the control flow map is at the top-level
-  /// (root) of a logical operator nest in a boolean expression prior to the
-  /// assignment of condition IDs.
-  bool isIdle() const { return (NextID == 0 && !NotMapped); }
+  : CGM(CGM), MCDCState(MCDCState), DecisionStack(1) {}
 
-  /// Return whether any IDs have been assigned in the build of the control
-  /// flow map, indicating that the map is being generated for this boolean
-  /// expression.
-  bool isBuilding() const { return (NextID > 0); }
+  bool isActive() const { return DecisionStack.back().Active; }
 
   /// Set the given condition's ID.
   void setCondID(const Expr *Cond, mcdc::ConditionID ID) {
-MCDCState.BranchByStmt[CodeGenFunction::stripCond(Cond)] = {ID,
-DecisionStmt};
+assert(isActive());
+MCDCState.BranchByStmt[CodeGenFunction::stripCond(Cond)] = {
+ID, DecisionStack.back().DecisionExpr};
   }
 
   /// Return the ID of a given condition.
@@ -797,83 +804

[llvm-branch-commits] [clang] [X86][AVX10] Disable m[no-]avx10.1 and switch m[no-]avx10.2 to alias of 512 bit options (#124511) (PR #125057)

2025-02-02 Thread Phoebe Wang via llvm-branch-commits

phoebewang wrote:

Ping @tstellar, any reason this was missing in rc1 release?

https://github.com/llvm/llvm-project/pull/125057
___
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] [X86][AVX10] Disable m[no-]avx10.1 and switch m[no-]avx10.2 to alias of 512 bit options (#124511) (PR #125057)

2025-02-02 Thread Phoebe Wang via llvm-branch-commits

https://github.com/phoebewang updated 
https://github.com/llvm/llvm-project/pull/125057

>From f816bd39f6986825e338198fce8747939ab1c882 Mon Sep 17 00:00:00 2001
From: Phoebe Wang 
Date: Thu, 30 Jan 2025 21:13:49 +0800
Subject: [PATCH] [X86][AVX10] Disable m[no-]avx10.1 and switch m[no-]avx10.2
 to alias of 512 bit options (#124511)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Per the feedback we got, we’d like to switch m[no-]avx10.2 to alias of
512 bit options and disable m[no-]avx10.1 due to they were alias of 256
bit options.

We also change -mno-avx10.[1,2]-512 to alias of 256 bit options to
disable both 256 and 512 instructions.
---
 clang/docs/ReleaseNotes.rst   |  4 
 clang/include/clang/Driver/Options.td | 12 +---
 clang/lib/Driver/ToolChains/Arch/X86.cpp  | 13 -
 clang/test/Driver/x86-target-features.c   | 16 ++--
 clang/test/Preprocessor/x86_target_features.c |  3 +--
 5 files changed, 28 insertions(+), 20 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index d8a94703bd9c57..c36a84c2b8362b 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -1159,6 +1159,10 @@ X86 Support
 - Support ISA of ``MOVRS``.
 
 - Supported ``-march/tune=diamondrapids``
+- Disable ``-m[no-]avx10.1`` and switch ``-m[no-]avx10.2`` to alias of 512 bit
+  options.
+- Change ``-mno-avx10.1-512`` to alias of ``-mno-avx10.1-256`` to disable both
+  256 and 512 bit instructions.
 
 Arm and AArch64 Support
 ^^^
diff --git a/clang/include/clang/Driver/Options.td 
b/clang/include/clang/Driver/Options.td
index 1af633e59d0bba..a2b47b943ef90d 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -6441,15 +6441,13 @@ def mno_avx : Flag<["-"], "mno-avx">, 
Group;
 def mavx10_1_256 : Flag<["-"], "mavx10.1-256">, 
Group;
 def mno_avx10_1_256 : Flag<["-"], "mno-avx10.1-256">, 
Group;
 def mavx10_1_512 : Flag<["-"], "mavx10.1-512">, 
Group;
-def mno_avx10_1_512 : Flag<["-"], "mno-avx10.1-512">, 
Group;
-def mavx10_1 : Flag<["-"], "mavx10.1">, Alias;
-def mno_avx10_1 : Flag<["-"], "mno-avx10.1">, Alias;
+def mno_avx10_1_512 : Flag<["-"], "mno-avx10.1-512">, Alias;
+def mavx10_1 : Flag<["-"], "mavx10.1">, Flags<[Unsupported]>;
+def mno_avx10_1 : Flag<["-"], "mno-avx10.1">, Flags<[Unsupported]>;
 def mavx10_2_256 : Flag<["-"], "mavx10.2-256">, 
Group;
-def mno_avx10_2_256 : Flag<["-"], "mno-avx10.2-256">, 
Group;
 def mavx10_2_512 : Flag<["-"], "mavx10.2-512">, 
Group;
-def mno_avx10_2_512 : Flag<["-"], "mno-avx10.2-512">, 
Group;
-def mavx10_2 : Flag<["-"], "mavx10.2">, Alias;
-def mno_avx10_2 : Flag<["-"], "mno-avx10.2">, Alias;
+def mavx10_2 : Flag<["-"], "mavx10.2">, Alias;
+def mno_avx10_2 : Flag<["-"], "mno-avx10.2">, 
Group;
 def mavx2 : Flag<["-"], "mavx2">, Group;
 def mno_avx2 : Flag<["-"], "mno-avx2">, Group;
 def mavx512f : Flag<["-"], "mavx512f">, Group;
diff --git a/clang/lib/Driver/ToolChains/Arch/X86.cpp 
b/clang/lib/Driver/ToolChains/Arch/X86.cpp
index b2109e11038fe8..47c2c3e23f9fd9 100644
--- a/clang/lib/Driver/ToolChains/Arch/X86.cpp
+++ b/clang/lib/Driver/ToolChains/Arch/X86.cpp
@@ -237,15 +237,18 @@ void x86::getX86TargetFeatures(const Driver &D, const 
llvm::Triple &Triple,
 
 bool IsNegative = Name.consume_front("no-");
 
-#ifndef NDEBUG
-assert(Name.starts_with("avx10.") && "Invalid AVX10 feature name.");
 StringRef Version, Width;
 std::tie(Version, Width) = Name.substr(6).split('-');
+assert(Name.starts_with("avx10.") && "Invalid AVX10 feature name.");
 assert((Version == "1" || Version == "2") && "Invalid AVX10 feature 
name.");
-assert((Width == "256" || Width == "512") && "Invalid AVX10 feature 
name.");
-#endif
 
-Features.push_back(Args.MakeArgString((IsNegative ? "-" : "+") + Name));
+if (Width == "") {
+  assert(IsNegative && "Only negative options can omit width.");
+  Features.push_back(Args.MakeArgString("-" + Name + "-256"));
+} else {
+  assert((Width == "256" || Width == "512") && "Invalid vector length.");
+  Features.push_back(Args.MakeArgString((IsNegative ? "-" : "+") + Name));
+}
   }
 
   // Now add any that the user explicitly requested on the command line,
diff --git a/clang/test/Driver/x86-target-features.c 
b/clang/test/Driver/x86-target-features.c
index 339f593dc760a8..18361251dcebc5 100644
--- a/clang/test/Driver/x86-target-features.c
+++ b/clang/test/Driver/x86-target-features.c
@@ -395,7 +395,8 @@
 // EVEX512: "-target-feature" "+evex512"
 // NO-EVEX512: "-target-feature" "-evex512"
 
-// RUN: %clang --target=i386 -mavx10.1 %s -### -o %t.o 2>&1 | FileCheck 
-check-prefix=AVX10_1_256 %s
+// RUN: not %clang --target=i386 -march=i386 -mavx10.1 %s -### -o %t.o 2>&1 | 
FileCheck -check-prefix=UNSUPPORT-AVX10 %s
+// RUN: not %clang --target=i386 -march=i386 -mno-avx10.1 %s -### -o %t.o 2>&1 
| FileChec

[llvm-branch-commits] [llvm] AMDGPU/GlobalISel: Temporal divergence lowering i1 (PR #124299)

2025-02-02 Thread Nicolai Hähnle via llvm-branch-commits


@@ -219,6 +220,54 @@ bool DivergenceLoweringHelper::lowerTemporalDivergence() {
   return false;
 }
 
+bool DivergenceLoweringHelper::lowerTemporalDivergenceI1() {
+  MachineRegisterInfo::VRegAttrs BoolS1 = {ST->getBoolRC(), LLT::scalar(1)};
+  initializeLaneMaskRegisterAttributes(BoolS1);
+
+  for (auto [Inst, UseInst, Cycle] : MUI->getTemporalDivergenceList()) {
+Register Reg = Inst->getOperand(0).getReg();
+if (MRI->getType(Reg) != LLT::scalar(1))
+  continue;
+
+Register MergedMask = MRI->createVirtualRegister(BoolS1);
+Register PrevIterMask = MRI->createVirtualRegister(BoolS1);
+
+MachineBasicBlock *CycleHeaderMBB = Cycle->getHeader();
+SmallVector ExitingBlocks;
+Cycle->getExitingBlocks(ExitingBlocks);
+assert(ExitingBlocks.size() == 1);
+MachineBasicBlock *CycleExitingMBB = ExitingBlocks[0];
+
+B.setInsertPt(*CycleHeaderMBB, CycleHeaderMBB->begin());
+auto CrossIterPHI = B.buildInstr(AMDGPU::PHI).addDef(PrevIterMask);
+
+// We only care about cycle iterration path - merge Reg with previous
+// iteration. For other incomings use implicit def.
+// Predecessors should be CyclePredecessor and CycleExitingMBB.
+// In older versions of irreducible control flow lowering there could be
+// cases with more predecessors. To keep this lowering as generic as
+// possible also handle those cases.
+for (auto MBB : CycleHeaderMBB->predecessors()) {
+  if (MBB == CycleExitingMBB) {
+CrossIterPHI.addReg(MergedMask);
+  } else {
+B.setInsertPt(*MBB, MBB->getFirstTerminator());
+auto ImplDef = B.buildInstr(AMDGPU::IMPLICIT_DEF, {BoolS1}, {});
+CrossIterPHI.addReg(ImplDef.getReg(0));
+  }
+  CrossIterPHI.addMBB(MBB);
+}
+
+MachineBasicBlock *MBB = Inst->getParent();
+buildMergeLaneMasks(*MBB, MBB->getFirstTerminator(), {}, MergedMask,
+PrevIterMask, Reg);

nhaehnle wrote:

In this case, it would be better to move the lane merging to directly after 
`Inst`.

The register pressure calculus is exactly opposite from the non-i1 case:

* In the non-i1 case, shifting the COPY down is good because it reduces the 
live range of the VGPR while potentially making the live range of the SGPR 
longer. VGPRs are more expensive than SGPRs, so this is a good trade-off.
* In the i1 case, we'll have a live range for the merged mask extending across 
the entire cycle anyway. By moving the lane merging closer to Inst, we leave 
the live range of the merged mask unchanged, but we (most likely) reduce the 
live range of the i1 value produced by Inst.

https://github.com/llvm/llvm-project/pull/124299
___
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/GlobalISel: Temporal divergence lowering i1 (PR #124299)

2025-02-02 Thread Nicolai Hähnle via llvm-branch-commits

https://github.com/nhaehnle edited 
https://github.com/llvm/llvm-project/pull/124299
___
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/GlobalISel: Temporal divergence lowering i1 (PR #124299)

2025-02-02 Thread Nicolai Hähnle via llvm-branch-commits

https://github.com/nhaehnle edited 
https://github.com/llvm/llvm-project/pull/124299
___
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/GlobalISel: Temporal divergence lowering i1 (PR #124299)

2025-02-02 Thread Nicolai Hähnle via llvm-branch-commits

https://github.com/nhaehnle edited 
https://github.com/llvm/llvm-project/pull/124299
___
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] [polly] [Polly] Update ScopInliner for NPM (PR #125427)

2025-02-02 Thread Michael Kruse via llvm-branch-commits

https://github.com/Meinersbur created 
https://github.com/llvm/llvm-project/pull/125427

None

>From 06b025db36dff8c1a3b0b22ae884d6506611f455 Mon Sep 17 00:00:00 2001
From: Michael Kruse 
Date: Sun, 2 Feb 2025 18:48:32 +0100
Subject: [PATCH] Update ScopInliner to support NPM

---
 polly/docs/ReleaseNotes.rst   |   2 +
 polly/include/polly/LinkAllPasses.h   |   2 +-
 polly/include/polly/ScopInliner.h |  34 
 polly/lib/Support/PollyPasses.def |   6 +
 polly/lib/Support/RegisterPasses.cpp  |  41 -
 polly/lib/Transform/ScopInliner.cpp   | 159 +++---
 polly/test/ScopInliner/ignore-declares.ll |   3 +-
 polly/test/ScopInliner/invariant-load-func.ll |   5 +-
 polly/test/ScopInliner/simple-inline-loop.ll  |   3 +-
 9 files changed, 184 insertions(+), 71 deletions(-)
 create mode 100644 polly/include/polly/ScopInliner.h

diff --git a/polly/docs/ReleaseNotes.rst b/polly/docs/ReleaseNotes.rst
index f7c9689089be278..f5ea47b69cf02b4 100644
--- a/polly/docs/ReleaseNotes.rst
+++ b/polly/docs/ReleaseNotes.rst
@@ -11,3 +11,5 @@ In Polly |version| the following important changes have been 
incorporated.
 the new features that have recently been committed to our development
 branch.
 
+ * ScopInliner has been updated for the New Pass Manager.
+
diff --git a/polly/include/polly/LinkAllPasses.h 
b/polly/include/polly/LinkAllPasses.h
index 54e7c5a43ab93f6..65846653f98e5f1 100644
--- a/polly/include/polly/LinkAllPasses.h
+++ b/polly/include/polly/LinkAllPasses.h
@@ -120,7 +120,7 @@ struct PollyForcePassLinking {
 
 namespace llvm {
 void initializeCodePreparationPass(llvm::PassRegistry &);
-void initializeScopInlinerPass(llvm::PassRegistry &);
+void initializeScopInlinerWrapperPassPass(llvm::PassRegistry &);
 void initializeScopDetectionWrapperPassPass(llvm::PassRegistry &);
 void initializeScopDetectionPrinterLegacyPassPass(llvm::PassRegistry &);
 void initializeScopInfoRegionPassPass(PassRegistry &);
diff --git a/polly/include/polly/ScopInliner.h 
b/polly/include/polly/ScopInliner.h
new file mode 100644
index 000..014667804330fb6
--- /dev/null
+++ b/polly/include/polly/ScopInliner.h
@@ -0,0 +1,34 @@
+//===-- ScopInliner.h ===//
+//
+// 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
+//
+//===--===//
+
+#ifndef POLLY_POLLYINLINER_H
+#define POLLY_POLLYINLINER_H
+
+#include "llvm/Analysis/CGSCCPassManager.h"
+#include "llvm/Analysis/LazyCallGraph.h"
+#include "llvm/IR/PassManager.h"
+
+namespace polly {
+class ScopInlinerPass : public llvm::PassInfoMixin {
+public:
+  ScopInlinerPass();
+
+  llvm::PreservedAnalyses run(llvm::LazyCallGraph::SCC &C,
+  llvm::CGSCCAnalysisManager &AM,
+  llvm::LazyCallGraph &CG,
+  llvm::CGSCCUpdateResult &UR);
+};
+
+llvm::Pass *createScopInlinerWrapperPass();
+} // namespace polly
+
+namespace llvm {
+void initializeScopInlinerWrapperPassPass(llvm::PassRegistry &);
+}
+
+#endif /* POLLY_POLLYINLINER_H */
diff --git a/polly/lib/Support/PollyPasses.def 
b/polly/lib/Support/PollyPasses.def
index e068f31fdb703c7..2c792a5867100f9 100644
--- a/polly/lib/Support/PollyPasses.def
+++ b/polly/lib/Support/PollyPasses.def
@@ -1,3 +1,9 @@
+#ifndef CGSCC_PASS
+#define CGSCC_PASS(NAME, CREATE_PASS, PARSER)
+#endif
+CGSCC_PASS("polly-inline", ScopInlinerPass(), parseNoOptions)
+#undef CGSCC_PASS
+
 #ifndef FUNCTION_ANALYSIS
 #define FUNCTION_ANALYSIS(NAME, CREATE_PASS)
 #endif
diff --git a/polly/lib/Support/RegisterPasses.cpp 
b/polly/lib/Support/RegisterPasses.cpp
index a46e61aafbeb759..3ace336cb588bed 100644
--- a/polly/lib/Support/RegisterPasses.cpp
+++ b/polly/lib/Support/RegisterPasses.cpp
@@ -35,6 +35,7 @@
 #include "polly/ScopDetection.h"
 #include "polly/ScopGraphPrinter.h"
 #include "polly/ScopInfo.h"
+#include "polly/ScopInliner.h"
 #include "polly/Simplify.h"
 #include "polly/Support/DumpFunctionPass.h"
 #include "polly/Support/DumpModulePass.h"
@@ -46,10 +47,13 @@
 #include "llvm/Passes/PassBuilder.h"
 #include "llvm/Passes/PassPlugin.h"
 #include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Error.h"
 #include "llvm/Support/TargetSelect.h"
 #include "llvm/Transforms/IPO.h"
 
+using namespace llvm;
 namespace cl = llvm::cl;
+using namespace polly;
 
 using llvm::FunctionPassManager;
 using llvm::OptimizationLevel;
@@ -233,7 +237,7 @@ void initializePollyPasses(llvm::PassRegistry &Registry) {
   initializePollyCanonicalizePass(Registry);
   initializeScopDetectionWrapperPassPass(Registry);
   initializeScopDetectionPrinterLegacyPassPass(Registry);
-  initializeScopInlinerPass(Registry);
+  initializeScopInlinerWrapperPassPass(Registry);

[llvm-branch-commits] [llvm] AMDGPU/GlobalISel: Temporal divergence lowering i1 (PR #124299)

2025-02-02 Thread Nicolai Hähnle via llvm-branch-commits

https://github.com/nhaehnle edited 
https://github.com/llvm/llvm-project/pull/124299
___
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/GlobalISel: Temporal divergence lowering i1 (PR #124299)

2025-02-02 Thread Nicolai Hähnle via llvm-branch-commits

https://github.com/nhaehnle edited 
https://github.com/llvm/llvm-project/pull/124299
___
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/GlobalISel: Temporal divergence lowering (non i1) (PR #124298)

2025-02-02 Thread Nicolai Hähnle via llvm-branch-commits


@@ -188,6 +190,35 @@ void 
DivergenceLoweringHelper::constrainAsLaneMask(Incoming &In) {
   In.Reg = Copy.getReg(0);
 }
 
+void replaceUsesOfRegInInstWith(Register Reg, MachineInstr *Inst,
+Register NewReg) {
+  for (MachineOperand &Op : Inst->operands()) {
+if (Op.isReg() && Op.getReg() == Reg)
+  Op.setReg(NewReg);
+  }
+}
+
+bool DivergenceLoweringHelper::lowerTemporalDivergence() {
+  AMDGPU::IntrinsicLaneMaskAnalyzer ILMA(*MF);
+
+  for (auto [Inst, UseInst, _] : MUI->getTemporalDivergenceList()) {
+Register Reg = Inst->getOperand(0).getReg();
+if (MRI->getType(Reg) == LLT::scalar(1) || MUI->isDivergent(Reg) ||
+ILMA.isS32S64LaneMask(Reg))
+  continue;
+
+MachineBasicBlock *MBB = Inst->getParent();
+B.setInsertPt(*MBB, 
MBB->SkipPHIsAndLabels(std::next(Inst->getIterator(;
+
+Register VgprReg = MRI->createGenericVirtualRegister(MRI->getType(Reg));
+B.buildInstr(AMDGPU::COPY, {VgprReg}, {Reg})
+.addUse(ExecReg, RegState::Implicit);
+
+replaceUsesOfRegInInstWith(Reg, UseInst, VgprReg);
+  }
+  return false;
+}

nhaehnle wrote:

I do have one high-level comment about this.

Every `Inst` may potentially appear with many `UseInst`s in the temporal 
divergence list. The current code will create multiple new registers and 
multiple `COPY` instructions, which seems wasteful even if downstream passes 
can often clean it up.

I would suggest capturing the created register in a `DenseMap` for re-use.

Also, how about inserting the `COPY` at the end of `Inst->getParent()`? That 
way, the live range of the VGPR is reduced.

https://github.com/llvm/llvm-project/pull/124298
___
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/GlobalISel: Temporal divergence lowering (non i1) (PR #124298)

2025-02-02 Thread Nicolai Hähnle via llvm-branch-commits

https://github.com/nhaehnle commented:

I haven't done a detailed review of the code, but from a high-level algorithmic 
view this change already looks pretty reasonable to me.

https://github.com/llvm/llvm-project/pull/124298
___
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/GlobalISel: Temporal divergence lowering (non i1) (PR #124298)

2025-02-02 Thread Nicolai Hähnle via llvm-branch-commits

https://github.com/nhaehnle edited 
https://github.com/llvm/llvm-project/pull/124298
___
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/GlobalISel: Temporal divergence lowering i1 (PR #124299)

2025-02-02 Thread Nicolai Hähnle via llvm-branch-commits

https://github.com/nhaehnle edited 
https://github.com/llvm/llvm-project/pull/124299
___
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/GlobalISel: Temporal divergence lowering i1 (PR #124299)

2025-02-02 Thread Nicolai Hähnle via llvm-branch-commits


@@ -219,6 +220,54 @@ bool DivergenceLoweringHelper::lowerTemporalDivergence() {
   return false;
 }
 
+bool DivergenceLoweringHelper::lowerTemporalDivergenceI1() {
+  MachineRegisterInfo::VRegAttrs BoolS1 = {ST->getBoolRC(), LLT::scalar(1)};
+  initializeLaneMaskRegisterAttributes(BoolS1);
+
+  for (auto [Inst, UseInst, Cycle] : MUI->getTemporalDivergenceList()) {
+Register Reg = Inst->getOperand(0).getReg();
+if (MRI->getType(Reg) != LLT::scalar(1))
+  continue;
+
+Register MergedMask = MRI->createVirtualRegister(BoolS1);
+Register PrevIterMask = MRI->createVirtualRegister(BoolS1);
+
+MachineBasicBlock *CycleHeaderMBB = Cycle->getHeader();
+SmallVector ExitingBlocks;
+Cycle->getExitingBlocks(ExitingBlocks);
+assert(ExitingBlocks.size() == 1);
+MachineBasicBlock *CycleExitingMBB = ExitingBlocks[0];
+
+B.setInsertPt(*CycleHeaderMBB, CycleHeaderMBB->begin());
+auto CrossIterPHI = B.buildInstr(AMDGPU::PHI).addDef(PrevIterMask);
+
+// We only care about cycle iterration path - merge Reg with previous
+// iteration. For other incomings use implicit def.
+// Predecessors should be CyclePredecessor and CycleExitingMBB.
+// In older versions of irreducible control flow lowering there could be
+// cases with more predecessors. To keep this lowering as generic as
+// possible also handle those cases.
+for (auto MBB : CycleHeaderMBB->predecessors()) {
+  if (MBB == CycleExitingMBB) {
+CrossIterPHI.addReg(MergedMask);
+  } else {
+B.setInsertPt(*MBB, MBB->getFirstTerminator());
+auto ImplDef = B.buildInstr(AMDGPU::IMPLICIT_DEF, {BoolS1}, {});
+CrossIterPHI.addReg(ImplDef.getReg(0));
+  }
+  CrossIterPHI.addMBB(MBB);
+}

nhaehnle wrote:

This still feels vaguely off to me.

First of all, can you please add a `Cycle->isReducible()` assert here just in 
case, since you're relying on there only being one header? (Actually, that 
assert should probably be in `GenericCycle::getHeader`.)

Second, I'm worried about that case distinction between different kinds of 
predecessors. It really doesn't feel properly generic to me. Latches and 
exiting blocks aren't necessarily the same thing. (The current structurizer 
tends to make it that way, but even with the structurizer we probably don't 
have a guarantee, let alone with a future different control flow lowering.)

Let's think through some cases:

* If the predecessor is outside the cycle, it should be an `IMPLICIT_DEF`
* If it is inside the cycle, i.e. a latch, there are two cases:
  * If the predecessor is dominated by `Inst`, then clearly use `MergedMask`
  * Otherwise, it's actually not clear: could it be possible that control flow 
leaves the dominance region of `Inst` and goes around the loop again?

On that last point, you could perhaps make a case that because the loop is 
temporally divergent, having the CFG in wave CFG form requires a certain 
structure. But I'm not convinced. In fact, consider:
```mermaid
flowchart TD
Header --> B
Header --> Inst
Inst --> B
B --> Header
Inst --> C
C --> Header
C --> Exit
```
Let's say the branches of Header and C are uniform; only the branch of the 
basic block containing Inst is divergent.

Then we have temporal divergence in Inst, and need to handle the `i1`. But the 
CFG is already *reconvergent*: the divergent branch is post-dominated by one of 
its immediate successors. This means it is possible to insert EXEC masking code 
for this CFG correctly without structuring it. Therefore, the code here should 
really handle this case correctly.

I think this calls for using MachineSSAUpdater for a robust solution:

* Initialize the updater with IMPLICIT_DEF in every predecessor of the header 
that is outside the cycle.
* Insert the MergedMask into the updater for the `Inst->getParent()`
* Then build the lane mask merging, querying the updater for the previous mask 
(i.e., let the updater create that register) 
* The MergedMask can still be used by UseInst due to dominance

Except now there's an additional issue with caching the MergedMask that doesn't 
exist for the non-i1 case: Different `UseInst`s could appear with respect to 
different `Cycle`s. The non-i1 case doesn't actually care about the cycle 
structure, but the code here does.

In particular, with my suggestions, it will use the cycle to determine how to 
initialize the updater.

We can still get away with a single `MergedMask` per `Inst`:

* The lazy way to do it would be to not initialize the updater with 
IMPLICIT_DEFs and just let it figure them out by itself. This would generate 
correct code.
  * However, this has a compile-time cost and could end up being too 
pessimistic in terms of the generated code.
  * The Inst and all its uses could be contained in a cycle. This naive way 
would lead to a phi node at the header of this cycle, and therefore needlessly 
extending the live range o

[llvm-branch-commits] [llvm] AMDGPU/GlobalISel: Temporal divergence lowering i1 (PR #124299)

2025-02-02 Thread Nicolai Hähnle via llvm-branch-commits

https://github.com/nhaehnle commented:

Thank you for moving the insert point.

An analogous comment applies here like in the non-i1 case: it would be good to 
cache the `MergedMask` register for re-use when the same `Inst` occurs with 
multiple `UseInst`s.

https://github.com/llvm/llvm-project/pull/124299
___
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/GlobalISel: Temporal divergence lowering i1 (PR #124299)

2025-02-02 Thread Nicolai Hähnle via llvm-branch-commits

https://github.com/nhaehnle edited 
https://github.com/llvm/llvm-project/pull/124299
___
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/GlobalISel: Temporal divergence lowering i1 (PR #124299)

2025-02-02 Thread Nicolai Hähnle via llvm-branch-commits

https://github.com/nhaehnle edited 
https://github.com/llvm/llvm-project/pull/124299
___
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] [polly] [Polly] Update ScopInliner for NPM (PR #125427)

2025-02-02 Thread Michael Kruse via llvm-branch-commits

https://github.com/Meinersbur edited 
https://github.com/llvm/llvm-project/pull/125427
___
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] [llvm] [llvm] Introduce type id operand bundle (PR #87573)

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

https://github.com/nikic edited https://github.com/llvm/llvm-project/pull/87573
___
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] [MC/DC] Refactor MCDCCoverageBuilder. NFC. (PR #125409)

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

llvmbot wrote:




@llvm/pr-subscribers-clang

Author: NAKAMURA Takumi (chapuni)


Changes

- Get rid of the old `DecisionStack` and dissolve it into push/pop `CurCondIDs` 
in `VisitBin`, since `VisitBin` is recursive.

- Introduce the new `DecisionStack` with `DecisionState` to handle the current 
`Decision` in nested `Decision`s.
  - The stack has the sentinel that has `DecisionExpr = nullptr`.
  - Split out `checkDecisionRootOrPush` from `pushAndAssignIDs` for non-BinOp. 
It assigns `CondID` to `E` (instead of assignment LHS in `pushAndAssignIDs`).
  - The stack is manupilated at the top Decision operator in `VisitBin`.
- The stack grows at the entrance of the Decision with the initial state.
- In the same level in `VisitBin`, the stack is popped and the `Decision` 
record is emitted.
- Introduce `DecisionEndToSince` to sweep `MCDCBranch`es partially in 
`cancelDecision`.

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


1 Files Affected:

- (modified) clang/lib/CodeGen/CoverageMappingGen.cpp (+187-122) 


``diff
diff --git a/clang/lib/CodeGen/CoverageMappingGen.cpp 
b/clang/lib/CodeGen/CoverageMappingGen.cpp
index 4dbc0c70e34d60..3a281fd39b4bcb 100644
--- a/clang/lib/CodeGen/CoverageMappingGen.cpp
+++ b/clang/lib/CodeGen/CoverageMappingGen.cpp
@@ -750,41 +750,48 @@ struct MCDCCoverageBuilder {
 
 private:
   CodeGenModule &CGM;
-
-  llvm::SmallVector DecisionStack;
   MCDC::State &MCDCState;
-  const Stmt *DecisionStmt = nullptr;
-  mcdc::ConditionID NextID = 0;
-  bool NotMapped = false;
 
-  /// Represent a sentinel value as a pair of final decisions for the bottom
-  // of DecisionStack.
-  static constexpr mcdc::ConditionIDs DecisionStackSentinel{-1, -1};
+  struct DecisionState {
+/// The root Decision
+const Expr *DecisionExpr = nullptr;
 
-  /// Is this a logical-AND operation?
-  bool isLAnd(const BinaryOperator *E) const {
-return E->getOpcode() == BO_LAnd;
-  }
+/// Pair of Destination conditions [false, true]
+/// -1, the final decision at the initial state.
+/// Modify before/after the traversal of BinOp LHS.
+mcdc::ConditionIDs CurCondIDs = {-1, -1};
+
+/// The ID to be assigned, and total number of conditions.
+mcdc::ConditionID NextID = 0;
+
+/// false if the Decision is recognized but should be ignored.
+bool Active = false;
+
+DecisionState() = default;
+DecisionState(const Expr *DecisionExpr, bool Valid)
+: DecisionExpr(DecisionExpr), Active(Valid) {}
+  };
+
+  /// The bottom [0] is the sentinel.
+  /// - DecisionExpr = nullptr, doesn't match to any Expr(s).
+  /// - Active = false
+  llvm::SmallVector DecisionStack;
+
+  /// , on SourceRegions.
+  /// Used for restoring MCDCBranch=>Branch.
+  llvm::DenseMap DecisionEndToSince;
 
 public:
   MCDCCoverageBuilder(CodeGenModule &CGM, MCDC::State &MCDCState)
-  : CGM(CGM), DecisionStack(1, DecisionStackSentinel),
-MCDCState(MCDCState) {}
-
-  /// Return whether the build of the control flow map is at the top-level
-  /// (root) of a logical operator nest in a boolean expression prior to the
-  /// assignment of condition IDs.
-  bool isIdle() const { return (NextID == 0 && !NotMapped); }
+  : CGM(CGM), MCDCState(MCDCState), DecisionStack(1) {}
 
-  /// Return whether any IDs have been assigned in the build of the control
-  /// flow map, indicating that the map is being generated for this boolean
-  /// expression.
-  bool isBuilding() const { return (NextID > 0); }
+  bool isActive() const { return DecisionStack.back().Active; }
 
   /// Set the given condition's ID.
   void setCondID(const Expr *Cond, mcdc::ConditionID ID) {
-MCDCState.BranchByStmt[CodeGenFunction::stripCond(Cond)] = {ID,
-DecisionStmt};
+assert(isActive());
+MCDCState.BranchByStmt[CodeGenFunction::stripCond(Cond)] = {
+ID, DecisionStack.back().DecisionExpr};
   }
 
   /// Return the ID of a given condition.
@@ -797,83 +804,99 @@ struct MCDCCoverageBuilder {
   }
 
   /// Return the LHS Decision ([0,0] if not set).
-  const mcdc::ConditionIDs &back() const { return DecisionStack.back(); }
+  auto &getCurCondIDs() { return DecisionStack.back().CurCondIDs; }
 
-  /// Push the binary operator statement to track the nest level and assign IDs
-  /// to the operator's LHS and RHS.  The RHS may be a larger subtree that is
-  /// broken up on successive levels.
-  void pushAndAssignIDs(const BinaryOperator *E) {
-if (!CGM.getCodeGenOpts().MCDCCoverage)
+  void swapConds() {
+if (!isActive())
   return;
 
-// If binary expression is disqualified, don't do mapping.
-if (!isBuilding() &&
-!MCDCState.DecisionByStmt.contains(CodeGenFunction::stripCond(E)))
-  NotMapped = true;
+std::swap(getCurCondIDs()[false], getCurCondIDs()[true]);
+  }
 
-// Don't go any further if we don't need to map condition IDs.
-if (NotMapped)
+  void checkDecisionRo

[llvm-branch-commits] [clang] [MC/DC] Create dedicated MCDCCondBitmapAddr for each Decision (PR #125411)

2025-02-02 Thread NAKAMURA Takumi via llvm-branch-commits

https://github.com/chapuni created 
https://github.com/llvm/llvm-project/pull/125411

MCDCCondBitmapAddr is moved from `CodeGenFunction` into `MCDCState` and created 
for each Decision.

In `maybeCreateMCDCCondBitmap`, Allocate bitmaps for all valid Decisions and 
emit them order by ID, to prevent nondeterminism.

>From c74e5af3fb458230931d7cbba5d32e5999c38bf4 Mon Sep 17 00:00:00 2001
From: NAKAMURA Takumi 
Date: Sun, 2 Feb 2025 22:01:40 +0900
Subject: [PATCH] [MC/DC] Create dedicated MCDCCondBitmapAddr for each Decision

MCDCCondBitmapAddr is moved from `CodeGenFunction` into `MCDCState`
and created for each Decision.

In `maybeCreateMCDCCondBitmap`, Allocate bitmaps for all valid
Decisions and emit them order by ID, to prevent nondeterminism.
---
 clang/lib/CodeGen/CodeGenFunction.h   |  17 +--
 clang/lib/CodeGen/CodeGenPGO.cpp  |  41 +--
 clang/lib/CodeGen/CodeGenPGO.h|   8 +-
 clang/lib/CodeGen/MCDCState.h |   2 +
 .../test/CoverageMapping/mcdc-single-cond.cpp | 101 ++
 clang/test/Profile/c-mcdc-logicalop-ternary.c |  18 ++--
 6 files changed, 160 insertions(+), 27 deletions(-)
 create mode 100644 clang/test/CoverageMapping/mcdc-single-cond.cpp

diff --git a/clang/lib/CodeGen/CodeGenFunction.h 
b/clang/lib/CodeGen/CodeGenFunction.h
index e978cad4336238..20d81ba3a3bde1 100644
--- a/clang/lib/CodeGen/CodeGenFunction.h
+++ b/clang/lib/CodeGen/CodeGenFunction.h
@@ -1628,9 +1628,6 @@ class CodeGenFunction : public CodeGenTypeCache {
 
   CodeGenPGO PGO;
 
-  /// Bitmap used by MC/DC to track condition outcomes of a boolean expression.
-  Address MCDCCondBitmapAddr = Address::invalid();
-
   /// Calculate branch weights appropriate for PGO data
   llvm::MDNode *createProfileWeights(uint64_t TrueCount,
  uint64_t FalseCount) const;
@@ -1669,8 +1666,12 @@ class CodeGenFunction : public CodeGenTypeCache {
   void maybeCreateMCDCCondBitmap() {
 if (isMCDCCoverageEnabled()) {
   PGO.emitMCDCParameters(Builder);
-  MCDCCondBitmapAddr =
-  CreateIRTemp(getContext().UnsignedIntTy, "mcdc.addr");
+
+  // Set up MCDCCondBitmapAddr for each Decision.
+  // Note: This doesn't initialize Addrs in invalidated Decisions.
+  for (auto *MCDCCondBitmapAddr : PGO.getMCDCCondBitmapAddrArray(Builder))
+*MCDCCondBitmapAddr =
+CreateIRTemp(getContext().UnsignedIntTy, "mcdc.addr");
 }
   }
 
@@ -1682,7 +1683,7 @@ class CodeGenFunction : public CodeGenTypeCache {
   /// Zero-init the MCDC temp value.
   void maybeResetMCDCCondBitmap(const Expr *E) {
 if (isMCDCCoverageEnabled() && isBinaryLogicalOp(E)) {
-  PGO.emitMCDCCondBitmapReset(Builder, E, MCDCCondBitmapAddr);
+  PGO.emitMCDCCondBitmapReset(Builder, E);
   PGO.setCurrentStmt(E);
 }
   }
@@ -1691,7 +1692,7 @@ class CodeGenFunction : public CodeGenTypeCache {
   /// If \p StepV is null, the default increment is 1.
   void maybeUpdateMCDCTestVectorBitmap(const Expr *E) {
 if (isMCDCCoverageEnabled() && isBinaryLogicalOp(E)) {
-  PGO.emitMCDCTestVectorBitmapUpdate(Builder, E, MCDCCondBitmapAddr, 
*this);
+  PGO.emitMCDCTestVectorBitmapUpdate(Builder, E, *this);
   PGO.setCurrentStmt(E);
 }
   }
@@ -1699,7 +1700,7 @@ class CodeGenFunction : public CodeGenTypeCache {
   /// Update the MCDC temp value with the condition's evaluated result.
   void maybeUpdateMCDCCondBitmap(const Expr *E, llvm::Value *Val) {
 if (isMCDCCoverageEnabled()) {
-  PGO.emitMCDCCondBitmapUpdate(Builder, E, MCDCCondBitmapAddr, Val, *this);
+  PGO.emitMCDCCondBitmapUpdate(Builder, E, Val, *this);
   PGO.setCurrentStmt(E);
 }
   }
diff --git a/clang/lib/CodeGen/CodeGenPGO.cpp b/clang/lib/CodeGen/CodeGenPGO.cpp
index 0331ff83e633f7..7d16f673ada419 100644
--- a/clang/lib/CodeGen/CodeGenPGO.cpp
+++ b/clang/lib/CodeGen/CodeGenPGO.cpp
@@ -1245,9 +1245,29 @@ void CodeGenPGO::emitMCDCParameters(CGBuilderTy 
&Builder) {
   CGM.getIntrinsic(llvm::Intrinsic::instrprof_mcdc_parameters), Args);
 }
 
+/// Fill mcdc.addr order by ID.
+std::vector
+CodeGenPGO::getMCDCCondBitmapAddrArray(CGBuilderTy &Builder) {
+  std::vector Result;
+
+  if (!canEmitMCDCCoverage(Builder) || !RegionMCDCState)
+return Result;
+
+  SmallVector> SortedPair;
+  for (auto &[_, V] : RegionMCDCState->DecisionByStmt)
+if (V.isValid())
+  SortedPair.emplace_back(V.ID, &V.MCDCCondBitmapAddr);
+
+  llvm::sort(SortedPair);
+
+  for (auto &[_, MCDCCondBitmapAddr] : SortedPair)
+Result.push_back(MCDCCondBitmapAddr);
+
+  return Result;
+}
+
 void CodeGenPGO::emitMCDCTestVectorBitmapUpdate(CGBuilderTy &Builder,
 const Expr *S,
-Address MCDCCondBitmapAddr,
 CodeGenFunction &CGF) {
   if (!canEmitMCDCCoverage(Builder) || !RegionMCDCState)
 return;
@@ -1258,6 +1278,10 @@ void

[llvm-branch-commits] [clang] [MC/DC] Prune MCDCLogOpStack and use CGF.isMCDCDecisionExpr (PR #125410)

2025-02-02 Thread NAKAMURA Takumi via llvm-branch-commits

https://github.com/chapuni created 
https://github.com/llvm/llvm-project/pull/125410

`MCDCLogOpStack` is used only for detection of the Decision root. It can be 
detected with `MCDC::State::DecisionByStmt`.

>From 8eff226c98bdcfcd1366120699a42e0c4c73375c Mon Sep 17 00:00:00 2001
From: NAKAMURA Takumi 
Date: Sun, 2 Feb 2025 22:00:48 +0900
Subject: [PATCH] [MC/DC] Prune MCDCLogOpStack and use CGF.isMCDCDecisionExpr

`MCDCLogOpStack` is used only for detection of the Decision root. It
can be detected with `MCDC::State::DecisionByStmt`.
---
 clang/lib/CodeGen/CGExprScalar.cpp| 40 ++-
 clang/lib/CodeGen/CodeGenFunction.cpp | 16 +++
 clang/lib/CodeGen/CodeGenFunction.h   |  8 --
 clang/lib/CodeGen/CodeGenPGO.h| 14 ++
 4 files changed, 37 insertions(+), 41 deletions(-)

diff --git a/clang/lib/CodeGen/CGExprScalar.cpp 
b/clang/lib/CodeGen/CGExprScalar.cpp
index df850421c72c6c..37b32977b8bd3e 100644
--- a/clang/lib/CodeGen/CGExprScalar.cpp
+++ b/clang/lib/CodeGen/CGExprScalar.cpp
@@ -4990,11 +4990,9 @@ Value *ScalarExprEmitter::VisitBinLAnd(const 
BinaryOperator *E) {
   CGF.incrementProfileCounter(E);
 
   // If the top of the logical operator nest, reset the MCDC temp to 0.
-  if (CGF.MCDCLogOpStack.empty())
+  if (CGF.isMCDCDecisionExpr(E))
 CGF.maybeResetMCDCCondBitmap(E);
 
-  CGF.MCDCLogOpStack.push_back(E);
-
   Value *RHSCond = CGF.EvaluateExprAsBool(E->getRHS());
 
   // If we're generating for profiling or coverage, generate a branch to a
@@ -5014,9 +5012,8 @@ Value *ScalarExprEmitter::VisitBinLAnd(const 
BinaryOperator *E) {
   } else
 CGF.markStmtMaybeUsed(E->getRHS());
 
-  CGF.MCDCLogOpStack.pop_back();
   // If the top of the logical operator nest, update the MCDC bitmap.
-  if (CGF.MCDCLogOpStack.empty())
+  if (CGF.isMCDCDecisionExpr(E))
 CGF.maybeUpdateMCDCTestVectorBitmap(E);
 
   // ZExt result to int or bool.
@@ -5031,11 +5028,9 @@ Value *ScalarExprEmitter::VisitBinLAnd(const 
BinaryOperator *E) {
   }
 
   // If the top of the logical operator nest, reset the MCDC temp to 0.
-  if (CGF.MCDCLogOpStack.empty())
+  if (CGF.isMCDCDecisionExpr(E))
 CGF.maybeResetMCDCCondBitmap(E);
 
-  CGF.MCDCLogOpStack.push_back(E);
-
   llvm::BasicBlock *ContBlock = CGF.createBasicBlock("land.end");
   llvm::BasicBlock *RHSBlock  = CGF.createBasicBlock("land.rhs");
 
@@ -5086,9 +5081,8 @@ Value *ScalarExprEmitter::VisitBinLAnd(const 
BinaryOperator *E) {
   // Insert an entry into the phi node for the edge with the value of RHSCond.
   PN->addIncoming(RHSCond, RHSBlock);
 
-  CGF.MCDCLogOpStack.pop_back();
   // If the top of the logical operator nest, update the MCDC bitmap.
-  if (CGF.MCDCLogOpStack.empty())
+  if (CGF.isMCDCDecisionExpr(E))
 CGF.maybeUpdateMCDCTestVectorBitmap(E);
 
   // Artificial location to preserve the scope information
@@ -5133,11 +5127,9 @@ Value *ScalarExprEmitter::VisitBinLOr(const 
BinaryOperator *E) {
   CGF.incrementProfileCounter(E);
 
   // If the top of the logical operator nest, reset the MCDC temp to 0.
-  if (CGF.MCDCLogOpStack.empty())
+  if (CGF.isMCDCDecisionExpr(E))
 CGF.maybeResetMCDCCondBitmap(E);
 
-  CGF.MCDCLogOpStack.push_back(E);
-
   Value *RHSCond = CGF.EvaluateExprAsBool(E->getRHS());
 
   // If we're generating for profiling or coverage, generate a branch to a
@@ -5157,9 +5149,8 @@ Value *ScalarExprEmitter::VisitBinLOr(const 
BinaryOperator *E) {
   } else
 CGF.markStmtMaybeUsed(E->getRHS());
 
-  CGF.MCDCLogOpStack.pop_back();
   // If the top of the logical operator nest, update the MCDC bitmap.
-  if (CGF.MCDCLogOpStack.empty())
+  if (CGF.isMCDCDecisionExpr(E))
 CGF.maybeUpdateMCDCTestVectorBitmap(E);
 
   // ZExt result to int or bool.
@@ -5174,11 +5165,9 @@ Value *ScalarExprEmitter::VisitBinLOr(const 
BinaryOperator *E) {
   }
 
   // If the top of the logical operator nest, reset the MCDC temp to 0.
-  if (CGF.MCDCLogOpStack.empty())
+  if (CGF.isMCDCDecisionExpr(E))
 CGF.maybeResetMCDCCondBitmap(E);
 
-  CGF.MCDCLogOpStack.push_back(E);
-
   llvm::BasicBlock *ContBlock = CGF.createBasicBlock("lor.end");
   llvm::BasicBlock *RHSBlock = CGF.createBasicBlock("lor.rhs");
 
@@ -5229,9 +5218,8 @@ Value *ScalarExprEmitter::VisitBinLOr(const 
BinaryOperator *E) {
   CGF.EmitBlock(ContBlock);
   PN->addIncoming(RHSCond, RHSBlock);
 
-  CGF.MCDCLogOpStack.pop_back();
   // If the top of the logical operator nest, update the MCDC bitmap.
-  if (CGF.MCDCLogOpStack.empty())
+  if (CGF.isMCDCDecisionExpr(E))
 CGF.maybeUpdateMCDCTestVectorBitmap(E);
 
   // ZExt result to int.
@@ -5390,8 +5378,8 @@ VisitAbstractConditionalOperator(const 
AbstractConditionalOperator *E) {
   }
 
   // If the top of the logical operator nest, reset the MCDC temp to 0.
-  if (CGF.MCDCLogOpStack.empty())
-CGF.maybeResetMCDCCondBitmap(condExpr);
+  if (auto E = C

[llvm-branch-commits] [clang] [MC/DC] Prune MCDCLogOpStack and use CGF.isMCDCDecisionExpr (PR #125410)

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

llvmbot wrote:




@llvm/pr-subscribers-clang-codegen

Author: NAKAMURA Takumi (chapuni)


Changes

`MCDCLogOpStack` is used only for detection of the Decision root. It can be 
detected with `MCDC::State::DecisionByStmt`.

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


4 Files Affected:

- (modified) clang/lib/CodeGen/CGExprScalar.cpp (+14-26) 
- (modified) clang/lib/CodeGen/CodeGenFunction.cpp (+4-12) 
- (modified) clang/lib/CodeGen/CodeGenFunction.h (+5-3) 
- (modified) clang/lib/CodeGen/CodeGenPGO.h (+14) 


``diff
diff --git a/clang/lib/CodeGen/CGExprScalar.cpp 
b/clang/lib/CodeGen/CGExprScalar.cpp
index df850421c72c6c..37b32977b8bd3e 100644
--- a/clang/lib/CodeGen/CGExprScalar.cpp
+++ b/clang/lib/CodeGen/CGExprScalar.cpp
@@ -4990,11 +4990,9 @@ Value *ScalarExprEmitter::VisitBinLAnd(const 
BinaryOperator *E) {
   CGF.incrementProfileCounter(E);
 
   // If the top of the logical operator nest, reset the MCDC temp to 0.
-  if (CGF.MCDCLogOpStack.empty())
+  if (CGF.isMCDCDecisionExpr(E))
 CGF.maybeResetMCDCCondBitmap(E);
 
-  CGF.MCDCLogOpStack.push_back(E);
-
   Value *RHSCond = CGF.EvaluateExprAsBool(E->getRHS());
 
   // If we're generating for profiling or coverage, generate a branch to a
@@ -5014,9 +5012,8 @@ Value *ScalarExprEmitter::VisitBinLAnd(const 
BinaryOperator *E) {
   } else
 CGF.markStmtMaybeUsed(E->getRHS());
 
-  CGF.MCDCLogOpStack.pop_back();
   // If the top of the logical operator nest, update the MCDC bitmap.
-  if (CGF.MCDCLogOpStack.empty())
+  if (CGF.isMCDCDecisionExpr(E))
 CGF.maybeUpdateMCDCTestVectorBitmap(E);
 
   // ZExt result to int or bool.
@@ -5031,11 +5028,9 @@ Value *ScalarExprEmitter::VisitBinLAnd(const 
BinaryOperator *E) {
   }
 
   // If the top of the logical operator nest, reset the MCDC temp to 0.
-  if (CGF.MCDCLogOpStack.empty())
+  if (CGF.isMCDCDecisionExpr(E))
 CGF.maybeResetMCDCCondBitmap(E);
 
-  CGF.MCDCLogOpStack.push_back(E);
-
   llvm::BasicBlock *ContBlock = CGF.createBasicBlock("land.end");
   llvm::BasicBlock *RHSBlock  = CGF.createBasicBlock("land.rhs");
 
@@ -5086,9 +5081,8 @@ Value *ScalarExprEmitter::VisitBinLAnd(const 
BinaryOperator *E) {
   // Insert an entry into the phi node for the edge with the value of RHSCond.
   PN->addIncoming(RHSCond, RHSBlock);
 
-  CGF.MCDCLogOpStack.pop_back();
   // If the top of the logical operator nest, update the MCDC bitmap.
-  if (CGF.MCDCLogOpStack.empty())
+  if (CGF.isMCDCDecisionExpr(E))
 CGF.maybeUpdateMCDCTestVectorBitmap(E);
 
   // Artificial location to preserve the scope information
@@ -5133,11 +5127,9 @@ Value *ScalarExprEmitter::VisitBinLOr(const 
BinaryOperator *E) {
   CGF.incrementProfileCounter(E);
 
   // If the top of the logical operator nest, reset the MCDC temp to 0.
-  if (CGF.MCDCLogOpStack.empty())
+  if (CGF.isMCDCDecisionExpr(E))
 CGF.maybeResetMCDCCondBitmap(E);
 
-  CGF.MCDCLogOpStack.push_back(E);
-
   Value *RHSCond = CGF.EvaluateExprAsBool(E->getRHS());
 
   // If we're generating for profiling or coverage, generate a branch to a
@@ -5157,9 +5149,8 @@ Value *ScalarExprEmitter::VisitBinLOr(const 
BinaryOperator *E) {
   } else
 CGF.markStmtMaybeUsed(E->getRHS());
 
-  CGF.MCDCLogOpStack.pop_back();
   // If the top of the logical operator nest, update the MCDC bitmap.
-  if (CGF.MCDCLogOpStack.empty())
+  if (CGF.isMCDCDecisionExpr(E))
 CGF.maybeUpdateMCDCTestVectorBitmap(E);
 
   // ZExt result to int or bool.
@@ -5174,11 +5165,9 @@ Value *ScalarExprEmitter::VisitBinLOr(const 
BinaryOperator *E) {
   }
 
   // If the top of the logical operator nest, reset the MCDC temp to 0.
-  if (CGF.MCDCLogOpStack.empty())
+  if (CGF.isMCDCDecisionExpr(E))
 CGF.maybeResetMCDCCondBitmap(E);
 
-  CGF.MCDCLogOpStack.push_back(E);
-
   llvm::BasicBlock *ContBlock = CGF.createBasicBlock("lor.end");
   llvm::BasicBlock *RHSBlock = CGF.createBasicBlock("lor.rhs");
 
@@ -5229,9 +5218,8 @@ Value *ScalarExprEmitter::VisitBinLOr(const 
BinaryOperator *E) {
   CGF.EmitBlock(ContBlock);
   PN->addIncoming(RHSCond, RHSBlock);
 
-  CGF.MCDCLogOpStack.pop_back();
   // If the top of the logical operator nest, update the MCDC bitmap.
-  if (CGF.MCDCLogOpStack.empty())
+  if (CGF.isMCDCDecisionExpr(E))
 CGF.maybeUpdateMCDCTestVectorBitmap(E);
 
   // ZExt result to int.
@@ -5390,8 +5378,8 @@ VisitAbstractConditionalOperator(const 
AbstractConditionalOperator *E) {
   }
 
   // If the top of the logical operator nest, reset the MCDC temp to 0.
-  if (CGF.MCDCLogOpStack.empty())
-CGF.maybeResetMCDCCondBitmap(condExpr);
+  if (auto E = CGF.stripCond(condExpr); CGF.isMCDCDecisionExpr(E))
+CGF.maybeResetMCDCCondBitmap(E);
 
   llvm::BasicBlock *LHSBlock = CGF.createBasicBlock("cond.true");
   llvm::BasicBlock *RHSBlock = CGF.createBasicBlock("cond.false");
@@ -5406,8 +5394,8 @@ VisitAbstractConditionalOpe

[llvm-branch-commits] [clang] [MC/DC] Create dedicated MCDCCondBitmapAddr for each Decision (PR #125411)

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

llvmbot wrote:




@llvm/pr-subscribers-clang

Author: NAKAMURA Takumi (chapuni)


Changes

MCDCCondBitmapAddr is moved from `CodeGenFunction` into `MCDCState` and created 
for each Decision.

In `maybeCreateMCDCCondBitmap`, Allocate bitmaps for all valid Decisions and 
emit them order by ID, to prevent nondeterminism.

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


6 Files Affected:

- (modified) clang/lib/CodeGen/CodeGenFunction.h (+9-8) 
- (modified) clang/lib/CodeGen/CodeGenPGO.cpp (+35-6) 
- (modified) clang/lib/CodeGen/CodeGenPGO.h (+3-5) 
- (modified) clang/lib/CodeGen/MCDCState.h (+2) 
- (added) clang/test/CoverageMapping/mcdc-single-cond.cpp (+101) 
- (modified) clang/test/Profile/c-mcdc-logicalop-ternary.c (+10-8) 


``diff
diff --git a/clang/lib/CodeGen/CodeGenFunction.h 
b/clang/lib/CodeGen/CodeGenFunction.h
index e978cad4336238..20d81ba3a3bde1 100644
--- a/clang/lib/CodeGen/CodeGenFunction.h
+++ b/clang/lib/CodeGen/CodeGenFunction.h
@@ -1628,9 +1628,6 @@ class CodeGenFunction : public CodeGenTypeCache {
 
   CodeGenPGO PGO;
 
-  /// Bitmap used by MC/DC to track condition outcomes of a boolean expression.
-  Address MCDCCondBitmapAddr = Address::invalid();
-
   /// Calculate branch weights appropriate for PGO data
   llvm::MDNode *createProfileWeights(uint64_t TrueCount,
  uint64_t FalseCount) const;
@@ -1669,8 +1666,12 @@ class CodeGenFunction : public CodeGenTypeCache {
   void maybeCreateMCDCCondBitmap() {
 if (isMCDCCoverageEnabled()) {
   PGO.emitMCDCParameters(Builder);
-  MCDCCondBitmapAddr =
-  CreateIRTemp(getContext().UnsignedIntTy, "mcdc.addr");
+
+  // Set up MCDCCondBitmapAddr for each Decision.
+  // Note: This doesn't initialize Addrs in invalidated Decisions.
+  for (auto *MCDCCondBitmapAddr : PGO.getMCDCCondBitmapAddrArray(Builder))
+*MCDCCondBitmapAddr =
+CreateIRTemp(getContext().UnsignedIntTy, "mcdc.addr");
 }
   }
 
@@ -1682,7 +1683,7 @@ class CodeGenFunction : public CodeGenTypeCache {
   /// Zero-init the MCDC temp value.
   void maybeResetMCDCCondBitmap(const Expr *E) {
 if (isMCDCCoverageEnabled() && isBinaryLogicalOp(E)) {
-  PGO.emitMCDCCondBitmapReset(Builder, E, MCDCCondBitmapAddr);
+  PGO.emitMCDCCondBitmapReset(Builder, E);
   PGO.setCurrentStmt(E);
 }
   }
@@ -1691,7 +1692,7 @@ class CodeGenFunction : public CodeGenTypeCache {
   /// If \p StepV is null, the default increment is 1.
   void maybeUpdateMCDCTestVectorBitmap(const Expr *E) {
 if (isMCDCCoverageEnabled() && isBinaryLogicalOp(E)) {
-  PGO.emitMCDCTestVectorBitmapUpdate(Builder, E, MCDCCondBitmapAddr, 
*this);
+  PGO.emitMCDCTestVectorBitmapUpdate(Builder, E, *this);
   PGO.setCurrentStmt(E);
 }
   }
@@ -1699,7 +1700,7 @@ class CodeGenFunction : public CodeGenTypeCache {
   /// Update the MCDC temp value with the condition's evaluated result.
   void maybeUpdateMCDCCondBitmap(const Expr *E, llvm::Value *Val) {
 if (isMCDCCoverageEnabled()) {
-  PGO.emitMCDCCondBitmapUpdate(Builder, E, MCDCCondBitmapAddr, Val, *this);
+  PGO.emitMCDCCondBitmapUpdate(Builder, E, Val, *this);
   PGO.setCurrentStmt(E);
 }
   }
diff --git a/clang/lib/CodeGen/CodeGenPGO.cpp b/clang/lib/CodeGen/CodeGenPGO.cpp
index 0331ff83e633f7..7d16f673ada419 100644
--- a/clang/lib/CodeGen/CodeGenPGO.cpp
+++ b/clang/lib/CodeGen/CodeGenPGO.cpp
@@ -1245,9 +1245,29 @@ void CodeGenPGO::emitMCDCParameters(CGBuilderTy 
&Builder) {
   CGM.getIntrinsic(llvm::Intrinsic::instrprof_mcdc_parameters), Args);
 }
 
+/// Fill mcdc.addr order by ID.
+std::vector
+CodeGenPGO::getMCDCCondBitmapAddrArray(CGBuilderTy &Builder) {
+  std::vector Result;
+
+  if (!canEmitMCDCCoverage(Builder) || !RegionMCDCState)
+return Result;
+
+  SmallVector> SortedPair;
+  for (auto &[_, V] : RegionMCDCState->DecisionByStmt)
+if (V.isValid())
+  SortedPair.emplace_back(V.ID, &V.MCDCCondBitmapAddr);
+
+  llvm::sort(SortedPair);
+
+  for (auto &[_, MCDCCondBitmapAddr] : SortedPair)
+Result.push_back(MCDCCondBitmapAddr);
+
+  return Result;
+}
+
 void CodeGenPGO::emitMCDCTestVectorBitmapUpdate(CGBuilderTy &Builder,
 const Expr *S,
-Address MCDCCondBitmapAddr,
 CodeGenFunction &CGF) {
   if (!canEmitMCDCCoverage(Builder) || !RegionMCDCState)
 return;
@@ -1258,6 +1278,10 @@ void 
CodeGenPGO::emitMCDCTestVectorBitmapUpdate(CGBuilderTy &Builder,
   if (DecisionStateIter == RegionMCDCState->DecisionByStmt.end())
 return;
 
+  auto &MCDCCondBitmapAddr = DecisionStateIter->second.MCDCCondBitmapAddr;
+  if (!MCDCCondBitmapAddr.isValid())
+return;
+
   // Don't create tvbitmap_update if the record is allocated but excluded.
   // Or `bitmap |= (1 << 0)` would be wrongly executed to the next bitmap.
   if (DecisionStateIter->second.I

[llvm-branch-commits] [clang] [MC/DC] Enable nested expressions (PR #125413)

2025-02-02 Thread NAKAMURA Takumi via llvm-branch-commits

https://github.com/chapuni created 
https://github.com/llvm/llvm-project/pull/125413

A warning "contains an operation with a nested boolean expression." is no 
longer emitted. At the moment, split expressions are treated as individual 
Decisions.

>From c56ecc30e9fd1a674073e362fbfcc6b43f2f52e2 Mon Sep 17 00:00:00 2001
From: NAKAMURA Takumi 
Date: Sun, 2 Feb 2025 22:06:32 +0900
Subject: [PATCH] [MC/DC] Enable nested expressions

A warning "contains an operation with a nested boolean expression." is
no longer emitter. At the moment, split expressions are treated as
individual Decisions.
---
 clang/lib/CodeGen/CodeGenPGO.cpp  | 150 ++
 .../test/CoverageMapping/mcdc-nested-expr.cpp |  30 +++-
 .../Frontend/custom-diag-werror-interaction.c |   4 +-
 3 files changed, 109 insertions(+), 75 deletions(-)

diff --git a/clang/lib/CodeGen/CodeGenPGO.cpp b/clang/lib/CodeGen/CodeGenPGO.cpp
index 7d16f673ada419e..0c3973aa4dccfdc 100644
--- a/clang/lib/CodeGen/CodeGenPGO.cpp
+++ b/clang/lib/CodeGen/CodeGenPGO.cpp
@@ -228,10 +228,17 @@ struct MapRegionCounters : public 
RecursiveASTVisitor {
   /// The stacks are also used to find error cases and notify the user.  A
   /// standard logical operator nest for a boolean expression could be in a 
form
   /// similar to this: "x = a && b && c && (d || f)"
-  unsigned NumCond = 0;
-  bool SplitNestedLogicalOp = false;
-  SmallVector NonLogOpStack;
-  SmallVector LogOpStack;
+  struct DecisionState {
+llvm::DenseSet Leaves; // Not BinOp
+const Expr *DecisionExpr;// Root
+bool Split;
+
+DecisionState() = delete;
+DecisionState(const Expr *E, bool Split = false)
+: DecisionExpr(E), Split(Split) {}
+  };
+
+  SmallVector DecisionStack;
 
   // Hook: dataTraverseStmtPre() is invoked prior to visiting an AST Stmt node.
   bool dataTraverseStmtPre(Stmt *S) {
@@ -239,34 +246,28 @@ struct MapRegionCounters : public 
RecursiveASTVisitor {
 if (MCDCMaxCond == 0)
   return true;
 
-/// At the top of the logical operator nest, reset the number of 
conditions,
-/// also forget previously seen split nesting cases.
-if (LogOpStack.empty()) {
-  NumCond = 0;
-  SplitNestedLogicalOp = false;
-}
-
-if (const Expr *E = dyn_cast(S)) {
-  const BinaryOperator *BinOp = 
dyn_cast(E->IgnoreParens());
-  if (BinOp && BinOp->isLogicalOp()) {
-/// Check for "split-nested" logical operators. This happens when a new
-/// boolean expression logical-op nest is encountered within an 
existing
-/// boolean expression, separated by a non-logical operator.  For
-/// example, in "x = (a && b && c && foo(d && f))", the "d && f" case
-/// starts a new boolean expression that is separated from the other
-/// conditions by the operator foo(). Split-nested cases are not
-/// supported by MC/DC.
-SplitNestedLogicalOp = SplitNestedLogicalOp || !NonLogOpStack.empty();
-
-LogOpStack.push_back(BinOp);
+/// Mark "in splitting" when a leaf is met.
+if (!DecisionStack.empty()) {
+  auto &StackTop = DecisionStack.back();
+  if (!StackTop.Split) {
+if (StackTop.Leaves.contains(S)) {
+  assert(!StackTop.Split);
+  StackTop.Split = true;
+}
 return true;
   }
+
+  // Split
+  assert(StackTop.Split);
+  assert(!StackTop.Leaves.contains(S));
 }
 
-/// Keep track of non-logical operators. These are OK as long as we don't
-/// encounter a new logical operator after seeing one.
-if (!LogOpStack.empty())
-  NonLogOpStack.push_back(S);
+if (const auto *E = dyn_cast(S)) {
+  if (const auto *BinOp =
+  dyn_cast(CodeGenFunction::stripCond(E));
+  BinOp && BinOp->isLogicalOp())
+DecisionStack.emplace_back(E);
+}
 
 return true;
   }
@@ -275,49 +276,57 @@ struct MapRegionCounters : public 
RecursiveASTVisitor {
   // an AST Stmt node.  MC/DC will use it to to signal when the top of a
   // logical operation (boolean expression) nest is encountered.
   bool dataTraverseStmtPost(Stmt *S) {
-/// If MC/DC is not enabled, MCDCMaxCond will be set to 0. Do nothing.
-if (MCDCMaxCond == 0)
+if (DecisionStack.empty())
   return true;
 
-if (const Expr *E = dyn_cast(S)) {
-  const BinaryOperator *BinOp = 
dyn_cast(E->IgnoreParens());
-  if (BinOp && BinOp->isLogicalOp()) {
-assert(LogOpStack.back() == BinOp);
-LogOpStack.pop_back();
-
-/// At the top of logical operator nest:
-if (LogOpStack.empty()) {
-  /// Was the "split-nested" logical operator case encountered?
-  if (SplitNestedLogicalOp) {
-unsigned DiagID = Diag.getCustomDiagID(
-DiagnosticsEngine::Warning,
-"unsupported MC/DC boolean expression; "
-"contains an operation with a nested boolean expression. "
-"Expression will not be

[llvm-branch-commits] [clang] [MC/DC] Enable nested expressions (PR #125413)

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

llvmbot wrote:




@llvm/pr-subscribers-clang

Author: NAKAMURA Takumi (chapuni)


Changes

A warning "contains an operation with a nested boolean expression." is no 
longer emitted. At the moment, split expressions are treated as individual 
Decisions.

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


3 Files Affected:

- (modified) clang/lib/CodeGen/CodeGenPGO.cpp (+81-69) 
- (modified) clang/test/CoverageMapping/mcdc-nested-expr.cpp (+26-4) 
- (modified) clang/test/Frontend/custom-diag-werror-interaction.c (+2-2) 


``diff
diff --git a/clang/lib/CodeGen/CodeGenPGO.cpp b/clang/lib/CodeGen/CodeGenPGO.cpp
index 7d16f673ada419..0c3973aa4dccfd 100644
--- a/clang/lib/CodeGen/CodeGenPGO.cpp
+++ b/clang/lib/CodeGen/CodeGenPGO.cpp
@@ -228,10 +228,17 @@ struct MapRegionCounters : public 
RecursiveASTVisitor {
   /// The stacks are also used to find error cases and notify the user.  A
   /// standard logical operator nest for a boolean expression could be in a 
form
   /// similar to this: "x = a && b && c && (d || f)"
-  unsigned NumCond = 0;
-  bool SplitNestedLogicalOp = false;
-  SmallVector NonLogOpStack;
-  SmallVector LogOpStack;
+  struct DecisionState {
+llvm::DenseSet Leaves; // Not BinOp
+const Expr *DecisionExpr;// Root
+bool Split;
+
+DecisionState() = delete;
+DecisionState(const Expr *E, bool Split = false)
+: DecisionExpr(E), Split(Split) {}
+  };
+
+  SmallVector DecisionStack;
 
   // Hook: dataTraverseStmtPre() is invoked prior to visiting an AST Stmt node.
   bool dataTraverseStmtPre(Stmt *S) {
@@ -239,34 +246,28 @@ struct MapRegionCounters : public 
RecursiveASTVisitor {
 if (MCDCMaxCond == 0)
   return true;
 
-/// At the top of the logical operator nest, reset the number of 
conditions,
-/// also forget previously seen split nesting cases.
-if (LogOpStack.empty()) {
-  NumCond = 0;
-  SplitNestedLogicalOp = false;
-}
-
-if (const Expr *E = dyn_cast(S)) {
-  const BinaryOperator *BinOp = 
dyn_cast(E->IgnoreParens());
-  if (BinOp && BinOp->isLogicalOp()) {
-/// Check for "split-nested" logical operators. This happens when a new
-/// boolean expression logical-op nest is encountered within an 
existing
-/// boolean expression, separated by a non-logical operator.  For
-/// example, in "x = (a && b && c && foo(d && f))", the "d && f" case
-/// starts a new boolean expression that is separated from the other
-/// conditions by the operator foo(). Split-nested cases are not
-/// supported by MC/DC.
-SplitNestedLogicalOp = SplitNestedLogicalOp || !NonLogOpStack.empty();
-
-LogOpStack.push_back(BinOp);
+/// Mark "in splitting" when a leaf is met.
+if (!DecisionStack.empty()) {
+  auto &StackTop = DecisionStack.back();
+  if (!StackTop.Split) {
+if (StackTop.Leaves.contains(S)) {
+  assert(!StackTop.Split);
+  StackTop.Split = true;
+}
 return true;
   }
+
+  // Split
+  assert(StackTop.Split);
+  assert(!StackTop.Leaves.contains(S));
 }
 
-/// Keep track of non-logical operators. These are OK as long as we don't
-/// encounter a new logical operator after seeing one.
-if (!LogOpStack.empty())
-  NonLogOpStack.push_back(S);
+if (const auto *E = dyn_cast(S)) {
+  if (const auto *BinOp =
+  dyn_cast(CodeGenFunction::stripCond(E));
+  BinOp && BinOp->isLogicalOp())
+DecisionStack.emplace_back(E);
+}
 
 return true;
   }
@@ -275,49 +276,57 @@ struct MapRegionCounters : public 
RecursiveASTVisitor {
   // an AST Stmt node.  MC/DC will use it to to signal when the top of a
   // logical operation (boolean expression) nest is encountered.
   bool dataTraverseStmtPost(Stmt *S) {
-/// If MC/DC is not enabled, MCDCMaxCond will be set to 0. Do nothing.
-if (MCDCMaxCond == 0)
+if (DecisionStack.empty())
   return true;
 
-if (const Expr *E = dyn_cast(S)) {
-  const BinaryOperator *BinOp = 
dyn_cast(E->IgnoreParens());
-  if (BinOp && BinOp->isLogicalOp()) {
-assert(LogOpStack.back() == BinOp);
-LogOpStack.pop_back();
-
-/// At the top of logical operator nest:
-if (LogOpStack.empty()) {
-  /// Was the "split-nested" logical operator case encountered?
-  if (SplitNestedLogicalOp) {
-unsigned DiagID = Diag.getCustomDiagID(
-DiagnosticsEngine::Warning,
-"unsupported MC/DC boolean expression; "
-"contains an operation with a nested boolean expression. "
-"Expression will not be covered");
-Diag.Report(S->getBeginLoc(), DiagID);
-return true;
-  }
-
-  /// Was the maximum number of conditions encountered?
-  if (NumCond > MCDCMaxCond) {
-unsigned DiagID = Diag.getCustomDiagID(
- 

[llvm-branch-commits] [clang] [clang] NFC: rename MatchedPackOnParmToNonPackOnArg to StrictPackMatch (PR #125418)

2025-02-02 Thread Matheus Izvekov via llvm-branch-commits

https://github.com/mizvekov created 
https://github.com/llvm/llvm-project/pull/125418

This rename follows the proposed wording in P3310R5, which introduces the term 
'strict pack match' to refer to the same thing.

>From 772973a841ad739172a9f23bc1403924eea4cba8 Mon Sep 17 00:00:00 2001
From: Matheus Izvekov 
Date: Sun, 2 Feb 2025 13:31:20 -0300
Subject: [PATCH] [clang] NFC: rename MatchedPackOnParmToNonPackOnArg to
 StrictPackMatch

This rename follows the proposed wording in P3310R5, which introduces
the term 'strict pack match' to refer to the same thing.
---
 clang/include/clang/AST/DeclTemplate.h| 12 +++
 clang/include/clang/Sema/Overload.h   |  5 ++-
 clang/include/clang/Sema/Sema.h   | 33 +--
 clang/include/clang/Sema/TemplateDeduction.h  | 10 ++
 clang/lib/AST/ASTImporter.cpp |  8 ++---
 clang/lib/AST/DeclTemplate.cpp| 18 --
 clang/lib/AST/TextNodeDumper.cpp  |  2 +-
 clang/lib/Sema/SemaOverload.cpp   | 30 +++--
 clang/lib/Sema/SemaTemplate.cpp   | 29 
 clang/lib/Sema/SemaTemplateDeduction.cpp  | 21 ++--
 clang/lib/Sema/SemaTemplateInstantiate.cpp| 16 -
 .../lib/Sema/SemaTemplateInstantiateDecl.cpp  |  2 +-
 clang/lib/Sema/SemaType.cpp   |  3 +-
 clang/lib/Serialization/ASTReaderDecl.cpp |  2 +-
 clang/lib/Serialization/ASTWriterDecl.cpp |  2 +-
 15 files changed, 84 insertions(+), 109 deletions(-)

diff --git a/clang/include/clang/AST/DeclTemplate.h 
b/clang/include/clang/AST/DeclTemplate.h
index 03c43765206b18..87406b0e030df1 100644
--- a/clang/include/clang/AST/DeclTemplate.h
+++ b/clang/include/clang/AST/DeclTemplate.h
@@ -1842,11 +1842,11 @@ class ClassTemplateSpecializationDecl : public 
CXXRecordDecl,
   unsigned SpecializationKind : 3;
 
   /// Indicate that we have matched a parameter pack with a non pack
-  /// argument, when the opposite match is also allowed (strict pack match).
+  /// argument, when the opposite match is also allowed.
   /// This needs to be cached as deduction is performed during declaration,
   /// and we need the information to be preserved so that it is consistent
   /// during instantiation.
-  bool MatchedPackOnParmToNonPackOnArg : 1;
+  bool StrictPackMatch : 1;
 
 protected:
   ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, TagKind TK,
@@ -1854,7 +1854,7 @@ class ClassTemplateSpecializationDecl : public 
CXXRecordDecl,
   SourceLocation IdLoc,
   ClassTemplateDecl *SpecializedTemplate,
   ArrayRef Args,
-  bool MatchedPackOnParmToNonPackOnArg,
+  bool StrictPackMatch,
   ClassTemplateSpecializationDecl *PrevDecl);
 
   ClassTemplateSpecializationDecl(ASTContext &C, Kind DK);
@@ -1867,7 +1867,7 @@ class ClassTemplateSpecializationDecl : public 
CXXRecordDecl,
   Create(ASTContext &Context, TagKind TK, DeclContext *DC,
  SourceLocation StartLoc, SourceLocation IdLoc,
  ClassTemplateDecl *SpecializedTemplate,
- ArrayRef Args, bool MatchedPackOnParmToNonPackOnArg,
+ ArrayRef Args, bool StrictPackMatch,
  ClassTemplateSpecializationDecl *PrevDecl);
   static ClassTemplateSpecializationDecl *CreateDeserialized(ASTContext &C,
  GlobalDeclID ID);
@@ -1938,9 +1938,7 @@ class ClassTemplateSpecializationDecl : public 
CXXRecordDecl,
 SpecializationKind = TSK;
   }
 
-  bool hasMatchedPackOnParmToNonPackOnArg() const {
-return MatchedPackOnParmToNonPackOnArg;
-  }
+  bool hasStrictPackMatch() const { return StrictPackMatch; }
 
   /// Get the point of instantiation (if any), or null if none.
   SourceLocation getPointOfInstantiation() const {
diff --git a/clang/include/clang/Sema/Overload.h 
b/clang/include/clang/Sema/Overload.h
index c7f2422b542dd1..c03ec00d03dc50 100644
--- a/clang/include/clang/Sema/Overload.h
+++ b/clang/include/clang/Sema/Overload.h
@@ -933,7 +933,7 @@ class Sema;
 /// Have we matched any packs on the parameter side, versus any non-packs 
on
 /// the argument side, in a context where the opposite matching is also
 /// allowed?
-bool HasMatchedPackOnParmToNonPackOnArg : 1;
+bool StrictPackMatch : 1;
 
 /// True if the candidate was found using ADL.
 LLVM_PREFERRED_TYPE(CallExpr::ADLCallKind)
@@ -1010,8 +1010,7 @@ class Sema;
 friend class OverloadCandidateSet;
 OverloadCandidate()
 : IsSurrogate(false), IgnoreObjectArgument(false),
-  TookAddressOfOverload(false),
-  HasMatchedPackOnParmToNonPackOnArg(false),
+  TookAddressOfOverload(false), StrictPackMatch(false),
   IsADLCandidate(llvm::to_underlying(CallExpr::NotADL)),
   RewriteKind(CRK_None) {}
   };
diff

[llvm-branch-commits] [clang] [clang] NFC: rename MatchedPackOnParmToNonPackOnArg to StrictPackMatch (PR #125418)

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

llvmbot wrote:



@llvm/pr-subscribers-clang-modules

@llvm/pr-subscribers-clang

Author: Matheus Izvekov (mizvekov)


Changes

This rename follows the proposed wording in P3310R5, which introduces the term 
'strict pack match' to refer to the same thing.

---

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


15 Files Affected:

- (modified) clang/include/clang/AST/DeclTemplate.h (+5-7) 
- (modified) clang/include/clang/Sema/Overload.h (+2-3) 
- (modified) clang/include/clang/Sema/Sema.h (+15-18) 
- (modified) clang/include/clang/Sema/TemplateDeduction.h (+3-7) 
- (modified) clang/lib/AST/ASTImporter.cpp (+4-4) 
- (modified) clang/lib/AST/DeclTemplate.cpp (+7-11) 
- (modified) clang/lib/AST/TextNodeDumper.cpp (+1-1) 
- (modified) clang/lib/Sema/SemaOverload.cpp (+12-18) 
- (modified) clang/lib/Sema/SemaTemplate.cpp (+14-15) 
- (modified) clang/lib/Sema/SemaTemplateDeduction.cpp (+10-11) 
- (modified) clang/lib/Sema/SemaTemplateInstantiate.cpp (+7-9) 
- (modified) clang/lib/Sema/SemaTemplateInstantiateDecl.cpp (+1-1) 
- (modified) clang/lib/Sema/SemaType.cpp (+1-2) 
- (modified) clang/lib/Serialization/ASTReaderDecl.cpp (+1-1) 
- (modified) clang/lib/Serialization/ASTWriterDecl.cpp (+1-1) 


``diff
diff --git a/clang/include/clang/AST/DeclTemplate.h 
b/clang/include/clang/AST/DeclTemplate.h
index 03c43765206b18..87406b0e030df1 100644
--- a/clang/include/clang/AST/DeclTemplate.h
+++ b/clang/include/clang/AST/DeclTemplate.h
@@ -1842,11 +1842,11 @@ class ClassTemplateSpecializationDecl : public 
CXXRecordDecl,
   unsigned SpecializationKind : 3;
 
   /// Indicate that we have matched a parameter pack with a non pack
-  /// argument, when the opposite match is also allowed (strict pack match).
+  /// argument, when the opposite match is also allowed.
   /// This needs to be cached as deduction is performed during declaration,
   /// and we need the information to be preserved so that it is consistent
   /// during instantiation.
-  bool MatchedPackOnParmToNonPackOnArg : 1;
+  bool StrictPackMatch : 1;
 
 protected:
   ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, TagKind TK,
@@ -1854,7 +1854,7 @@ class ClassTemplateSpecializationDecl : public 
CXXRecordDecl,
   SourceLocation IdLoc,
   ClassTemplateDecl *SpecializedTemplate,
   ArrayRef Args,
-  bool MatchedPackOnParmToNonPackOnArg,
+  bool StrictPackMatch,
   ClassTemplateSpecializationDecl *PrevDecl);
 
   ClassTemplateSpecializationDecl(ASTContext &C, Kind DK);
@@ -1867,7 +1867,7 @@ class ClassTemplateSpecializationDecl : public 
CXXRecordDecl,
   Create(ASTContext &Context, TagKind TK, DeclContext *DC,
  SourceLocation StartLoc, SourceLocation IdLoc,
  ClassTemplateDecl *SpecializedTemplate,
- ArrayRef Args, bool MatchedPackOnParmToNonPackOnArg,
+ ArrayRef Args, bool StrictPackMatch,
  ClassTemplateSpecializationDecl *PrevDecl);
   static ClassTemplateSpecializationDecl *CreateDeserialized(ASTContext &C,
  GlobalDeclID ID);
@@ -1938,9 +1938,7 @@ class ClassTemplateSpecializationDecl : public 
CXXRecordDecl,
 SpecializationKind = TSK;
   }
 
-  bool hasMatchedPackOnParmToNonPackOnArg() const {
-return MatchedPackOnParmToNonPackOnArg;
-  }
+  bool hasStrictPackMatch() const { return StrictPackMatch; }
 
   /// Get the point of instantiation (if any), or null if none.
   SourceLocation getPointOfInstantiation() const {
diff --git a/clang/include/clang/Sema/Overload.h 
b/clang/include/clang/Sema/Overload.h
index c7f2422b542dd1..c03ec00d03dc50 100644
--- a/clang/include/clang/Sema/Overload.h
+++ b/clang/include/clang/Sema/Overload.h
@@ -933,7 +933,7 @@ class Sema;
 /// Have we matched any packs on the parameter side, versus any non-packs 
on
 /// the argument side, in a context where the opposite matching is also
 /// allowed?
-bool HasMatchedPackOnParmToNonPackOnArg : 1;
+bool StrictPackMatch : 1;
 
 /// True if the candidate was found using ADL.
 LLVM_PREFERRED_TYPE(CallExpr::ADLCallKind)
@@ -1010,8 +1010,7 @@ class Sema;
 friend class OverloadCandidateSet;
 OverloadCandidate()
 : IsSurrogate(false), IgnoreObjectArgument(false),
-  TookAddressOfOverload(false),
-  HasMatchedPackOnParmToNonPackOnArg(false),
+  TookAddressOfOverload(false), StrictPackMatch(false),
   IsADLCandidate(llvm::to_underlying(CallExpr::NotADL)),
   RewriteKind(CRK_None) {}
   };
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 79bf6c04ee4969..9fae6bfa58d254 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -10174,18 +10174,15 @@ class Sema fina

[llvm-branch-commits] [clang] release/20.x: [AArch64] Enable vscale_range with +sme (#124466) (PR #125386)

2025-02-02 Thread Amara Emerson via llvm-branch-commits

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


https://github.com/llvm/llvm-project/pull/125386
___
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] [lld] release/20.x: [ELF] Refine isExported/isPreemptible condition (PR #125334)

2025-02-02 Thread Fangrui Song via llvm-branch-commits

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


https://github.com/llvm/llvm-project/pull/125334
___
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: [ORC][LLI] Remove redundant eh-frame registration plugin construction from lli. (PR #125431)

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

https://github.com/llvmbot milestoned 
https://github.com/llvm/llvm-project/pull/125431
___
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] [SelectionDAG][X86] Remove unused elements from atomic vector. (PR #125432)

2025-02-02 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 76e068350de93eee06b3cc4616adadf33e9d84c0 
fbe99a2a2d6f3c95978c520812046567ec7811cd --extensions h,cpp -- 
llvm/include/llvm/CodeGen/SelectionDAG.h 
llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp 
llvm/lib/CodeGen/SelectionDAG/SelectionDAGAddressAnalysis.cpp 
llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp 
llvm/lib/Target/X86/X86ISelLowering.cpp
``





View the diff from clang-format here.


``diff
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGAddressAnalysis.cpp 
b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGAddressAnalysis.cpp
index a19af64a79..d09bc81d50 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGAddressAnalysis.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGAddressAnalysis.cpp
@@ -195,8 +195,7 @@ bool BaseIndexOffset::contains(const SelectionDAG &DAG, 
int64_t BitSize,
 }
 
 template 
-static BaseIndexOffset matchSDNode(const T *N,
-   const SelectionDAG &DAG) {
+static BaseIndexOffset matchSDNode(const T *N, const SelectionDAG &DAG) {
   SDValue Ptr = N->getBasePtr();
 
   // (((B + I*M) + c)) + c ...
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp 
b/llvm/lib/Target/X86/X86ISelLowering.cpp
index 3b8f3dd1e9..4f78623fa8 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -7079,8 +7079,7 @@ static bool findEltLoadSrc(SDValue Elt, MemSDNode *&Ld, 
int64_t &ByteOffset) {
 Ld = BaseLd;
 ByteOffset = 0;
 return true;
-  }
-  else if (auto *BaseLd = dyn_cast(Elt))
+  } else if (auto *BaseLd = dyn_cast(Elt))
 if (ISD::isNON_EXTLoad(Elt.getNode())) {
   if (!BaseLd->isSimple())
 return false;
@@ -7140,7 +7139,7 @@ static SDValue EltsFromConsecutiveLoads(EVT VT, 
ArrayRef Elts,
   APInt ZeroMask = APInt::getZero(NumElems);
   APInt UndefMask = APInt::getZero(NumElems);
 
-  SmallVector Loads(NumElems, nullptr);
+  SmallVector Loads(NumElems, nullptr);
   SmallVector ByteOffsets(NumElems, 0);
 
   // For each element in the initializer, see if we've found a load, zero or an

``




https://github.com/llvm/llvm-project/pull/125432
___
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: [ORC][LLI] Remove redundant eh-frame registration plugin construction from lli. (PR #125431)

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

https://github.com/llvmbot created 
https://github.com/llvm/llvm-project/pull/125431

Backport 9052b37ab1aa67a039b34356f37236fecc42bac2

Requested by: @mgorny

>From 03d6f704d07aa3650a2f59be6f7802a8735460c3 Mon Sep 17 00:00:00 2001
From: Lang Hames 
Date: Wed, 29 Jan 2025 03:58:29 +
Subject: [PATCH] [ORC][LLI] Remove redundant eh-frame registration plugin
 construction from lli.

As of d0052ebbe2e the setUpGenericLLVMIRPlatform function will automatically
add an instance of the EHFrameRegistrationPlugin (for LLJIT instances whose
object linking layers are ObjectLinkingLayers, not RTDyldObjectLinkingLayers).

This commit removes the redundant plugin creation in the object linking
layer constructor function in lli.cpp to prevent duplicate registration of
eh-frames, which is likely the cause of recent bot failures, e.g.
https://lab.llvm.org/buildbot/#/builders/108/builds/8685.

(cherry picked from commit 9052b37ab1aa67a039b34356f37236fecc42bac2)
---
 llvm/tools/lli/lli.cpp | 14 --
 1 file changed, 4 insertions(+), 10 deletions(-)

diff --git a/llvm/tools/lli/lli.cpp b/llvm/tools/lli/lli.cpp
index 448660a539a0b0..19246f03941673 100644
--- a/llvm/tools/lli/lli.cpp
+++ b/llvm/tools/lli/lli.cpp
@@ -27,9 +27,7 @@
 #include "llvm/ExecutionEngine/Orc/AbsoluteSymbols.h"
 #include "llvm/ExecutionEngine/Orc/DebugUtils.h"
 #include "llvm/ExecutionEngine/Orc/Debugging/DebuggerSupport.h"
-#include "llvm/ExecutionEngine/Orc/EHFrameRegistrationPlugin.h"
 #include "llvm/ExecutionEngine/Orc/EPCDynamicLibrarySearchGenerator.h"
-#include "llvm/ExecutionEngine/Orc/EPCEHFrameRegistrar.h"
 #include "llvm/ExecutionEngine/Orc/EPCGenericRTDyldMemoryManager.h"
 #include "llvm/ExecutionEngine/Orc/ExecutionUtils.h"
 #include "llvm/ExecutionEngine/Orc/IRPartitionLayer.h"
@@ -1033,14 +1031,10 @@ int runOrcJIT(const char *ProgName) {
 Builder.getJITTargetMachineBuilder()
 ->setRelocationModel(Reloc::PIC_)
 .setCodeModel(CodeModel::Small);
-Builder.setObjectLinkingLayerCreator([&P](orc::ExecutionSession &ES,
-  const Triple &TT) {
-  auto L = std::make_unique(ES);
-  if (P != LLJITPlatform::ExecutorNative)
-L->addPlugin(std::make_unique(
-ES, ExitOnErr(orc::EPCEHFrameRegistrar::Create(ES;
-  return L;
-});
+Builder.setObjectLinkingLayerCreator(
+[&](orc::ExecutionSession &ES, const Triple &TT) {
+  return std::make_unique(ES);
+});
   }
 
   auto J = ExitOnErr(Builder.create());

___
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] [SelectionDAG][X86] Split via Concat vector types for atomic load (PR #120640)

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

https://github.com/jofrn edited https://github.com/llvm/llvm-project/pull/120640
___
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] [AtomicExpand] Add bitcasts when expanding load atomic vector (PR #120716)

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

https://github.com/jofrn updated 
https://github.com/llvm/llvm-project/pull/120716

>From d1a877b226e5e72b5131f26db78491553c774bb0 Mon Sep 17 00:00:00 2001
From: jofrn 
Date: Fri, 20 Dec 2024 06:14:28 -0500
Subject: [PATCH] [AtomicExpand] Add bitcasts when expanding load atomic vector

AtomicExpand fails for aligned `load atomic ` because it
does not find a compatible library call. This change adds appropriate
bitcasts so that the call can be lowered.

commit-id:f430c1af
---
 llvm/lib/CodeGen/AtomicExpandPass.cpp | 18 -
 llvm/test/CodeGen/ARM/atomic-load-store.ll| 51 +++
 llvm/test/CodeGen/X86/atomic-load-store.ll| 30 +
 .../X86/expand-atomic-non-integer.ll  | 65 +++
 4 files changed, 161 insertions(+), 3 deletions(-)

diff --git a/llvm/lib/CodeGen/AtomicExpandPass.cpp 
b/llvm/lib/CodeGen/AtomicExpandPass.cpp
index a75fa688d87a8dd..644977f225d834a 100644
--- a/llvm/lib/CodeGen/AtomicExpandPass.cpp
+++ b/llvm/lib/CodeGen/AtomicExpandPass.cpp
@@ -2060,9 +2060,21 @@ bool AtomicExpandImpl::expandAtomicOpToLibcall(
 I->replaceAllUsesWith(V);
   } else if (HasResult) {
 Value *V;
-if (UseSizedLibcall)
-  V = Builder.CreateBitOrPointerCast(Result, I->getType());
-else {
+if (UseSizedLibcall) {
+  // Add bitcasts from Result's scalar type to I's  vector type
+  if (I->getType()->getScalarType()->isPointerTy() &&
+  I->getType()->isVectorTy() && !Result->getType()->isVectorTy()) {
+unsigned AS = cast(
+I->getType()->getScalarType())->getAddressSpace();
+ElementCount EC = cast(I->getType())->getElementCount();
+Value *BC = Builder.CreateBitCast(Result, VectorType::get(
+IntegerType::get(Ctx, DL.getPointerSizeInBits(AS)), EC));
+Value *IntToPtr = Builder.CreateIntToPtr(BC, VectorType::get(
+PointerType::get(Ctx, AS), EC));
+V = Builder.CreateBitOrPointerCast(IntToPtr, I->getType());
+  } else
+V = Builder.CreateBitOrPointerCast(Result, I->getType());
+} else {
   V = Builder.CreateAlignedLoad(I->getType(), AllocaResult,
 AllocaAlignment);
   Builder.CreateLifetimeEnd(AllocaResult, SizeVal64);
diff --git a/llvm/test/CodeGen/ARM/atomic-load-store.ll 
b/llvm/test/CodeGen/ARM/atomic-load-store.ll
index 560dfde356c29d9..36c1305a7c5df39 100644
--- a/llvm/test/CodeGen/ARM/atomic-load-store.ll
+++ b/llvm/test/CodeGen/ARM/atomic-load-store.ll
@@ -983,3 +983,54 @@ define void @store_atomic_f64__seq_cst(ptr %ptr, double 
%val1) {
   store atomic double %val1, ptr %ptr seq_cst, align 8
   ret void
 }
+
+define <1 x ptr> @atomic_vec1_ptr(ptr %x) #0 {
+; ARM-LABEL: atomic_vec1_ptr:
+; ARM:   @ %bb.0:
+; ARM-NEXT:ldr r0, [r0]
+; ARM-NEXT:dmb ish
+; ARM-NEXT:bx lr
+;
+; ARMOPTNONE-LABEL: atomic_vec1_ptr:
+; ARMOPTNONE:   @ %bb.0:
+; ARMOPTNONE-NEXT:ldr r0, [r0]
+; ARMOPTNONE-NEXT:dmb ish
+; ARMOPTNONE-NEXT:bx lr
+;
+; THUMBTWO-LABEL: atomic_vec1_ptr:
+; THUMBTWO:   @ %bb.0:
+; THUMBTWO-NEXT:ldr r0, [r0]
+; THUMBTWO-NEXT:dmb ish
+; THUMBTWO-NEXT:bx lr
+;
+; THUMBONE-LABEL: atomic_vec1_ptr:
+; THUMBONE:   @ %bb.0:
+; THUMBONE-NEXT:push {r7, lr}
+; THUMBONE-NEXT:movs r1, #0
+; THUMBONE-NEXT:mov r2, r1
+; THUMBONE-NEXT:bl __sync_val_compare_and_swap_4
+; THUMBONE-NEXT:pop {r7, pc}
+;
+; ARMV4-LABEL: atomic_vec1_ptr:
+; ARMV4:   @ %bb.0:
+; ARMV4-NEXT:push {r11, lr}
+; ARMV4-NEXT:mov r1, #2
+; ARMV4-NEXT:bl __atomic_load_4
+; ARMV4-NEXT:pop {r11, lr}
+; ARMV4-NEXT:mov pc, lr
+;
+; ARMV6-LABEL: atomic_vec1_ptr:
+; ARMV6:   @ %bb.0:
+; ARMV6-NEXT:mov r1, #0
+; ARMV6-NEXT:mcr p15, #0, r1, c7, c10, #5
+; ARMV6-NEXT:ldr r0, [r0]
+; ARMV6-NEXT:bx lr
+;
+; THUMBM-LABEL: atomic_vec1_ptr:
+; THUMBM:   @ %bb.0:
+; THUMBM-NEXT:ldr r0, [r0]
+; THUMBM-NEXT:dmb sy
+; THUMBM-NEXT:bx lr
+  %ret = load atomic <1 x ptr>, ptr %x acquire, align 4
+  ret <1 x ptr> %ret
+}
diff --git a/llvm/test/CodeGen/X86/atomic-load-store.ll 
b/llvm/test/CodeGen/X86/atomic-load-store.ll
index 08d0405345f5736..4293df8c13571f0 100644
--- a/llvm/test/CodeGen/X86/atomic-load-store.ll
+++ b/llvm/test/CodeGen/X86/atomic-load-store.ll
@@ -371,6 +371,21 @@ define <2 x i32> @atomic_vec2_i32(ptr %x) nounwind {
   ret <2 x i32> %ret
 }
 
+define <2 x ptr> @atomic_vec2_ptr_align(ptr %x) nounwind {
+; CHECK-LABEL: atomic_vec2_ptr_align:
+; CHECK:   ## %bb.0:
+; CHECK-NEXT:pushq %rax
+; CHECK-NEXT:movl $2, %esi
+; CHECK-NEXT:callq ___atomic_load_16
+; CHECK-NEXT:movq %rdx, %xmm1
+; CHECK-NEXT:movq %rax, %xmm0
+; CHECK-NEXT:punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]
+; CHECK-NEXT:popq %rax
+; CHECK-NEXT:retq
+  %ret = load atomic <2 x ptr>, ptr %x acquire, align 16
+  ret <2 x ptr> %ret
+}
+
 define <4 x i8> @atomic_vec4_i8(ptr %x) nounwind {
 ; CHECK3-LABEL: atomic_vec4_i8:
 ; CHECK3: 

[llvm-branch-commits] [llvm] [SelectionDAG][X86] Remove unused elements from atomic vector. (PR #125432)

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

https://github.com/jofrn updated 
https://github.com/llvm/llvm-project/pull/125432

>From 1c10a4c81c1c8d05ed62ab5fa1ee24539f76f889 Mon Sep 17 00:00:00 2001
From: jofrn 
Date: Fri, 31 Jan 2025 13:12:56 -0500
Subject: [PATCH] [SelectionDAG][X86] Remove unused elements from atomic
 vector.

After splitting, all elements are created. The elements are
placed back into a concat_vectors. This change extends EltsFromConsecutiveLoads
to understand AtomicSDNode so that its concat_vectors can be
mapped to a BUILD_VECTOR and so unused elements are no longer
referenced.

commit-id:b83937a8
---
 llvm/include/llvm/CodeGen/SelectionDAG.h  |   4 +-
 .../lib/CodeGen/SelectionDAG/SelectionDAG.cpp |  20 ++-
 .../SelectionDAGAddressAnalysis.cpp   |  29 +--
 .../SelectionDAG/SelectionDAGBuilder.cpp  |   6 +-
 llvm/lib/Target/X86/X86ISelLowering.cpp   |  28 +--
 llvm/test/CodeGen/X86/atomic-load-store.ll| 167 ++
 6 files changed, 69 insertions(+), 185 deletions(-)

diff --git a/llvm/include/llvm/CodeGen/SelectionDAG.h 
b/llvm/include/llvm/CodeGen/SelectionDAG.h
index 461c0c1ead16d2c..bea5958ec0bba6e 100644
--- a/llvm/include/llvm/CodeGen/SelectionDAG.h
+++ b/llvm/include/llvm/CodeGen/SelectionDAG.h
@@ -1840,7 +1840,7 @@ class SelectionDAG {
   /// chain to the token factor. This ensures that the new memory node will 
have
   /// the same relative memory dependency position as the old load. Returns the
   /// new merged load chain.
-  SDValue makeEquivalentMemoryOrdering(LoadSDNode *OldLoad, SDValue NewMemOp);
+  SDValue makeEquivalentMemoryOrdering(MemSDNode *OldLoad, SDValue NewMemOp);
 
   /// Topological-sort the AllNodes list and a
   /// assign a unique node id for each node in the DAG based on their
@@ -2264,7 +2264,7 @@ class SelectionDAG {
   /// merged. Check that both are nonvolatile and if LD is loading
   /// 'Bytes' bytes from a location that is 'Dist' units away from the
   /// location that the 'Base' load is loading from.
-  bool areNonVolatileConsecutiveLoads(LoadSDNode *LD, LoadSDNode *Base,
+  bool areNonVolatileConsecutiveLoads(MemSDNode *LD, MemSDNode *Base,
   unsigned Bytes, int Dist) const;
 
   /// Infer alignment of a load / store address. Return std::nullopt if it
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp 
b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index b416c0efbbc4fc6..5f274fabfe8d640 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -12167,7 +12167,7 @@ SDValue 
SelectionDAG::makeEquivalentMemoryOrdering(SDValue OldChain,
   return TokenFactor;
 }
 
-SDValue SelectionDAG::makeEquivalentMemoryOrdering(LoadSDNode *OldLoad,
+SDValue SelectionDAG::makeEquivalentMemoryOrdering(MemSDNode *OldLoad,
SDValue NewMemOp) {
   assert(isa(NewMemOp.getNode()) && "Expected a memop node");
   SDValue OldChain = SDValue(OldLoad, 1);
@@ -12879,17 +12879,21 @@ std::pair 
SelectionDAG::UnrollVectorOverflowOp(
 getBuildVector(NewOvVT, dl, OvScalars));
 }
 
-bool SelectionDAG::areNonVolatileConsecutiveLoads(LoadSDNode *LD,
-  LoadSDNode *Base,
+bool SelectionDAG::areNonVolatileConsecutiveLoads(MemSDNode *LD,
+  MemSDNode *Base,
   unsigned Bytes,
   int Dist) const {
   if (LD->isVolatile() || Base->isVolatile())
 return false;
-  // TODO: probably too restrictive for atomics, revisit
-  if (!LD->isSimple())
-return false;
-  if (LD->isIndexed() || Base->isIndexed())
-return false;
+  if (auto Ld = dyn_cast(LD)) {
+if (!Ld->isSimple())
+  return false;
+if (Ld->isIndexed())
+  return false;
+  }
+  if (auto Ld = dyn_cast(Base))
+if (Ld->isIndexed())
+  return false;
   if (LD->getChain() != Base->getChain())
 return false;
   EVT VT = LD->getMemoryVT();
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGAddressAnalysis.cpp 
b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGAddressAnalysis.cpp
index f2ab88851b780ef..28b473231e7e545 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGAddressAnalysis.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGAddressAnalysis.cpp
@@ -195,7 +195,8 @@ bool BaseIndexOffset::contains(const SelectionDAG &DAG, 
int64_t BitSize,
 }
 
 /// Parses tree in Ptr for base, index, offset addresses.
-static BaseIndexOffset matchLSNode(const LSBaseSDNode *N,
+template 
+static BaseIndexOffset matchSDNode(const T *N,
const SelectionDAG &DAG) {
   SDValue Ptr = N->getBasePtr();
 
@@ -206,16 +207,18 @@ static BaseIndexOffset matchLSNode(const LSBaseSDNode *N,
   bool IsIndexSignExt = false;
 
   // pre-inc/pre-dec ops are components of EA.
-  if (N->getAddressingMode() == ISD::PRE_INC) {
-if (aut

[llvm-branch-commits] [llvm] [AtomicExpand] Add bitcasts when expanding load atomic vector (PR #120716)

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

https://github.com/jofrn updated 
https://github.com/llvm/llvm-project/pull/120716

>From d1a877b226e5e72b5131f26db78491553c774bb0 Mon Sep 17 00:00:00 2001
From: jofrn 
Date: Fri, 20 Dec 2024 06:14:28 -0500
Subject: [PATCH] [AtomicExpand] Add bitcasts when expanding load atomic vector

AtomicExpand fails for aligned `load atomic ` because it
does not find a compatible library call. This change adds appropriate
bitcasts so that the call can be lowered.

commit-id:f430c1af
---
 llvm/lib/CodeGen/AtomicExpandPass.cpp | 18 -
 llvm/test/CodeGen/ARM/atomic-load-store.ll| 51 +++
 llvm/test/CodeGen/X86/atomic-load-store.ll| 30 +
 .../X86/expand-atomic-non-integer.ll  | 65 +++
 4 files changed, 161 insertions(+), 3 deletions(-)

diff --git a/llvm/lib/CodeGen/AtomicExpandPass.cpp 
b/llvm/lib/CodeGen/AtomicExpandPass.cpp
index a75fa688d87a8dd..644977f225d834a 100644
--- a/llvm/lib/CodeGen/AtomicExpandPass.cpp
+++ b/llvm/lib/CodeGen/AtomicExpandPass.cpp
@@ -2060,9 +2060,21 @@ bool AtomicExpandImpl::expandAtomicOpToLibcall(
 I->replaceAllUsesWith(V);
   } else if (HasResult) {
 Value *V;
-if (UseSizedLibcall)
-  V = Builder.CreateBitOrPointerCast(Result, I->getType());
-else {
+if (UseSizedLibcall) {
+  // Add bitcasts from Result's scalar type to I's  vector type
+  if (I->getType()->getScalarType()->isPointerTy() &&
+  I->getType()->isVectorTy() && !Result->getType()->isVectorTy()) {
+unsigned AS = cast(
+I->getType()->getScalarType())->getAddressSpace();
+ElementCount EC = cast(I->getType())->getElementCount();
+Value *BC = Builder.CreateBitCast(Result, VectorType::get(
+IntegerType::get(Ctx, DL.getPointerSizeInBits(AS)), EC));
+Value *IntToPtr = Builder.CreateIntToPtr(BC, VectorType::get(
+PointerType::get(Ctx, AS), EC));
+V = Builder.CreateBitOrPointerCast(IntToPtr, I->getType());
+  } else
+V = Builder.CreateBitOrPointerCast(Result, I->getType());
+} else {
   V = Builder.CreateAlignedLoad(I->getType(), AllocaResult,
 AllocaAlignment);
   Builder.CreateLifetimeEnd(AllocaResult, SizeVal64);
diff --git a/llvm/test/CodeGen/ARM/atomic-load-store.ll 
b/llvm/test/CodeGen/ARM/atomic-load-store.ll
index 560dfde356c29d9..36c1305a7c5df39 100644
--- a/llvm/test/CodeGen/ARM/atomic-load-store.ll
+++ b/llvm/test/CodeGen/ARM/atomic-load-store.ll
@@ -983,3 +983,54 @@ define void @store_atomic_f64__seq_cst(ptr %ptr, double 
%val1) {
   store atomic double %val1, ptr %ptr seq_cst, align 8
   ret void
 }
+
+define <1 x ptr> @atomic_vec1_ptr(ptr %x) #0 {
+; ARM-LABEL: atomic_vec1_ptr:
+; ARM:   @ %bb.0:
+; ARM-NEXT:ldr r0, [r0]
+; ARM-NEXT:dmb ish
+; ARM-NEXT:bx lr
+;
+; ARMOPTNONE-LABEL: atomic_vec1_ptr:
+; ARMOPTNONE:   @ %bb.0:
+; ARMOPTNONE-NEXT:ldr r0, [r0]
+; ARMOPTNONE-NEXT:dmb ish
+; ARMOPTNONE-NEXT:bx lr
+;
+; THUMBTWO-LABEL: atomic_vec1_ptr:
+; THUMBTWO:   @ %bb.0:
+; THUMBTWO-NEXT:ldr r0, [r0]
+; THUMBTWO-NEXT:dmb ish
+; THUMBTWO-NEXT:bx lr
+;
+; THUMBONE-LABEL: atomic_vec1_ptr:
+; THUMBONE:   @ %bb.0:
+; THUMBONE-NEXT:push {r7, lr}
+; THUMBONE-NEXT:movs r1, #0
+; THUMBONE-NEXT:mov r2, r1
+; THUMBONE-NEXT:bl __sync_val_compare_and_swap_4
+; THUMBONE-NEXT:pop {r7, pc}
+;
+; ARMV4-LABEL: atomic_vec1_ptr:
+; ARMV4:   @ %bb.0:
+; ARMV4-NEXT:push {r11, lr}
+; ARMV4-NEXT:mov r1, #2
+; ARMV4-NEXT:bl __atomic_load_4
+; ARMV4-NEXT:pop {r11, lr}
+; ARMV4-NEXT:mov pc, lr
+;
+; ARMV6-LABEL: atomic_vec1_ptr:
+; ARMV6:   @ %bb.0:
+; ARMV6-NEXT:mov r1, #0
+; ARMV6-NEXT:mcr p15, #0, r1, c7, c10, #5
+; ARMV6-NEXT:ldr r0, [r0]
+; ARMV6-NEXT:bx lr
+;
+; THUMBM-LABEL: atomic_vec1_ptr:
+; THUMBM:   @ %bb.0:
+; THUMBM-NEXT:ldr r0, [r0]
+; THUMBM-NEXT:dmb sy
+; THUMBM-NEXT:bx lr
+  %ret = load atomic <1 x ptr>, ptr %x acquire, align 4
+  ret <1 x ptr> %ret
+}
diff --git a/llvm/test/CodeGen/X86/atomic-load-store.ll 
b/llvm/test/CodeGen/X86/atomic-load-store.ll
index 08d0405345f5736..4293df8c13571f0 100644
--- a/llvm/test/CodeGen/X86/atomic-load-store.ll
+++ b/llvm/test/CodeGen/X86/atomic-load-store.ll
@@ -371,6 +371,21 @@ define <2 x i32> @atomic_vec2_i32(ptr %x) nounwind {
   ret <2 x i32> %ret
 }
 
+define <2 x ptr> @atomic_vec2_ptr_align(ptr %x) nounwind {
+; CHECK-LABEL: atomic_vec2_ptr_align:
+; CHECK:   ## %bb.0:
+; CHECK-NEXT:pushq %rax
+; CHECK-NEXT:movl $2, %esi
+; CHECK-NEXT:callq ___atomic_load_16
+; CHECK-NEXT:movq %rdx, %xmm1
+; CHECK-NEXT:movq %rax, %xmm0
+; CHECK-NEXT:punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]
+; CHECK-NEXT:popq %rax
+; CHECK-NEXT:retq
+  %ret = load atomic <2 x ptr>, ptr %x acquire, align 16
+  ret <2 x ptr> %ret
+}
+
 define <4 x i8> @atomic_vec4_i8(ptr %x) nounwind {
 ; CHECK3-LABEL: atomic_vec4_i8:
 ; CHECK3: 

[llvm-branch-commits] [llvm] [AtomicExpand] Add bitcasts when expanding load atomic vector (PR #120716)

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

https://github.com/jofrn updated 
https://github.com/llvm/llvm-project/pull/120716

>From d1a877b226e5e72b5131f26db78491553c774bb0 Mon Sep 17 00:00:00 2001
From: jofrn 
Date: Fri, 20 Dec 2024 06:14:28 -0500
Subject: [PATCH] [AtomicExpand] Add bitcasts when expanding load atomic vector

AtomicExpand fails for aligned `load atomic ` because it
does not find a compatible library call. This change adds appropriate
bitcasts so that the call can be lowered.

commit-id:f430c1af
---
 llvm/lib/CodeGen/AtomicExpandPass.cpp | 18 -
 llvm/test/CodeGen/ARM/atomic-load-store.ll| 51 +++
 llvm/test/CodeGen/X86/atomic-load-store.ll| 30 +
 .../X86/expand-atomic-non-integer.ll  | 65 +++
 4 files changed, 161 insertions(+), 3 deletions(-)

diff --git a/llvm/lib/CodeGen/AtomicExpandPass.cpp 
b/llvm/lib/CodeGen/AtomicExpandPass.cpp
index a75fa688d87a8d..644977f225d834 100644
--- a/llvm/lib/CodeGen/AtomicExpandPass.cpp
+++ b/llvm/lib/CodeGen/AtomicExpandPass.cpp
@@ -2060,9 +2060,21 @@ bool AtomicExpandImpl::expandAtomicOpToLibcall(
 I->replaceAllUsesWith(V);
   } else if (HasResult) {
 Value *V;
-if (UseSizedLibcall)
-  V = Builder.CreateBitOrPointerCast(Result, I->getType());
-else {
+if (UseSizedLibcall) {
+  // Add bitcasts from Result's scalar type to I's  vector type
+  if (I->getType()->getScalarType()->isPointerTy() &&
+  I->getType()->isVectorTy() && !Result->getType()->isVectorTy()) {
+unsigned AS = cast(
+I->getType()->getScalarType())->getAddressSpace();
+ElementCount EC = cast(I->getType())->getElementCount();
+Value *BC = Builder.CreateBitCast(Result, VectorType::get(
+IntegerType::get(Ctx, DL.getPointerSizeInBits(AS)), EC));
+Value *IntToPtr = Builder.CreateIntToPtr(BC, VectorType::get(
+PointerType::get(Ctx, AS), EC));
+V = Builder.CreateBitOrPointerCast(IntToPtr, I->getType());
+  } else
+V = Builder.CreateBitOrPointerCast(Result, I->getType());
+} else {
   V = Builder.CreateAlignedLoad(I->getType(), AllocaResult,
 AllocaAlignment);
   Builder.CreateLifetimeEnd(AllocaResult, SizeVal64);
diff --git a/llvm/test/CodeGen/ARM/atomic-load-store.ll 
b/llvm/test/CodeGen/ARM/atomic-load-store.ll
index 560dfde356c29d..36c1305a7c5df3 100644
--- a/llvm/test/CodeGen/ARM/atomic-load-store.ll
+++ b/llvm/test/CodeGen/ARM/atomic-load-store.ll
@@ -983,3 +983,54 @@ define void @store_atomic_f64__seq_cst(ptr %ptr, double 
%val1) {
   store atomic double %val1, ptr %ptr seq_cst, align 8
   ret void
 }
+
+define <1 x ptr> @atomic_vec1_ptr(ptr %x) #0 {
+; ARM-LABEL: atomic_vec1_ptr:
+; ARM:   @ %bb.0:
+; ARM-NEXT:ldr r0, [r0]
+; ARM-NEXT:dmb ish
+; ARM-NEXT:bx lr
+;
+; ARMOPTNONE-LABEL: atomic_vec1_ptr:
+; ARMOPTNONE:   @ %bb.0:
+; ARMOPTNONE-NEXT:ldr r0, [r0]
+; ARMOPTNONE-NEXT:dmb ish
+; ARMOPTNONE-NEXT:bx lr
+;
+; THUMBTWO-LABEL: atomic_vec1_ptr:
+; THUMBTWO:   @ %bb.0:
+; THUMBTWO-NEXT:ldr r0, [r0]
+; THUMBTWO-NEXT:dmb ish
+; THUMBTWO-NEXT:bx lr
+;
+; THUMBONE-LABEL: atomic_vec1_ptr:
+; THUMBONE:   @ %bb.0:
+; THUMBONE-NEXT:push {r7, lr}
+; THUMBONE-NEXT:movs r1, #0
+; THUMBONE-NEXT:mov r2, r1
+; THUMBONE-NEXT:bl __sync_val_compare_and_swap_4
+; THUMBONE-NEXT:pop {r7, pc}
+;
+; ARMV4-LABEL: atomic_vec1_ptr:
+; ARMV4:   @ %bb.0:
+; ARMV4-NEXT:push {r11, lr}
+; ARMV4-NEXT:mov r1, #2
+; ARMV4-NEXT:bl __atomic_load_4
+; ARMV4-NEXT:pop {r11, lr}
+; ARMV4-NEXT:mov pc, lr
+;
+; ARMV6-LABEL: atomic_vec1_ptr:
+; ARMV6:   @ %bb.0:
+; ARMV6-NEXT:mov r1, #0
+; ARMV6-NEXT:mcr p15, #0, r1, c7, c10, #5
+; ARMV6-NEXT:ldr r0, [r0]
+; ARMV6-NEXT:bx lr
+;
+; THUMBM-LABEL: atomic_vec1_ptr:
+; THUMBM:   @ %bb.0:
+; THUMBM-NEXT:ldr r0, [r0]
+; THUMBM-NEXT:dmb sy
+; THUMBM-NEXT:bx lr
+  %ret = load atomic <1 x ptr>, ptr %x acquire, align 4
+  ret <1 x ptr> %ret
+}
diff --git a/llvm/test/CodeGen/X86/atomic-load-store.ll 
b/llvm/test/CodeGen/X86/atomic-load-store.ll
index 08d0405345f573..4293df8c13571f 100644
--- a/llvm/test/CodeGen/X86/atomic-load-store.ll
+++ b/llvm/test/CodeGen/X86/atomic-load-store.ll
@@ -371,6 +371,21 @@ define <2 x i32> @atomic_vec2_i32(ptr %x) nounwind {
   ret <2 x i32> %ret
 }
 
+define <2 x ptr> @atomic_vec2_ptr_align(ptr %x) nounwind {
+; CHECK-LABEL: atomic_vec2_ptr_align:
+; CHECK:   ## %bb.0:
+; CHECK-NEXT:pushq %rax
+; CHECK-NEXT:movl $2, %esi
+; CHECK-NEXT:callq ___atomic_load_16
+; CHECK-NEXT:movq %rdx, %xmm1
+; CHECK-NEXT:movq %rax, %xmm0
+; CHECK-NEXT:punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]
+; CHECK-NEXT:popq %rax
+; CHECK-NEXT:retq
+  %ret = load atomic <2 x ptr>, ptr %x acquire, align 16
+  ret <2 x ptr> %ret
+}
+
 define <4 x i8> @atomic_vec4_i8(ptr %x) nounwind {
 ; CHECK3-LABEL: atomic_vec4_i8:
 ; CHECK3:   

[llvm-branch-commits] [llvm] [SelectionDAG][X86] Remove unused elements from atomic vector. (PR #125432)

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

llvmbot wrote:



@llvm/pr-subscribers-llvm-selectiondag

@llvm/pr-subscribers-backend-x86

Author: None (jofrn)


Changes

After splitting, all elements are created. The elements are
placed back into a concat_vectors. This change extends EltsFromConsecutiveLoads
to understand AtomicSDNode so that its concat_vectors can be
mapped to a BUILD_VECTOR and so unused elements are no longer
referenced.

---

**Stack**:
- #120716
- #125432 ⬅
- #120640
- #120598
- #120387
- #120386
- #120385
- #120384


⚠️ *Part of a stack created by [spr](https://github.com/ejoffe/spr). Do not 
merge manually using the UI - doing so may have unexpected results.*

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


6 Files Affected:

- (modified) llvm/include/llvm/CodeGen/SelectionDAG.h (+2-2) 
- (modified) llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp (+12-8) 
- (modified) llvm/lib/CodeGen/SelectionDAG/SelectionDAGAddressAnalysis.cpp 
(+17-13) 
- (modified) llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp (+5-1) 
- (modified) llvm/lib/Target/X86/X86ISelLowering.cpp (+17-11) 
- (modified) llvm/test/CodeGen/X86/atomic-load-store.ll (+16-151) 


``diff
diff --git a/llvm/include/llvm/CodeGen/SelectionDAG.h 
b/llvm/include/llvm/CodeGen/SelectionDAG.h
index 461c0c1ead16d2..bea5958ec0bba6 100644
--- a/llvm/include/llvm/CodeGen/SelectionDAG.h
+++ b/llvm/include/llvm/CodeGen/SelectionDAG.h
@@ -1840,7 +1840,7 @@ class SelectionDAG {
   /// chain to the token factor. This ensures that the new memory node will 
have
   /// the same relative memory dependency position as the old load. Returns the
   /// new merged load chain.
-  SDValue makeEquivalentMemoryOrdering(LoadSDNode *OldLoad, SDValue NewMemOp);
+  SDValue makeEquivalentMemoryOrdering(MemSDNode *OldLoad, SDValue NewMemOp);
 
   /// Topological-sort the AllNodes list and a
   /// assign a unique node id for each node in the DAG based on their
@@ -2264,7 +2264,7 @@ class SelectionDAG {
   /// merged. Check that both are nonvolatile and if LD is loading
   /// 'Bytes' bytes from a location that is 'Dist' units away from the
   /// location that the 'Base' load is loading from.
-  bool areNonVolatileConsecutiveLoads(LoadSDNode *LD, LoadSDNode *Base,
+  bool areNonVolatileConsecutiveLoads(MemSDNode *LD, MemSDNode *Base,
   unsigned Bytes, int Dist) const;
 
   /// Infer alignment of a load / store address. Return std::nullopt if it
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp 
b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index b416c0efbbc4fc..5f274fabfe8d64 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -12167,7 +12167,7 @@ SDValue 
SelectionDAG::makeEquivalentMemoryOrdering(SDValue OldChain,
   return TokenFactor;
 }
 
-SDValue SelectionDAG::makeEquivalentMemoryOrdering(LoadSDNode *OldLoad,
+SDValue SelectionDAG::makeEquivalentMemoryOrdering(MemSDNode *OldLoad,
SDValue NewMemOp) {
   assert(isa(NewMemOp.getNode()) && "Expected a memop node");
   SDValue OldChain = SDValue(OldLoad, 1);
@@ -12879,17 +12879,21 @@ std::pair 
SelectionDAG::UnrollVectorOverflowOp(
 getBuildVector(NewOvVT, dl, OvScalars));
 }
 
-bool SelectionDAG::areNonVolatileConsecutiveLoads(LoadSDNode *LD,
-  LoadSDNode *Base,
+bool SelectionDAG::areNonVolatileConsecutiveLoads(MemSDNode *LD,
+  MemSDNode *Base,
   unsigned Bytes,
   int Dist) const {
   if (LD->isVolatile() || Base->isVolatile())
 return false;
-  // TODO: probably too restrictive for atomics, revisit
-  if (!LD->isSimple())
-return false;
-  if (LD->isIndexed() || Base->isIndexed())
-return false;
+  if (auto Ld = dyn_cast(LD)) {
+if (!Ld->isSimple())
+  return false;
+if (Ld->isIndexed())
+  return false;
+  }
+  if (auto Ld = dyn_cast(Base))
+if (Ld->isIndexed())
+  return false;
   if (LD->getChain() != Base->getChain())
 return false;
   EVT VT = LD->getMemoryVT();
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGAddressAnalysis.cpp 
b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGAddressAnalysis.cpp
index f2ab88851b780e..a19af64a796229 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGAddressAnalysis.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGAddressAnalysis.cpp
@@ -194,8 +194,8 @@ bool BaseIndexOffset::contains(const SelectionDAG &DAG, 
int64_t BitSize,
   return false;
 }
 
-/// Parses tree in Ptr for base, index, offset addresses.
-static BaseIndexOffset matchLSNode(const LSBaseSDNode *N,
+template 
+static BaseIndexOffset matchSDNode(const T *N,
const SelectionDAG &DAG) {
   SDValue Ptr = N->getBasePtr();
 
@@ -206,16 +206,18 @@ static Base

[llvm-branch-commits] [llvm] [SelectionDAG] Legalize <1 x T> vector types for atomic load (PR #120385)

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

https://github.com/jofrn edited https://github.com/llvm/llvm-project/pull/120385
___
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] [SelectionDAG][X86] Split via Concat vector types for atomic load (PR #120640)

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

https://github.com/jofrn updated 
https://github.com/llvm/llvm-project/pull/120640

>From 76e068350de93eee06b3cc4616adadf33e9d84c0 Mon Sep 17 00:00:00 2001
From: jofrn 
Date: Thu, 19 Dec 2024 16:25:55 -0500
Subject: [PATCH] [SelectionDAG][X86] Split via Concat  vector types for
 atomic load

Vector types that aren't widened are 'split' via CONCAT_VECTORS
so that a single ATOMIC_LOAD is issued for the entire vector at once.
This change utilizes the load vectorization infrastructure in
SelectionDAG in order to group the vectors. This enables SelectionDAG
to translate vectors with type bfloat,half.

commit-id:3a045357
---
 llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h |   1 +
 .../SelectionDAG/LegalizeVectorTypes.cpp  |  32 
 llvm/test/CodeGen/X86/atomic-load-store.ll| 171 ++
 3 files changed, 204 insertions(+)

diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h 
b/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h
index 593d511f50f5c3..da7622db4bde23 100644
--- a/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h
+++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h
@@ -948,6 +948,7 @@ class LLVM_LIBRARY_VISIBILITY DAGTypeLegalizer {
   void SplitVecRes_FPOp_MultiType(SDNode *N, SDValue &Lo, SDValue &Hi);
   void SplitVecRes_IS_FPCLASS(SDNode *N, SDValue &Lo, SDValue &Hi);
   void SplitVecRes_INSERT_VECTOR_ELT(SDNode *N, SDValue &Lo, SDValue &Hi);
+  void SplitVecRes_ATOMIC_LOAD(AtomicSDNode *LD);
   void SplitVecRes_LOAD(LoadSDNode *LD, SDValue &Lo, SDValue &Hi);
   void SplitVecRes_VP_LOAD(VPLoadSDNode *LD, SDValue &Lo, SDValue &Hi);
   void SplitVecRes_VP_STRIDED_LOAD(VPStridedLoadSDNode *SLD, SDValue &Lo,
diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp 
b/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
index f794e4f35c8343..789866d31bf356 100644
--- a/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
@@ -1152,6 +1152,9 @@ void DAGTypeLegalizer::SplitVectorResult(SDNode *N, 
unsigned ResNo) {
 SplitVecRes_STEP_VECTOR(N, Lo, Hi);
 break;
   case ISD::SIGN_EXTEND_INREG: SplitVecRes_InregOp(N, Lo, Hi); break;
+  case ISD::ATOMIC_LOAD:
+SplitVecRes_ATOMIC_LOAD(cast(N));
+break;
   case ISD::LOAD:
 SplitVecRes_LOAD(cast(N), Lo, Hi);
 break;
@@ -1395,6 +1398,35 @@ void DAGTypeLegalizer::SplitVectorResult(SDNode *N, 
unsigned ResNo) {
 SetSplitVector(SDValue(N, ResNo), Lo, Hi);
 }
 
+void DAGTypeLegalizer::SplitVecRes_ATOMIC_LOAD(AtomicSDNode *LD) {
+  SDLoc dl(LD);
+
+  EVT MemoryVT = LD->getMemoryVT();
+  unsigned NumElts = MemoryVT.getVectorMinNumElements();
+
+  EVT IntMemoryVT = EVT::getVectorVT(*DAG.getContext(), MVT::i16, NumElts);
+  EVT ElemVT = EVT::getVectorVT(*DAG.getContext(),
+MemoryVT.getVectorElementType(), 1);
+
+  // Create a single atomic to load all the elements at once.
+  SDValue Atomic = DAG.getAtomic(ISD::ATOMIC_LOAD, dl, IntMemoryVT, 
IntMemoryVT,
+ LD->getChain(), LD->getBasePtr(),
+ LD->getMemOperand());
+
+  // Instead of splitting, put all the elements back into a vector.
+  SmallVector Ops;
+  for (unsigned i = 0; i < NumElts; ++i) {
+SDValue Elt = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, MVT::i16, Atomic,
+  DAG.getVectorIdxConstant(i, dl));
+Elt = DAG.getBitcast(ElemVT, Elt);
+Ops.push_back(Elt);
+  }
+  SDValue Concat = DAG.getNode(ISD::CONCAT_VECTORS, dl, MemoryVT, Ops);
+
+  ReplaceValueWith(SDValue(LD, 0), Concat);
+  ReplaceValueWith(SDValue(LD, 1), LD->getChain());
+}
+
 void DAGTypeLegalizer::IncrementPointer(MemSDNode *N, EVT MemVT,
 MachinePointerInfo &MPI, SDValue &Ptr,
 uint64_t *ScaledOffset) {
diff --git a/llvm/test/CodeGen/X86/atomic-load-store.ll 
b/llvm/test/CodeGen/X86/atomic-load-store.ll
index 935d058a52f8fe..42b09558242934 100644
--- a/llvm/test/CodeGen/X86/atomic-load-store.ll
+++ b/llvm/test/CodeGen/X86/atomic-load-store.ll
@@ -204,6 +204,68 @@ define <2 x float> @atomic_vec2_float_align(ptr %x) {
   ret <2 x float> %ret
 }
 
+define <2 x half> @atomic_vec2_half(ptr %x) {
+; CHECK3-LABEL: atomic_vec2_half:
+; CHECK3:   ## %bb.0:
+; CHECK3-NEXT:movl (%rdi), %eax
+; CHECK3-NEXT:pinsrw $0, %eax, %xmm0
+; CHECK3-NEXT:shrl $16, %eax
+; CHECK3-NEXT:pinsrw $0, %eax, %xmm1
+; CHECK3-NEXT:punpcklwd {{.*#+}} xmm0 = 
xmm0[0],xmm1[0],xmm0[1],xmm1[1],xmm0[2],xmm1[2],xmm0[3],xmm1[3]
+; CHECK3-NEXT:retq
+;
+; CHECK0-LABEL: atomic_vec2_half:
+; CHECK0:   ## %bb.0:
+; CHECK0-NEXT:movl (%rdi), %eax
+; CHECK0-NEXT:movl %eax, %ecx
+; CHECK0-NEXT:shrl $16, %ecx
+; CHECK0-NEXT:movw %cx, %dx
+; CHECK0-NEXT:## implicit-def: $ecx
+; CHECK0-NEXT:movw %dx, %cx
+; CHECK0-NEXT:## implicit-def: $xmm1
+; CHECK0-NEXT:pinsrw $0, %ecx, %xmm1
+; CHECK0-NEXT:movw %ax, %cx
+; C

[llvm-branch-commits] [llvm] [X86] Add atomic vector tests for unaligned >1 sizes. (PR #120387)

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

https://github.com/jofrn updated 
https://github.com/llvm/llvm-project/pull/120387

>From 05e7afdcb910b7773f65159b3ee431b39527b4c1 Mon Sep 17 00:00:00 2001
From: jofrn 
Date: Wed, 18 Dec 2024 03:40:32 -0500
Subject: [PATCH] [X86] Add atomic vector tests for unaligned >1 sizes.

Unaligned atomic vectors with size >1 are lowered to calls.
Adding their tests separately here.

commit-id:a06a5cc6
---
 llvm/test/CodeGen/X86/atomic-load-store.ll | 253 +
 1 file changed, 253 insertions(+)

diff --git a/llvm/test/CodeGen/X86/atomic-load-store.ll 
b/llvm/test/CodeGen/X86/atomic-load-store.ll
index 6efcbb80c0ce6d..39e9fdfa5e62b0 100644
--- a/llvm/test/CodeGen/X86/atomic-load-store.ll
+++ b/llvm/test/CodeGen/X86/atomic-load-store.ll
@@ -146,6 +146,34 @@ define <1 x i64> @atomic_vec1_i64_align(ptr %x) nounwind {
   ret <1 x i64> %ret
 }
 
+define <1 x ptr> @atomic_vec1_ptr(ptr %x) nounwind {
+; CHECK3-LABEL: atomic_vec1_ptr:
+; CHECK3:   ## %bb.0:
+; CHECK3-NEXT:pushq %rax
+; CHECK3-NEXT:movq %rdi, %rsi
+; CHECK3-NEXT:movq %rsp, %rdx
+; CHECK3-NEXT:movl $8, %edi
+; CHECK3-NEXT:movl $2, %ecx
+; CHECK3-NEXT:callq ___atomic_load
+; CHECK3-NEXT:movq (%rsp), %rax
+; CHECK3-NEXT:popq %rcx
+; CHECK3-NEXT:retq
+;
+; CHECK0-LABEL: atomic_vec1_ptr:
+; CHECK0:   ## %bb.0:
+; CHECK0-NEXT:pushq %rax
+; CHECK0-NEXT:movq %rdi, %rsi
+; CHECK0-NEXT:movl $8, %edi
+; CHECK0-NEXT:movq %rsp, %rdx
+; CHECK0-NEXT:movl $2, %ecx
+; CHECK0-NEXT:callq ___atomic_load
+; CHECK0-NEXT:movq (%rsp), %rax
+; CHECK0-NEXT:popq %rcx
+; CHECK0-NEXT:retq
+  %ret = load atomic <1 x ptr>, ptr %x acquire, align 4
+  ret <1 x ptr> %ret
+}
+
 define <1 x half> @atomic_vec1_half(ptr %x) {
 ; CHECK3-LABEL: atomic_vec1_half:
 ; CHECK3:   ## %bb.0:
@@ -182,3 +210,228 @@ define <1 x double> @atomic_vec1_double_align(ptr %x) 
nounwind {
   %ret = load atomic <1 x double>, ptr %x acquire, align 8
   ret <1 x double> %ret
 }
+
+define <1 x i64> @atomic_vec1_i64(ptr %x) nounwind {
+; CHECK3-LABEL: atomic_vec1_i64:
+; CHECK3:   ## %bb.0:
+; CHECK3-NEXT:pushq %rax
+; CHECK3-NEXT:movq %rdi, %rsi
+; CHECK3-NEXT:movq %rsp, %rdx
+; CHECK3-NEXT:movl $8, %edi
+; CHECK3-NEXT:movl $2, %ecx
+; CHECK3-NEXT:callq ___atomic_load
+; CHECK3-NEXT:movq (%rsp), %rax
+; CHECK3-NEXT:popq %rcx
+; CHECK3-NEXT:retq
+;
+; CHECK0-LABEL: atomic_vec1_i64:
+; CHECK0:   ## %bb.0:
+; CHECK0-NEXT:pushq %rax
+; CHECK0-NEXT:movq %rdi, %rsi
+; CHECK0-NEXT:movl $8, %edi
+; CHECK0-NEXT:movq %rsp, %rdx
+; CHECK0-NEXT:movl $2, %ecx
+; CHECK0-NEXT:callq ___atomic_load
+; CHECK0-NEXT:movq (%rsp), %rax
+; CHECK0-NEXT:popq %rcx
+; CHECK0-NEXT:retq
+  %ret = load atomic <1 x i64>, ptr %x acquire, align 4
+  ret <1 x i64> %ret
+}
+
+define <1 x double> @atomic_vec1_double(ptr %x) nounwind {
+; CHECK3-LABEL: atomic_vec1_double:
+; CHECK3:   ## %bb.0:
+; CHECK3-NEXT:pushq %rax
+; CHECK3-NEXT:movq %rdi, %rsi
+; CHECK3-NEXT:movq %rsp, %rdx
+; CHECK3-NEXT:movl $8, %edi
+; CHECK3-NEXT:movl $2, %ecx
+; CHECK3-NEXT:callq ___atomic_load
+; CHECK3-NEXT:movsd {{.*#+}} xmm0 = mem[0],zero
+; CHECK3-NEXT:popq %rax
+; CHECK3-NEXT:retq
+;
+; CHECK0-LABEL: atomic_vec1_double:
+; CHECK0:   ## %bb.0:
+; CHECK0-NEXT:pushq %rax
+; CHECK0-NEXT:movq %rdi, %rsi
+; CHECK0-NEXT:movl $8, %edi
+; CHECK0-NEXT:movq %rsp, %rdx
+; CHECK0-NEXT:movl $2, %ecx
+; CHECK0-NEXT:callq ___atomic_load
+; CHECK0-NEXT:movsd {{.*#+}} xmm0 = mem[0],zero
+; CHECK0-NEXT:popq %rax
+; CHECK0-NEXT:retq
+  %ret = load atomic <1 x double>, ptr %x acquire, align 4
+  ret <1 x double> %ret
+}
+
+define <2 x i32> @atomic_vec2_i32(ptr %x) nounwind {
+; CHECK3-LABEL: atomic_vec2_i32:
+; CHECK3:   ## %bb.0:
+; CHECK3-NEXT:pushq %rax
+; CHECK3-NEXT:movq %rdi, %rsi
+; CHECK3-NEXT:movq %rsp, %rdx
+; CHECK3-NEXT:movl $8, %edi
+; CHECK3-NEXT:movl $2, %ecx
+; CHECK3-NEXT:callq ___atomic_load
+; CHECK3-NEXT:movsd {{.*#+}} xmm0 = mem[0],zero
+; CHECK3-NEXT:popq %rax
+; CHECK3-NEXT:retq
+;
+; CHECK0-LABEL: atomic_vec2_i32:
+; CHECK0:   ## %bb.0:
+; CHECK0-NEXT:pushq %rax
+; CHECK0-NEXT:movq %rdi, %rsi
+; CHECK0-NEXT:movl $8, %edi
+; CHECK0-NEXT:movq %rsp, %rdx
+; CHECK0-NEXT:movl $2, %ecx
+; CHECK0-NEXT:callq ___atomic_load
+; CHECK0-NEXT:movq {{.*#+}} xmm0 = mem[0],zero
+; CHECK0-NEXT:popq %rax
+; CHECK0-NEXT:retq
+  %ret = load atomic <2 x i32>, ptr %x acquire, align 4
+  ret <2 x i32> %ret
+}
+
+define <4 x float> @atomic_vec4_float_align(ptr %x) nounwind {
+; CHECK-LABEL: atomic_vec4_float_align:
+; CHECK:   ## %bb.0:
+; CHECK-NEXT:pushq %rax
+; CHECK-NEXT:movl $2, %esi
+; CHECK-NEXT:callq ___atomic_load_16
+; CHECK-NEXT:movq %rdx, %xmm1
+; CHECK-NEXT:movq %rax, %xmm0
+; CHECK-NEXT:punpcklqdq {{.*#+}} xmm0 = xmm

[llvm-branch-commits] [llvm] [X86] Add atomic vector tests for unaligned >1 sizes. (PR #120387)

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

https://github.com/jofrn edited https://github.com/llvm/llvm-project/pull/120387
___
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] [SelectionDAG][X86] Split via Concat vector types for atomic load (PR #120640)

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

https://github.com/jofrn edited https://github.com/llvm/llvm-project/pull/120640
___
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] [SelectionDAG][X86] Widen <2 x T> vector types for atomic load (PR #120598)

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

https://github.com/jofrn updated 
https://github.com/llvm/llvm-project/pull/120598

>From 4df72a297c3be02f7dc46fbb4f4dcf1cb69c21f1 Mon Sep 17 00:00:00 2001
From: jofrn 
Date: Thu, 19 Dec 2024 11:19:39 -0500
Subject: [PATCH] [SelectionDAG][X86] Widen <2 x T> vector types for atomic
 load

Vector types of 2 elements must be widened. This change does this
for vector types of atomic load in SelectionDAG
so that it can translate aligned vectors of >1 size. Also,
it also adds Pats to remove an extra MOV.

commit-id:2894ccd1
---
 llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h |  1 +
 .../SelectionDAG/LegalizeVectorTypes.cpp  | 79 ++
 llvm/lib/Target/X86/X86InstrCompiler.td   |  7 ++
 llvm/test/CodeGen/X86/atomic-load-store.ll| 81 +++
 llvm/test/CodeGen/X86/atomic-unordered.ll |  3 +-
 5 files changed, 169 insertions(+), 2 deletions(-)

diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h 
b/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h
index 893fca233d191be..593d511f50f5c3a 100644
--- a/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h
+++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h
@@ -1048,6 +1048,7 @@ class LLVM_LIBRARY_VISIBILITY DAGTypeLegalizer {
   SDValue WidenVecRes_EXTRACT_SUBVECTOR(SDNode* N);
   SDValue WidenVecRes_INSERT_SUBVECTOR(SDNode *N);
   SDValue WidenVecRes_INSERT_VECTOR_ELT(SDNode* N);
+  SDValue WidenVecRes_ATOMIC_LOAD(AtomicSDNode *N);
   SDValue WidenVecRes_LOAD(SDNode* N);
   SDValue WidenVecRes_VP_LOAD(VPLoadSDNode *N);
   SDValue WidenVecRes_VP_STRIDED_LOAD(VPStridedLoadSDNode *N);
diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp 
b/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
index 78e6c84c3fb40c5..f794e4f35c8343e 100644
--- a/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
@@ -4521,6 +4521,9 @@ void DAGTypeLegalizer::WidenVectorResult(SDNode *N, 
unsigned ResNo) {
 break;
   case ISD::EXTRACT_SUBVECTOR: Res = WidenVecRes_EXTRACT_SUBVECTOR(N); break;
   case ISD::INSERT_VECTOR_ELT: Res = WidenVecRes_INSERT_VECTOR_ELT(N); break;
+  case ISD::ATOMIC_LOAD:
+Res = WidenVecRes_ATOMIC_LOAD(cast(N));
+break;
   case ISD::LOAD:  Res = WidenVecRes_LOAD(N); break;
   case ISD::STEP_VECTOR:
   case ISD::SPLAT_VECTOR:
@@ -5907,6 +5910,82 @@ SDValue 
DAGTypeLegalizer::WidenVecRes_INSERT_VECTOR_ELT(SDNode *N) {
  N->getOperand(1), N->getOperand(2));
 }
 
+static std::optional findMemType(SelectionDAG &DAG,
+  const TargetLowering &TLI, unsigned 
Width,
+  EVT WidenVT, unsigned Align,
+  unsigned WidenEx);
+
+SDValue DAGTypeLegalizer::WidenVecRes_ATOMIC_LOAD(AtomicSDNode *LD) {
+  EVT WidenVT = 
TLI.getTypeToTransformTo(*DAG.getContext(),LD->getValueType(0));
+  EVT LdVT= LD->getMemoryVT();
+  SDLoc dl(LD);
+  assert(LdVT.isVector() && WidenVT.isVector());
+  assert(LdVT.isScalableVector() == WidenVT.isScalableVector());
+  assert(LdVT.getVectorElementType() == WidenVT.getVectorElementType());
+
+  // Load information
+  SDValue Chain = LD->getChain();
+  SDValue BasePtr = LD->getBasePtr();
+  MachineMemOperand::Flags MMOFlags = LD->getMemOperand()->getFlags();
+  AAMDNodes AAInfo = LD->getAAInfo();
+
+  TypeSize LdWidth = LdVT.getSizeInBits();
+  TypeSize WidenWidth = WidenVT.getSizeInBits();
+  TypeSize WidthDiff = WidenWidth - LdWidth;
+  // Allow wider loads if they are sufficiently aligned to avoid memory faults
+  // and if the original load is simple.
+  unsigned LdAlign =
+  (!LD->isSimple() || LdVT.isScalableVector()) ? 0 : 
LD->getAlign().value();
+
+  // Find the vector type that can load from.
+  std::optional FirstVT =
+  findMemType(DAG, TLI, LdWidth.getKnownMinValue(), WidenVT, LdAlign,
+  WidthDiff.getKnownMinValue());
+
+  if (!FirstVT)
+return SDValue();
+
+  SmallVector MemVTs;
+  TypeSize FirstVTWidth = FirstVT->getSizeInBits();
+
+  SDValue LdOp = DAG.getAtomic(ISD::ATOMIC_LOAD, dl, *FirstVT, *FirstVT, Chain,
+ BasePtr, LD->getMemOperand());
+
+  // Load the element with one instruction.
+  SDValue Result;
+  assert(TypeSize::isKnownLE(LdWidth, FirstVTWidth));
+  if (!FirstVT->isVector()) {
+unsigned NumElts =
+WidenWidth.getFixedValue() / FirstVTWidth.getFixedValue();
+EVT NewVecVT = EVT::getVectorVT(*DAG.getContext(), *FirstVT, NumElts);
+SDValue VecOp = DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, NewVecVT, LdOp);
+Result = DAG.getNode(ISD::BITCAST, dl, WidenVT, VecOp);
+  }
+  else if (FirstVT == WidenVT)
+Result = LdOp;
+  else {
+// TODO: We don't currently have any tests that exercise this code path.
+assert(WidenWidth.getFixedValue() % FirstVTWidth.getFixedValue() == 0);
+unsigned NumConcat =
+WidenWidth.getFixedValue() / FirstVTWidth.getFixedValue();
+SmallVector ConcatOps(Num

[llvm-branch-commits] [llvm] [X86] Manage atomic load of fp -> int promotion in DAG (PR #120386)

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

https://github.com/jofrn updated 
https://github.com/llvm/llvm-project/pull/120386

>From f096c88041cc230ad66b40e4394563cbc696b7a6 Mon Sep 17 00:00:00 2001
From: jofrn 
Date: Wed, 18 Dec 2024 03:38:23 -0500
Subject: [PATCH] [X86] Manage atomic load of fp -> int promotion in DAG

When lowering atomic <1 x T> vector types with floats, selection can fail since
this pattern is unsupported. To support this, floats can be casted to
an integer type of the same size.

commit-id:f9d761c5
---
 llvm/lib/Target/X86/X86ISelLowering.cpp|  4 +++
 llvm/test/CodeGen/X86/atomic-load-store.ll | 37 ++
 2 files changed, 41 insertions(+)

diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp 
b/llvm/lib/Target/X86/X86ISelLowering.cpp
index 8f904209d8a3ad9..ba9ac2f21c7564d 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -2638,6 +2638,10 @@ X86TargetLowering::X86TargetLowering(const 
X86TargetMachine &TM,
 setOperationAction(Op, MVT::f32, Promote);
   }
 
+  setOperationPromotedToType(ISD::ATOMIC_LOAD, MVT::f16, MVT::i16);
+  setOperationPromotedToType(ISD::ATOMIC_LOAD, MVT::f32, MVT::i32);
+  setOperationPromotedToType(ISD::ATOMIC_LOAD, MVT::f64, MVT::i64);
+
   // We have target-specific dag combine patterns for the following nodes:
   setTargetDAGCombine({ISD::VECTOR_SHUFFLE,
ISD::SCALAR_TO_VECTOR,
diff --git a/llvm/test/CodeGen/X86/atomic-load-store.ll 
b/llvm/test/CodeGen/X86/atomic-load-store.ll
index d23cfb89f9fc871..6efcbb80c0ce6d9 100644
--- a/llvm/test/CodeGen/X86/atomic-load-store.ll
+++ b/llvm/test/CodeGen/X86/atomic-load-store.ll
@@ -145,3 +145,40 @@ define <1 x i64> @atomic_vec1_i64_align(ptr %x) nounwind {
   %ret = load atomic <1 x i64>, ptr %x acquire, align 8
   ret <1 x i64> %ret
 }
+
+define <1 x half> @atomic_vec1_half(ptr %x) {
+; CHECK3-LABEL: atomic_vec1_half:
+; CHECK3:   ## %bb.0:
+; CHECK3-NEXT:movzwl (%rdi), %eax
+; CHECK3-NEXT:pinsrw $0, %eax, %xmm0
+; CHECK3-NEXT:retq
+;
+; CHECK0-LABEL: atomic_vec1_half:
+; CHECK0:   ## %bb.0:
+; CHECK0-NEXT:movw (%rdi), %cx
+; CHECK0-NEXT:## implicit-def: $eax
+; CHECK0-NEXT:movw %cx, %ax
+; CHECK0-NEXT:## implicit-def: $xmm0
+; CHECK0-NEXT:pinsrw $0, %eax, %xmm0
+; CHECK0-NEXT:retq
+  %ret = load atomic <1 x half>, ptr %x acquire, align 2
+  ret <1 x half> %ret
+}
+
+define <1 x float> @atomic_vec1_float(ptr %x) {
+; CHECK-LABEL: atomic_vec1_float:
+; CHECK:   ## %bb.0:
+; CHECK-NEXT:movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
+; CHECK-NEXT:retq
+  %ret = load atomic <1 x float>, ptr %x acquire, align 4
+  ret <1 x float> %ret
+}
+
+define <1 x double> @atomic_vec1_double_align(ptr %x) nounwind {
+; CHECK-LABEL: atomic_vec1_double_align:
+; CHECK:   ## %bb.0:
+; CHECK-NEXT:movsd {{.*#+}} xmm0 = mem[0],zero
+; CHECK-NEXT:retq
+  %ret = load atomic <1 x double>, ptr %x acquire, align 8
+  ret <1 x double> %ret
+}

___
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] [SelectionDAG] Legalize <1 x T> vector types for atomic load (PR #120385)

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

https://github.com/jofrn updated 
https://github.com/llvm/llvm-project/pull/120385

>From d536a40973710676f89fb60ed688fa9c335a7f5a Mon Sep 17 00:00:00 2001
From: jofrn 
Date: Wed, 18 Dec 2024 03:37:17 -0500
Subject: [PATCH] [SelectionDAG] Legalize <1 x T> vector types for atomic load

`load atomic <1 x T>` is not valid. This change legalizes
vector types of atomic load via scalarization in SelectionDAG
so that it can, for example, translate from `v1i32` to `i32`.

commit-id:5c36cc8c
---
 llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h |   1 +
 .../SelectionDAG/LegalizeVectorTypes.cpp  |  15 +++
 llvm/test/CodeGen/X86/atomic-load-store.ll| 121 +-
 3 files changed, 135 insertions(+), 2 deletions(-)

diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h 
b/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h
index f13f70e66cfaa6..893fca233d191b 100644
--- a/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h
+++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h
@@ -863,6 +863,7 @@ class LLVM_LIBRARY_VISIBILITY DAGTypeLegalizer {
   SDValue ScalarizeVecRes_UnaryOpWithExtraInput(SDNode *N);
   SDValue ScalarizeVecRes_INSERT_VECTOR_ELT(SDNode *N);
   SDValue ScalarizeVecRes_LOAD(LoadSDNode *N);
+  SDValue ScalarizeVecRes_ATOMIC_LOAD(AtomicSDNode *N);
   SDValue ScalarizeVecRes_SCALAR_TO_VECTOR(SDNode *N);
   SDValue ScalarizeVecRes_VSELECT(SDNode *N);
   SDValue ScalarizeVecRes_SELECT(SDNode *N);
diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp 
b/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
index 1000235ab4061f..78e6c84c3fb40c 100644
--- a/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
@@ -64,6 +64,9 @@ void DAGTypeLegalizer::ScalarizeVectorResult(SDNode *N, 
unsigned ResNo) {
 R = ScalarizeVecRes_UnaryOpWithExtraInput(N);
 break;
   case ISD::INSERT_VECTOR_ELT: R = ScalarizeVecRes_INSERT_VECTOR_ELT(N); break;
+  case ISD::ATOMIC_LOAD:
+R = ScalarizeVecRes_ATOMIC_LOAD(cast(N));
+break;
   case ISD::LOAD:   R = 
ScalarizeVecRes_LOAD(cast(N));break;
   case ISD::SCALAR_TO_VECTOR:  R = ScalarizeVecRes_SCALAR_TO_VECTOR(N); break;
   case ISD::SIGN_EXTEND_INREG: R = ScalarizeVecRes_InregOp(N); break;
@@ -457,6 +460,18 @@ SDValue 
DAGTypeLegalizer::ScalarizeVecRes_INSERT_VECTOR_ELT(SDNode *N) {
   return Op;
 }
 
+SDValue DAGTypeLegalizer::ScalarizeVecRes_ATOMIC_LOAD(AtomicSDNode *N) {
+  SDValue Result = DAG.getAtomic(
+  ISD::ATOMIC_LOAD, SDLoc(N), N->getMemoryVT().getVectorElementType(),
+  N->getValueType(0).getVectorElementType(), N->getChain(), 
N->getBasePtr(),
+  N->getMemOperand());
+
+  // Legalize the chain result - switch anything that used the old chain to
+  // use the new one.
+  ReplaceValueWith(SDValue(N, 1), Result.getValue(1));
+  return Result;
+}
+
 SDValue DAGTypeLegalizer::ScalarizeVecRes_LOAD(LoadSDNode *N) {
   assert(N->isUnindexed() && "Indexed vector load?");
 
diff --git a/llvm/test/CodeGen/X86/atomic-load-store.ll 
b/llvm/test/CodeGen/X86/atomic-load-store.ll
index 5bce4401f7bdb0..d23cfb89f9fc87 100644
--- a/llvm/test/CodeGen/X86/atomic-load-store.ll
+++ b/llvm/test/CodeGen/X86/atomic-load-store.ll
@@ -1,6 +1,6 @@
 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
-; RUN: llc < %s -mtriple=x86_64-apple-macosx10.7.0 -verify-machineinstrs | 
FileCheck %s
-; RUN: llc < %s -mtriple=x86_64-apple-macosx10.7.0 -verify-machineinstrs -O0 | 
FileCheck %s
+; RUN: llc < %s -mtriple=x86_64-apple-macosx10.7.0 -verify-machineinstrs | 
FileCheck %s --check-prefixes=CHECK,CHECK3
+; RUN: llc < %s -mtriple=x86_64-apple-macosx10.7.0 -verify-machineinstrs -O0 | 
FileCheck %s --check-prefixes=CHECK,CHECK0
 
 define void @test1(ptr %ptr, i32 %val1) {
 ; CHECK-LABEL: test1:
@@ -28,3 +28,120 @@ define i32 @test3(ptr %ptr) {
   %val = load atomic i32, ptr %ptr seq_cst, align 4
   ret i32 %val
 }
+
+define <1 x i32> @atomic_vec1_i32(ptr %x) {
+; CHECK-LABEL: atomic_vec1_i32:
+; CHECK:   ## %bb.0:
+; CHECK-NEXT:movl (%rdi), %eax
+; CHECK-NEXT:retq
+  %ret = load atomic <1 x i32>, ptr %x acquire, align 4
+  ret <1 x i32> %ret
+}
+
+define <1 x i8> @atomic_vec1_i8(ptr %x) {
+; CHECK3-LABEL: atomic_vec1_i8:
+; CHECK3:   ## %bb.0:
+; CHECK3-NEXT:movzbl (%rdi), %eax
+; CHECK3-NEXT:retq
+;
+; CHECK0-LABEL: atomic_vec1_i8:
+; CHECK0:   ## %bb.0:
+; CHECK0-NEXT:movb (%rdi), %al
+; CHECK0-NEXT:retq
+  %ret = load atomic <1 x i8>, ptr %x acquire, align 1
+  ret <1 x i8> %ret
+}
+
+define <1 x i16> @atomic_vec1_i16(ptr %x) {
+; CHECK3-LABEL: atomic_vec1_i16:
+; CHECK3:   ## %bb.0:
+; CHECK3-NEXT:movzwl (%rdi), %eax
+; CHECK3-NEXT:retq
+;
+; CHECK0-LABEL: atomic_vec1_i16:
+; CHECK0:   ## %bb.0:
+; CHECK0-NEXT:movw (%rdi), %ax
+; CHECK0-NEXT:retq
+  %ret = load atomic <1 x i16>, ptr %x acquire, align 2
+  ret <1 x i16> %ret
+}
+
+define <1 x i32> @atomic_vec1_i8_zext(ptr %x) {
+; CHECK3-LABEL: atomic_

[llvm-branch-commits] [llvm] [X86] Manage atomic load of fp -> int promotion in DAG (PR #120386)

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

https://github.com/jofrn edited https://github.com/llvm/llvm-project/pull/120386
___
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] [AtomicExpand] Add bitcasts when expanding load atomic vector (PR #120716)

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

https://github.com/jofrn edited https://github.com/llvm/llvm-project/pull/120716
___
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] [SelectionDAG][X86] Widen <2 x T> vector types for atomic load (PR #120598)

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

https://github.com/jofrn edited https://github.com/llvm/llvm-project/pull/120598
___
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] [SelectionDAG][X86] Remove unused elements from atomic vector. (PR #125432)

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

https://github.com/jofrn created 
https://github.com/llvm/llvm-project/pull/125432

After splitting, all elements are created. The elements are
placed back into a concat_vectors. This change extends EltsFromConsecutiveLoads
to understand AtomicSDNode so that its concat_vectors can be
mapped to a BUILD_VECTOR and so unused elements are no longer
referenced.

---

**Stack**:
- #120716
- #125432 ⬅
- #120640
- #120598
- #120387
- #120386
- #120385
- #120384


⚠️ *Part of a stack created by [spr](https://github.com/ejoffe/spr). Do not 
merge manually using the UI - doing so may have unexpected results.*

>From fbe99a2a2d6f3c95978c520812046567ec7811cd Mon Sep 17 00:00:00 2001
From: jofrn 
Date: Fri, 31 Jan 2025 13:12:56 -0500
Subject: [PATCH] [SelectionDAG][X86] Remove unused elements from atomic
 vector.

After splitting, all elements are created. The elements are
placed back into a concat_vectors. This change extends EltsFromConsecutiveLoads
to understand AtomicSDNode so that its concat_vectors can be
mapped to a BUILD_VECTOR and so unused elements are no longer
referenced.

commit-id:b83937a8
---
 llvm/include/llvm/CodeGen/SelectionDAG.h  |   4 +-
 .../lib/CodeGen/SelectionDAG/SelectionDAG.cpp |  20 ++-
 .../SelectionDAGAddressAnalysis.cpp   |  30 ++--
 .../SelectionDAG/SelectionDAGBuilder.cpp  |   6 +-
 llvm/lib/Target/X86/X86ISelLowering.cpp   |  28 +--
 llvm/test/CodeGen/X86/atomic-load-store.ll| 167 ++
 6 files changed, 69 insertions(+), 186 deletions(-)

diff --git a/llvm/include/llvm/CodeGen/SelectionDAG.h 
b/llvm/include/llvm/CodeGen/SelectionDAG.h
index 461c0c1ead16d2c..bea5958ec0bba6e 100644
--- a/llvm/include/llvm/CodeGen/SelectionDAG.h
+++ b/llvm/include/llvm/CodeGen/SelectionDAG.h
@@ -1840,7 +1840,7 @@ class SelectionDAG {
   /// chain to the token factor. This ensures that the new memory node will 
have
   /// the same relative memory dependency position as the old load. Returns the
   /// new merged load chain.
-  SDValue makeEquivalentMemoryOrdering(LoadSDNode *OldLoad, SDValue NewMemOp);
+  SDValue makeEquivalentMemoryOrdering(MemSDNode *OldLoad, SDValue NewMemOp);
 
   /// Topological-sort the AllNodes list and a
   /// assign a unique node id for each node in the DAG based on their
@@ -2264,7 +2264,7 @@ class SelectionDAG {
   /// merged. Check that both are nonvolatile and if LD is loading
   /// 'Bytes' bytes from a location that is 'Dist' units away from the
   /// location that the 'Base' load is loading from.
-  bool areNonVolatileConsecutiveLoads(LoadSDNode *LD, LoadSDNode *Base,
+  bool areNonVolatileConsecutiveLoads(MemSDNode *LD, MemSDNode *Base,
   unsigned Bytes, int Dist) const;
 
   /// Infer alignment of a load / store address. Return std::nullopt if it
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp 
b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index b416c0efbbc4fc6..5f274fabfe8d640 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -12167,7 +12167,7 @@ SDValue 
SelectionDAG::makeEquivalentMemoryOrdering(SDValue OldChain,
   return TokenFactor;
 }
 
-SDValue SelectionDAG::makeEquivalentMemoryOrdering(LoadSDNode *OldLoad,
+SDValue SelectionDAG::makeEquivalentMemoryOrdering(MemSDNode *OldLoad,
SDValue NewMemOp) {
   assert(isa(NewMemOp.getNode()) && "Expected a memop node");
   SDValue OldChain = SDValue(OldLoad, 1);
@@ -12879,17 +12879,21 @@ std::pair 
SelectionDAG::UnrollVectorOverflowOp(
 getBuildVector(NewOvVT, dl, OvScalars));
 }
 
-bool SelectionDAG::areNonVolatileConsecutiveLoads(LoadSDNode *LD,
-  LoadSDNode *Base,
+bool SelectionDAG::areNonVolatileConsecutiveLoads(MemSDNode *LD,
+  MemSDNode *Base,
   unsigned Bytes,
   int Dist) const {
   if (LD->isVolatile() || Base->isVolatile())
 return false;
-  // TODO: probably too restrictive for atomics, revisit
-  if (!LD->isSimple())
-return false;
-  if (LD->isIndexed() || Base->isIndexed())
-return false;
+  if (auto Ld = dyn_cast(LD)) {
+if (!Ld->isSimple())
+  return false;
+if (Ld->isIndexed())
+  return false;
+  }
+  if (auto Ld = dyn_cast(Base))
+if (Ld->isIndexed())
+  return false;
   if (LD->getChain() != Base->getChain())
 return false;
   EVT VT = LD->getMemoryVT();
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGAddressAnalysis.cpp 
b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGAddressAnalysis.cpp
index f2ab88851b780ef..a19af64a7962291 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGAddressAnalysis.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGAddressAnalysis.cpp
@@ -194,8 +194,8 @@ bool BaseIndexOffset::contains(const SelectionDAG &DAG

[llvm-branch-commits] [polly] [Polly] Update ScopInliner for NPM (PR #125427)

2025-02-02 Thread Michael Kruse via llvm-branch-commits

https://github.com/Meinersbur ready_for_review 
https://github.com/llvm/llvm-project/pull/125427
___
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] [polly] [Polly] Introduce PhaseManager and remove LPM support (PR #125442)

2025-02-02 Thread Michael Kruse via llvm-branch-commits

https://github.com/Meinersbur edited 
https://github.com/llvm/llvm-project/pull/125442
___
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: rename MatchedPackOnParmToNonPackOnArg to StrictPackMatch (PR #125418)

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


@@ -1842,19 +1842,19 @@ class ClassTemplateSpecializationDecl : public 
CXXRecordDecl,
   unsigned SpecializationKind : 3;
 
   /// Indicate that we have matched a parameter pack with a non pack
-  /// argument, when the opposite match is also allowed (strict pack match).
+  /// argument, when the opposite match is also allowed.
   /// This needs to be cached as deduction is performed during declaration,
   /// and we need the information to be preserved so that it is consistent
   /// during instantiation.
-  bool MatchedPackOnParmToNonPackOnArg : 1;
+  bool StrictPackMatch : 1;

cor3ntin wrote:

Maybe `DeduceByStrictPackMatchRules` / `wasDeduceByStrictPackMatchRules` (for 
the getter)

https://github.com/llvm/llvm-project/pull/125418
___
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] [polly] [Polly] Introduce PhaseManager and remove LPM support (PR #125442)

2025-02-02 Thread Karthika Devi C via llvm-branch-commits

kartcq wrote:

[like]  Karthika Devi C reacted to your message:

From: Eli Friedman ***@***.***>
Sent: Monday, February 3, 2025 1:40:45 AM
To: llvm/llvm-project ***@***.***>
Cc: Karthika Devi C (QUIC) ***@***.***>; Review requested ***@***.***>
Subject: Re: [llvm/llvm-project] [Polly] Introduce PhaseManager and remove LPM 
support (PR #125442)


WARNING: This email originated from outside of Qualcomm. Please be wary of any 
links or attachments, and do not enable macros.

@efriedma-quic requested your review on: 
#125442 [Polly] Introduce 
PhaseManager and remove LPM support.

—
Reply to this email directly, view it on 
GitHub, or 
unsubscribe.
You are receiving this because your review was requested.Message ID: 
***@***.***>


https://github.com/llvm/llvm-project/pull/125442
___
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: [InstSimplify] Add additional checks when substituting pointers (#125385) (PR #125398)

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

llvmbot wrote:




@llvm/pr-subscribers-llvm-transforms

Author: None (llvmbot)


Changes

Backport 1af627b592dd15bbe58136f902ced46251fc344d

Requested by: @dtcxzyw

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


2 Files Affected:

- (modified) llvm/lib/Analysis/InstructionSimplify.cpp (+11-6) 
- (modified) llvm/test/Transforms/InstSimplify/select-icmp.ll (+32) 


``diff
diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp 
b/llvm/lib/Analysis/InstructionSimplify.cpp
index d69747e30f884d7..4e550f8fa6a9fd1 100644
--- a/llvm/lib/Analysis/InstructionSimplify.cpp
+++ b/llvm/lib/Analysis/InstructionSimplify.cpp
@@ -27,6 +27,7 @@
 #include "llvm/Analysis/CmpInstAnalysis.h"
 #include "llvm/Analysis/ConstantFolding.h"
 #include "llvm/Analysis/InstSimplifyFolder.h"
+#include "llvm/Analysis/Loads.h"
 #include "llvm/Analysis/LoopAnalysisManager.h"
 #include "llvm/Analysis/MemoryBuiltins.h"
 #include "llvm/Analysis/OverflowInstAnalysis.h"
@@ -4737,12 +4738,16 @@ static Value *simplifySelectWithICmpCond(Value 
*CondVal, Value *TrueVal,
   // the arms of the select. See if substituting this value into the arm and
   // simplifying the result yields the same value as the other arm.
   if (Pred == ICmpInst::ICMP_EQ) {
-if (Value *V = simplifySelectWithEquivalence({{CmpLHS, CmpRHS}}, TrueVal,
- FalseVal, Q, MaxRecurse))
-  return V;
-if (Value *V = simplifySelectWithEquivalence({{CmpRHS, CmpLHS}}, TrueVal,
- FalseVal, Q, MaxRecurse))
-  return V;
+if (CmpLHS->getType()->isIntOrIntVectorTy() ||
+canReplacePointersIfEqual(CmpLHS, CmpRHS, Q.DL))
+  if (Value *V = simplifySelectWithEquivalence({{CmpLHS, CmpRHS}}, TrueVal,
+   FalseVal, Q, MaxRecurse))
+return V;
+if (CmpLHS->getType()->isIntOrIntVectorTy() ||
+canReplacePointersIfEqual(CmpRHS, CmpLHS, Q.DL))
+  if (Value *V = simplifySelectWithEquivalence({{CmpRHS, CmpLHS}}, TrueVal,
+   FalseVal, Q, MaxRecurse))
+return V;
 
 Value *X;
 Value *Y;
diff --git a/llvm/test/Transforms/InstSimplify/select-icmp.ll 
b/llvm/test/Transforms/InstSimplify/select-icmp.ll
index a6ef937760a5899..64c0d1d7553feb9 100755
--- a/llvm/test/Transforms/InstSimplify/select-icmp.ll
+++ b/llvm/test/Transforms/InstSimplify/select-icmp.ll
@@ -244,3 +244,35 @@ cond.true:; preds 
= %entry
 cond.end: ; preds = %entry, %cond.true
   ret i8 0
 }
+
+define ptr @icmp_ptr_eq_replace(ptr %a, ptr %b) {
+; CHECK-LABEL: @icmp_ptr_eq_replace(
+; CHECK-NEXT:[[CMP:%.*]] = icmp eq ptr [[A:%.*]], [[B1:%.*]]
+; CHECK-NEXT:[[B:%.*]] = select i1 [[CMP]], ptr [[A]], ptr [[B1]]
+; CHECK-NEXT:ret ptr [[B]]
+;
+  %cmp = icmp eq ptr %a, %b
+  %sel = select i1 %cmp, ptr %a, ptr %b
+  ret ptr %sel
+}
+
+define ptr @icmp_ptr_eq_replace_null(ptr %a) {
+; CHECK-LABEL: @icmp_ptr_eq_replace_null(
+; CHECK-NEXT:ret ptr [[A:%.*]]
+;
+  %cmp = icmp eq ptr %a, null
+  %sel = select i1 %cmp, ptr null, ptr %a
+  ret ptr %sel
+}
+
+define ptr @ptr_eq_replace_same_underlying_object(ptr %st, i64 %i, i64 %j) {
+; CHECK-LABEL: @ptr_eq_replace_same_underlying_object(
+; CHECK-NEXT:[[B:%.*]] = getelementptr inbounds i8, ptr [[ST:%.*]], i64 
[[J:%.*]]
+; CHECK-NEXT:ret ptr [[B]]
+;
+  %a = getelementptr inbounds i8, ptr %st, i64 %i
+  %b = getelementptr inbounds i8, ptr %st, i64 %j
+  %cmp = icmp eq ptr %a, %b
+  %sel = select i1 %cmp, ptr %a, ptr %b
+  ret ptr %sel
+}

``




https://github.com/llvm/llvm-project/pull/125398
___
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: [InstSimplify] Add additional checks when substituting pointers (#125385) (PR #125398)

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

llvmbot wrote:




@llvm/pr-subscribers-llvm-analysis

Author: None (llvmbot)


Changes

Backport 1af627b592dd15bbe58136f902ced46251fc344d

Requested by: @dtcxzyw

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


2 Files Affected:

- (modified) llvm/lib/Analysis/InstructionSimplify.cpp (+11-6) 
- (modified) llvm/test/Transforms/InstSimplify/select-icmp.ll (+32) 


``diff
diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp 
b/llvm/lib/Analysis/InstructionSimplify.cpp
index d69747e30f884d..4e550f8fa6a9fd 100644
--- a/llvm/lib/Analysis/InstructionSimplify.cpp
+++ b/llvm/lib/Analysis/InstructionSimplify.cpp
@@ -27,6 +27,7 @@
 #include "llvm/Analysis/CmpInstAnalysis.h"
 #include "llvm/Analysis/ConstantFolding.h"
 #include "llvm/Analysis/InstSimplifyFolder.h"
+#include "llvm/Analysis/Loads.h"
 #include "llvm/Analysis/LoopAnalysisManager.h"
 #include "llvm/Analysis/MemoryBuiltins.h"
 #include "llvm/Analysis/OverflowInstAnalysis.h"
@@ -4737,12 +4738,16 @@ static Value *simplifySelectWithICmpCond(Value 
*CondVal, Value *TrueVal,
   // the arms of the select. See if substituting this value into the arm and
   // simplifying the result yields the same value as the other arm.
   if (Pred == ICmpInst::ICMP_EQ) {
-if (Value *V = simplifySelectWithEquivalence({{CmpLHS, CmpRHS}}, TrueVal,
- FalseVal, Q, MaxRecurse))
-  return V;
-if (Value *V = simplifySelectWithEquivalence({{CmpRHS, CmpLHS}}, TrueVal,
- FalseVal, Q, MaxRecurse))
-  return V;
+if (CmpLHS->getType()->isIntOrIntVectorTy() ||
+canReplacePointersIfEqual(CmpLHS, CmpRHS, Q.DL))
+  if (Value *V = simplifySelectWithEquivalence({{CmpLHS, CmpRHS}}, TrueVal,
+   FalseVal, Q, MaxRecurse))
+return V;
+if (CmpLHS->getType()->isIntOrIntVectorTy() ||
+canReplacePointersIfEqual(CmpRHS, CmpLHS, Q.DL))
+  if (Value *V = simplifySelectWithEquivalence({{CmpRHS, CmpLHS}}, TrueVal,
+   FalseVal, Q, MaxRecurse))
+return V;
 
 Value *X;
 Value *Y;
diff --git a/llvm/test/Transforms/InstSimplify/select-icmp.ll 
b/llvm/test/Transforms/InstSimplify/select-icmp.ll
index a6ef937760a589..64c0d1d7553feb 100755
--- a/llvm/test/Transforms/InstSimplify/select-icmp.ll
+++ b/llvm/test/Transforms/InstSimplify/select-icmp.ll
@@ -244,3 +244,35 @@ cond.true:; preds 
= %entry
 cond.end: ; preds = %entry, %cond.true
   ret i8 0
 }
+
+define ptr @icmp_ptr_eq_replace(ptr %a, ptr %b) {
+; CHECK-LABEL: @icmp_ptr_eq_replace(
+; CHECK-NEXT:[[CMP:%.*]] = icmp eq ptr [[A:%.*]], [[B1:%.*]]
+; CHECK-NEXT:[[B:%.*]] = select i1 [[CMP]], ptr [[A]], ptr [[B1]]
+; CHECK-NEXT:ret ptr [[B]]
+;
+  %cmp = icmp eq ptr %a, %b
+  %sel = select i1 %cmp, ptr %a, ptr %b
+  ret ptr %sel
+}
+
+define ptr @icmp_ptr_eq_replace_null(ptr %a) {
+; CHECK-LABEL: @icmp_ptr_eq_replace_null(
+; CHECK-NEXT:ret ptr [[A:%.*]]
+;
+  %cmp = icmp eq ptr %a, null
+  %sel = select i1 %cmp, ptr null, ptr %a
+  ret ptr %sel
+}
+
+define ptr @ptr_eq_replace_same_underlying_object(ptr %st, i64 %i, i64 %j) {
+; CHECK-LABEL: @ptr_eq_replace_same_underlying_object(
+; CHECK-NEXT:[[B:%.*]] = getelementptr inbounds i8, ptr [[ST:%.*]], i64 
[[J:%.*]]
+; CHECK-NEXT:ret ptr [[B]]
+;
+  %a = getelementptr inbounds i8, ptr %st, i64 %i
+  %b = getelementptr inbounds i8, ptr %st, i64 %j
+  %cmp = icmp eq ptr %a, %b
+  %sel = select i1 %cmp, ptr %a, ptr %b
+  ret ptr %sel
+}

``




https://github.com/llvm/llvm-project/pull/125398
___
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: [InstSimplify] Add additional checks when substituting pointers (#125385) (PR #125398)

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

https://github.com/llvmbot created 
https://github.com/llvm/llvm-project/pull/125398

Backport 1af627b592dd15bbe58136f902ced46251fc344d

Requested by: @dtcxzyw

>From 1e0bfeed4d8f888cf5ddbeeeb9af13a047b67fa5 Mon Sep 17 00:00:00 2001
From: Yingwei Zheng 
Date: Sun, 2 Feb 2025 19:04:23 +0800
Subject: [PATCH] [InstSimplify] Add additional checks when substituting
 pointers (#125385)

Compile-time impact:
https://llvm-compile-time-tracker.com/compare.php?from=d09b521624f263b5f1296f8d4771836b97e600cb&to=e437ba2cb83bb965e13ef00727671896f03ff84f&stat=instructions:u
IR diff looks acceptable.
Closes https://github.com/llvm/llvm-project/issues/115574

(cherry picked from commit 1af627b592dd15bbe58136f902ced46251fc344d)
---
 llvm/lib/Analysis/InstructionSimplify.cpp | 17 ++
 .../Transforms/InstSimplify/select-icmp.ll| 32 +++
 2 files changed, 43 insertions(+), 6 deletions(-)

diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp 
b/llvm/lib/Analysis/InstructionSimplify.cpp
index d69747e30f884d..4e550f8fa6a9fd 100644
--- a/llvm/lib/Analysis/InstructionSimplify.cpp
+++ b/llvm/lib/Analysis/InstructionSimplify.cpp
@@ -27,6 +27,7 @@
 #include "llvm/Analysis/CmpInstAnalysis.h"
 #include "llvm/Analysis/ConstantFolding.h"
 #include "llvm/Analysis/InstSimplifyFolder.h"
+#include "llvm/Analysis/Loads.h"
 #include "llvm/Analysis/LoopAnalysisManager.h"
 #include "llvm/Analysis/MemoryBuiltins.h"
 #include "llvm/Analysis/OverflowInstAnalysis.h"
@@ -4737,12 +4738,16 @@ static Value *simplifySelectWithICmpCond(Value 
*CondVal, Value *TrueVal,
   // the arms of the select. See if substituting this value into the arm and
   // simplifying the result yields the same value as the other arm.
   if (Pred == ICmpInst::ICMP_EQ) {
-if (Value *V = simplifySelectWithEquivalence({{CmpLHS, CmpRHS}}, TrueVal,
- FalseVal, Q, MaxRecurse))
-  return V;
-if (Value *V = simplifySelectWithEquivalence({{CmpRHS, CmpLHS}}, TrueVal,
- FalseVal, Q, MaxRecurse))
-  return V;
+if (CmpLHS->getType()->isIntOrIntVectorTy() ||
+canReplacePointersIfEqual(CmpLHS, CmpRHS, Q.DL))
+  if (Value *V = simplifySelectWithEquivalence({{CmpLHS, CmpRHS}}, TrueVal,
+   FalseVal, Q, MaxRecurse))
+return V;
+if (CmpLHS->getType()->isIntOrIntVectorTy() ||
+canReplacePointersIfEqual(CmpRHS, CmpLHS, Q.DL))
+  if (Value *V = simplifySelectWithEquivalence({{CmpRHS, CmpLHS}}, TrueVal,
+   FalseVal, Q, MaxRecurse))
+return V;
 
 Value *X;
 Value *Y;
diff --git a/llvm/test/Transforms/InstSimplify/select-icmp.ll 
b/llvm/test/Transforms/InstSimplify/select-icmp.ll
index a6ef937760a589..64c0d1d7553feb 100755
--- a/llvm/test/Transforms/InstSimplify/select-icmp.ll
+++ b/llvm/test/Transforms/InstSimplify/select-icmp.ll
@@ -244,3 +244,35 @@ cond.true:; preds 
= %entry
 cond.end: ; preds = %entry, %cond.true
   ret i8 0
 }
+
+define ptr @icmp_ptr_eq_replace(ptr %a, ptr %b) {
+; CHECK-LABEL: @icmp_ptr_eq_replace(
+; CHECK-NEXT:[[CMP:%.*]] = icmp eq ptr [[A:%.*]], [[B1:%.*]]
+; CHECK-NEXT:[[B:%.*]] = select i1 [[CMP]], ptr [[A]], ptr [[B1]]
+; CHECK-NEXT:ret ptr [[B]]
+;
+  %cmp = icmp eq ptr %a, %b
+  %sel = select i1 %cmp, ptr %a, ptr %b
+  ret ptr %sel
+}
+
+define ptr @icmp_ptr_eq_replace_null(ptr %a) {
+; CHECK-LABEL: @icmp_ptr_eq_replace_null(
+; CHECK-NEXT:ret ptr [[A:%.*]]
+;
+  %cmp = icmp eq ptr %a, null
+  %sel = select i1 %cmp, ptr null, ptr %a
+  ret ptr %sel
+}
+
+define ptr @ptr_eq_replace_same_underlying_object(ptr %st, i64 %i, i64 %j) {
+; CHECK-LABEL: @ptr_eq_replace_same_underlying_object(
+; CHECK-NEXT:[[B:%.*]] = getelementptr inbounds i8, ptr [[ST:%.*]], i64 
[[J:%.*]]
+; CHECK-NEXT:ret ptr [[B]]
+;
+  %a = getelementptr inbounds i8, ptr %st, i64 %i
+  %b = getelementptr inbounds i8, ptr %st, i64 %j
+  %cmp = icmp eq ptr %a, %b
+  %sel = select i1 %cmp, ptr %a, ptr %b
+  ret ptr %sel
+}

___
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: [InstSimplify] Add additional checks when substituting pointers (#125385) (PR #125398)

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

https://github.com/llvmbot milestoned 
https://github.com/llvm/llvm-project/pull/125398
___
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: [InstSimplify] Add additional checks when substituting pointers (#125385) (PR #125398)

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

llvmbot wrote:

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

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