[llvm-branch-commits] [llvm] [HLSL] Add descriptor table metadata parsing (PR #142492)

2025-06-19 Thread via llvm-branch-commits

https://github.com/joaosaffran edited 
https://github.com/llvm/llvm-project/pull/142492
___
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] Deal with POISON for INSERT_VECTOR_ELT/INSERT_SUBVECTOR (part 2) (PR #143103)

2025-06-19 Thread Björn Pettersson via llvm-branch-commits

https://github.com/bjope updated 
https://github.com/llvm/llvm-project/pull/143103

From e2556d39b810a074048e143ec083e553cdf4135d Mon Sep 17 00:00:00 2001
From: Bjorn Pettersson 
Date: Tue, 3 Jun 2025 10:01:01 +0200
Subject: [PATCH] [SelectionDAG] Deal with POISON for
 INSERT_VECTOR_ELT/INSERT_SUBVECTOR (part 2)

Add support in isGuaranteedNotToBeUndefOrPoison to avoid regressions
seen after a previous commit fixing #141034.
---
 llvm/include/llvm/CodeGen/SelectionDAGNodes.h |   6 +
 .../lib/CodeGen/SelectionDAG/SelectionDAG.cpp |  70 +
 llvm/test/CodeGen/Thumb2/mve-vld3.ll  |   4 +-
 .../X86/merge-consecutive-loads-128.ll|  78 ++
 llvm/test/CodeGen/X86/mmx-build-vector.ll | 255 +-
 llvm/test/CodeGen/X86/pr62286.ll  |  14 +-
 .../CodeGen/X86/vector-shuffle-combining.ll   |  21 +-
 llvm/test/CodeGen/X86/vector-trunc.ll | 140 ++
 .../zero_extend_vector_inreg_of_broadcast.ll  |   3 +-
 9 files changed, 205 insertions(+), 386 deletions(-)

diff --git a/llvm/include/llvm/CodeGen/SelectionDAGNodes.h 
b/llvm/include/llvm/CodeGen/SelectionDAGNodes.h
index 06217337a46f6..94ef11db3584e 100644
--- a/llvm/include/llvm/CodeGen/SelectionDAGNodes.h
+++ b/llvm/include/llvm/CodeGen/SelectionDAGNodes.h
@@ -1881,6 +1881,12 @@ LLVM_ABI SDValue peekThroughExtractSubvectors(SDValue V);
 /// If \p V is not a truncation, it is returned as-is.
 LLVM_ABI SDValue peekThroughTruncates(SDValue V);
 
+/// Recursively peek through INSERT_VECTOR_ELT nodes, returning the source
+/// vector operand of \p V, as long as \p V is an INSERT_VECTOR_ELT operation
+/// that do not insert into any of the demanded vector elts.
+LLVM_ABI SDValue peekThroughInsertVectorElt(SDValue V,
+const APInt &DemandedElts);
+
 /// Returns true if \p V is a bitwise not operation. Assumes that an all ones
 /// constant is canonicalized to be operand 1.
 LLVM_ABI bool isBitwiseNot(SDValue V, bool AllowUndefs = false);
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp 
b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index 5ec1ee30bcf4b..8fcfdc344fff2 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -5454,6 +5454,59 @@ bool 
SelectionDAG::isGuaranteedNotToBeUndefOrPoison(SDValue Op,
 }
 return true;
 
+  case ISD::INSERT_SUBVECTOR: {
+if (Op.getValueType().isScalableVector())
+  break;
+SDValue Src = Op.getOperand(0);
+SDValue Sub = Op.getOperand(1);
+uint64_t Idx = Op.getConstantOperandVal(2);
+unsigned NumSubElts = Sub.getValueType().getVectorNumElements();
+APInt DemandedSubElts = DemandedElts.extractBits(NumSubElts, Idx);
+APInt DemandedSrcElts = DemandedElts;
+DemandedSrcElts.clearBits(Idx, Idx + NumSubElts);
+
+if (!!DemandedSubElts && !isGuaranteedNotToBeUndefOrPoison(
+ Sub, DemandedSubElts, PoisonOnly, Depth + 1))
+  return false;
+if (!!DemandedSrcElts && !isGuaranteedNotToBeUndefOrPoison(
+ Src, DemandedSrcElts, PoisonOnly, Depth + 1))
+  return false;
+return true;
+  }
+
+  case ISD::INSERT_VECTOR_ELT: {
+SDValue InVec = Op.getOperand(0);
+SDValue InVal = Op.getOperand(1);
+SDValue EltNo = Op.getOperand(2);
+EVT VT = InVec.getValueType();
+auto *IndexC = dyn_cast(EltNo);
+if (IndexC && VT.isFixedLengthVector() &&
+IndexC->getZExtValue() < VT.getVectorNumElements()) {
+  if (DemandedElts[IndexC->getZExtValue()] &&
+  !isGuaranteedNotToBeUndefOrPoison(InVal, PoisonOnly, Depth + 1))
+return false;
+  APInt InVecDemandedElts = DemandedElts;
+  InVecDemandedElts.clearBit(IndexC->getZExtValue());
+  if (!!InVecDemandedElts &&
+  !isGuaranteedNotToBeUndefOrPoison(
+  peekThroughInsertVectorElt(InVec, InVecDemandedElts),
+  InVecDemandedElts, PoisonOnly, Depth + 1))
+return false;
+  return true;
+}
+break;
+  }
+
+  case ISD::SCALAR_TO_VECTOR:
+// If only demanding upper (undef) elements.
+if (DemandedElts.ugt(1))
+  return PoisonOnly;
+// If only demanding element 0, or only considering poison.
+if (PoisonOnly || DemandedElts == 0)
+  return isGuaranteedNotToBeUndefOrPoison(Op.getOperand(0), PoisonOnly,
+  Depth + 1);
+return false;
+
   case ISD::SPLAT_VECTOR:
 return isGuaranteedNotToBeUndefOrPoison(Op.getOperand(0), PoisonOnly,
 Depth + 1);
@@ -12471,6 +12524,23 @@ SDValue llvm::peekThroughTruncates(SDValue V) {
   return V;
 }
 
+SDValue llvm::peekThroughInsertVectorElt(SDValue V, const APInt &DemandedElts) 
{
+  while (V.getOpcode() == ISD::INSERT_VECTOR_ELT) {
+SDValue InVec = V.getOperand(0);
+SDValue EltNo = V.getOperand(2);
+EVT VT = InVec.getValueType();
+auto *IndexC = dyn_cast(EltNo);

[llvm-branch-commits] [llvm] TableGen: Handle setting runtime libcall calling conventions (PR #144980)

2025-06-19 Thread Matt Arsenault via llvm-branch-commits

https://github.com/arsenm ready_for_review 
https://github.com/llvm/llvm-project/pull/144980
___
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-tools-extra] [clang-doc] add support for concepts (PR #144430)

2025-06-19 Thread Erick Velez via llvm-branch-commits

https://github.com/evelez7 ready_for_review 
https://github.com/llvm/llvm-project/pull/144430
___
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] Add a GUIDLIST table to bitcode (PR #139497)

2025-06-19 Thread Owen Rodley via llvm-branch-commits

https://github.com/orodley updated 
https://github.com/llvm/llvm-project/pull/139497

>From bf53f8766fe4e5d4421dea919bf2abb8d4b13004 Mon Sep 17 00:00:00 2001
From: Owen Rodley 
Date: Mon, 12 May 2025 15:50:22 +1000
Subject: [PATCH] Add a GUIDLIST table to bitcode

---
 llvm/include/llvm/Bitcode/LLVMBitCodes.h  |  3 +++
 llvm/lib/Bitcode/Reader/BitcodeReader.cpp | 11 +++---
 llvm/lib/Bitcode/Writer/BitcodeWriter.cpp | 25 +++
 3 files changed, 36 insertions(+), 3 deletions(-)

diff --git a/llvm/include/llvm/Bitcode/LLVMBitCodes.h 
b/llvm/include/llvm/Bitcode/LLVMBitCodes.h
index b362a88963f6c..8fa3a89536d75 100644
--- a/llvm/include/llvm/Bitcode/LLVMBitCodes.h
+++ b/llvm/include/llvm/Bitcode/LLVMBitCodes.h
@@ -120,6 +120,9 @@ enum ModuleCodes {
 
   // IFUNC: [ifunc value type, addrspace, resolver val#, linkage, visibility]
   MODULE_CODE_IFUNC = 18,
+
+  // GUIDLIST: [n x i64]
+  MODULE_CODE_GUIDLIST = 19,
 };
 
 /// PARAMATTR blocks have code for defining a parameter attribute set.
diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp 
b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
index fde934fbb3cf1..3994f8469078b 100644
--- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
+++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
@@ -976,6 +976,9 @@ class ModuleSummaryIndexBitcodeReader : public 
BitcodeReaderBase {
   /// the CallStackRadixTreeBuilder class in ProfileData/MemProf.h for format.
   std::vector RadixArray;
 
+  // A table which maps ValueID to the GUID for that value.
+  std::vector DefinedGUIDs;
+
 public:
   ModuleSummaryIndexBitcodeReader(
   BitstreamCursor Stream, StringRef Strtab, ModuleSummaryIndex &TheIndex,
@@ -7162,9 +7165,7 @@ 
ModuleSummaryIndexBitcodeReader::getValueInfoFromValueId(unsigned ValueId) {
 void ModuleSummaryIndexBitcodeReader::setValueGUID(
 uint64_t ValueID, StringRef ValueName, GlobalValue::LinkageTypes Linkage,
 StringRef SourceFileName) {
-  std::string GlobalId =
-  GlobalValue::getGlobalIdentifier(ValueName, Linkage, SourceFileName);
-  auto ValueGUID = GlobalValue::getGUIDAssumingExternalLinkage(GlobalId);
+  auto ValueGUID = DefinedGUIDs[ValueID];
   auto OriginalNameID = ValueGUID;
   if (GlobalValue::isLocalLinkage(Linkage))
 OriginalNameID = GlobalValue::getGUIDAssumingExternalLinkage(ValueName);
@@ -7387,6 +7388,10 @@ Error ModuleSummaryIndexBitcodeReader::parseModule() {
   // was historically always the start of the regular bitcode header.
   VSTOffset = Record[0] - 1;
   break;
+// MODULE_CODE_GUIDLIST: [i64 x N]
+case bitc::MODULE_CODE_GUIDLIST:
+  llvm::append_range(DefinedGUIDs, Record);
+  break;
 // v1 GLOBALVAR: [pointer type, isconst, initid,   linkage, 
...]
 // v1 FUNCTION:  [type, callingconv, isproto,  linkage, 
...]
 // v1 ALIAS: [alias type,   addrspace,   aliasee val#, linkage, 
...]
diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp 
b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
index 628b939af19ce..a72f55bd7d0d1 100644
--- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
+++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
@@ -244,6 +244,7 @@ class ModuleBitcodeWriterBase : public BitcodeWriterBase {
 
 protected:
   void writePerModuleGlobalValueSummary();
+  void writeGUIDList();
 
 private:
   void writePerModuleFunctionSummaryRecord(
@@ -1583,6 +1584,8 @@ void ModuleBitcodeWriter::writeModuleInfo() {
 Vals.clear();
   }
 
+  writeGUIDList();
+
   // Emit the global variable information.
   for (const GlobalVariable &GV : M.globals()) {
 unsigned AbbrevToUse = 0;
@@ -4790,6 +4793,26 @@ void 
ModuleBitcodeWriterBase::writePerModuleGlobalValueSummary() {
   Stream.ExitBlock();
 }
 
+void ModuleBitcodeWriterBase::writeGUIDList() {
+  std::vector GUIDs;
+  GUIDs.reserve(M.global_size() + M.size() + M.alias_size());
+
+  for (const GlobalValue &GV : M.global_objects()) {
+if (GV.isDeclaration()) {
+  GUIDs.push_back(
+  GlobalValue::getGUIDAssumingExternalLinkage(GV.getName()));
+} else {
+  GUIDs.push_back(GV.getGUID());
+}
+  }
+  for (const GlobalAlias &GA : M.aliases()) {
+// Equivalent to the above loop, as GlobalAliases are always definitions.
+GUIDs.push_back(GA.getGUID());
+  }
+
+  Stream.EmitRecord(bitc::MODULE_CODE_GUIDLIST, GUIDs);
+}
+
 /// Emit the combined summary section into the combined index file.
 void IndexBitcodeWriter::writeCombinedGlobalValueSummary() {
   Stream.EnterSubblock(bitc::GLOBALVAL_SUMMARY_BLOCK_ID, 4);
@@ -5578,6 +5601,8 @@ void ThinLinkBitcodeWriter::writeSimplifiedModuleInfo() {
 Vals.clear();
   }
 
+  writeGUIDList();
+
   // Emit the global variable information.
   for (const GlobalVariable &GV : M.globals()) {
 // GLOBALVAR: [strtab offset, strtab size, 0, 0, 0, linkage]

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

[llvm-branch-commits] [llvm] Add a GUIDLIST table to bitcode (PR #139497)

2025-06-19 Thread Owen Rodley via llvm-branch-commits

https://github.com/orodley updated 
https://github.com/llvm/llvm-project/pull/139497

>From bf53f8766fe4e5d4421dea919bf2abb8d4b13004 Mon Sep 17 00:00:00 2001
From: Owen Rodley 
Date: Mon, 12 May 2025 15:50:22 +1000
Subject: [PATCH] Add a GUIDLIST table to bitcode

---
 llvm/include/llvm/Bitcode/LLVMBitCodes.h  |  3 +++
 llvm/lib/Bitcode/Reader/BitcodeReader.cpp | 11 +++---
 llvm/lib/Bitcode/Writer/BitcodeWriter.cpp | 25 +++
 3 files changed, 36 insertions(+), 3 deletions(-)

diff --git a/llvm/include/llvm/Bitcode/LLVMBitCodes.h 
b/llvm/include/llvm/Bitcode/LLVMBitCodes.h
index b362a88963f6c..8fa3a89536d75 100644
--- a/llvm/include/llvm/Bitcode/LLVMBitCodes.h
+++ b/llvm/include/llvm/Bitcode/LLVMBitCodes.h
@@ -120,6 +120,9 @@ enum ModuleCodes {
 
   // IFUNC: [ifunc value type, addrspace, resolver val#, linkage, visibility]
   MODULE_CODE_IFUNC = 18,
+
+  // GUIDLIST: [n x i64]
+  MODULE_CODE_GUIDLIST = 19,
 };
 
 /// PARAMATTR blocks have code for defining a parameter attribute set.
diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp 
b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
index fde934fbb3cf1..3994f8469078b 100644
--- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
+++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
@@ -976,6 +976,9 @@ class ModuleSummaryIndexBitcodeReader : public 
BitcodeReaderBase {
   /// the CallStackRadixTreeBuilder class in ProfileData/MemProf.h for format.
   std::vector RadixArray;
 
+  // A table which maps ValueID to the GUID for that value.
+  std::vector DefinedGUIDs;
+
 public:
   ModuleSummaryIndexBitcodeReader(
   BitstreamCursor Stream, StringRef Strtab, ModuleSummaryIndex &TheIndex,
@@ -7162,9 +7165,7 @@ 
ModuleSummaryIndexBitcodeReader::getValueInfoFromValueId(unsigned ValueId) {
 void ModuleSummaryIndexBitcodeReader::setValueGUID(
 uint64_t ValueID, StringRef ValueName, GlobalValue::LinkageTypes Linkage,
 StringRef SourceFileName) {
-  std::string GlobalId =
-  GlobalValue::getGlobalIdentifier(ValueName, Linkage, SourceFileName);
-  auto ValueGUID = GlobalValue::getGUIDAssumingExternalLinkage(GlobalId);
+  auto ValueGUID = DefinedGUIDs[ValueID];
   auto OriginalNameID = ValueGUID;
   if (GlobalValue::isLocalLinkage(Linkage))
 OriginalNameID = GlobalValue::getGUIDAssumingExternalLinkage(ValueName);
@@ -7387,6 +7388,10 @@ Error ModuleSummaryIndexBitcodeReader::parseModule() {
   // was historically always the start of the regular bitcode header.
   VSTOffset = Record[0] - 1;
   break;
+// MODULE_CODE_GUIDLIST: [i64 x N]
+case bitc::MODULE_CODE_GUIDLIST:
+  llvm::append_range(DefinedGUIDs, Record);
+  break;
 // v1 GLOBALVAR: [pointer type, isconst, initid,   linkage, 
...]
 // v1 FUNCTION:  [type, callingconv, isproto,  linkage, 
...]
 // v1 ALIAS: [alias type,   addrspace,   aliasee val#, linkage, 
...]
diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp 
b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
index 628b939af19ce..a72f55bd7d0d1 100644
--- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
+++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
@@ -244,6 +244,7 @@ class ModuleBitcodeWriterBase : public BitcodeWriterBase {
 
 protected:
   void writePerModuleGlobalValueSummary();
+  void writeGUIDList();
 
 private:
   void writePerModuleFunctionSummaryRecord(
@@ -1583,6 +1584,8 @@ void ModuleBitcodeWriter::writeModuleInfo() {
 Vals.clear();
   }
 
+  writeGUIDList();
+
   // Emit the global variable information.
   for (const GlobalVariable &GV : M.globals()) {
 unsigned AbbrevToUse = 0;
@@ -4790,6 +4793,26 @@ void 
ModuleBitcodeWriterBase::writePerModuleGlobalValueSummary() {
   Stream.ExitBlock();
 }
 
+void ModuleBitcodeWriterBase::writeGUIDList() {
+  std::vector GUIDs;
+  GUIDs.reserve(M.global_size() + M.size() + M.alias_size());
+
+  for (const GlobalValue &GV : M.global_objects()) {
+if (GV.isDeclaration()) {
+  GUIDs.push_back(
+  GlobalValue::getGUIDAssumingExternalLinkage(GV.getName()));
+} else {
+  GUIDs.push_back(GV.getGUID());
+}
+  }
+  for (const GlobalAlias &GA : M.aliases()) {
+// Equivalent to the above loop, as GlobalAliases are always definitions.
+GUIDs.push_back(GA.getGUID());
+  }
+
+  Stream.EmitRecord(bitc::MODULE_CODE_GUIDLIST, GUIDs);
+}
+
 /// Emit the combined summary section into the combined index file.
 void IndexBitcodeWriter::writeCombinedGlobalValueSummary() {
   Stream.EnterSubblock(bitc::GLOBALVAL_SUMMARY_BLOCK_ID, 4);
@@ -5578,6 +5601,8 @@ void ThinLinkBitcodeWriter::writeSimplifiedModuleInfo() {
 Vals.clear();
   }
 
+  writeGUIDList();
+
   // Emit the global variable information.
   for (const GlobalVariable &GV : M.globals()) {
 // GLOBALVAR: [strtab offset, strtab size, 0, 0, 0, linkage]

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

[llvm-branch-commits] [clang-tools-extra] [clang-doc] add support for concepts (PR #144430)

2025-06-19 Thread Erick Velez via llvm-branch-commits

https://github.com/evelez7 updated 
https://github.com/llvm/llvm-project/pull/144430

>From 2febdc89f0c2b2f9abe47415f5c115ad8305ed2d Mon Sep 17 00:00:00 2001
From: Erick Velez 
Date: Mon, 16 Jun 2025 10:50:35 -0700
Subject: [PATCH] add serializeArray for infos with URLs

---
 clang-tools-extra/clang-doc/BitcodeReader.cpp |  72 +++
 clang-tools-extra/clang-doc/BitcodeWriter.cpp |  44 ++-
 clang-tools-extra/clang-doc/BitcodeWriter.h   |  12 +-
 clang-tools-extra/clang-doc/HTMLGenerator.cpp |   4 +
 .../clang-doc/HTMLMustacheGenerator.cpp   |   2 +
 clang-tools-extra/clang-doc/JSONGenerator.cpp |  50 
 clang-tools-extra/clang-doc/MDGenerator.cpp   |   5 +
 clang-tools-extra/clang-doc/Mapper.cpp|   4 +
 clang-tools-extra/clang-doc/Mapper.h  |   1 +
 .../clang-doc/Representation.cpp  |  20 +++
 clang-tools-extra/clang-doc/Representation.h  |  26 +++-
 clang-tools-extra/clang-doc/Serialize.cpp |  90 +
 clang-tools-extra/clang-doc/Serialize.h   |   4 +
 clang-tools-extra/clang-doc/YAMLGenerator.cpp |   2 +
 .../test/clang-doc/json/class-requires.cpp|  18 +--
 .../clang-doc/json/compound-constraints.cpp   | 121 ++
 .../test/clang-doc/json/concept.cpp   |  48 +++
 .../test/clang-doc/json/function-requires.cpp |  36 +++---
 .../unittests/clang-doc/BitcodeTest.cpp   |   2 +
 19 files changed, 505 insertions(+), 56 deletions(-)
 create mode 100644 
clang-tools-extra/test/clang-doc/json/compound-constraints.cpp

diff --git a/clang-tools-extra/clang-doc/BitcodeReader.cpp 
b/clang-tools-extra/clang-doc/BitcodeReader.cpp
index 35058abab0663..5b70280e7dba8 100644
--- a/clang-tools-extra/clang-doc/BitcodeReader.cpp
+++ b/clang-tools-extra/clang-doc/BitcodeReader.cpp
@@ -92,6 +92,7 @@ static llvm::Error decodeRecord(const Record &R, InfoType 
&Field,
   case InfoType::IT_default:
   case InfoType::IT_enum:
   case InfoType::IT_typedef:
+  case InfoType::IT_concept:
 Field = IT;
 return llvm::Error::success();
   }
@@ -108,6 +109,7 @@ static llvm::Error decodeRecord(const Record &R, FieldId 
&Field,
   case FieldId::F_type:
   case FieldId::F_child_namespace:
   case FieldId::F_child_record:
+  case FieldId::F_concept:
   case FieldId::F_default:
 Field = F;
 return llvm::Error::success();
@@ -391,6 +393,29 @@ static llvm::Error parseRecord(const Record &R, unsigned 
ID,
  "invalid field for TemplateParamInfo");
 }
 
+static llvm::Error parseRecord(const Record &R, unsigned ID,
+   llvm::StringRef Blob, ConceptInfo *I) {
+  switch (ID) {
+  case CONCEPT_USR:
+return decodeRecord(R, I->USR, Blob);
+  case CONCEPT_NAME:
+return decodeRecord(R, I->Name, Blob);
+  case CONCEPT_IS_TYPE:
+return decodeRecord(R, I->IsType, Blob);
+  case CONCEPT_CONSTRAINT_EXPRESSION:
+return decodeRecord(R, I->ConstraintExpression, Blob);
+  }
+  llvm_unreachable("invalid field for ConceptInfo");
+}
+
+static llvm::Error parseRecord(const Record &R, unsigned ID,
+   llvm::StringRef Blob, ConstraintInfo *I) {
+  if (ID == CONSTRAINT_EXPRESSION)
+return decodeRecord(R, I->Expression, Blob);
+  return llvm::createStringError(llvm::inconvertibleErrorCode(),
+ "invalid field for ConstraintInfo");
+}
+
 template  static llvm::Expected getCommentInfo(T I) 
{
   return llvm::createStringError(llvm::inconvertibleErrorCode(),
  "invalid type cannot contain CommentInfo");
@@ -429,6 +454,10 @@ template <> llvm::Expected 
getCommentInfo(CommentInfo *I) {
   return I->Children.back().get();
 }
 
+template <> llvm::Expected getCommentInfo(ConceptInfo *I) {
+  return &I->Description.emplace_back();
+}
+
 // When readSubBlock encounters a TypeInfo sub-block, it calls addTypeInfo on
 // the parent block to set it. The template specializations define what to do
 // for each supported parent block.
@@ -584,6 +613,18 @@ template <> llvm::Error addReference(RecordInfo *I, 
Reference &&R, FieldId F) {
   }
 }
 
+template <>
+llvm::Error addReference(ConstraintInfo *I, Reference &&R, FieldId F) {
+  switch (F) {
+  case FieldId::F_concept:
+I->ConceptRef = std::move(R);
+return llvm::Error::success();
+  default:
+return llvm::createStringError(llvm::inconvertibleErrorCode(),
+   "invalid type cannot contain Reference");
+  }
+}
+
 template 
 static void addChild(T I, ChildInfoType &&R) {
   llvm::errs() << "invalid child type for info";
@@ -600,6 +641,9 @@ template <> void addChild(NamespaceInfo *I, EnumInfo &&R) {
 template <> void addChild(NamespaceInfo *I, TypedefInfo &&R) {
   I->Children.Typedefs.emplace_back(std::move(R));
 }
+template <> void addChild(NamespaceInfo *I, ConceptInfo &&R) {
+  I->Children.Concepts.emplace_back(std::move(R));
+}
 
 // Record children:
 template <> void addChild(RecordInfo *I, FunctionInfo &&R) {
@@ -

[llvm-branch-commits] [llvm] [DirectX] Improve error handling and validation in root signature parsing (PR #144577)

2025-06-19 Thread via llvm-branch-commits

https://github.com/joaosaffran edited 
https://github.com/llvm/llvm-project/pull/144577
___
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] [DirectX] Improve error accumulation in root signature parsing (PR #144465)

2025-06-19 Thread via llvm-branch-commits

https://github.com/joaosaffran edited 
https://github.com/llvm/llvm-project/pull/144465
___
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] RuntimeLibcalls: Associate calling convention with libcall impls (PR #144979)

2025-06-19 Thread Matt Arsenault via llvm-branch-commits

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

Instead of associating the libcall with the RTLIB::Libcall, put it
into a table indexed by the RTLIB::LibcallImpl. The LibcallImpls
should contain all ABI details for a particular implementation, not
the abstract Libcall. In the future the wrappers in terms of the
RTLIB::Libcall should be removed.

>From 191a077fa9f39768f64abe6e5f017630cfb867f8 Mon Sep 17 00:00:00 2001
From: Matt Arsenault 
Date: Tue, 17 Jun 2025 16:25:50 +0900
Subject: [PATCH] RuntimeLibcalls: Associate calling convention with libcall
 impls

Instead of associating the libcall with the RTLIB::Libcall, put it
into a table indexed by the RTLIB::LibcallImpl. The LibcallImpls
should contain all ABI details for a particular implementation, not
the abstract Libcall. In the future the wrappers in terms of the
RTLIB::Libcall should be removed.
---
 llvm/include/llvm/CodeGen/TargetLowering.h| 16 -
 llvm/include/llvm/IR/RuntimeLibcalls.h| 32 ++---
 llvm/lib/IR/RuntimeLibcalls.cpp   | 70 +++
 llvm/lib/Target/ARM/ARMISelLowering.cpp   | 24 ---
 llvm/lib/Target/Lanai/LanaiISelLowering.cpp   |  4 +-
 llvm/lib/Target/MSP430/MSP430ISelLowering.cpp |  3 +-
 6 files changed, 98 insertions(+), 51 deletions(-)

diff --git a/llvm/include/llvm/CodeGen/TargetLowering.h 
b/llvm/include/llvm/CodeGen/TargetLowering.h
index 69ae4f80297d5..fa08eb64642de 100644
--- a/llvm/include/llvm/CodeGen/TargetLowering.h
+++ b/llvm/include/llvm/CodeGen/TargetLowering.h
@@ -3562,6 +3562,11 @@ class LLVM_ABI TargetLoweringBase {
 Libcalls.setLibcallImpl(Call, Impl);
   }
 
+  /// Get the libcall impl routine name for the specified libcall.
+  RTLIB::LibcallImpl getLibcallImpl(RTLIB::Libcall Call) const {
+return Libcalls.getLibcallImpl(Call);
+  }
+
   /// Get the libcall routine name for the specified libcall.
   const char *getLibcallName(RTLIB::Libcall Call) const {
 return Libcalls.getLibcallName(Call);
@@ -3584,11 +3589,18 @@ class LLVM_ABI TargetLoweringBase {
   }
 
   /// Set the CallingConv that should be used for the specified libcall.
-  void setLibcallCallingConv(RTLIB::Libcall Call, CallingConv::ID CC) {
-Libcalls.setLibcallCallingConv(Call, CC);
+  void setLibcallImplCallingConv(RTLIB::LibcallImpl Call, CallingConv::ID CC) {
+Libcalls.setLibcallImplCallingConv(Call, CC);
+  }
+
+  /// Get the CallingConv that should be used for the specified libcall
+  /// implementation.
+  CallingConv::ID getLibcallImplCallingConv(RTLIB::LibcallImpl Call) const {
+return Libcalls.getLibcallImplCallingConv(Call);
   }
 
   /// Get the CallingConv that should be used for the specified libcall.
+  // FIXME: Remove this wrapper and directly use the used LibcallImpl
   CallingConv::ID getLibcallCallingConv(RTLIB::Libcall Call) const {
 return Libcalls.getLibcallCallingConv(Call);
   }
diff --git a/llvm/include/llvm/IR/RuntimeLibcalls.h 
b/llvm/include/llvm/IR/RuntimeLibcalls.h
index d69c23753da7a..dce16ab99171f 100644
--- a/llvm/include/llvm/IR/RuntimeLibcalls.h
+++ b/llvm/include/llvm/IR/RuntimeLibcalls.h
@@ -37,6 +37,10 @@ template <> struct enum_iteration_traits {
   static constexpr bool is_iterable = true;
 };
 
+template <> struct enum_iteration_traits {
+  static constexpr bool is_iterable = true;
+};
+
 namespace RTLIB {
 
 // Return an iterator over all Libcall values.
@@ -44,6 +48,10 @@ static inline auto libcalls() {
   return enum_seq(static_cast(0), RTLIB::UNKNOWN_LIBCALL);
 }
 
+static inline auto libcall_impls() {
+  return enum_seq(static_cast(1), RTLIB::NumLibcallImpls);
+}
+
 /// A simple container for information about the supported runtime calls.
 struct RuntimeLibcallsInfo {
   explicit RuntimeLibcallsInfo(
@@ -76,16 +84,21 @@ struct RuntimeLibcallsInfo {
 return LibcallImpls[Call];
   }
 
-  /// Set the CallingConv that should be used for the specified libcall.
-  // FIXME: This should be a function of RTLIB::LibcallImpl
-  void setLibcallCallingConv(RTLIB::Libcall Call, CallingConv::ID CC) {
-LibcallCallingConvs[Call] = CC;
+  /// Set the CallingConv that should be used for the specified libcall
+  /// implementation
+  void setLibcallImplCallingConv(RTLIB::LibcallImpl Call, CallingConv::ID CC) {
+LibcallImplCallingConvs[Call] = CC;
   }
 
-  /// Get the CallingConv that should be used for the specified libcall.
-  // FIXME: This should be a function of RTLIB::LibcallImpl
+  // FIXME: Remove this wrapper in favor of directly using
+  // getLibcallImplCallingConv
   CallingConv::ID getLibcallCallingConv(RTLIB::Libcall Call) const {
-return LibcallCallingConvs[Call];
+return LibcallImplCallingConvs[LibcallImpls[Call]];
+  }
+
+  /// Get the CallingConv that should be used for the specified libcall.
+  CallingConv::ID getLibcallImplCallingConv(RTLIB::LibcallImpl Call) const {
+return LibcallImplCallingConvs[Call];
   }
 
   ArrayRef getLibcallImpls() const {
@@ -130,8 +143,9 @

[llvm-branch-commits] [llvm] TableGen: Allow defining sets of runtime libraries (PR #144978)

2025-06-19 Thread Matt Arsenault via llvm-branch-commits

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

Add a way to define a SystemLibrary for a complete set of
libcalls, subdivided by a predicate based on the triple.
Libraries can be defined using dag set operations, and the
prior default set can be subtracted from and added to (though
I think eventually all targets should move to explicit opt-ins.
We're still doing things like reporting ppcf128 libcalls as
available dy default on all targets).

Start migrating some of the easier targets to only use the new
system. Targets that don't define a SystemLibrary are still
manually mutating a table set to the old defaults.

As a side effect, also fixes a missing # prefix for the windows
arm64ec case when emitting __arm_sc libcalls.

>From f5f142d6ecc0c42974023c1eb6294004ad192272 Mon Sep 17 00:00:00 2001
From: Matt Arsenault 
Date: Sat, 7 Jun 2025 20:57:31 +0900
Subject: [PATCH] TableGen: Allow defining sets of runtime libraries

Add a way to define a SystemLibrary for a complete set of
libcalls, subdivided by a predicate based on the triple.
Libraries can be defined using dag set operations, and the
prior default set can be subtracted from and added to (though
I think eventually all targets should move to explicit opt-ins.
We're still doing things like reporting ppcf128 libcalls as
available dy default on all targets).

Start migrating some of the easier targets to only use the new
system. Targets that don't define a SystemLibrary are still
manually mutating a table set to the old defaults.
---
 llvm/include/llvm/IR/RuntimeLibcalls.h|  10 +-
 llvm/include/llvm/IR/RuntimeLibcalls.td   | 493 +++---
 llvm/include/llvm/IR/RuntimeLibcallsImpl.td   |  36 ++
 llvm/include/llvm/TableGen/SetTheory.td   |  27 +
 llvm/lib/IR/RuntimeLibcalls.cpp   | 127 +
 .../RuntimeLibcallEmitter-conflict-warning.td |  60 +++
 ...eLibcallEmitter-nested-predicates-error.td |  18 +
 llvm/test/TableGen/RuntimeLibcallEmitter.td   | 185 ++-
 .../TableGen/Basic/RuntimeLibcallsEmitter.cpp | 351 +
 9 files changed, 889 insertions(+), 418 deletions(-)
 create mode 100644 llvm/include/llvm/TableGen/SetTheory.td
 create mode 100644 llvm/test/TableGen/RuntimeLibcallEmitter-conflict-warning.td
 create mode 100644 
llvm/test/TableGen/RuntimeLibcallEmitter-nested-predicates-error.td

diff --git a/llvm/include/llvm/IR/RuntimeLibcalls.h 
b/llvm/include/llvm/IR/RuntimeLibcalls.h
index 912715fbf6b19..d69c23753da7a 100644
--- a/llvm/include/llvm/IR/RuntimeLibcalls.h
+++ b/llvm/include/llvm/IR/RuntimeLibcalls.h
@@ -52,7 +52,6 @@ struct RuntimeLibcallsInfo {
   FloatABI::ABIType FloatABI = FloatABI::Default,
   EABI EABIVersion = EABI::Default) {
 initSoftFloatCmpLibcallPredicates();
-initDefaultLibCallImpls();
 initLibcalls(TT, ExceptionModel, FloatABI, EABIVersion);
   }
 
@@ -97,6 +96,7 @@ struct RuntimeLibcallsInfo {
   /// Get the comparison predicate that's to be used to test the result of the
   /// comparison libcall against zero. This should only be used with
   /// floating-point compare libcalls.
+  // FIXME: This should be a function of RTLIB::LibcallImpl
   CmpInst::Predicate
   getSoftFloatCmpLibcallPredicate(RTLIB::Libcall Call) const {
 return SoftFloatCompareLibcallPredicates[Call];
@@ -172,13 +172,7 @@ struct RuntimeLibcallsInfo {
   void initDefaultLibCallImpls();
 
   /// Generated by tablegen.
-  void setPPCLibCallNameOverrides();
-
-  /// Generated by tablegen.
-  void setZOSLibCallNameOverrides();
-
-  /// Generated by tablegen.
-  void setWindowsArm64LibCallNameOverrides();
+  void setTargetRuntimeLibcallSets(const Triple &TT);
 
   void initSoftFloatCmpLibcallPredicates();
 
diff --git a/llvm/include/llvm/IR/RuntimeLibcalls.td 
b/llvm/include/llvm/IR/RuntimeLibcalls.td
index 1d9f02dcf8ba8..e24b4c928b421 100644
--- a/llvm/include/llvm/IR/RuntimeLibcalls.td
+++ b/llvm/include/llvm/IR/RuntimeLibcalls.td
@@ -891,6 +891,17 @@ def calloc : RuntimeLibcallImpl;
 } // End let IsDefault = true
 } // End defset DefaultRuntimeLibcallImpls
 
+defvar DefaultLibCalls =
+!foreach(entry, DefaultRuntimeLibcallImpls, entry.Provides);
+
+defvar DefaultRuntimeLibcallImpls_f128 =
+!filter(entry, DefaultRuntimeLibcallImpls,
+!match(!cast(entry.Provides), "_F128"));
+
+defvar DefaultRuntimeLibcallImpls_atomic =
+!filter(entry, DefaultRuntimeLibcallImpls,
+!match(!cast(entry.Provides), "ATOMIC"));
+
 //
 // Define implementation other libcalls
 //
@@ -915,58 +926,61 @@ def _Unwind_SjLj_Resume : 
RuntimeLibcallImpl;
 // F128 libm Runtime Libcalls
 
//===--===//
 
-def logf128 : RuntimeLibcallImpl;
-def log2f128 : RuntimeLibcallImpl;
-def log10f128 : RuntimeLibcallImpl;
-def expf128 : RuntimeLibcallImpl;
-def e

[llvm-branch-commits] [llvm] TableGen: Add runtime libcall backend (PR #144972)

2025-06-19 Thread Matt Arsenault via llvm-branch-commits

arsenm wrote:

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

* **#144979** https://app.graphite.dev/github/pr/llvm/llvm-project/144979?utm_source=stack-comment-icon";
 target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" 
width="10px" height="10px"/>
* **#144978** https://app.graphite.dev/github/pr/llvm/llvm-project/144978?utm_source=stack-comment-icon";
 target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" 
width="10px" height="10px"/>
* **#144977** https://app.graphite.dev/github/pr/llvm/llvm-project/144977?utm_source=stack-comment-icon";
 target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" 
width="10px" height="10px"/>
* **#144976** https://app.graphite.dev/github/pr/llvm/llvm-project/144976?utm_source=stack-comment-icon";
 target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" 
width="10px" height="10px"/>
* **#144975** https://app.graphite.dev/github/pr/llvm/llvm-project/144975?utm_source=stack-comment-icon";
 target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" 
width="10px" height="10px"/>
* **#144974** https://app.graphite.dev/github/pr/llvm/llvm-project/144974?utm_source=stack-comment-icon";
 target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" 
width="10px" height="10px"/>
* **#144973** https://app.graphite.dev/github/pr/llvm/llvm-project/144973?utm_source=stack-comment-icon";
 target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" 
width="10px" height="10px"/>
* **#144972** https://app.graphite.dev/github/pr/llvm/llvm-project/144972?utm_source=stack-comment-icon";
 target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" 
width="10px" height="10px"/> 👈 https://app.graphite.dev/github/pr/llvm/llvm-project/144972?utm_source=stack-comment-view-in-graphite";
 target="_blank">(View in Graphite)
* **#143836** https://app.graphite.dev/github/pr/llvm/llvm-project/143836?utm_source=stack-comment-icon";
 target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" 
width="10px" height="10px"/>
* `main`




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


https://github.com/llvm/llvm-project/pull/144972
___
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] TableGen: Handle setting runtime libcall calling conventions (PR #144980)

2025-06-19 Thread Matt Arsenault via llvm-branch-commits

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

Allow associating a non-default CallingConv with a set of library
functions, and applying a default for a SystemLibrary.

I also wanted to be able to apply a default calling conv
to a RuntimeLibcallImpl, but that turned out to be annoying
so leave it for later.

>From f847af321a1fed66af72cd32e48aa3925d74805b Mon Sep 17 00:00:00 2001
From: Matt Arsenault 
Date: Fri, 13 Jun 2025 15:54:41 +0900
Subject: [PATCH] TableGen: Handle setting runtime libcall calling conventions

Allow associating a non-default CallingConv with a set of library
functions, and applying a default for a SystemLibrary.

I also wanted to be able to apply a default calling conv
to a RuntimeLibcallImpl, but that turned out to be annoying
so leave it for later.
---
 llvm/include/llvm/IR/RuntimeLibcalls.td   | 140 +++--
 llvm/include/llvm/IR/RuntimeLibcallsImpl.td   |  26 +++-
 llvm/lib/IR/RuntimeLibcalls.cpp   | 141 --
 .../RuntimeLibcallEmitter-calling-conv.td |  85 +++
 llvm/test/TableGen/RuntimeLibcallEmitter.td   |  19 ++-
 .../TableGen/Basic/RuntimeLibcallsEmitter.cpp | 111 +++---
 6 files changed, 344 insertions(+), 178 deletions(-)
 create mode 100644 llvm/test/TableGen/RuntimeLibcallEmitter-calling-conv.td

diff --git a/llvm/include/llvm/IR/RuntimeLibcalls.td 
b/llvm/include/llvm/IR/RuntimeLibcalls.td
index e24b4c928b421..03ac9f5926f87 100644
--- a/llvm/include/llvm/IR/RuntimeLibcalls.td
+++ b/llvm/include/llvm/IR/RuntimeLibcalls.td
@@ -1254,11 +1254,12 @@ def __gnu_h2f_ieee : RuntimeLibcallImpl;
 
//===--===//
 
 // Several of the runtime library functions use a special calling conv
-def __divmodqi4 : RuntimeLibcallImpl; // CallingConv::AVR_BUILTIN
-def __divmodhi4 : RuntimeLibcallImpl; // CallingConv::AVR_BUILTIN
+def __divmodqi4 : RuntimeLibcallImpl;
+def __divmodhi4 : RuntimeLibcallImpl;
+def __udivmodqi4 : RuntimeLibcallImpl;
+def __udivmodhi4 : RuntimeLibcallImpl;
+
 //def __divmodsi4 : RuntimeLibcallImpl;
-def __udivmodqi4 : RuntimeLibcallImpl; // CallingConv::AVR_BUILTIN
-def __udivmodhi4 : RuntimeLibcallImpl; // CallingConv::AVR_BUILTIN
 //def __udivmodsi4 : RuntimeLibcallImpl;
 
 // Standard sinf/cosf name replaced with "sin" and "cos". Define a
@@ -1284,9 +1285,12 @@ def AVRSystemLibrary
// Standard f64 names are replaced
sin, cos, sinf, cosf),
 
-  __divmodqi4, __divmodhi4, __divmodsi4, __udivmodqi4, 
__udivmodhi4,
-  __udivmodsi4,
-
+  // Several of the runtime library functions use a special calling
+  // conv
+  LibcallsWithCC<(add __divmodqi4, __divmodhi4, __udivmodqi4,
+ __udivmodhi4),
+ AVR_BUILTIN>,
+  __divmodsi4, __udivmodsi4,
   // Trigonometric rtlib functions
   avr_sin, avr_cos)>;
 
@@ -1509,6 +1513,117 @@ def __mspabi_mpyll : RuntimeLibcallImpl;
 
 // setLibcallCallingConv(MUL_I64, CallingConv::MSP430_BUILTIN);
 
+def isMSP430 : RuntimeLibcallPredicate<"TT.getArch() == Triple::msp430">;
+
+defvar MSP430DefaultOptOut = [
+  __addsf3, __divsf3, __extendsfdf2, __truncdfsf2, __fixsfsi,
+  __fixsfdi, __fixunssfsi, __mulsf3, __eqsf2, __gesf2, __gtsf2,
+  __divhi3, __divsi3, __ashlsi3, __floatsidf, __floatsisf,
+  __ashrsi3, __modhi3, __udivsi3, __fixdfsi, __fixunssfdi,
+  __udivhi3, __umodsi3, __nesf2, __lesf2, __floatundisf,
+  __fixdfdi, __fixunsdfsi, __modsi3, __floatunsisf,
+  __fixunsdfdi, __ltsf2, __floatdisf, __floatdidf,
+  __lshrsi3, __subsf3, __umodhi3, __floatunsidf,
+  __floatundidf
+];
+
+// EABI Libcalls - EABI Section 6.2
+def MSP430SystemLibrary
+: SystemRuntimeLibrary,
+  __mspabi_cmpf__oeq,
+  __mspabi_cmpf__une,
+  __mspabi_cmpf__oge,
+  __mspabi_cmpf__olt,
+  __mspabi_cmpf__ole,
+  __mspabi_cmpf__ogt,
+
+  // Floating point arithmetic - EABI Table 8
+  LibcallsWithCC<(add __mspabi_addd,
+  __mspabi_subd,
+  __mspabi_mpyd,
+  __mspabi_divd), MSP430_BUILTIN>,
+
+  __mspabi_addf,
+  __mspabi_subf,
+  __mspabi_mpyf,
+  __mspabi_divf,
+
+  // The following are NOT implemented in libgcc
+  // __mspabi_negd,
+  // __mspabi_negf,
+
+  // Universal Integer Operations - EABI Table 9
+  __mspabi_divi,
+  __mspabi_divli,
+  LibcallsWithCC<(add __mspabi_divlli), MSP430_BUILTIN>,
+  __mspabi_divu,
+  __mspabi_divul,
+  LibcallsWithCC<(add __mspabi_divull), MSP430_BUILTIN>,
+  __mspabi_remi,
+  __mspabi_remli,
+  LibcallsWithCC<(add __mspabi_remlli), MSP430_BUILTIN>,
+  __mspabi_remu,
+  __mspabi_remul,
+  LibcallsWithCC<(add __mspabi_remull), MSP430_BUILTIN>,
+
+  // Bitwise Operations - EABI Table 10
+  // TODO: __mspabi_[srli/srai/slli] ARE implemented in libgcc
+  __msp

[llvm-branch-commits] [llvm] ARM: Add runtime libcall definitions for aebi memory functions (PR #144974)

2025-06-19 Thread Matt Arsenault via llvm-branch-commits

arsenm wrote:

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

* **#144979** https://app.graphite.dev/github/pr/llvm/llvm-project/144979?utm_source=stack-comment-icon";
 target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" 
width="10px" height="10px"/>
* **#144978** https://app.graphite.dev/github/pr/llvm/llvm-project/144978?utm_source=stack-comment-icon";
 target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" 
width="10px" height="10px"/>
* **#144977** https://app.graphite.dev/github/pr/llvm/llvm-project/144977?utm_source=stack-comment-icon";
 target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" 
width="10px" height="10px"/>
* **#144976** https://app.graphite.dev/github/pr/llvm/llvm-project/144976?utm_source=stack-comment-icon";
 target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" 
width="10px" height="10px"/>
* **#144975** https://app.graphite.dev/github/pr/llvm/llvm-project/144975?utm_source=stack-comment-icon";
 target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" 
width="10px" height="10px"/>
* **#144974** https://app.graphite.dev/github/pr/llvm/llvm-project/144974?utm_source=stack-comment-icon";
 target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" 
width="10px" height="10px"/> 👈 https://app.graphite.dev/github/pr/llvm/llvm-project/144974?utm_source=stack-comment-view-in-graphite";
 target="_blank">(View in Graphite)
* **#144973** https://app.graphite.dev/github/pr/llvm/llvm-project/144973?utm_source=stack-comment-icon";
 target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" 
width="10px" height="10px"/>
* **#144972** https://app.graphite.dev/github/pr/llvm/llvm-project/144972?utm_source=stack-comment-icon";
 target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" 
width="10px" height="10px"/>
* **#143836** https://app.graphite.dev/github/pr/llvm/llvm-project/143836?utm_source=stack-comment-icon";
 target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" 
width="10px" height="10px"/>
* `main`




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


https://github.com/llvm/llvm-project/pull/144974
___
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] AArch64: Add libcall impl declarations for __arm_sc* memory functions (PR #144977)

2025-06-19 Thread Matt Arsenault via llvm-branch-commits

arsenm wrote:

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

* **#144979** https://app.graphite.dev/github/pr/llvm/llvm-project/144979?utm_source=stack-comment-icon";
 target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" 
width="10px" height="10px"/>
* **#144978** https://app.graphite.dev/github/pr/llvm/llvm-project/144978?utm_source=stack-comment-icon";
 target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" 
width="10px" height="10px"/>
* **#144977** https://app.graphite.dev/github/pr/llvm/llvm-project/144977?utm_source=stack-comment-icon";
 target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" 
width="10px" height="10px"/> 👈 https://app.graphite.dev/github/pr/llvm/llvm-project/144977?utm_source=stack-comment-view-in-graphite";
 target="_blank">(View in Graphite)
* **#144976** https://app.graphite.dev/github/pr/llvm/llvm-project/144976?utm_source=stack-comment-icon";
 target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" 
width="10px" height="10px"/>
* **#144975** https://app.graphite.dev/github/pr/llvm/llvm-project/144975?utm_source=stack-comment-icon";
 target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" 
width="10px" height="10px"/>
* **#144974** https://app.graphite.dev/github/pr/llvm/llvm-project/144974?utm_source=stack-comment-icon";
 target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" 
width="10px" height="10px"/>
* **#144973** https://app.graphite.dev/github/pr/llvm/llvm-project/144973?utm_source=stack-comment-icon";
 target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" 
width="10px" height="10px"/>
* **#144972** https://app.graphite.dev/github/pr/llvm/llvm-project/144972?utm_source=stack-comment-icon";
 target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" 
width="10px" height="10px"/>
* **#143836** https://app.graphite.dev/github/pr/llvm/llvm-project/143836?utm_source=stack-comment-icon";
 target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" 
width="10px" height="10px"/>
* `main`




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


https://github.com/llvm/llvm-project/pull/144977
___
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] Hexagon: Add libcall declarations for special memcpy (PR #144975)

2025-06-19 Thread Matt Arsenault via llvm-branch-commits

arsenm wrote:

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

* **#144979** https://app.graphite.dev/github/pr/llvm/llvm-project/144979?utm_source=stack-comment-icon";
 target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" 
width="10px" height="10px"/>
* **#144978** https://app.graphite.dev/github/pr/llvm/llvm-project/144978?utm_source=stack-comment-icon";
 target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" 
width="10px" height="10px"/>
* **#144977** https://app.graphite.dev/github/pr/llvm/llvm-project/144977?utm_source=stack-comment-icon";
 target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" 
width="10px" height="10px"/>
* **#144976** https://app.graphite.dev/github/pr/llvm/llvm-project/144976?utm_source=stack-comment-icon";
 target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" 
width="10px" height="10px"/>
* **#144975** https://app.graphite.dev/github/pr/llvm/llvm-project/144975?utm_source=stack-comment-icon";
 target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" 
width="10px" height="10px"/> 👈 https://app.graphite.dev/github/pr/llvm/llvm-project/144975?utm_source=stack-comment-view-in-graphite";
 target="_blank">(View in Graphite)
* **#144974** https://app.graphite.dev/github/pr/llvm/llvm-project/144974?utm_source=stack-comment-icon";
 target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" 
width="10px" height="10px"/>
* **#144973** https://app.graphite.dev/github/pr/llvm/llvm-project/144973?utm_source=stack-comment-icon";
 target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" 
width="10px" height="10px"/>
* **#144972** https://app.graphite.dev/github/pr/llvm/llvm-project/144972?utm_source=stack-comment-icon";
 target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" 
width="10px" height="10px"/>
* **#143836** https://app.graphite.dev/github/pr/llvm/llvm-project/143836?utm_source=stack-comment-icon";
 target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" 
width="10px" height="10px"/>
* `main`




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


https://github.com/llvm/llvm-project/pull/144975
___
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] XCore: Declare libcalls used for align 4 memcpy (PR #144976)

2025-06-19 Thread Matt Arsenault via llvm-branch-commits

arsenm wrote:

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

* **#144979** https://app.graphite.dev/github/pr/llvm/llvm-project/144979?utm_source=stack-comment-icon";
 target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" 
width="10px" height="10px"/>
* **#144978** https://app.graphite.dev/github/pr/llvm/llvm-project/144978?utm_source=stack-comment-icon";
 target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" 
width="10px" height="10px"/>
* **#144977** https://app.graphite.dev/github/pr/llvm/llvm-project/144977?utm_source=stack-comment-icon";
 target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" 
width="10px" height="10px"/>
* **#144976** https://app.graphite.dev/github/pr/llvm/llvm-project/144976?utm_source=stack-comment-icon";
 target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" 
width="10px" height="10px"/> 👈 https://app.graphite.dev/github/pr/llvm/llvm-project/144976?utm_source=stack-comment-view-in-graphite";
 target="_blank">(View in Graphite)
* **#144975** https://app.graphite.dev/github/pr/llvm/llvm-project/144975?utm_source=stack-comment-icon";
 target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" 
width="10px" height="10px"/>
* **#144974** https://app.graphite.dev/github/pr/llvm/llvm-project/144974?utm_source=stack-comment-icon";
 target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" 
width="10px" height="10px"/>
* **#144973** https://app.graphite.dev/github/pr/llvm/llvm-project/144973?utm_source=stack-comment-icon";
 target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" 
width="10px" height="10px"/>
* **#144972** https://app.graphite.dev/github/pr/llvm/llvm-project/144972?utm_source=stack-comment-icon";
 target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" 
width="10px" height="10px"/>
* **#143836** https://app.graphite.dev/github/pr/llvm/llvm-project/143836?utm_source=stack-comment-icon";
 target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" 
width="10px" height="10px"/>
* `main`




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


https://github.com/llvm/llvm-project/pull/144976
___
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] TableGen: Generate enum for runtime libcall implementations (PR #144973)

2025-06-19 Thread Matt Arsenault via llvm-branch-commits

arsenm wrote:

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

* **#144979** https://app.graphite.dev/github/pr/llvm/llvm-project/144979?utm_source=stack-comment-icon";
 target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" 
width="10px" height="10px"/>
* **#144978** https://app.graphite.dev/github/pr/llvm/llvm-project/144978?utm_source=stack-comment-icon";
 target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" 
width="10px" height="10px"/>
* **#144977** https://app.graphite.dev/github/pr/llvm/llvm-project/144977?utm_source=stack-comment-icon";
 target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" 
width="10px" height="10px"/>
* **#144976** https://app.graphite.dev/github/pr/llvm/llvm-project/144976?utm_source=stack-comment-icon";
 target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" 
width="10px" height="10px"/>
* **#144975** https://app.graphite.dev/github/pr/llvm/llvm-project/144975?utm_source=stack-comment-icon";
 target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" 
width="10px" height="10px"/>
* **#144974** https://app.graphite.dev/github/pr/llvm/llvm-project/144974?utm_source=stack-comment-icon";
 target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" 
width="10px" height="10px"/>
* **#144973** https://app.graphite.dev/github/pr/llvm/llvm-project/144973?utm_source=stack-comment-icon";
 target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" 
width="10px" height="10px"/> 👈 https://app.graphite.dev/github/pr/llvm/llvm-project/144973?utm_source=stack-comment-view-in-graphite";
 target="_blank">(View in Graphite)
* **#144972** https://app.graphite.dev/github/pr/llvm/llvm-project/144972?utm_source=stack-comment-icon";
 target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" 
width="10px" height="10px"/>
* **#143836** https://app.graphite.dev/github/pr/llvm/llvm-project/143836?utm_source=stack-comment-icon";
 target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" 
width="10px" height="10px"/>
* `main`




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


https://github.com/llvm/llvm-project/pull/144973
___
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] XCore: Declare libcalls used for align 4 memcpy (PR #144976)

2025-06-19 Thread Matt Arsenault via llvm-branch-commits

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

This usage was hidden in XCoreSelectionDAGInfo and bypassed
the usual libcall system, so define these for later use.

>From 99598fb6ea1451223c65fd1be59ab1cc737eea8b Mon Sep 17 00:00:00 2001
From: Matt Arsenault 
Date: Mon, 16 Jun 2025 16:27:41 +0900
Subject: [PATCH] XCore: Declare libcalls used for align 4 memcpy

This usage was hidden in XCoreSelectionDAGInfo and bypassed
the usual libcall system, so define these for later use.
---
 llvm/include/llvm/IR/RuntimeLibcalls.td |  9 +
 llvm/lib/IR/RuntimeLibcalls.cpp |  3 +++
 llvm/lib/Target/XCore/XCoreSelectionDAGInfo.cpp | 13 -
 3 files changed, 20 insertions(+), 5 deletions(-)

diff --git a/llvm/include/llvm/IR/RuntimeLibcalls.td 
b/llvm/include/llvm/IR/RuntimeLibcalls.td
index 2efe823a760db..57ad6f09e8b57 100644
--- a/llvm/include/llvm/IR/RuntimeLibcalls.td
+++ b/llvm/include/llvm/IR/RuntimeLibcalls.td
@@ -371,6 +371,9 @@ def AEABI_MEMCLR8 : RuntimeLibcall;
 // Hexagon calls
 def HEXAGON_MEMCPY_LIKELY_ALIGNED_MIN32BYTES_MULT8BYTES : RuntimeLibcall;
 
+// XCore calls
+def MEMCPY_ALIGN_4 : RuntimeLibcall;
+
 //
 // Define implementation default libcalls
 //
@@ -1544,6 +1547,12 @@ def _allrem : RuntimeLibcallImpl; // 
CallingConv::X86_StdCall
 def _aullrem : RuntimeLibcallImpl; // CallingConv::X86_StdCall
 def _allmul : RuntimeLibcallImpl; // CallingConv::X86_StdCall
 
+//===--===//
+// XCore Runtime Libcalls
+//===--===//
+
+def __memcpy_4 : RuntimeLibcallImpl;
+
 
//===--===//
 // ZOS Runtime Libcalls
 
//===--===//
diff --git a/llvm/lib/IR/RuntimeLibcalls.cpp b/llvm/lib/IR/RuntimeLibcalls.cpp
index 873ee6b509e2d..0f92371f05529 100644
--- a/llvm/lib/IR/RuntimeLibcalls.cpp
+++ b/llvm/lib/IR/RuntimeLibcalls.cpp
@@ -627,4 +627,7 @@ void RuntimeLibcallsInfo::initLibcalls(const Triple &TT,
 
   if (TT.isSystemZ() && TT.isOSzOS())
 setZOSLibCallNameOverrides();
+
+  if (TT.getArch() == Triple::ArchType::xcore)
+setLibcallImpl(RTLIB::MEMCPY_ALIGN_4, RTLIB::__memcpy_4);
 }
diff --git a/llvm/lib/Target/XCore/XCoreSelectionDAGInfo.cpp 
b/llvm/lib/Target/XCore/XCoreSelectionDAGInfo.cpp
index bc34ab4319690..1bd92a2b49475 100644
--- a/llvm/lib/Target/XCore/XCoreSelectionDAGInfo.cpp
+++ b/llvm/lib/Target/XCore/XCoreSelectionDAGInfo.cpp
@@ -39,14 +39,17 @@ SDValue XCoreSelectionDAGInfo::EmitTargetCodeForMemcpy(
 Entry.Node = Src; Args.push_back(Entry);
 Entry.Node = Size; Args.push_back(Entry);
 
+const char *MemcpyAlign4Name = TLI.getLibcallName(RTLIB::MEMCPY_ALIGN_4);
+CallingConv::ID CC = TLI.getLibcallCallingConv(RTLIB::MEMCPY_ALIGN_4);
+
 TargetLowering::CallLoweringInfo CLI(DAG);
 CLI.setDebugLoc(dl)
 .setChain(Chain)
-.setLibCallee(TLI.getLibcallCallingConv(RTLIB::MEMCPY),
-  Type::getVoidTy(*DAG.getContext()),
-  DAG.getExternalSymbol(
-  "__memcpy_4", TLI.getPointerTy(DAG.getDataLayout())),
-  std::move(Args))
+.setLibCallee(
+CC, Type::getVoidTy(*DAG.getContext()),
+DAG.getExternalSymbol(MemcpyAlign4Name,
+  TLI.getPointerTy(DAG.getDataLayout())),
+std::move(Args))
 .setDiscardResult();
 
 std::pair CallResult = TLI.LowerCallTo(CLI);

___
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] AArch64: Add libcall impl declarations for __arm_sc* memory functions (PR #144977)

2025-06-19 Thread Matt Arsenault via llvm-branch-commits

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

These were bypassing the ordinary libcall emission mechanism. Make sure
we have entries in RuntimeLibcalls, which should include all possible
calls the compiler could emit.

Fixes not emitting the # prefix in the arm64ec case.

>From ec3e89d2b07a33225475a43850aba9d23ecd9c96 Mon Sep 17 00:00:00 2001
From: Matt Arsenault 
Date: Mon, 16 Jun 2025 14:56:26 +0900
Subject: [PATCH] AArch64: Add libcall impl declarations for __arm_sc* memory
 functions

These were bypassing the ordinary libcall emission mechanism. Make sure
we have entries in RuntimeLibcalls, which should include all possible
calls the compiler could emit.

Fixes not emitting the # prefix in the arm64ec case.
---
 llvm/include/llvm/IR/RuntimeLibcalls.td   |  9 +
 llvm/lib/IR/RuntimeLibcalls.cpp   | 11 ++-
 .../Target/AArch64/AArch64SelectionDAGInfo.cpp| 15 +++
 llvm/test/CodeGen/AArch64/arm64ec-builtins.ll |  9 +++--
 4 files changed, 29 insertions(+), 15 deletions(-)

diff --git a/llvm/include/llvm/IR/RuntimeLibcalls.td 
b/llvm/include/llvm/IR/RuntimeLibcalls.td
index 57ad6f09e8b57..1d9f02dcf8ba8 100644
--- a/llvm/include/llvm/IR/RuntimeLibcalls.td
+++ b/llvm/include/llvm/IR/RuntimeLibcalls.td
@@ -357,6 +357,11 @@ multiclass LibmLongDoubleLibCall;
 }
 
+// AArch64 calls
+def SC_MEMCPY : RuntimeLibcall;
+def SC_MEMMOVE : RuntimeLibcall;
+def SC_MEMSET : RuntimeLibcall;
+
 // ARM EABI calls
 def AEABI_MEMCPY4 : RuntimeLibcall; // Align 4
 def AEABI_MEMCPY8 : RuntimeLibcall; // Align 8
@@ -985,6 +990,10 @@ defset list AArch64LibcallImpls = {
 defm __aarch64_ldeor#MemSize
 : AtomicOrderSizeLibcallImpl<"OUTLINE_ATOMIC_LDEOR"#MemSize>;
   }
+
+  def __arm_sc_memcpy : RuntimeLibcallImpl;
+  def __arm_sc_memmove : RuntimeLibcallImpl;
+  def __arm_sc_memset : RuntimeLibcallImpl;
 }
 
 foreach libcall = AArch64LibcallImpls in {
diff --git a/llvm/lib/IR/RuntimeLibcalls.cpp b/llvm/lib/IR/RuntimeLibcalls.cpp
index 0f92371f05529..67f872b4574b1 100644
--- a/llvm/lib/IR/RuntimeLibcalls.cpp
+++ b/llvm/lib/IR/RuntimeLibcalls.cpp
@@ -521,8 +521,17 @@ void RuntimeLibcallsInfo::initLibcalls(const Triple &TT,
   }
 
   if (TT.isAArch64()) {
-if (TT.isWindowsArm64EC())
+if (TT.isWindowsArm64EC()) {
   setWindowsArm64LibCallNameOverrides();
+  setLibcallImpl(RTLIB::SC_MEMCPY, RTLIB::arm64ec___arm_sc_memcpy);
+  setLibcallImpl(RTLIB::SC_MEMMOVE, RTLIB::arm64ec___arm_sc_memmove);
+  setLibcallImpl(RTLIB::SC_MEMSET, RTLIB::arm64ec___arm_sc_memset);
+} else {
+  setLibcallImpl(RTLIB::SC_MEMCPY, RTLIB::__arm_sc_memcpy);
+  setLibcallImpl(RTLIB::SC_MEMMOVE, RTLIB::__arm_sc_memmove);
+  setLibcallImpl(RTLIB::SC_MEMSET, RTLIB::__arm_sc_memset);
+}
+
 setAArch64LibcallNames(*this, TT);
   } else if (TT.isARM() || TT.isThumb()) {
 setARMLibcallNames(*this, TT, FloatABI, EABIVersion);
diff --git a/llvm/lib/Target/AArch64/AArch64SelectionDAGInfo.cpp 
b/llvm/lib/Target/AArch64/AArch64SelectionDAGInfo.cpp
index 90f6fc2ea664b..d719f234b27f7 100644
--- a/llvm/lib/Target/AArch64/AArch64SelectionDAGInfo.cpp
+++ b/llvm/lib/Target/AArch64/AArch64SelectionDAGInfo.cpp
@@ -164,35 +164,34 @@ SDValue 
AArch64SelectionDAGInfo::EmitStreamingCompatibleMemLibCall(
   const AArch64Subtarget &STI =
   DAG.getMachineFunction().getSubtarget();
   const AArch64TargetLowering *TLI = STI.getTargetLowering();
-  SDValue Symbol;
   TargetLowering::ArgListEntry DstEntry;
   DstEntry.Ty = PointerType::getUnqual(*DAG.getContext());
   DstEntry.Node = Dst;
   TargetLowering::ArgListTy Args;
   Args.push_back(DstEntry);
-  EVT PointerVT = TLI->getPointerTy(DAG.getDataLayout());
 
+  RTLIB::Libcall NewLC;
   switch (LC) {
   case RTLIB::MEMCPY: {
+NewLC = RTLIB::SC_MEMCPY;
 TargetLowering::ArgListEntry Entry;
 Entry.Ty = PointerType::getUnqual(*DAG.getContext());
-Symbol = DAG.getExternalSymbol("__arm_sc_memcpy", PointerVT);
 Entry.Node = Src;
 Args.push_back(Entry);
 break;
   }
   case RTLIB::MEMMOVE: {
+NewLC = RTLIB::SC_MEMMOVE;
 TargetLowering::ArgListEntry Entry;
 Entry.Ty = PointerType::getUnqual(*DAG.getContext());
-Symbol = DAG.getExternalSymbol("__arm_sc_memmove", PointerVT);
 Entry.Node = Src;
 Args.push_back(Entry);
 break;
   }
   case RTLIB::MEMSET: {
+NewLC = RTLIB::SC_MEMSET;
 TargetLowering::ArgListEntry Entry;
 Entry.Ty = Type::getInt32Ty(*DAG.getContext());
-Symbol = DAG.getExternalSymbol("__arm_sc_memset", PointerVT);
 Src = DAG.getZExtOrTrunc(Src, DL, MVT::i32);
 Entry.Node = Src;
 Args.push_back(Entry);
@@ -202,17 +201,17 @@ SDValue 
AArch64SelectionDAGInfo::EmitStreamingCompatibleMemLibCall(
 return SDValue();
   }
 
+  EVT PointerVT = TLI->getPointerTy(DAG.getDataLayout());
+  SDValue Symbol = DAG.getExternalSymbol(TLI->getLibcallName(NewLC), 
PointerVT);
   TargetLowering::ArgListEntry Siz

[llvm-branch-commits] [llvm] ARM: Add runtime libcall definitions for aebi memory functions (PR #144974)

2025-06-19 Thread Matt Arsenault via llvm-branch-commits

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

Fix bypassing ordinary RuntimeLibcalls APIs for cases handled
in ARMSelectionDAGInfo

>From bdbc320f70d3fd80fd4d50f89ec4cdbe5d02b7db Mon Sep 17 00:00:00 2001
From: Matt Arsenault 
Date: Mon, 16 Jun 2025 15:50:24 +0900
Subject: [PATCH] ARM: Add runtime libcall definitions for eabi memory
 functions

Fix bypassing ordinary RuntimeLibcalls APIs for cases handled
in ARMSelectionDAGInfo
---
 llvm/include/llvm/IR/RuntimeLibcalls.td | 23 +
 llvm/lib/Target/ARM/ARMISelLowering.cpp | 17 +++
 llvm/lib/Target/ARM/ARMSelectionDAGInfo.cpp | 18 +---
 3 files changed, 50 insertions(+), 8 deletions(-)

diff --git a/llvm/include/llvm/IR/RuntimeLibcalls.td 
b/llvm/include/llvm/IR/RuntimeLibcalls.td
index c910fce2edd80..71efecdf082af 100644
--- a/llvm/include/llvm/IR/RuntimeLibcalls.td
+++ b/llvm/include/llvm/IR/RuntimeLibcalls.td
@@ -357,6 +357,17 @@ multiclass LibmLongDoubleLibCall;
 }
 
+// ARM EABI calls
+def AEABI_MEMCPY4 : RuntimeLibcall; // Align 4
+def AEABI_MEMCPY8 : RuntimeLibcall; // Align 8
+def AEABI_MEMMOVE4 : RuntimeLibcall;
+def AEABI_MEMMOVE8 : RuntimeLibcall;
+def AEABI_MEMSET4 : RuntimeLibcall;
+def AEABI_MEMSET8 : RuntimeLibcall;
+def AEABI_MEMCLR : RuntimeLibcall;
+def AEABI_MEMCLR4 : RuntimeLibcall;
+def AEABI_MEMCLR8 : RuntimeLibcall;
+
 //
 // Define implementation default libcalls
 //
@@ -1134,8 +1145,20 @@ def __aeabi_uidivmod : RuntimeLibcallImpl; 
//  CallingConv::ARM_AAP
 // Memory operations
 // RTABI chapter 4.3.4
 def __aeabi_memcpy : RuntimeLibcallImpl; // CallingConv::ARM_AAPCS
+def __aeabi_memcpy4 : RuntimeLibcallImpl;
+def __aeabi_memcpy8 : RuntimeLibcallImpl;
+
 def __aeabi_memmove : RuntimeLibcallImpl; // CallingConv::ARM_AAPCS
+def __aeabi_memmove4 : RuntimeLibcallImpl;
+def __aeabi_memmove8 : RuntimeLibcallImpl;
+
 def __aeabi_memset : RuntimeLibcallImpl; // CallingConv::ARM_AAPCS
+def __aeabi_memset4 : RuntimeLibcallImpl;
+def __aeabi_memset8 : RuntimeLibcallImpl;
+
+def __aeabi_memclr : RuntimeLibcallImpl;
+def __aeabi_memclr4 : RuntimeLibcallImpl;
+def __aeabi_memclr8 : RuntimeLibcallImpl;
 
 // isTargetWindows()
 def __stoi64 : RuntimeLibcallImpl; // 
CallingConv::ARM_AAPCS_VFP
diff --git a/llvm/lib/Target/ARM/ARMISelLowering.cpp 
b/llvm/lib/Target/ARM/ARMISelLowering.cpp
index 81b535e19bc71..478791699df88 100644
--- a/llvm/lib/Target/ARM/ARMISelLowering.cpp
+++ b/llvm/lib/Target/ARM/ARMISelLowering.cpp
@@ -704,6 +704,23 @@ ARMTargetLowering::ARMTargetLowering(const TargetMachine 
&TM_,
   {RTLIB::MEMCPY, RTLIB::__aeabi_memcpy, CallingConv::ARM_AAPCS},
   {RTLIB::MEMMOVE, RTLIB::__aeabi_memmove, CallingConv::ARM_AAPCS},
   {RTLIB::MEMSET, RTLIB::__aeabi_memset, CallingConv::ARM_AAPCS},
+  {RTLIB::AEABI_MEMCPY4, RTLIB::__aeabi_memcpy4,
+   CallingConv::ARM_AAPCS},
+  {RTLIB::AEABI_MEMCPY8, RTLIB::__aeabi_memcpy8,
+   CallingConv::ARM_AAPCS},
+  {RTLIB::AEABI_MEMMOVE4, RTLIB::__aeabi_memmove4,
+   CallingConv::ARM_AAPCS},
+  {RTLIB::AEABI_MEMMOVE8, RTLIB::__aeabi_memmove8,
+   CallingConv::ARM_AAPCS},
+  {RTLIB::AEABI_MEMSET4, RTLIB::__aeabi_memset4,
+   CallingConv::ARM_AAPCS},
+  {RTLIB::AEABI_MEMSET8, RTLIB::__aeabi_memset8,
+   CallingConv::ARM_AAPCS},
+  {RTLIB::AEABI_MEMCLR, RTLIB::__aeabi_memclr, CallingConv::ARM_AAPCS},
+  {RTLIB::AEABI_MEMCLR4, RTLIB::__aeabi_memclr4,
+   CallingConv::ARM_AAPCS},
+  {RTLIB::AEABI_MEMCLR8, RTLIB::__aeabi_memclr8,
+   CallingConv::ARM_AAPCS},
   };
 
   for (const auto &LC : MemOpsLibraryCalls) {
diff --git a/llvm/lib/Target/ARM/ARMSelectionDAGInfo.cpp 
b/llvm/lib/Target/ARM/ARMSelectionDAGInfo.cpp
index 77f4782699c96..b4677a8bfb035 100644
--- a/llvm/lib/Target/ARM/ARMSelectionDAGInfo.cpp
+++ b/llvm/lib/Target/ARM/ARMSelectionDAGInfo.cpp
@@ -121,18 +121,20 @@ SDValue ARMSelectionDAGInfo::EmitSpecializedLibcall(
 Args.push_back(Entry);
   }
 
-  char const *FunctionNames[4][3] = {
-{ "__aeabi_memcpy",  "__aeabi_memcpy4",  "__aeabi_memcpy8"  },
-{ "__aeabi_memmove", "__aeabi_memmove4", "__aeabi_memmove8" },
-{ "__aeabi_memset",  "__aeabi_memset4",  "__aeabi_memset8"  },
-{ "__aeabi_memclr",  "__aeabi_memclr4",  "__aeabi_memclr8"  }
-  };
+  static const RTLIB::Libcall FunctionImpls[4][3] = {
+  {RTLIB::MEMCPY, RTLIB::AEABI_MEMCPY4, RTLIB::AEABI_MEMCPY8},
+  {RTLIB::MEMMOVE, RTLIB::AEABI_MEMMOVE4, RTLIB::AEABI_MEMMOVE8},
+  {RTLIB::MEMSET, RTLIB::AEABI_MEMSET4, RTLIB::AEABI_MEMSET8},
+  {RTLIB::AEABI_MEMCLR, RTLIB::AEABI_MEMCLR4, RTLIB::AEABI_MEMCLR8}};
+
+  RTLIB::Libcall NewLC = FunctionImpls[AEABILibcall][AlignVariant];
+
   TargetLowering::CallLoweringInfo CLI(DAG);
   CLI.

[llvm-branch-commits] [llvm] Hexagon: Add libcall declarations for special memcpy (PR #144975)

2025-06-19 Thread Matt Arsenault via llvm-branch-commits

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

HexagonSelectionDAGInfo was bypassing the ordinary RuntimeLibcallInfo
handling for this case, so define a libcall for it and use it.

>From a845b0e8b095dad7ce55d0a64b0b57b515602144 Mon Sep 17 00:00:00 2001
From: Matt Arsenault 
Date: Mon, 16 Jun 2025 16:14:09 +0900
Subject: [PATCH] Hexagon: Add libcall declarations for special memcpy

HexagonSelectionDAGInfo was bypassing the ordinary RuntimeLibcallInfo
handling for this case, so define a libcall for it and use it.
---
 llvm/include/llvm/IR/RuntimeLibcalls.td |  6 ++
 llvm/lib/IR/RuntimeLibcalls.cpp |  4 
 llvm/lib/Target/Hexagon/HexagonSelectionDAGInfo.cpp | 10 ++
 3 files changed, 16 insertions(+), 4 deletions(-)

diff --git a/llvm/include/llvm/IR/RuntimeLibcalls.td 
b/llvm/include/llvm/IR/RuntimeLibcalls.td
index 71efecdf082af..2efe823a760db 100644
--- a/llvm/include/llvm/IR/RuntimeLibcalls.td
+++ b/llvm/include/llvm/IR/RuntimeLibcalls.td
@@ -368,6 +368,9 @@ def AEABI_MEMCLR : RuntimeLibcall;
 def AEABI_MEMCLR4 : RuntimeLibcall;
 def AEABI_MEMCLR8 : RuntimeLibcall;
 
+// Hexagon calls
+def HEXAGON_MEMCPY_LIKELY_ALIGNED_MIN32BYTES_MULT8BYTES : RuntimeLibcall;
+
 //
 // Define implementation default libcalls
 //
@@ -1247,6 +1250,9 @@ def __hexagon_fast2_sqrtf : RuntimeLibcallImpl;
 // This is the only fast library function for sqrtd.
 def __hexagon_fast2_sqrtdf2 : RuntimeLibcallImpl;
 
+def __hexagon_memcpy_likely_aligned_min32bytes_mult8bytes
+: RuntimeLibcallImpl;
+
 
//===--===//
 // Mips16 Runtime Libcalls
 
//===--===//
diff --git a/llvm/lib/IR/RuntimeLibcalls.cpp b/llvm/lib/IR/RuntimeLibcalls.cpp
index 5fccb23e6c5ff..873ee6b509e2d 100644
--- a/llvm/lib/IR/RuntimeLibcalls.cpp
+++ b/llvm/lib/IR/RuntimeLibcalls.cpp
@@ -616,6 +616,10 @@ void RuntimeLibcallsInfo::initLibcalls(const Triple &TT,
   setLibcallImpl(RTLIB::SQRT_F32, RTLIB::__hexagon_fast2_sqrtf);
 else
   setLibcallImpl(RTLIB::SQRT_F32, RTLIB::__hexagon_sqrtf);
+
+setLibcallImpl(
+RTLIB::HEXAGON_MEMCPY_LIKELY_ALIGNED_MIN32BYTES_MULT8BYTES,
+RTLIB::__hexagon_memcpy_likely_aligned_min32bytes_mult8bytes);
   }
 
   if (TT.getArch() == Triple::ArchType::msp430)
diff --git a/llvm/lib/Target/Hexagon/HexagonSelectionDAGInfo.cpp 
b/llvm/lib/Target/Hexagon/HexagonSelectionDAGInfo.cpp
index 1b724e8fcae91..610a81fe45c2f 100644
--- a/llvm/lib/Target/Hexagon/HexagonSelectionDAGInfo.cpp
+++ b/llvm/lib/Target/Hexagon/HexagonSelectionDAGInfo.cpp
@@ -41,18 +41,20 @@ SDValue HexagonSelectionDAGInfo::EmitTargetCodeForMemcpy(
   Entry.Node = Size;
   Args.push_back(Entry);
 
-  const char *SpecialMemcpyName =
-  "__hexagon_memcpy_likely_aligned_min32bytes_mult8bytes";
+  const char *SpecialMemcpyName = TLI.getLibcallName(
+  RTLIB::HEXAGON_MEMCPY_LIKELY_ALIGNED_MIN32BYTES_MULT8BYTES);
   const MachineFunction &MF = DAG.getMachineFunction();
   bool LongCalls = MF.getSubtarget().useLongCalls();
   unsigned Flags = LongCalls ? HexagonII::HMOTF_ConstExtended : 0;
 
+  CallingConv::ID CC = TLI.getLibcallCallingConv(
+  RTLIB::HEXAGON_MEMCPY_LIKELY_ALIGNED_MIN32BYTES_MULT8BYTES);
+
   TargetLowering::CallLoweringInfo CLI(DAG);
   CLI.setDebugLoc(dl)
   .setChain(Chain)
   .setLibCallee(
-  TLI.getLibcallCallingConv(RTLIB::MEMCPY),
-  Type::getVoidTy(*DAG.getContext()),
+  CC, Type::getVoidTy(*DAG.getContext()),
   DAG.getTargetExternalSymbol(
   SpecialMemcpyName, TLI.getPointerTy(DAG.getDataLayout()), Flags),
   std::move(Args))

___
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] TableGen: Add runtime libcall backend (PR #144972)

2025-06-19 Thread via llvm-branch-commits

llvmbot wrote:




@llvm/pr-subscribers-llvm-ir

Author: Matt Arsenault (arsenm)


Changes

Replace RuntimeLibcalls.def with a tablegenerated version. This
is in preparation for splitting RuntimeLibcalls into two components.
For now match the existing functionality.

---

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


13 Files Affected:

- (modified) llvm/include/llvm/IR/CMakeLists.txt (+3) 
- (removed) llvm/include/llvm/IR/RuntimeLibcalls.def (-701) 
- (modified) llvm/include/llvm/IR/RuntimeLibcalls.h (+20-16) 
- (added) llvm/include/llvm/IR/RuntimeLibcalls.td (+1054) 
- (added) llvm/include/llvm/IR/RuntimeLibcallsImpl.td (+32) 
- (modified) llvm/include/module.modulemap (-1) 
- (modified) llvm/lib/IR/RuntimeLibcalls.cpp (+31-77) 
- (removed) llvm/lib/IR/ZOSLibcallNames.def (-100) 
- (modified) llvm/lib/Object/IRSymtab.cpp (+1-1) 
- (added) llvm/test/TableGen/RuntimeLibcallEmitter.td (+40) 
- (modified) llvm/utils/TableGen/Basic/CMakeLists.txt (+1) 
- (added) llvm/utils/TableGen/Basic/RuntimeLibcallsEmitter.cpp (+305) 
- (modified) llvm/utils/gn/secondary/llvm/utils/TableGen/Basic/BUILD.gn (+1) 


``diff
diff --git a/llvm/include/llvm/IR/CMakeLists.txt 
b/llvm/include/llvm/IR/CMakeLists.txt
index 468d663796ed4..c5c4cc4d21b84 100644
--- a/llvm/include/llvm/IR/CMakeLists.txt
+++ b/llvm/include/llvm/IR/CMakeLists.txt
@@ -1,6 +1,9 @@
 set(LLVM_TARGET_DEFINITIONS Attributes.td)
 tablegen(LLVM Attributes.inc -gen-attrs)
 
+set(LLVM_TARGET_DEFINITIONS RuntimeLibcalls.td)
+tablegen(LLVM RuntimeLibcalls.inc -gen-runtime-libcalls)
+
 set(LLVM_TARGET_DEFINITIONS Intrinsics.td)
 tablegen(LLVM IntrinsicImpl.inc -gen-intrinsic-impl)
 tablegen(LLVM IntrinsicEnums.inc -gen-intrinsic-enums)
diff --git a/llvm/include/llvm/IR/RuntimeLibcalls.def 
b/llvm/include/llvm/IR/RuntimeLibcalls.def
deleted file mode 100644
index 247643525ff48..0
--- a/llvm/include/llvm/IR/RuntimeLibcalls.def
+++ /dev/null
@@ -1,701 +0,0 @@
-//===-- llvm/RuntimeLibcalls.def - File that describes libcalls -*- C++ 
-*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===--===//
-//
-// This file defines all of the runtime library calls the backend can emit.
-// The various long double types cannot be merged, because 80-bit library
-// functions use "xf" and 128-bit use "tf".
-//
-// When adding PPCF128 functions here, note that their names generally need
-// to be overridden for Darwin with the xxx$LDBL128 form.  See
-// PPCISelLowering.cpp.
-//
-//===--===//
-
-// NOTE: NO INCLUDE GUARD DESIRED!
-
-// Provide definitions of macros so that users of this file do not have to
-// define everything to use it...
-
-// Declare the enumerator for each libcall, along with its default name. Some
-// libcalls have different names on particular OSes or architectures. These
-// are set in InitLibcalls() in TargetLoweringBase.cpp and/or by targets
-// using TargetLoweringBase::setLibcallName()
-#ifndef HANDLE_LIBCALL
-#error "HANDLE_LIBCALL must be defined"
-#endif
-
-// Integer
-HANDLE_LIBCALL(SHL_I16, "__ashlhi3")
-HANDLE_LIBCALL(SHL_I32, "__ashlsi3")
-HANDLE_LIBCALL(SHL_I64, "__ashldi3")
-HANDLE_LIBCALL(SHL_I128, "__ashlti3")
-HANDLE_LIBCALL(SRL_I16, "__lshrhi3")
-HANDLE_LIBCALL(SRL_I32, "__lshrsi3")
-HANDLE_LIBCALL(SRL_I64, "__lshrdi3")
-HANDLE_LIBCALL(SRL_I128, "__lshrti3")
-HANDLE_LIBCALL(SRA_I16, "__ashrhi3")
-HANDLE_LIBCALL(SRA_I32, "__ashrsi3")
-HANDLE_LIBCALL(SRA_I64, "__ashrdi3")
-HANDLE_LIBCALL(SRA_I128, "__ashrti3")
-HANDLE_LIBCALL(MUL_I8, "__mulqi3")
-HANDLE_LIBCALL(MUL_I16, "__mulhi3")
-HANDLE_LIBCALL(MUL_I32, "__mulsi3")
-HANDLE_LIBCALL(MUL_I64, "__muldi3")
-HANDLE_LIBCALL(MUL_I128, "__multi3")
-HANDLE_LIBCALL(MULO_I32, "__mulosi4")
-HANDLE_LIBCALL(MULO_I64, "__mulodi4")
-HANDLE_LIBCALL(MULO_I128, "__muloti4")
-HANDLE_LIBCALL(SDIV_I8, "__divqi3")
-HANDLE_LIBCALL(SDIV_I16, "__divhi3")
-HANDLE_LIBCALL(SDIV_I32, "__divsi3")
-HANDLE_LIBCALL(SDIV_I64, "__divdi3")
-HANDLE_LIBCALL(SDIV_I128, "__divti3")
-HANDLE_LIBCALL(UDIV_I8, "__udivqi3")
-HANDLE_LIBCALL(UDIV_I16, "__udivhi3")
-HANDLE_LIBCALL(UDIV_I32, "__udivsi3")
-HANDLE_LIBCALL(UDIV_I64, "__udivdi3")
-HANDLE_LIBCALL(UDIV_I128, "__udivti3")
-HANDLE_LIBCALL(SREM_I8, "__modqi3")
-HANDLE_LIBCALL(SREM_I16, "__modhi3")
-HANDLE_LIBCALL(SREM_I32, "__modsi3")
-HANDLE_LIBCALL(SREM_I64, "__moddi3")
-HANDLE_LIBCALL(SREM_I128, "__modti3")
-HANDLE_LIBCALL(UREM_I8, "__umodqi3")
-HANDLE_LIBCALL(UREM_I16, "__umodhi3")
-HANDLE_LIBCALL(UREM_I32, "__umodsi3")
-HANDLE_LIBCALL(UREM_I64, "__umoddi3")
-HANDLE_LIBCALL(UREM_I128, "__umodti3")
-HANDLE_LIBCALL(SDIVREM_I8, LIBCALL_NO_NAME)
-HANDLE_LIBCALL(SDIVREM_I16, LIBCALL_NO_NAME)

[llvm-branch-commits] [llvm] TableGen: Allow defining sets of runtime libraries (PR #144978)

2025-06-19 Thread Matt Arsenault via llvm-branch-commits

arsenm wrote:

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

* **#144980** https://app.graphite.dev/github/pr/llvm/llvm-project/144980?utm_source=stack-comment-icon";
 target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" 
width="10px" height="10px"/>
* **#144979** https://app.graphite.dev/github/pr/llvm/llvm-project/144979?utm_source=stack-comment-icon";
 target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" 
width="10px" height="10px"/>
* **#144978** https://app.graphite.dev/github/pr/llvm/llvm-project/144978?utm_source=stack-comment-icon";
 target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" 
width="10px" height="10px"/> 👈 https://app.graphite.dev/github/pr/llvm/llvm-project/144978?utm_source=stack-comment-view-in-graphite";
 target="_blank">(View in Graphite)
* **#144977** https://app.graphite.dev/github/pr/llvm/llvm-project/144977?utm_source=stack-comment-icon";
 target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" 
width="10px" height="10px"/>
* **#144976** https://app.graphite.dev/github/pr/llvm/llvm-project/144976?utm_source=stack-comment-icon";
 target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" 
width="10px" height="10px"/>
* **#144975** https://app.graphite.dev/github/pr/llvm/llvm-project/144975?utm_source=stack-comment-icon";
 target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" 
width="10px" height="10px"/>
* **#144974** https://app.graphite.dev/github/pr/llvm/llvm-project/144974?utm_source=stack-comment-icon";
 target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" 
width="10px" height="10px"/>
* **#144973** https://app.graphite.dev/github/pr/llvm/llvm-project/144973?utm_source=stack-comment-icon";
 target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" 
width="10px" height="10px"/>
* **#144972** https://app.graphite.dev/github/pr/llvm/llvm-project/144972?utm_source=stack-comment-icon";
 target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" 
width="10px" height="10px"/>
* **#143836** https://app.graphite.dev/github/pr/llvm/llvm-project/143836?utm_source=stack-comment-icon";
 target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" 
width="10px" height="10px"/>
* `main`




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


https://github.com/llvm/llvm-project/pull/144978
___
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] TableGen: Handle setting runtime libcall calling conventions (PR #144980)

2025-06-19 Thread Matt Arsenault via llvm-branch-commits

arsenm wrote:

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

* **#144980** https://app.graphite.dev/github/pr/llvm/llvm-project/144980?utm_source=stack-comment-icon";
 target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" 
width="10px" height="10px"/> 👈 https://app.graphite.dev/github/pr/llvm/llvm-project/144980?utm_source=stack-comment-view-in-graphite";
 target="_blank">(View in Graphite)
* **#144979** https://app.graphite.dev/github/pr/llvm/llvm-project/144979?utm_source=stack-comment-icon";
 target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" 
width="10px" height="10px"/>
* **#144978** https://app.graphite.dev/github/pr/llvm/llvm-project/144978?utm_source=stack-comment-icon";
 target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" 
width="10px" height="10px"/>
* **#144977** https://app.graphite.dev/github/pr/llvm/llvm-project/144977?utm_source=stack-comment-icon";
 target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" 
width="10px" height="10px"/>
* **#144976** https://app.graphite.dev/github/pr/llvm/llvm-project/144976?utm_source=stack-comment-icon";
 target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" 
width="10px" height="10px"/>
* **#144975** https://app.graphite.dev/github/pr/llvm/llvm-project/144975?utm_source=stack-comment-icon";
 target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" 
width="10px" height="10px"/>
* **#144974** https://app.graphite.dev/github/pr/llvm/llvm-project/144974?utm_source=stack-comment-icon";
 target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" 
width="10px" height="10px"/>
* **#144973** https://app.graphite.dev/github/pr/llvm/llvm-project/144973?utm_source=stack-comment-icon";
 target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" 
width="10px" height="10px"/>
* **#144972** https://app.graphite.dev/github/pr/llvm/llvm-project/144972?utm_source=stack-comment-icon";
 target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" 
width="10px" height="10px"/>
* **#143836** https://app.graphite.dev/github/pr/llvm/llvm-project/143836?utm_source=stack-comment-icon";
 target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" 
width="10px" height="10px"/>
* `main`




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


https://github.com/llvm/llvm-project/pull/144980
___
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] RuntimeLibcalls: Associate calling convention with libcall impls (PR #144979)

2025-06-19 Thread Matt Arsenault via llvm-branch-commits

arsenm wrote:

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

* **#144980** https://app.graphite.dev/github/pr/llvm/llvm-project/144980?utm_source=stack-comment-icon";
 target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" 
width="10px" height="10px"/>
* **#144979** https://app.graphite.dev/github/pr/llvm/llvm-project/144979?utm_source=stack-comment-icon";
 target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" 
width="10px" height="10px"/> 👈 https://app.graphite.dev/github/pr/llvm/llvm-project/144979?utm_source=stack-comment-view-in-graphite";
 target="_blank">(View in Graphite)
* **#144978** https://app.graphite.dev/github/pr/llvm/llvm-project/144978?utm_source=stack-comment-icon";
 target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" 
width="10px" height="10px"/>
* **#144977** https://app.graphite.dev/github/pr/llvm/llvm-project/144977?utm_source=stack-comment-icon";
 target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" 
width="10px" height="10px"/>
* **#144976** https://app.graphite.dev/github/pr/llvm/llvm-project/144976?utm_source=stack-comment-icon";
 target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" 
width="10px" height="10px"/>
* **#144975** https://app.graphite.dev/github/pr/llvm/llvm-project/144975?utm_source=stack-comment-icon";
 target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" 
width="10px" height="10px"/>
* **#144974** https://app.graphite.dev/github/pr/llvm/llvm-project/144974?utm_source=stack-comment-icon";
 target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" 
width="10px" height="10px"/>
* **#144973** https://app.graphite.dev/github/pr/llvm/llvm-project/144973?utm_source=stack-comment-icon";
 target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" 
width="10px" height="10px"/>
* **#144972** https://app.graphite.dev/github/pr/llvm/llvm-project/144972?utm_source=stack-comment-icon";
 target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" 
width="10px" height="10px"/>
* **#143836** https://app.graphite.dev/github/pr/llvm/llvm-project/143836?utm_source=stack-comment-icon";
 target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" 
width="10px" height="10px"/>
* `main`




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


https://github.com/llvm/llvm-project/pull/144979
___
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] TableGen: Allow defining sets of runtime libraries (PR #144978)

2025-06-19 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 HEAD~1 HEAD --extensions cpp,h -- 
llvm/include/llvm/IR/RuntimeLibcalls.h llvm/lib/IR/RuntimeLibcalls.cpp 
llvm/utils/TableGen/Basic/RuntimeLibcallsEmitter.cpp
``





View the diff from clang-format here.


``diff
diff --git a/llvm/utils/TableGen/Basic/RuntimeLibcallsEmitter.cpp 
b/llvm/utils/TableGen/Basic/RuntimeLibcallsEmitter.cpp
index 30fcca47a..a4b6c8d7f 100644
--- a/llvm/utils/TableGen/Basic/RuntimeLibcallsEmitter.cpp
+++ b/llvm/utils/TableGen/Basic/RuntimeLibcallsEmitter.cpp
@@ -349,9 +349,8 @@ void 
RuntimeLibcallEmitter::emitSystemRuntimeLibrarySetCalls(
 SetTheory Sets;
 
 DenseMap> Func2Preds;
-Sets.addExpander(
-"LibcallImpls",
-std::make_unique(*this, Func2Preds));
+Sets.addExpander("LibcallImpls", 
std::make_unique(
+ *this, Func2Preds));
 
 const SetTheory::RecVec *Elements =
 Sets.expand(R->getValueAsDef("MemberList"));

``




https://github.com/llvm/llvm-project/pull/144978
___
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] TableGen: Add runtime libcall backend (PR #144972)

2025-06-19 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 HEAD~1 HEAD --extensions cpp,h -- 
llvm/utils/TableGen/Basic/RuntimeLibcallsEmitter.cpp 
llvm/include/llvm/IR/RuntimeLibcalls.h llvm/lib/IR/RuntimeLibcalls.cpp 
llvm/lib/Object/IRSymtab.cpp
``





View the diff from clang-format here.


``diff
diff --git a/llvm/include/llvm/IR/RuntimeLibcalls.h 
b/llvm/include/llvm/IR/RuntimeLibcalls.h
index e063076fa..fdded7694 100644
--- a/llvm/include/llvm/IR/RuntimeLibcalls.h
+++ b/llvm/include/llvm/IR/RuntimeLibcalls.h
@@ -107,8 +107,8 @@ struct RuntimeLibcallsInfo {
   }
 
 private:
-  static const char *const
-  DefaultLibcallRoutineNames[RTLIB::UNKNOWN_LIBCALL + 1];
+  static const char
+  *const DefaultLibcallRoutineNames[RTLIB::UNKNOWN_LIBCALL + 1];
 
   /// Stores the name each libcall.
   const char *LibcallRoutineNames[RTLIB::UNKNOWN_LIBCALL + 1] = {nullptr};

``




https://github.com/llvm/llvm-project/pull/144972
___
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] TableGen: Add runtime libcall backend (PR #144972)

2025-06-19 Thread Matt Arsenault via llvm-branch-commits

https://github.com/arsenm ready_for_review 
https://github.com/llvm/llvm-project/pull/144972
___
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] Hexagon: Add libcall declarations for special memcpy (PR #144975)

2025-06-19 Thread Matt Arsenault via llvm-branch-commits

https://github.com/arsenm ready_for_review 
https://github.com/llvm/llvm-project/pull/144975
___
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] TableGen: Generate enum for runtime libcall implementations (PR #144973)

2025-06-19 Thread via llvm-branch-commits

llvmbot wrote:




@llvm/pr-subscribers-llvm-ir

Author: Matt Arsenault (arsenm)


Changes

Work towards separating the ABI existence of libcalls vs. the
lowering selection. Set libcall selection through enums, rather
than through raw string names.

---

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


12 Files Affected:

- (modified) llvm/include/llvm/CodeGen/TargetLowering.h (+2-7) 
- (modified) llvm/include/llvm/IR/RuntimeLibcalls.h (+38-17) 
- (modified) llvm/include/llvm/IR/RuntimeLibcalls.td (+561-1) 
- (modified) llvm/lib/IR/RuntimeLibcalls.cpp (+268-263) 
- (modified) llvm/lib/LTO/LTO.cpp (+8-2) 
- (modified) llvm/lib/Object/IRSymtab.cpp (+3-3) 
- (modified) llvm/lib/Target/ARM/ARMISelLowering.cpp (+108-102) 
- (modified) llvm/lib/Target/MSP430/MSP430ISelLowering.cpp (+32-32) 
- (modified) llvm/lib/Target/Mips/Mips16ISelLowering.cpp (+49-40) 
- (modified) llvm/lib/Target/Sparc/SparcISelLowering.cpp (+43-43) 
- (modified) llvm/test/TableGen/RuntimeLibcallEmitter.td (+45-8) 
- (modified) llvm/utils/TableGen/Basic/RuntimeLibcallsEmitter.cpp (+60-20) 


``diff
diff --git a/llvm/include/llvm/CodeGen/TargetLowering.h 
b/llvm/include/llvm/CodeGen/TargetLowering.h
index 727526055e592..69ae4f80297d5 100644
--- a/llvm/include/llvm/CodeGen/TargetLowering.h
+++ b/llvm/include/llvm/CodeGen/TargetLowering.h
@@ -3558,13 +3558,8 @@ class LLVM_ABI TargetLoweringBase {
 return nullptr;
   }
 
-  /// Rename the default libcall routine name for the specified libcall.
-  void setLibcallName(RTLIB::Libcall Call, const char *Name) {
-Libcalls.setLibcallName(Call, Name);
-  }
-
-  void setLibcallName(ArrayRef Calls, const char *Name) {
-Libcalls.setLibcallName(Calls, Name);
+  void setLibcallImpl(RTLIB::Libcall Call, RTLIB::LibcallImpl Impl) {
+Libcalls.setLibcallImpl(Call, Impl);
   }
 
   /// Get the libcall routine name for the specified libcall.
diff --git a/llvm/include/llvm/IR/RuntimeLibcalls.h 
b/llvm/include/llvm/IR/RuntimeLibcalls.h
index e063076fac71a..912715fbf6b19 100644
--- a/llvm/include/llvm/IR/RuntimeLibcalls.h
+++ b/llvm/include/llvm/IR/RuntimeLibcalls.h
@@ -23,6 +23,10 @@
 #include "llvm/Support/Compiler.h"
 #include "llvm/TargetParser/Triple.h"
 
+/// TableGen will produce 2 enums, RTLIB::Libcall and
+/// RTLIB::LibcallImpl. RTLIB::Libcall describes abstract functionality the
+/// compiler may choose to access, RTLIB::LibcallImpl describes a particular 
ABI
+/// implementation, which includes a name and type signature.
 #define GET_RUNTIME_LIBCALL_ENUM
 #include "llvm/IR/RuntimeLibcalls.inc"
 #undef GET_RUNTIME_LIBCALL_ENUM
@@ -48,38 +52,46 @@ struct RuntimeLibcallsInfo {
   FloatABI::ABIType FloatABI = FloatABI::Default,
   EABI EABIVersion = EABI::Default) {
 initSoftFloatCmpLibcallPredicates();
-initDefaultLibCallNames();
+initDefaultLibCallImpls();
 initLibcalls(TT, ExceptionModel, FloatABI, EABIVersion);
   }
 
   /// Rename the default libcall routine name for the specified libcall.
-  void setLibcallName(RTLIB::Libcall Call, const char *Name) {
-LibcallRoutineNames[Call] = Name;
-  }
-
-  void setLibcallName(ArrayRef Calls, const char *Name) {
-for (auto Call : Calls)
-  setLibcallName(Call, Name);
+  void setLibcallImpl(RTLIB::Libcall Call, RTLIB::LibcallImpl Impl) {
+LibcallImpls[Call] = Impl;
   }
 
   /// Get the libcall routine name for the specified libcall.
+  // FIXME: This should be removed. Only LibcallImpl should have a name.
   const char *getLibcallName(RTLIB::Libcall Call) const {
-return LibcallRoutineNames[Call];
+return LibCallImplNames[LibcallImpls[Call]];
+  }
+
+  /// Get the libcall routine name for the specified libcall implementation.
+  const char *getLibcallImplName(RTLIB::LibcallImpl CallImpl) const {
+return LibCallImplNames[CallImpl];
+  }
+
+  /// Return the lowering's selection of implementation call for \p Call
+  RTLIB::LibcallImpl getLibcallImpl(RTLIB::Libcall Call) const {
+return LibcallImpls[Call];
   }
 
   /// Set the CallingConv that should be used for the specified libcall.
+  // FIXME: This should be a function of RTLIB::LibcallImpl
   void setLibcallCallingConv(RTLIB::Libcall Call, CallingConv::ID CC) {
 LibcallCallingConvs[Call] = CC;
   }
 
   /// Get the CallingConv that should be used for the specified libcall.
+  // FIXME: This should be a function of RTLIB::LibcallImpl
   CallingConv::ID getLibcallCallingConv(RTLIB::Libcall Call) const {
 return LibcallCallingConvs[Call];
   }
 
-  ArrayRef getLibcallNames() const {
-// Trim UNKNOWN_LIBCALL from the end
-return ArrayRef(LibcallRoutineNames).drop_back();
+  ArrayRef getLibcallImpls() const {
+// Trim Unsupported from the start
+return ArrayRef(LibcallImpls).drop_front();
   }
 
   /// Get the comparison predicate that's to be used to test the result of the
@@ -91,6 +103,7 @@ struct RuntimeLibcallsInfo {
   }
 
   // FIXME: Th

[llvm-branch-commits] [llvm] ARM: Add runtime libcall definitions for aebi memory functions (PR #144974)

2025-06-19 Thread via llvm-branch-commits

llvmbot wrote:




@llvm/pr-subscribers-llvm-ir

Author: Matt Arsenault (arsenm)


Changes

Fix bypassing ordinary RuntimeLibcalls APIs for cases handled
in ARMSelectionDAGInfo

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


3 Files Affected:

- (modified) llvm/include/llvm/IR/RuntimeLibcalls.td (+23) 
- (modified) llvm/lib/Target/ARM/ARMISelLowering.cpp (+17) 
- (modified) llvm/lib/Target/ARM/ARMSelectionDAGInfo.cpp (+10-8) 


``diff
diff --git a/llvm/include/llvm/IR/RuntimeLibcalls.td 
b/llvm/include/llvm/IR/RuntimeLibcalls.td
index c910fce2edd80..71efecdf082af 100644
--- a/llvm/include/llvm/IR/RuntimeLibcalls.td
+++ b/llvm/include/llvm/IR/RuntimeLibcalls.td
@@ -357,6 +357,17 @@ multiclass LibmLongDoubleLibCall;
 }
 
+// ARM EABI calls
+def AEABI_MEMCPY4 : RuntimeLibcall; // Align 4
+def AEABI_MEMCPY8 : RuntimeLibcall; // Align 8
+def AEABI_MEMMOVE4 : RuntimeLibcall;
+def AEABI_MEMMOVE8 : RuntimeLibcall;
+def AEABI_MEMSET4 : RuntimeLibcall;
+def AEABI_MEMSET8 : RuntimeLibcall;
+def AEABI_MEMCLR : RuntimeLibcall;
+def AEABI_MEMCLR4 : RuntimeLibcall;
+def AEABI_MEMCLR8 : RuntimeLibcall;
+
 //
 // Define implementation default libcalls
 //
@@ -1134,8 +1145,20 @@ def __aeabi_uidivmod : RuntimeLibcallImpl; 
//  CallingConv::ARM_AAP
 // Memory operations
 // RTABI chapter 4.3.4
 def __aeabi_memcpy : RuntimeLibcallImpl; // CallingConv::ARM_AAPCS
+def __aeabi_memcpy4 : RuntimeLibcallImpl;
+def __aeabi_memcpy8 : RuntimeLibcallImpl;
+
 def __aeabi_memmove : RuntimeLibcallImpl; // CallingConv::ARM_AAPCS
+def __aeabi_memmove4 : RuntimeLibcallImpl;
+def __aeabi_memmove8 : RuntimeLibcallImpl;
+
 def __aeabi_memset : RuntimeLibcallImpl; // CallingConv::ARM_AAPCS
+def __aeabi_memset4 : RuntimeLibcallImpl;
+def __aeabi_memset8 : RuntimeLibcallImpl;
+
+def __aeabi_memclr : RuntimeLibcallImpl;
+def __aeabi_memclr4 : RuntimeLibcallImpl;
+def __aeabi_memclr8 : RuntimeLibcallImpl;
 
 // isTargetWindows()
 def __stoi64 : RuntimeLibcallImpl; // 
CallingConv::ARM_AAPCS_VFP
diff --git a/llvm/lib/Target/ARM/ARMISelLowering.cpp 
b/llvm/lib/Target/ARM/ARMISelLowering.cpp
index 81b535e19bc71..478791699df88 100644
--- a/llvm/lib/Target/ARM/ARMISelLowering.cpp
+++ b/llvm/lib/Target/ARM/ARMISelLowering.cpp
@@ -704,6 +704,23 @@ ARMTargetLowering::ARMTargetLowering(const TargetMachine 
&TM_,
   {RTLIB::MEMCPY, RTLIB::__aeabi_memcpy, CallingConv::ARM_AAPCS},
   {RTLIB::MEMMOVE, RTLIB::__aeabi_memmove, CallingConv::ARM_AAPCS},
   {RTLIB::MEMSET, RTLIB::__aeabi_memset, CallingConv::ARM_AAPCS},
+  {RTLIB::AEABI_MEMCPY4, RTLIB::__aeabi_memcpy4,
+   CallingConv::ARM_AAPCS},
+  {RTLIB::AEABI_MEMCPY8, RTLIB::__aeabi_memcpy8,
+   CallingConv::ARM_AAPCS},
+  {RTLIB::AEABI_MEMMOVE4, RTLIB::__aeabi_memmove4,
+   CallingConv::ARM_AAPCS},
+  {RTLIB::AEABI_MEMMOVE8, RTLIB::__aeabi_memmove8,
+   CallingConv::ARM_AAPCS},
+  {RTLIB::AEABI_MEMSET4, RTLIB::__aeabi_memset4,
+   CallingConv::ARM_AAPCS},
+  {RTLIB::AEABI_MEMSET8, RTLIB::__aeabi_memset8,
+   CallingConv::ARM_AAPCS},
+  {RTLIB::AEABI_MEMCLR, RTLIB::__aeabi_memclr, CallingConv::ARM_AAPCS},
+  {RTLIB::AEABI_MEMCLR4, RTLIB::__aeabi_memclr4,
+   CallingConv::ARM_AAPCS},
+  {RTLIB::AEABI_MEMCLR8, RTLIB::__aeabi_memclr8,
+   CallingConv::ARM_AAPCS},
   };
 
   for (const auto &LC : MemOpsLibraryCalls) {
diff --git a/llvm/lib/Target/ARM/ARMSelectionDAGInfo.cpp 
b/llvm/lib/Target/ARM/ARMSelectionDAGInfo.cpp
index 77f4782699c96..b4677a8bfb035 100644
--- a/llvm/lib/Target/ARM/ARMSelectionDAGInfo.cpp
+++ b/llvm/lib/Target/ARM/ARMSelectionDAGInfo.cpp
@@ -121,18 +121,20 @@ SDValue ARMSelectionDAGInfo::EmitSpecializedLibcall(
 Args.push_back(Entry);
   }
 
-  char const *FunctionNames[4][3] = {
-{ "__aeabi_memcpy",  "__aeabi_memcpy4",  "__aeabi_memcpy8"  },
-{ "__aeabi_memmove", "__aeabi_memmove4", "__aeabi_memmove8" },
-{ "__aeabi_memset",  "__aeabi_memset4",  "__aeabi_memset8"  },
-{ "__aeabi_memclr",  "__aeabi_memclr4",  "__aeabi_memclr8"  }
-  };
+  static const RTLIB::Libcall FunctionImpls[4][3] = {
+  {RTLIB::MEMCPY, RTLIB::AEABI_MEMCPY4, RTLIB::AEABI_MEMCPY8},
+  {RTLIB::MEMMOVE, RTLIB::AEABI_MEMMOVE4, RTLIB::AEABI_MEMMOVE8},
+  {RTLIB::MEMSET, RTLIB::AEABI_MEMSET4, RTLIB::AEABI_MEMSET8},
+  {RTLIB::AEABI_MEMCLR, RTLIB::AEABI_MEMCLR4, RTLIB::AEABI_MEMCLR8}};
+
+  RTLIB::Libcall NewLC = FunctionImpls[AEABILibcall][AlignVariant];
+
   TargetLowering::CallLoweringInfo CLI(DAG);
   CLI.setDebugLoc(dl)
   .setChain(Chain)
   .setLibCallee(
-  TLI->getLibcallCallingConv(LC), Type::getVoidTy(*DAG.getContext()),
-  DAG.getExternalSymbol(FunctionNames[AEABILibcall][AlignVariant],
+  TLI->getLibcallCallingConv(NewLC

[llvm-branch-commits] [llvm] Hexagon: Add libcall declarations for special memcpy (PR #144975)

2025-06-19 Thread via llvm-branch-commits

llvmbot wrote:




@llvm/pr-subscribers-llvm-ir

Author: Matt Arsenault (arsenm)


Changes

HexagonSelectionDAGInfo was bypassing the ordinary RuntimeLibcallInfo
handling for this case, so define a libcall for it and use it.

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


3 Files Affected:

- (modified) llvm/include/llvm/IR/RuntimeLibcalls.td (+6) 
- (modified) llvm/lib/IR/RuntimeLibcalls.cpp (+4) 
- (modified) llvm/lib/Target/Hexagon/HexagonSelectionDAGInfo.cpp (+6-4) 


``diff
diff --git a/llvm/include/llvm/IR/RuntimeLibcalls.td 
b/llvm/include/llvm/IR/RuntimeLibcalls.td
index 71efecdf082af..2efe823a760db 100644
--- a/llvm/include/llvm/IR/RuntimeLibcalls.td
+++ b/llvm/include/llvm/IR/RuntimeLibcalls.td
@@ -368,6 +368,9 @@ def AEABI_MEMCLR : RuntimeLibcall;
 def AEABI_MEMCLR4 : RuntimeLibcall;
 def AEABI_MEMCLR8 : RuntimeLibcall;
 
+// Hexagon calls
+def HEXAGON_MEMCPY_LIKELY_ALIGNED_MIN32BYTES_MULT8BYTES : RuntimeLibcall;
+
 //
 // Define implementation default libcalls
 //
@@ -1247,6 +1250,9 @@ def __hexagon_fast2_sqrtf : RuntimeLibcallImpl;
 // This is the only fast library function for sqrtd.
 def __hexagon_fast2_sqrtdf2 : RuntimeLibcallImpl;
 
+def __hexagon_memcpy_likely_aligned_min32bytes_mult8bytes
+: RuntimeLibcallImpl;
+
 
//===--===//
 // Mips16 Runtime Libcalls
 
//===--===//
diff --git a/llvm/lib/IR/RuntimeLibcalls.cpp b/llvm/lib/IR/RuntimeLibcalls.cpp
index 5fccb23e6c5ff..873ee6b509e2d 100644
--- a/llvm/lib/IR/RuntimeLibcalls.cpp
+++ b/llvm/lib/IR/RuntimeLibcalls.cpp
@@ -616,6 +616,10 @@ void RuntimeLibcallsInfo::initLibcalls(const Triple &TT,
   setLibcallImpl(RTLIB::SQRT_F32, RTLIB::__hexagon_fast2_sqrtf);
 else
   setLibcallImpl(RTLIB::SQRT_F32, RTLIB::__hexagon_sqrtf);
+
+setLibcallImpl(
+RTLIB::HEXAGON_MEMCPY_LIKELY_ALIGNED_MIN32BYTES_MULT8BYTES,
+RTLIB::__hexagon_memcpy_likely_aligned_min32bytes_mult8bytes);
   }
 
   if (TT.getArch() == Triple::ArchType::msp430)
diff --git a/llvm/lib/Target/Hexagon/HexagonSelectionDAGInfo.cpp 
b/llvm/lib/Target/Hexagon/HexagonSelectionDAGInfo.cpp
index 1b724e8fcae91..610a81fe45c2f 100644
--- a/llvm/lib/Target/Hexagon/HexagonSelectionDAGInfo.cpp
+++ b/llvm/lib/Target/Hexagon/HexagonSelectionDAGInfo.cpp
@@ -41,18 +41,20 @@ SDValue HexagonSelectionDAGInfo::EmitTargetCodeForMemcpy(
   Entry.Node = Size;
   Args.push_back(Entry);
 
-  const char *SpecialMemcpyName =
-  "__hexagon_memcpy_likely_aligned_min32bytes_mult8bytes";
+  const char *SpecialMemcpyName = TLI.getLibcallName(
+  RTLIB::HEXAGON_MEMCPY_LIKELY_ALIGNED_MIN32BYTES_MULT8BYTES);
   const MachineFunction &MF = DAG.getMachineFunction();
   bool LongCalls = MF.getSubtarget().useLongCalls();
   unsigned Flags = LongCalls ? HexagonII::HMOTF_ConstExtended : 0;
 
+  CallingConv::ID CC = TLI.getLibcallCallingConv(
+  RTLIB::HEXAGON_MEMCPY_LIKELY_ALIGNED_MIN32BYTES_MULT8BYTES);
+
   TargetLowering::CallLoweringInfo CLI(DAG);
   CLI.setDebugLoc(dl)
   .setChain(Chain)
   .setLibCallee(
-  TLI.getLibcallCallingConv(RTLIB::MEMCPY),
-  Type::getVoidTy(*DAG.getContext()),
+  CC, Type::getVoidTy(*DAG.getContext()),
   DAG.getTargetExternalSymbol(
   SpecialMemcpyName, TLI.getPointerTy(DAG.getDataLayout()), Flags),
   std::move(Args))

``




https://github.com/llvm/llvm-project/pull/144975
___
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] XCore: Declare libcalls used for align 4 memcpy (PR #144976)

2025-06-19 Thread via llvm-branch-commits

llvmbot wrote:




@llvm/pr-subscribers-llvm-ir

Author: Matt Arsenault (arsenm)


Changes

This usage was hidden in XCoreSelectionDAGInfo and bypassed
the usual libcall system, so define these for later use.

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


3 Files Affected:

- (modified) llvm/include/llvm/IR/RuntimeLibcalls.td (+9) 
- (modified) llvm/lib/IR/RuntimeLibcalls.cpp (+3) 
- (modified) llvm/lib/Target/XCore/XCoreSelectionDAGInfo.cpp (+8-5) 


``diff
diff --git a/llvm/include/llvm/IR/RuntimeLibcalls.td 
b/llvm/include/llvm/IR/RuntimeLibcalls.td
index 2efe823a760db..57ad6f09e8b57 100644
--- a/llvm/include/llvm/IR/RuntimeLibcalls.td
+++ b/llvm/include/llvm/IR/RuntimeLibcalls.td
@@ -371,6 +371,9 @@ def AEABI_MEMCLR8 : RuntimeLibcall;
 // Hexagon calls
 def HEXAGON_MEMCPY_LIKELY_ALIGNED_MIN32BYTES_MULT8BYTES : RuntimeLibcall;
 
+// XCore calls
+def MEMCPY_ALIGN_4 : RuntimeLibcall;
+
 //
 // Define implementation default libcalls
 //
@@ -1544,6 +1547,12 @@ def _allrem : RuntimeLibcallImpl; // 
CallingConv::X86_StdCall
 def _aullrem : RuntimeLibcallImpl; // CallingConv::X86_StdCall
 def _allmul : RuntimeLibcallImpl; // CallingConv::X86_StdCall
 
+//===--===//
+// XCore Runtime Libcalls
+//===--===//
+
+def __memcpy_4 : RuntimeLibcallImpl;
+
 
//===--===//
 // ZOS Runtime Libcalls
 
//===--===//
diff --git a/llvm/lib/IR/RuntimeLibcalls.cpp b/llvm/lib/IR/RuntimeLibcalls.cpp
index 873ee6b509e2d..0f92371f05529 100644
--- a/llvm/lib/IR/RuntimeLibcalls.cpp
+++ b/llvm/lib/IR/RuntimeLibcalls.cpp
@@ -627,4 +627,7 @@ void RuntimeLibcallsInfo::initLibcalls(const Triple &TT,
 
   if (TT.isSystemZ() && TT.isOSzOS())
 setZOSLibCallNameOverrides();
+
+  if (TT.getArch() == Triple::ArchType::xcore)
+setLibcallImpl(RTLIB::MEMCPY_ALIGN_4, RTLIB::__memcpy_4);
 }
diff --git a/llvm/lib/Target/XCore/XCoreSelectionDAGInfo.cpp 
b/llvm/lib/Target/XCore/XCoreSelectionDAGInfo.cpp
index bc34ab4319690..1bd92a2b49475 100644
--- a/llvm/lib/Target/XCore/XCoreSelectionDAGInfo.cpp
+++ b/llvm/lib/Target/XCore/XCoreSelectionDAGInfo.cpp
@@ -39,14 +39,17 @@ SDValue XCoreSelectionDAGInfo::EmitTargetCodeForMemcpy(
 Entry.Node = Src; Args.push_back(Entry);
 Entry.Node = Size; Args.push_back(Entry);
 
+const char *MemcpyAlign4Name = TLI.getLibcallName(RTLIB::MEMCPY_ALIGN_4);
+CallingConv::ID CC = TLI.getLibcallCallingConv(RTLIB::MEMCPY_ALIGN_4);
+
 TargetLowering::CallLoweringInfo CLI(DAG);
 CLI.setDebugLoc(dl)
 .setChain(Chain)
-.setLibCallee(TLI.getLibcallCallingConv(RTLIB::MEMCPY),
-  Type::getVoidTy(*DAG.getContext()),
-  DAG.getExternalSymbol(
-  "__memcpy_4", TLI.getPointerTy(DAG.getDataLayout())),
-  std::move(Args))
+.setLibCallee(
+CC, Type::getVoidTy(*DAG.getContext()),
+DAG.getExternalSymbol(MemcpyAlign4Name,
+  TLI.getPointerTy(DAG.getDataLayout())),
+std::move(Args))
 .setDiscardResult();
 
 std::pair CallResult = TLI.LowerCallTo(CLI);

``




https://github.com/llvm/llvm-project/pull/144976
___
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] AArch64: Add libcall impl declarations for __arm_sc* memory functions (PR #144977)

2025-06-19 Thread Matt Arsenault via llvm-branch-commits

https://github.com/arsenm ready_for_review 
https://github.com/llvm/llvm-project/pull/144977
___
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] TableGen: Allow defining sets of runtime libraries (PR #144978)

2025-06-19 Thread Matt Arsenault via llvm-branch-commits

https://github.com/arsenm edited 
https://github.com/llvm/llvm-project/pull/144978
___
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] ARM: Add runtime libcall definitions for aebi memory functions (PR #144974)

2025-06-19 Thread Matt Arsenault via llvm-branch-commits

https://github.com/arsenm ready_for_review 
https://github.com/llvm/llvm-project/pull/144974
___
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] TableGen: Generate enum for runtime libcall implementations (PR #144973)

2025-06-19 Thread Matt Arsenault via llvm-branch-commits

https://github.com/arsenm ready_for_review 
https://github.com/llvm/llvm-project/pull/144973
___
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] XCore: Declare libcalls used for align 4 memcpy (PR #144976)

2025-06-19 Thread Matt Arsenault via llvm-branch-commits

https://github.com/arsenm ready_for_review 
https://github.com/llvm/llvm-project/pull/144976
___
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] AArch64: Add libcall impl declarations for __arm_sc* memory functions (PR #144977)

2025-06-19 Thread via llvm-branch-commits

llvmbot wrote:




@llvm/pr-subscribers-llvm-ir

Author: Matt Arsenault (arsenm)


Changes

These were bypassing the ordinary libcall emission mechanism. Make sure
we have entries in RuntimeLibcalls, which should include all possible
calls the compiler could emit.

Fixes not emitting the # prefix in the arm64ec case.

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


4 Files Affected:

- (modified) llvm/include/llvm/IR/RuntimeLibcalls.td (+9) 
- (modified) llvm/lib/IR/RuntimeLibcalls.cpp (+10-1) 
- (modified) llvm/lib/Target/AArch64/AArch64SelectionDAGInfo.cpp (+7-8) 
- (modified) llvm/test/CodeGen/AArch64/arm64ec-builtins.ll (+3-6) 


``diff
diff --git a/llvm/include/llvm/IR/RuntimeLibcalls.td 
b/llvm/include/llvm/IR/RuntimeLibcalls.td
index 57ad6f09e8b57..1d9f02dcf8ba8 100644
--- a/llvm/include/llvm/IR/RuntimeLibcalls.td
+++ b/llvm/include/llvm/IR/RuntimeLibcalls.td
@@ -357,6 +357,11 @@ multiclass LibmLongDoubleLibCall;
 }
 
+// AArch64 calls
+def SC_MEMCPY : RuntimeLibcall;
+def SC_MEMMOVE : RuntimeLibcall;
+def SC_MEMSET : RuntimeLibcall;
+
 // ARM EABI calls
 def AEABI_MEMCPY4 : RuntimeLibcall; // Align 4
 def AEABI_MEMCPY8 : RuntimeLibcall; // Align 8
@@ -985,6 +990,10 @@ defset list AArch64LibcallImpls = {
 defm __aarch64_ldeor#MemSize
 : AtomicOrderSizeLibcallImpl<"OUTLINE_ATOMIC_LDEOR"#MemSize>;
   }
+
+  def __arm_sc_memcpy : RuntimeLibcallImpl;
+  def __arm_sc_memmove : RuntimeLibcallImpl;
+  def __arm_sc_memset : RuntimeLibcallImpl;
 }
 
 foreach libcall = AArch64LibcallImpls in {
diff --git a/llvm/lib/IR/RuntimeLibcalls.cpp b/llvm/lib/IR/RuntimeLibcalls.cpp
index 0f92371f05529..67f872b4574b1 100644
--- a/llvm/lib/IR/RuntimeLibcalls.cpp
+++ b/llvm/lib/IR/RuntimeLibcalls.cpp
@@ -521,8 +521,17 @@ void RuntimeLibcallsInfo::initLibcalls(const Triple &TT,
   }
 
   if (TT.isAArch64()) {
-if (TT.isWindowsArm64EC())
+if (TT.isWindowsArm64EC()) {
   setWindowsArm64LibCallNameOverrides();
+  setLibcallImpl(RTLIB::SC_MEMCPY, RTLIB::arm64ec___arm_sc_memcpy);
+  setLibcallImpl(RTLIB::SC_MEMMOVE, RTLIB::arm64ec___arm_sc_memmove);
+  setLibcallImpl(RTLIB::SC_MEMSET, RTLIB::arm64ec___arm_sc_memset);
+} else {
+  setLibcallImpl(RTLIB::SC_MEMCPY, RTLIB::__arm_sc_memcpy);
+  setLibcallImpl(RTLIB::SC_MEMMOVE, RTLIB::__arm_sc_memmove);
+  setLibcallImpl(RTLIB::SC_MEMSET, RTLIB::__arm_sc_memset);
+}
+
 setAArch64LibcallNames(*this, TT);
   } else if (TT.isARM() || TT.isThumb()) {
 setARMLibcallNames(*this, TT, FloatABI, EABIVersion);
diff --git a/llvm/lib/Target/AArch64/AArch64SelectionDAGInfo.cpp 
b/llvm/lib/Target/AArch64/AArch64SelectionDAGInfo.cpp
index 90f6fc2ea664b..d719f234b27f7 100644
--- a/llvm/lib/Target/AArch64/AArch64SelectionDAGInfo.cpp
+++ b/llvm/lib/Target/AArch64/AArch64SelectionDAGInfo.cpp
@@ -164,35 +164,34 @@ SDValue 
AArch64SelectionDAGInfo::EmitStreamingCompatibleMemLibCall(
   const AArch64Subtarget &STI =
   DAG.getMachineFunction().getSubtarget();
   const AArch64TargetLowering *TLI = STI.getTargetLowering();
-  SDValue Symbol;
   TargetLowering::ArgListEntry DstEntry;
   DstEntry.Ty = PointerType::getUnqual(*DAG.getContext());
   DstEntry.Node = Dst;
   TargetLowering::ArgListTy Args;
   Args.push_back(DstEntry);
-  EVT PointerVT = TLI->getPointerTy(DAG.getDataLayout());
 
+  RTLIB::Libcall NewLC;
   switch (LC) {
   case RTLIB::MEMCPY: {
+NewLC = RTLIB::SC_MEMCPY;
 TargetLowering::ArgListEntry Entry;
 Entry.Ty = PointerType::getUnqual(*DAG.getContext());
-Symbol = DAG.getExternalSymbol("__arm_sc_memcpy", PointerVT);
 Entry.Node = Src;
 Args.push_back(Entry);
 break;
   }
   case RTLIB::MEMMOVE: {
+NewLC = RTLIB::SC_MEMMOVE;
 TargetLowering::ArgListEntry Entry;
 Entry.Ty = PointerType::getUnqual(*DAG.getContext());
-Symbol = DAG.getExternalSymbol("__arm_sc_memmove", PointerVT);
 Entry.Node = Src;
 Args.push_back(Entry);
 break;
   }
   case RTLIB::MEMSET: {
+NewLC = RTLIB::SC_MEMSET;
 TargetLowering::ArgListEntry Entry;
 Entry.Ty = Type::getInt32Ty(*DAG.getContext());
-Symbol = DAG.getExternalSymbol("__arm_sc_memset", PointerVT);
 Src = DAG.getZExtOrTrunc(Src, DL, MVT::i32);
 Entry.Node = Src;
 Args.push_back(Entry);
@@ -202,17 +201,17 @@ SDValue 
AArch64SelectionDAGInfo::EmitStreamingCompatibleMemLibCall(
 return SDValue();
   }
 
+  EVT PointerVT = TLI->getPointerTy(DAG.getDataLayout());
+  SDValue Symbol = DAG.getExternalSymbol(TLI->getLibcallName(NewLC), 
PointerVT);
   TargetLowering::ArgListEntry SizeEntry;
   SizeEntry.Node = Size;
   SizeEntry.Ty = DAG.getDataLayout().getIntPtrType(*DAG.getContext());
   Args.push_back(SizeEntry);
-  assert(Symbol->getOpcode() == ISD::ExternalSymbol &&
- "Function name is not set");
 
   TargetLowering::CallLoweringInfo CLI(DAG);
   PointerType *RetTy = PointerType::getUnqual(*DAG.getContext());
   CLI.setDebugLoc(DL).setChain(Chain).setLibCallee(
-  TLI-

[llvm-branch-commits] [llvm] TableGen: Allow defining sets of runtime libraries (PR #144978)

2025-06-19 Thread via llvm-branch-commits

llvmbot wrote:




@llvm/pr-subscribers-llvm-ir

Author: Matt Arsenault (arsenm)


Changes

Add a way to define a SystemLibrary for a complete set of
libcalls, subdivided by a predicate based on the triple.
Libraries can be defined using dag set operations, and the
prior default set can be subtracted from and added to (though
I think eventually all targets should move to explicit opt-ins.
We're still doing things like reporting ppcf128 libcalls as
available dy default on all targets).

Start migrating some of the easier targets to only use the new
system. Targets that don't define a SystemLibrary are still
manually mutating a table set to the old defaults.

---

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


9 Files Affected:

- (modified) llvm/include/llvm/IR/RuntimeLibcalls.h (+2-8) 
- (modified) llvm/include/llvm/IR/RuntimeLibcalls.td (+309-184) 
- (modified) llvm/include/llvm/IR/RuntimeLibcallsImpl.td (+36) 
- (added) llvm/include/llvm/TableGen/SetTheory.td (+27) 
- (modified) llvm/lib/IR/RuntimeLibcalls.cpp (+6-121) 
- (added) llvm/test/TableGen/RuntimeLibcallEmitter-conflict-warning.td (+60) 
- (added) llvm/test/TableGen/RuntimeLibcallEmitter-nested-predicates-error.td 
(+18) 
- (modified) llvm/test/TableGen/RuntimeLibcallEmitter.td (+174-11) 
- (modified) llvm/utils/TableGen/Basic/RuntimeLibcallsEmitter.cpp (+257-94) 


``diff
diff --git a/llvm/include/llvm/IR/RuntimeLibcalls.h 
b/llvm/include/llvm/IR/RuntimeLibcalls.h
index 912715fbf6b19..d69c23753da7a 100644
--- a/llvm/include/llvm/IR/RuntimeLibcalls.h
+++ b/llvm/include/llvm/IR/RuntimeLibcalls.h
@@ -52,7 +52,6 @@ struct RuntimeLibcallsInfo {
   FloatABI::ABIType FloatABI = FloatABI::Default,
   EABI EABIVersion = EABI::Default) {
 initSoftFloatCmpLibcallPredicates();
-initDefaultLibCallImpls();
 initLibcalls(TT, ExceptionModel, FloatABI, EABIVersion);
   }
 
@@ -97,6 +96,7 @@ struct RuntimeLibcallsInfo {
   /// Get the comparison predicate that's to be used to test the result of the
   /// comparison libcall against zero. This should only be used with
   /// floating-point compare libcalls.
+  // FIXME: This should be a function of RTLIB::LibcallImpl
   CmpInst::Predicate
   getSoftFloatCmpLibcallPredicate(RTLIB::Libcall Call) const {
 return SoftFloatCompareLibcallPredicates[Call];
@@ -172,13 +172,7 @@ struct RuntimeLibcallsInfo {
   void initDefaultLibCallImpls();
 
   /// Generated by tablegen.
-  void setPPCLibCallNameOverrides();
-
-  /// Generated by tablegen.
-  void setZOSLibCallNameOverrides();
-
-  /// Generated by tablegen.
-  void setWindowsArm64LibCallNameOverrides();
+  void setTargetRuntimeLibcallSets(const Triple &TT);
 
   void initSoftFloatCmpLibcallPredicates();
 
diff --git a/llvm/include/llvm/IR/RuntimeLibcalls.td 
b/llvm/include/llvm/IR/RuntimeLibcalls.td
index 1d9f02dcf8ba8..e24b4c928b421 100644
--- a/llvm/include/llvm/IR/RuntimeLibcalls.td
+++ b/llvm/include/llvm/IR/RuntimeLibcalls.td
@@ -891,6 +891,17 @@ def calloc : RuntimeLibcallImpl;
 } // End let IsDefault = true
 } // End defset DefaultRuntimeLibcallImpls
 
+defvar DefaultLibCalls =
+!foreach(entry, DefaultRuntimeLibcallImpls, entry.Provides);
+
+defvar DefaultRuntimeLibcallImpls_f128 =
+!filter(entry, DefaultRuntimeLibcallImpls,
+!match(!cast(entry.Provides), "_F128"));
+
+defvar DefaultRuntimeLibcallImpls_atomic =
+!filter(entry, DefaultRuntimeLibcallImpls,
+!match(!cast(entry.Provides), "ATOMIC"));
+
 //
 // Define implementation other libcalls
 //
@@ -915,58 +926,61 @@ def _Unwind_SjLj_Resume : 
RuntimeLibcallImpl;
 // F128 libm Runtime Libcalls
 
//===--===//
 
-def logf128 : RuntimeLibcallImpl;
-def log2f128 : RuntimeLibcallImpl;
-def log10f128 : RuntimeLibcallImpl;
-def expf128 : RuntimeLibcallImpl;
-def exp2f128 : RuntimeLibcallImpl;
-def exp10f128 : RuntimeLibcallImpl;
-def sinf128 : RuntimeLibcallImpl;
-def cosf128 : RuntimeLibcallImpl;
-def tanf128 : RuntimeLibcallImpl;
-def tanhf128 : RuntimeLibcallImpl;
-def sincosf128 : RuntimeLibcallImpl;
-def powf128 : RuntimeLibcallImpl;
-def fminf128 : RuntimeLibcallImpl;
-def fmaxf128 : RuntimeLibcallImpl;
-def fmodf128 : RuntimeLibcallImpl;
-def sqrtf128 : RuntimeLibcallImpl;
-def ceilf128 : RuntimeLibcallImpl;
-def floorf128 : RuntimeLibcallImpl;
-def truncf128 : RuntimeLibcallImpl;
-def roundf128 : RuntimeLibcallImpl;
-def lroundf128 : RuntimeLibcallImpl;
-def llroundf128 : RuntimeLibcallImpl;
-def rintf128 : RuntimeLibcallImpl;
-def lrintf128 : RuntimeLibcallImpl;
-def llrintf128 : RuntimeLibcallImpl;
-def nearbyintf128 : RuntimeLibcallImpl;
-def fmaf128 : RuntimeLibcallImpl;
-def frexpf128 : RuntimeLibcallImpl;
-
-def cbrtf128 : RuntimeLibcallImpl;
-def fminimumf128 : R

[llvm-branch-commits] [llvm] TableGen: Allow defining sets of runtime libraries (PR #144978)

2025-06-19 Thread Matt Arsenault via llvm-branch-commits

https://github.com/arsenm ready_for_review 
https://github.com/llvm/llvm-project/pull/144978
___
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] RuntimeLibcalls: Associate calling convention with libcall impls (PR #144979)

2025-06-19 Thread via llvm-branch-commits

llvmbot wrote:




@llvm/pr-subscribers-llvm-ir

Author: Matt Arsenault (arsenm)


Changes

Instead of associating the libcall with the RTLIB::Libcall, put it
into a table indexed by the RTLIB::LibcallImpl. The LibcallImpls
should contain all ABI details for a particular implementation, not
the abstract Libcall. In the future the wrappers in terms of the
RTLIB::Libcall should be removed.

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


6 Files Affected:

- (modified) llvm/include/llvm/CodeGen/TargetLowering.h (+14-2) 
- (modified) llvm/include/llvm/IR/RuntimeLibcalls.h (+23-9) 
- (modified) llvm/lib/IR/RuntimeLibcalls.cpp (+42-28) 
- (modified) llvm/lib/Target/ARM/ARMISelLowering.cpp (+15-9) 
- (modified) llvm/lib/Target/Lanai/LanaiISelLowering.cpp (+2-2) 
- (modified) llvm/lib/Target/MSP430/MSP430ISelLowering.cpp (+2-1) 


``diff
diff --git a/llvm/include/llvm/CodeGen/TargetLowering.h 
b/llvm/include/llvm/CodeGen/TargetLowering.h
index 69ae4f80297d5..fa08eb64642de 100644
--- a/llvm/include/llvm/CodeGen/TargetLowering.h
+++ b/llvm/include/llvm/CodeGen/TargetLowering.h
@@ -3562,6 +3562,11 @@ class LLVM_ABI TargetLoweringBase {
 Libcalls.setLibcallImpl(Call, Impl);
   }
 
+  /// Get the libcall impl routine name for the specified libcall.
+  RTLIB::LibcallImpl getLibcallImpl(RTLIB::Libcall Call) const {
+return Libcalls.getLibcallImpl(Call);
+  }
+
   /// Get the libcall routine name for the specified libcall.
   const char *getLibcallName(RTLIB::Libcall Call) const {
 return Libcalls.getLibcallName(Call);
@@ -3584,11 +3589,18 @@ class LLVM_ABI TargetLoweringBase {
   }
 
   /// Set the CallingConv that should be used for the specified libcall.
-  void setLibcallCallingConv(RTLIB::Libcall Call, CallingConv::ID CC) {
-Libcalls.setLibcallCallingConv(Call, CC);
+  void setLibcallImplCallingConv(RTLIB::LibcallImpl Call, CallingConv::ID CC) {
+Libcalls.setLibcallImplCallingConv(Call, CC);
+  }
+
+  /// Get the CallingConv that should be used for the specified libcall
+  /// implementation.
+  CallingConv::ID getLibcallImplCallingConv(RTLIB::LibcallImpl Call) const {
+return Libcalls.getLibcallImplCallingConv(Call);
   }
 
   /// Get the CallingConv that should be used for the specified libcall.
+  // FIXME: Remove this wrapper and directly use the used LibcallImpl
   CallingConv::ID getLibcallCallingConv(RTLIB::Libcall Call) const {
 return Libcalls.getLibcallCallingConv(Call);
   }
diff --git a/llvm/include/llvm/IR/RuntimeLibcalls.h 
b/llvm/include/llvm/IR/RuntimeLibcalls.h
index d69c23753da7a..dce16ab99171f 100644
--- a/llvm/include/llvm/IR/RuntimeLibcalls.h
+++ b/llvm/include/llvm/IR/RuntimeLibcalls.h
@@ -37,6 +37,10 @@ template <> struct enum_iteration_traits {
   static constexpr bool is_iterable = true;
 };
 
+template <> struct enum_iteration_traits {
+  static constexpr bool is_iterable = true;
+};
+
 namespace RTLIB {
 
 // Return an iterator over all Libcall values.
@@ -44,6 +48,10 @@ static inline auto libcalls() {
   return enum_seq(static_cast(0), RTLIB::UNKNOWN_LIBCALL);
 }
 
+static inline auto libcall_impls() {
+  return enum_seq(static_cast(1), RTLIB::NumLibcallImpls);
+}
+
 /// A simple container for information about the supported runtime calls.
 struct RuntimeLibcallsInfo {
   explicit RuntimeLibcallsInfo(
@@ -76,16 +84,21 @@ struct RuntimeLibcallsInfo {
 return LibcallImpls[Call];
   }
 
-  /// Set the CallingConv that should be used for the specified libcall.
-  // FIXME: This should be a function of RTLIB::LibcallImpl
-  void setLibcallCallingConv(RTLIB::Libcall Call, CallingConv::ID CC) {
-LibcallCallingConvs[Call] = CC;
+  /// Set the CallingConv that should be used for the specified libcall
+  /// implementation
+  void setLibcallImplCallingConv(RTLIB::LibcallImpl Call, CallingConv::ID CC) {
+LibcallImplCallingConvs[Call] = CC;
   }
 
-  /// Get the CallingConv that should be used for the specified libcall.
-  // FIXME: This should be a function of RTLIB::LibcallImpl
+  // FIXME: Remove this wrapper in favor of directly using
+  // getLibcallImplCallingConv
   CallingConv::ID getLibcallCallingConv(RTLIB::Libcall Call) const {
-return LibcallCallingConvs[Call];
+return LibcallImplCallingConvs[LibcallImpls[Call]];
+  }
+
+  /// Get the CallingConv that should be used for the specified libcall.
+  CallingConv::ID getLibcallImplCallingConv(RTLIB::LibcallImpl Call) const {
+return LibcallImplCallingConvs[Call];
   }
 
   ArrayRef getLibcallImpls() const {
@@ -130,8 +143,9 @@ struct RuntimeLibcallsInfo {
   static_assert(static_cast(CallingConv::C) == 0,
 "default calling conv should be encoded as 0");
 
-  /// Stores the CallingConv that should be used for each libcall.
-  CallingConv::ID LibcallCallingConvs[RTLIB::UNKNOWN_LIBCALL] = {};
+  /// Stores the CallingConv that should be used for each libcall
+  /// implementation.;
+  CallingConv::ID LibcallImplCallingConvs[RTLIB::NumLibcallImpls] =

[llvm-branch-commits] [llvm] RuntimeLibcalls: Associate calling convention with libcall impls (PR #144979)

2025-06-19 Thread Matt Arsenault via llvm-branch-commits

https://github.com/arsenm ready_for_review 
https://github.com/llvm/llvm-project/pull/144979
___
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] TableGen: Handle setting runtime libcall calling conventions (PR #144980)

2025-06-19 Thread via llvm-branch-commits

llvmbot wrote:




@llvm/pr-subscribers-llvm-ir

Author: Matt Arsenault (arsenm)


Changes

Allow associating a non-default CallingConv with a set of library
functions, and applying a default for a SystemLibrary.

I also wanted to be able to apply a default calling conv
to a RuntimeLibcallImpl, but that turned out to be annoying
so leave it for later.

---

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


6 Files Affected:

- (modified) llvm/include/llvm/IR/RuntimeLibcalls.td (+128-12) 
- (modified) llvm/include/llvm/IR/RuntimeLibcallsImpl.td (+25-1) 
- (modified) llvm/lib/IR/RuntimeLibcalls.cpp (-141) 
- (added) llvm/test/TableGen/RuntimeLibcallEmitter-calling-conv.td (+85) 
- (modified) llvm/test/TableGen/RuntimeLibcallEmitter.td (+13-6) 
- (modified) llvm/utils/TableGen/Basic/RuntimeLibcallsEmitter.cpp (+93-18) 


``diff
diff --git a/llvm/include/llvm/IR/RuntimeLibcalls.td 
b/llvm/include/llvm/IR/RuntimeLibcalls.td
index e24b4c928b421..03ac9f5926f87 100644
--- a/llvm/include/llvm/IR/RuntimeLibcalls.td
+++ b/llvm/include/llvm/IR/RuntimeLibcalls.td
@@ -1254,11 +1254,12 @@ def __gnu_h2f_ieee : RuntimeLibcallImpl;
 
//===--===//
 
 // Several of the runtime library functions use a special calling conv
-def __divmodqi4 : RuntimeLibcallImpl; // CallingConv::AVR_BUILTIN
-def __divmodhi4 : RuntimeLibcallImpl; // CallingConv::AVR_BUILTIN
+def __divmodqi4 : RuntimeLibcallImpl;
+def __divmodhi4 : RuntimeLibcallImpl;
+def __udivmodqi4 : RuntimeLibcallImpl;
+def __udivmodhi4 : RuntimeLibcallImpl;
+
 //def __divmodsi4 : RuntimeLibcallImpl;
-def __udivmodqi4 : RuntimeLibcallImpl; // CallingConv::AVR_BUILTIN
-def __udivmodhi4 : RuntimeLibcallImpl; // CallingConv::AVR_BUILTIN
 //def __udivmodsi4 : RuntimeLibcallImpl;
 
 // Standard sinf/cosf name replaced with "sin" and "cos". Define a
@@ -1284,9 +1285,12 @@ def AVRSystemLibrary
// Standard f64 names are replaced
sin, cos, sinf, cosf),
 
-  __divmodqi4, __divmodhi4, __divmodsi4, __udivmodqi4, 
__udivmodhi4,
-  __udivmodsi4,
-
+  // Several of the runtime library functions use a special calling
+  // conv
+  LibcallsWithCC<(add __divmodqi4, __divmodhi4, __udivmodqi4,
+ __udivmodhi4),
+ AVR_BUILTIN>,
+  __divmodsi4, __udivmodsi4,
   // Trigonometric rtlib functions
   avr_sin, avr_cos)>;
 
@@ -1509,6 +1513,117 @@ def __mspabi_mpyll : RuntimeLibcallImpl;
 
 // setLibcallCallingConv(MUL_I64, CallingConv::MSP430_BUILTIN);
 
+def isMSP430 : RuntimeLibcallPredicate<"TT.getArch() == Triple::msp430">;
+
+defvar MSP430DefaultOptOut = [
+  __addsf3, __divsf3, __extendsfdf2, __truncdfsf2, __fixsfsi,
+  __fixsfdi, __fixunssfsi, __mulsf3, __eqsf2, __gesf2, __gtsf2,
+  __divhi3, __divsi3, __ashlsi3, __floatsidf, __floatsisf,
+  __ashrsi3, __modhi3, __udivsi3, __fixdfsi, __fixunssfdi,
+  __udivhi3, __umodsi3, __nesf2, __lesf2, __floatundisf,
+  __fixdfdi, __fixunsdfsi, __modsi3, __floatunsisf,
+  __fixunsdfdi, __ltsf2, __floatdisf, __floatdidf,
+  __lshrsi3, __subsf3, __umodhi3, __floatunsidf,
+  __floatundidf
+];
+
+// EABI Libcalls - EABI Section 6.2
+def MSP430SystemLibrary
+: SystemRuntimeLibrary,
+  __mspabi_cmpf__oeq,
+  __mspabi_cmpf__une,
+  __mspabi_cmpf__oge,
+  __mspabi_cmpf__olt,
+  __mspabi_cmpf__ole,
+  __mspabi_cmpf__ogt,
+
+  // Floating point arithmetic - EABI Table 8
+  LibcallsWithCC<(add __mspabi_addd,
+  __mspabi_subd,
+  __mspabi_mpyd,
+  __mspabi_divd), MSP430_BUILTIN>,
+
+  __mspabi_addf,
+  __mspabi_subf,
+  __mspabi_mpyf,
+  __mspabi_divf,
+
+  // The following are NOT implemented in libgcc
+  // __mspabi_negd,
+  // __mspabi_negf,
+
+  // Universal Integer Operations - EABI Table 9
+  __mspabi_divi,
+  __mspabi_divli,
+  LibcallsWithCC<(add __mspabi_divlli), MSP430_BUILTIN>,
+  __mspabi_divu,
+  __mspabi_divul,
+  LibcallsWithCC<(add __mspabi_divull), MSP430_BUILTIN>,
+  __mspabi_remi,
+  __mspabi_remli,
+  LibcallsWithCC<(add __mspabi_remlli), MSP430_BUILTIN>,
+  __mspabi_remu,
+  __mspabi_remul,
+  LibcallsWithCC<(add __mspabi_remull), MSP430_BUILTIN>,
+
+  // Bitwise Operations - EABI Table 10
+  // TODO: __mspabi_[srli/srai/slli] ARE implemented in libgcc
+  __mspabi_srll,
+  __mspabi_sral,
+  __mspabi_slll
+  // __mspabi_[srlll/srall/s/rlli/rlll] are NOT implemented in libgcc
+  )
+>;
+
 
//===--===//
 // NVPTX Runtime Libcalls
 
//===--===//
@@ -1655,11 +1770,12 @@ def _Q_ulltoq : RuntimeLibcallImpl;
 
//===-

[llvm-branch-commits] [lld] [llvm] release/20.x: [lld][WebAssembly] Support for the custom-page-sizes WebAssembly proposal (#128942) (PR #129762)

2025-06-19 Thread Dan Gohman via llvm-branch-commits

sunfishcode wrote:

The patch changes LLVM's public API, so it's not suitable for backporting. This 
feature will ship in the next release, LLVM 21.

https://github.com/llvm/llvm-project/pull/129762
___
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] [llvm] release/20.x: [lld][WebAssembly] Support for the custom-page-sizes WebAssembly proposal (#128942) (PR #129762)

2025-06-19 Thread Dan Gohman via llvm-branch-commits

https://github.com/sunfishcode closed 
https://github.com/llvm/llvm-project/pull/129762
___
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] [DirectX] Add static sampler support to root signature (PR #143422)

2025-06-19 Thread via llvm-branch-commits

https://github.com/joaosaffran edited 
https://github.com/llvm/llvm-project/pull/143422
___
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] [HLSL] Add descriptor table metadata parsing (PR #142492)

2025-06-19 Thread via llvm-branch-commits

https://github.com/joaosaffran edited 
https://github.com/llvm/llvm-project/pull/142492
___
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] [DirectX] Add static sampler support to root signature (PR #143422)

2025-06-19 Thread via llvm-branch-commits

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


[llvm-branch-commits] [flang] [mlir] [flang][OpenMP][NFC] remove globals with mlir::StateStack (PR #144898)

2025-06-19 Thread Sergio Afonso via llvm-branch-commits

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


[llvm-branch-commits] [flang] [mlir] [flang][OpenMP][NFC] remove globals with mlir::StateStack (PR #144898)

2025-06-19 Thread Sergio Afonso via llvm-branch-commits


@@ -200,9 +201,41 @@ class HostEvalInfo {
 /// the handling of the outer region by keeping a stack of information
 /// structures, but it will probably still require some further work to support
 /// reverse offloading.
-static llvm::SmallVector hostEvalInfo;
-static llvm::SmallVector
-sectionsStack;
+class HostEvalInfoStackFrame
+: public mlir::StateStackFrameBase {
+public:
+  MLIR_DEFINE_EXPLICIT_INTERNAL_INLINE_TYPE_ID(HostEvalInfoStackFrame)
+
+  HostEvalInfo info;
+};
+
+static HostEvalInfo *
+getHostEvalInfoStackTop(lower::AbstractConverter &converter) {
+  HostEvalInfoStackFrame *frame =
+  converter.getStateStack().getStackTop();
+  return frame ? &frame->info : nullptr;
+}
+
+/// Stack frame for storing the OpenMPSectionsConstruct currently being
+/// processed so that it can be refered to when lowering the construct.

skatrak wrote:

```suggestion
/// processed so that it can be referred to when lowering the construct.
```

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


[llvm-branch-commits] [flang] [mlir] [flang][OpenMP][NFC] remove globals with mlir::StateStack (PR #144898)

2025-06-19 Thread Sergio Afonso via llvm-branch-commits

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

Thank you Tom for working on this, I think it's a very nice improvement! LGTM.

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


[llvm-branch-commits] [flang] [mlir] [flang][OpenMP][NFC] remove globals with mlir::StateStack (PR #144898)

2025-06-19 Thread Sergio Afonso via llvm-branch-commits


@@ -2224,10 +2260,13 @@ genSectionsOp(lower::AbstractConverter &converter, 
lower::SymMap &symTable,
   lower::pft::Evaluation &eval, mlir::Location loc,
   const ConstructQueue &queue,
   ConstructQueue::const_iterator item) {
-  assert(!sectionsStack.empty());
+  const parser::OpenMPSectionsConstruct *sectionsConstruct =
+  getSectionsConstructStackTop(converter);
+  assert(sectionsConstruct);
+
   const auto §ionBlocks =
-  std::get(sectionsStack.back()->t);
-  sectionsStack.pop_back();
+  std::get(sectionsConstruct->t);
+  converter.getStateStack().stackPop();

skatrak wrote:

Nit: Wouldn't it be possible to let this call be handled by the same function 
that pushes the stack frame? We could potentially use `SaveStateStack` then.

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


[llvm-branch-commits] [flang] [mlir] [flang][OpenMP][NFC] remove globals with mlir::StateStack (PR #144898)

2025-06-19 Thread Sergio Afonso via llvm-branch-commits


@@ -1818,16 +1852,17 @@ static void genTargetClauses(
 llvm::SmallVectorImpl &hasDeviceAddrSyms,
 llvm::SmallVectorImpl &isDevicePtrSyms,
 llvm::SmallVectorImpl &mapSyms) {
+  HostEvalInfo *hostEvalInfo = getHostEvalInfoStackTop(converter);
   ClauseProcessor cp(converter, semaCtx, clauses);
   cp.processBare(clauseOps);
   cp.processDefaultMap(stmtCtx, defaultMaps);
   cp.processDepend(symTable, stmtCtx, clauseOps);
   cp.processDevice(stmtCtx, clauseOps);
   cp.processHasDeviceAddr(stmtCtx, clauseOps, hasDeviceAddrSyms);
-  if (!hostEvalInfo.empty()) {
+  if (hostEvalInfo) {

skatrak wrote:

Nit: For consistency with `genBodyOfTargetOp`, and general conciseness
```suggestion
  if (HostEvalInfo *hostEvalInfo = getHostEvalInfoStackTop(converter)) {
```

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


[llvm-branch-commits] [flang] [mlir] [flang][OpenMP][NFC] remove globals with mlir::StateStack (PR #144898)

2025-06-19 Thread Sergio Afonso via llvm-branch-commits


@@ -2224,10 +2260,13 @@ genSectionsOp(lower::AbstractConverter &converter, 
lower::SymMap &symTable,
   lower::pft::Evaluation &eval, mlir::Location loc,
   const ConstructQueue &queue,
   ConstructQueue::const_iterator item) {
-  assert(!sectionsStack.empty());
+  const parser::OpenMPSectionsConstruct *sectionsConstruct =
+  getSectionsConstructStackTop(converter);
+  assert(sectionsConstruct);

skatrak wrote:

Nit: Add small message to the assert.

https://github.com/llvm/llvm-project/pull/144898
___
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-tools-extra] [clang-doc] add support for concepts (PR #144430)

2025-06-19 Thread Erick Velez via llvm-branch-commits

https://github.com/evelez7 updated 
https://github.com/llvm/llvm-project/pull/144430

>From 9754f70f3255e250c51c177bb00ef955e8d92f9c Mon Sep 17 00:00:00 2001
From: Erick Velez 
Date: Mon, 16 Jun 2025 10:50:35 -0700
Subject: [PATCH] add serializeArray for infos with URLs

---
 clang-tools-extra/clang-doc/BitcodeReader.cpp |  72 +++
 clang-tools-extra/clang-doc/BitcodeWriter.cpp |  44 ++-
 clang-tools-extra/clang-doc/BitcodeWriter.h   |  12 +-
 clang-tools-extra/clang-doc/HTMLGenerator.cpp |   4 +
 .../clang-doc/HTMLMustacheGenerator.cpp   |   2 +
 clang-tools-extra/clang-doc/JSONGenerator.cpp |  54 
 clang-tools-extra/clang-doc/MDGenerator.cpp   |   5 +
 clang-tools-extra/clang-doc/Mapper.cpp|   4 +
 clang-tools-extra/clang-doc/Mapper.h  |   1 +
 .../clang-doc/Representation.cpp  |  13 ++
 clang-tools-extra/clang-doc/Representation.h  |  26 +++-
 clang-tools-extra/clang-doc/Serialize.cpp |  90 +
 clang-tools-extra/clang-doc/Serialize.h   |   4 +
 clang-tools-extra/clang-doc/YAMLGenerator.cpp |   2 +
 .../test/clang-doc/json/class-requires.cpp|  18 +--
 .../clang-doc/json/compound-constraints.cpp   | 121 ++
 .../test/clang-doc/json/concept.cpp   |  48 +++
 .../test/clang-doc/json/function-requires.cpp |  36 +++---
 .../unittests/clang-doc/BitcodeTest.cpp   |   2 +
 19 files changed, 502 insertions(+), 56 deletions(-)
 create mode 100644 
clang-tools-extra/test/clang-doc/json/compound-constraints.cpp

diff --git a/clang-tools-extra/clang-doc/BitcodeReader.cpp 
b/clang-tools-extra/clang-doc/BitcodeReader.cpp
index 35058abab0663..5b70280e7dba8 100644
--- a/clang-tools-extra/clang-doc/BitcodeReader.cpp
+++ b/clang-tools-extra/clang-doc/BitcodeReader.cpp
@@ -92,6 +92,7 @@ static llvm::Error decodeRecord(const Record &R, InfoType 
&Field,
   case InfoType::IT_default:
   case InfoType::IT_enum:
   case InfoType::IT_typedef:
+  case InfoType::IT_concept:
 Field = IT;
 return llvm::Error::success();
   }
@@ -108,6 +109,7 @@ static llvm::Error decodeRecord(const Record &R, FieldId 
&Field,
   case FieldId::F_type:
   case FieldId::F_child_namespace:
   case FieldId::F_child_record:
+  case FieldId::F_concept:
   case FieldId::F_default:
 Field = F;
 return llvm::Error::success();
@@ -391,6 +393,29 @@ static llvm::Error parseRecord(const Record &R, unsigned 
ID,
  "invalid field for TemplateParamInfo");
 }
 
+static llvm::Error parseRecord(const Record &R, unsigned ID,
+   llvm::StringRef Blob, ConceptInfo *I) {
+  switch (ID) {
+  case CONCEPT_USR:
+return decodeRecord(R, I->USR, Blob);
+  case CONCEPT_NAME:
+return decodeRecord(R, I->Name, Blob);
+  case CONCEPT_IS_TYPE:
+return decodeRecord(R, I->IsType, Blob);
+  case CONCEPT_CONSTRAINT_EXPRESSION:
+return decodeRecord(R, I->ConstraintExpression, Blob);
+  }
+  llvm_unreachable("invalid field for ConceptInfo");
+}
+
+static llvm::Error parseRecord(const Record &R, unsigned ID,
+   llvm::StringRef Blob, ConstraintInfo *I) {
+  if (ID == CONSTRAINT_EXPRESSION)
+return decodeRecord(R, I->Expression, Blob);
+  return llvm::createStringError(llvm::inconvertibleErrorCode(),
+ "invalid field for ConstraintInfo");
+}
+
 template  static llvm::Expected getCommentInfo(T I) 
{
   return llvm::createStringError(llvm::inconvertibleErrorCode(),
  "invalid type cannot contain CommentInfo");
@@ -429,6 +454,10 @@ template <> llvm::Expected 
getCommentInfo(CommentInfo *I) {
   return I->Children.back().get();
 }
 
+template <> llvm::Expected getCommentInfo(ConceptInfo *I) {
+  return &I->Description.emplace_back();
+}
+
 // When readSubBlock encounters a TypeInfo sub-block, it calls addTypeInfo on
 // the parent block to set it. The template specializations define what to do
 // for each supported parent block.
@@ -584,6 +613,18 @@ template <> llvm::Error addReference(RecordInfo *I, 
Reference &&R, FieldId F) {
   }
 }
 
+template <>
+llvm::Error addReference(ConstraintInfo *I, Reference &&R, FieldId F) {
+  switch (F) {
+  case FieldId::F_concept:
+I->ConceptRef = std::move(R);
+return llvm::Error::success();
+  default:
+return llvm::createStringError(llvm::inconvertibleErrorCode(),
+   "invalid type cannot contain Reference");
+  }
+}
+
 template 
 static void addChild(T I, ChildInfoType &&R) {
   llvm::errs() << "invalid child type for info";
@@ -600,6 +641,9 @@ template <> void addChild(NamespaceInfo *I, EnumInfo &&R) {
 template <> void addChild(NamespaceInfo *I, TypedefInfo &&R) {
   I->Children.Typedefs.emplace_back(std::move(R));
 }
+template <> void addChild(NamespaceInfo *I, ConceptInfo &&R) {
+  I->Children.Concepts.emplace_back(std::move(R));
+}
 
 // Record children:
 template <> void addChild(RecordInfo *I, FunctionInfo &&R) {
@@ -6

[llvm-branch-commits] [llvm] RuntimeLibcalls: Pass in exception handling type (PR #144696)

2025-06-19 Thread Matt Arsenault via llvm-branch-commits

arsenm wrote:

### Merge activity

* **Jun 19, 9:57 AM UTC**: A user started a stack merge that includes this pull 
request via 
[Graphite](https://app.graphite.dev/github/pr/llvm/llvm-project/144696).


https://github.com/llvm/llvm-project/pull/144696
___
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: Add waterfall lowering in regbanklegalize (PR #142790)

2025-06-19 Thread Petar Avramovic via llvm-branch-commits

petar-avramovic wrote:

ping

https://github.com/llvm/llvm-project/pull/142790
___
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] [BOLT] Gadget scanner: prevent false positives due to jump tables (PR #138884)

2025-06-19 Thread Anatoly Trosinenko via llvm-branch-commits

https://github.com/atrosinenko updated 
https://github.com/llvm/llvm-project/pull/138884

>From e72572049530d58764cff1ce1081c1765838188a Mon Sep 17 00:00:00 2001
From: Anatoly Trosinenko 
Date: Tue, 6 May 2025 11:31:03 +0300
Subject: [PATCH] [BOLT] Gadget scanner: prevent false positives due to jump
 tables

As part of PAuth hardening, AArch64 LLVM backend can use a special
BR_JumpTable pseudo (enabled by -faarch64-jump-table-hardening
Clang option) which is expanded in the AsmPrinter into a contiguous
sequence without unsafe instructions in the middle.

This commit adds another target-specific callback to MCPlusBuilder
to make it possible to inhibit false positives for known-safe jump
table dispatch sequences. Without special handling, the branch
instruction is likely to be reported as a non-protected call (as its
destination is not produced by an auth instruction, PC-relative address
materialization, etc.) and possibly as a tail call being performed with
unsafe link register (as the detection whether the branch instruction
is a tail call is an heuristic).

For now, only the specific instruction sequence used by the AArch64
LLVM backend is matched.
---
 bolt/include/bolt/Core/MCInstUtils.h  |   9 +
 bolt/include/bolt/Core/MCPlusBuilder.h|  14 +
 bolt/lib/Core/MCInstUtils.cpp |  20 +
 bolt/lib/Passes/PAuthGadgetScanner.cpp|  10 +
 .../Target/AArch64/AArch64MCPlusBuilder.cpp   |  73 ++
 .../AArch64/gs-pauth-jump-table.s | 703 ++
 6 files changed, 829 insertions(+)
 create mode 100644 bolt/test/binary-analysis/AArch64/gs-pauth-jump-table.s

diff --git a/bolt/include/bolt/Core/MCInstUtils.h 
b/bolt/include/bolt/Core/MCInstUtils.h
index 50b7d56470c99..33d36cccbcfff 100644
--- a/bolt/include/bolt/Core/MCInstUtils.h
+++ b/bolt/include/bolt/Core/MCInstUtils.h
@@ -154,6 +154,15 @@ class MCInstReference {
 return nullptr;
   }
 
+  /// Returns the only preceding instruction, or std::nullopt if multiple or no
+  /// predecessors are possible.
+  ///
+  /// If CFG information is available, basic block boundary can be crossed,
+  /// provided there is exactly one predecessor. If CFG is not available, the
+  /// preceding instruction in the offset order is returned, unless this is the
+  /// first instruction of the function.
+  std::optional getSinglePredecessor();
+
   raw_ostream &print(raw_ostream &OS) const;
 };
 
diff --git a/bolt/include/bolt/Core/MCPlusBuilder.h 
b/bolt/include/bolt/Core/MCPlusBuilder.h
index c31c9984ed43e..b6f70fc831fca 100644
--- a/bolt/include/bolt/Core/MCPlusBuilder.h
+++ b/bolt/include/bolt/Core/MCPlusBuilder.h
@@ -14,6 +14,7 @@
 #ifndef BOLT_CORE_MCPLUSBUILDER_H
 #define BOLT_CORE_MCPLUSBUILDER_H
 
+#include "bolt/Core/MCInstUtils.h"
 #include "bolt/Core/MCPlus.h"
 #include "bolt/Core/Relocation.h"
 #include "llvm/ADT/ArrayRef.h"
@@ -700,6 +701,19 @@ class MCPlusBuilder {
 return std::nullopt;
   }
 
+  /// Tests if BranchInst corresponds to an instruction sequence which is known
+  /// to be a safe dispatch via jump table.
+  ///
+  /// The target can decide which instruction sequences to consider "safe" from
+  /// the Pointer Authentication point of view, such as any jump table dispatch
+  /// sequence without function calls inside, any sequence which is contiguous,
+  /// or only some specific well-known sequences.
+  virtual bool
+  isSafeJumpTableBranchForPtrAuth(MCInstReference BranchInst) const {
+llvm_unreachable("not implemented");
+return false;
+  }
+
   virtual bool isTerminator(const MCInst &Inst) const;
 
   virtual bool isNoop(const MCInst &Inst) const {
diff --git a/bolt/lib/Core/MCInstUtils.cpp b/bolt/lib/Core/MCInstUtils.cpp
index 40f6edd59135c..b7c6d898988af 100644
--- a/bolt/lib/Core/MCInstUtils.cpp
+++ b/bolt/lib/Core/MCInstUtils.cpp
@@ -55,3 +55,23 @@ raw_ostream &MCInstReference::print(raw_ostream &OS) const {
   OS << ">";
   return OS;
 }
+
+std::optional MCInstReference::getSinglePredecessor() {
+  if (const RefInBB *Ref = tryGetRefInBB()) {
+if (Ref->It != Ref->BB->begin())
+  return MCInstReference(Ref->BB, &*std::prev(Ref->It));
+
+if (Ref->BB->pred_size() != 1)
+  return std::nullopt;
+
+BinaryBasicBlock *PredBB = *Ref->BB->pred_begin();
+assert(!PredBB->empty() && "Empty basic blocks are not supported yet");
+return MCInstReference(PredBB, &*PredBB->rbegin());
+  }
+
+  const RefInBF &Ref = getRefInBF();
+  if (Ref.It == Ref.BF->instrs().begin())
+return std::nullopt;
+
+  return MCInstReference(Ref.BF, std::prev(Ref.It));
+}
diff --git a/bolt/lib/Passes/PAuthGadgetScanner.cpp 
b/bolt/lib/Passes/PAuthGadgetScanner.cpp
index ee873f7c2c21d..3514c953030a6 100644
--- a/bolt/lib/Passes/PAuthGadgetScanner.cpp
+++ b/bolt/lib/Passes/PAuthGadgetScanner.cpp
@@ -1363,6 +1363,11 @@ shouldReportUnsafeTailCall(const BinaryContext &BC, 
const BinaryFunction &BF,
 return std::nullopt;
   }
 
+  if (BC.MIB->isSafeJumpTableBranchForPtrAuth(Inst)) {
+LL

[llvm-branch-commits] [llvm] [BOLT] Gadget scanner: detect untrusted LR before tail call (PR #137224)

2025-06-19 Thread Anatoly Trosinenko via llvm-branch-commits

https://github.com/atrosinenko updated 
https://github.com/llvm/llvm-project/pull/137224

>From a0c9617031dd31157686a519743048e12c01ac97 Mon Sep 17 00:00:00 2001
From: Anatoly Trosinenko 
Date: Tue, 22 Apr 2025 21:43:14 +0300
Subject: [PATCH] [BOLT] Gadget scanner: detect untrusted LR before tail call

Implement the detection of tail calls performed with untrusted link
register, which violates the assumption made on entry to every function.

Unlike other pauth gadgets, this one involves some amount of guessing
which branch instructions should be checked as tail calls.
---
 bolt/lib/Passes/PAuthGadgetScanner.cpp|  80 +++
 .../AArch64/gs-pauth-tail-calls.s | 597 ++
 2 files changed, 677 insertions(+)
 create mode 100644 bolt/test/binary-analysis/AArch64/gs-pauth-tail-calls.s

diff --git a/bolt/lib/Passes/PAuthGadgetScanner.cpp 
b/bolt/lib/Passes/PAuthGadgetScanner.cpp
index 05309a47aba40..b5b46390d4586 100644
--- a/bolt/lib/Passes/PAuthGadgetScanner.cpp
+++ b/bolt/lib/Passes/PAuthGadgetScanner.cpp
@@ -1319,6 +1319,83 @@ shouldReportReturnGadget(const BinaryContext &BC, const 
MCInstReference &Inst,
   return make_gadget_report(RetKind, Inst, *RetReg);
 }
 
+/// While BOLT already marks some of the branch instructions as tail calls,
+/// this function tries to improve the coverage by including less obvious cases
+/// when it is possible to do without introducing too many false positives.
+static bool shouldAnalyzeTailCallInst(const BinaryContext &BC,
+  const BinaryFunction &BF,
+  const MCInstReference &Inst) {
+  // Some BC.MIB->isXYZ(Inst) methods simply delegate to MCInstrDesc::isXYZ()
+  // (such as isBranch at the time of writing this comment), some don't (such
+  // as isCall). For that reason, call MCInstrDesc's methods explicitly when
+  // it is important.
+  const MCInstrDesc &Desc =
+  BC.MII->get(static_cast(Inst).getOpcode());
+  // Tail call should be a branch (but not necessarily an indirect one).
+  if (!Desc.isBranch())
+return false;
+
+  // Always analyze the branches already marked as tail calls by BOLT.
+  if (BC.MIB->isTailCall(Inst))
+return true;
+
+  // Try to also check the branches marked as "UNKNOWN CONTROL FLOW" - the
+  // below is a simplified condition from BinaryContext::printInstruction.
+  bool IsUnknownControlFlow =
+  BC.MIB->isIndirectBranch(Inst) && !BC.MIB->getJumpTable(Inst);
+
+  if (BF.hasCFG() && IsUnknownControlFlow)
+return true;
+
+  return false;
+}
+
+static std::optional>
+shouldReportUnsafeTailCall(const BinaryContext &BC, const BinaryFunction &BF,
+   const MCInstReference &Inst, const SrcState &S) {
+  static const GadgetKind UntrustedLRKind(
+  "untrusted link register found before tail call");
+
+  if (!shouldAnalyzeTailCallInst(BC, BF, Inst))
+return std::nullopt;
+
+  // Not only the set of registers returned by getTrustedLiveInRegs() can be
+  // seen as a reasonable target-independent _approximation_ of "the LR", these
+  // are *exactly* those registers used by SrcSafetyAnalysis to initialize the
+  // set of trusted registers on function entry.
+  // Thus, this function basically checks that the precondition expected to be
+  // imposed by a function call instruction (which is hardcoded into the 
target-
+  // specific getTrustedLiveInRegs() function) is also respected on tail calls.
+  SmallVector RegsToCheck = BC.MIB->getTrustedLiveInRegs();
+  LLVM_DEBUG({
+traceInst(BC, "Found tail call inst", Inst);
+traceRegMask(BC, "Trusted regs", S.TrustedRegs);
+  });
+
+  // In musl on AArch64, the _start function sets LR to zero and calls the next
+  // stage initialization function at the end, something along these lines:
+  //
+  //   _start:
+  // mov x30, #0
+  // ; ... other initialization ...
+  // b   _start_c ; performs "exit" system call at some point
+  //
+  // As this would produce a false positive for every executable linked with
+  // such libc, ignore tail calls performed by ELF entry function.
+  if (BC.StartFunctionAddress &&
+  *BC.StartFunctionAddress == Inst.getFunction()->getAddress()) {
+LLVM_DEBUG({ dbgs() << "  Skipping tail call in ELF entry function.\n"; });
+return std::nullopt;
+  }
+
+  // Returns at most one report per instruction - this is probably OK...
+  for (auto Reg : RegsToCheck)
+if (!S.TrustedRegs[Reg])
+  return make_gadget_report(UntrustedLRKind, Inst, Reg);
+
+  return std::nullopt;
+}
+
 static std::optional>
 shouldReportCallGadget(const BinaryContext &BC, const MCInstReference &Inst,
const SrcState &S) {
@@ -1473,6 +1550,9 @@ void FunctionAnalysisContext::findUnsafeUses(
 if (PacRetGadgetsOnly)
   return;
 
+if (auto Report = shouldReportUnsafeTailCall(BC, BF, Inst, S))
+  Reports.push_back(*Report);
+
 if (auto Report = shouldReportCallGadget(BC, Inst, S))

[llvm-branch-commits] [llvm] [LoopVectorizer] Bundle partial reductions with different extensions (PR #136997)

2025-06-19 Thread Sam Tebbs via llvm-branch-commits

SamTebbs33 wrote:

Superseded by https://github.com/llvm/llvm-project/pull/144908

https://github.com/llvm/llvm-project/pull/136997
___
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] [LoopVectorizer] Bundle partial reductions with different extensions (PR #136997)

2025-06-19 Thread Sam Tebbs via llvm-branch-commits

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


[llvm-branch-commits] [flang] [mlir] [flang][OpenMP][NFC] remove globals with mlir::StateStack (PR #144898)

2025-06-19 Thread via llvm-branch-commits

llvmbot wrote:




@llvm/pr-subscribers-flang-fir-hlfir

Author: Tom Eccles (tblah)


Changes

Idea suggested by @skatrak

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


4 Files Affected:

- (modified) flang/include/flang/Lower/AbstractConverter.h (+3) 
- (modified) flang/lib/Lower/Bridge.cpp (+6) 
- (modified) flang/lib/Lower/OpenMP/OpenMP.cpp (+71-31) 
- (modified) mlir/include/mlir/Support/StateStack.h (+11) 


``diff
diff --git a/flang/include/flang/Lower/AbstractConverter.h 
b/flang/include/flang/Lower/AbstractConverter.h
index 8ae68e143cd2f..de3e833f60699 100644
--- a/flang/include/flang/Lower/AbstractConverter.h
+++ b/flang/include/flang/Lower/AbstractConverter.h
@@ -26,6 +26,7 @@
 
 namespace mlir {
 class SymbolTable;
+class StateStack;
 }
 
 namespace fir {
@@ -361,6 +362,8 @@ class AbstractConverter {
   /// functions in order to be in sync).
   virtual mlir::SymbolTable *getMLIRSymbolTable() = 0;
 
+  virtual mlir::StateStack &getStateStack() = 0;
+
 private:
   /// Options controlling lowering behavior.
   const Fortran::lower::LoweringOptions &loweringOptions;
diff --git a/flang/lib/Lower/Bridge.cpp b/flang/lib/Lower/Bridge.cpp
index 64b16b3abe991..462ceb8dff736 100644
--- a/flang/lib/Lower/Bridge.cpp
+++ b/flang/lib/Lower/Bridge.cpp
@@ -78,6 +78,7 @@
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/Path.h"
 #include "llvm/Target/TargetMachine.h"
+#include "mlir/Support/StateStack.h"
 #include 
 
 #define DEBUG_TYPE "flang-lower-bridge"
@@ -1237,6 +1238,8 @@ class FirConverter : public 
Fortran::lower::AbstractConverter {
 
   mlir::SymbolTable *getMLIRSymbolTable() override { return &mlirSymbolTable; }
 
+  mlir::StateStack &getStateStack() override { return stateStack; }
+
   /// Add the symbol to the local map and return `true`. If the symbol is
   /// already in the map and \p forced is `false`, the map is not updated.
   /// Instead the value `false` is returned.
@@ -6552,6 +6555,9 @@ class FirConverter : public 
Fortran::lower::AbstractConverter {
   /// attribute since mlirSymbolTable must pro-actively be maintained when
   /// new Symbol operations are created.
   mlir::SymbolTable mlirSymbolTable;
+
+  /// Used to store context while recursing into regions during lowering.
+  mlir::StateStack stateStack;
 };
 
 } // namespace
diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp 
b/flang/lib/Lower/OpenMP/OpenMP.cpp
index 7ad8869597274..bff3321af2814 100644
--- a/flang/lib/Lower/OpenMP/OpenMP.cpp
+++ b/flang/lib/Lower/OpenMP/OpenMP.cpp
@@ -38,6 +38,7 @@
 #include "flang/Support/OpenMP-utils.h"
 #include "mlir/Dialect/ControlFlow/IR/ControlFlowOps.h"
 #include "mlir/Dialect/OpenMP/OpenMPDialect.h"
+#include "mlir/Support/StateStack.h"
 #include "mlir/Transforms/RegionUtils.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/Frontend/OpenMP/OMPConstants.h"
@@ -200,9 +201,41 @@ class HostEvalInfo {
 /// the handling of the outer region by keeping a stack of information
 /// structures, but it will probably still require some further work to support
 /// reverse offloading.
-static llvm::SmallVector hostEvalInfo;
-static llvm::SmallVector
-sectionsStack;
+class HostEvalInfoStackFrame
+: public mlir::StateStackFrameBase {
+public:
+  MLIR_DEFINE_EXPLICIT_INTERNAL_INLINE_TYPE_ID(HostEvalInfoStackFrame)
+
+  HostEvalInfo info;
+};
+
+static HostEvalInfo *
+getHostEvalInfoStackTop(lower::AbstractConverter &converter) {
+  HostEvalInfoStackFrame *frame =
+  converter.getStateStack().getStackTop();
+  return frame ? &frame->info : nullptr;
+}
+
+/// Stack frame for storing the OpenMPSectionsConstruct currently being
+/// processed so that it can be refered to when lowering the construct.
+class SectionsConstructStackFrame
+: public mlir::StateStackFrameBase {
+public:
+  MLIR_DEFINE_EXPLICIT_INTERNAL_INLINE_TYPE_ID(SectionsConstructStackFrame)
+
+  explicit SectionsConstructStackFrame(
+  const parser::OpenMPSectionsConstruct §ionsConstruct)
+  : sectionsConstruct{sectionsConstruct} {}
+
+  const parser::OpenMPSectionsConstruct §ionsConstruct;
+};
+
+static const parser::OpenMPSectionsConstruct *
+getSectionsConstructStackTop(lower::AbstractConverter &converter) {
+  SectionsConstructStackFrame *frame =
+  converter.getStateStack().getStackTop();
+  return frame ? &frame->sectionsConstruct : nullptr;
+}
 
 /// Bind symbols to their corresponding entry block arguments.
 ///
@@ -537,31 +570,32 @@ static void 
processHostEvalClauses(lower::AbstractConverter &converter,
 if (!ompEval)
   return;
 
-HostEvalInfo &hostInfo = hostEvalInfo.back();
+HostEvalInfo *hostInfo = getHostEvalInfoStackTop(converter);
+assert(hostInfo && "expected HOST_EVAL info structure");
 
 switch (extractOmpDirective(*ompEval)) {
 case OMPD_teams_distribute_parallel_do:
 case OMPD_teams_distribute_parallel_do_simd:
-  cp.processThreadLimit(stmtCtx, hostInfo.ops);
+  cp.processThreadLimit(stmtCtx, hostInfo->ops);
  

[llvm-branch-commits] [flang] [mlir] [flang][OpenMP][NFC] remove globals with mlir::StateStack (PR #144898)

2025-06-19 Thread via llvm-branch-commits

llvmbot wrote:




@llvm/pr-subscribers-mlir-core

Author: Tom Eccles (tblah)


Changes

Idea suggested by @skatrak

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


4 Files Affected:

- (modified) flang/include/flang/Lower/AbstractConverter.h (+3) 
- (modified) flang/lib/Lower/Bridge.cpp (+6) 
- (modified) flang/lib/Lower/OpenMP/OpenMP.cpp (+71-31) 
- (modified) mlir/include/mlir/Support/StateStack.h (+11) 


``diff
diff --git a/flang/include/flang/Lower/AbstractConverter.h 
b/flang/include/flang/Lower/AbstractConverter.h
index 8ae68e143cd2f..de3e833f60699 100644
--- a/flang/include/flang/Lower/AbstractConverter.h
+++ b/flang/include/flang/Lower/AbstractConverter.h
@@ -26,6 +26,7 @@
 
 namespace mlir {
 class SymbolTable;
+class StateStack;
 }
 
 namespace fir {
@@ -361,6 +362,8 @@ class AbstractConverter {
   /// functions in order to be in sync).
   virtual mlir::SymbolTable *getMLIRSymbolTable() = 0;
 
+  virtual mlir::StateStack &getStateStack() = 0;
+
 private:
   /// Options controlling lowering behavior.
   const Fortran::lower::LoweringOptions &loweringOptions;
diff --git a/flang/lib/Lower/Bridge.cpp b/flang/lib/Lower/Bridge.cpp
index 64b16b3abe991..462ceb8dff736 100644
--- a/flang/lib/Lower/Bridge.cpp
+++ b/flang/lib/Lower/Bridge.cpp
@@ -78,6 +78,7 @@
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/Path.h"
 #include "llvm/Target/TargetMachine.h"
+#include "mlir/Support/StateStack.h"
 #include 
 
 #define DEBUG_TYPE "flang-lower-bridge"
@@ -1237,6 +1238,8 @@ class FirConverter : public 
Fortran::lower::AbstractConverter {
 
   mlir::SymbolTable *getMLIRSymbolTable() override { return &mlirSymbolTable; }
 
+  mlir::StateStack &getStateStack() override { return stateStack; }
+
   /// Add the symbol to the local map and return `true`. If the symbol is
   /// already in the map and \p forced is `false`, the map is not updated.
   /// Instead the value `false` is returned.
@@ -6552,6 +6555,9 @@ class FirConverter : public 
Fortran::lower::AbstractConverter {
   /// attribute since mlirSymbolTable must pro-actively be maintained when
   /// new Symbol operations are created.
   mlir::SymbolTable mlirSymbolTable;
+
+  /// Used to store context while recursing into regions during lowering.
+  mlir::StateStack stateStack;
 };
 
 } // namespace
diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp 
b/flang/lib/Lower/OpenMP/OpenMP.cpp
index 7ad8869597274..bff3321af2814 100644
--- a/flang/lib/Lower/OpenMP/OpenMP.cpp
+++ b/flang/lib/Lower/OpenMP/OpenMP.cpp
@@ -38,6 +38,7 @@
 #include "flang/Support/OpenMP-utils.h"
 #include "mlir/Dialect/ControlFlow/IR/ControlFlowOps.h"
 #include "mlir/Dialect/OpenMP/OpenMPDialect.h"
+#include "mlir/Support/StateStack.h"
 #include "mlir/Transforms/RegionUtils.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/Frontend/OpenMP/OMPConstants.h"
@@ -200,9 +201,41 @@ class HostEvalInfo {
 /// the handling of the outer region by keeping a stack of information
 /// structures, but it will probably still require some further work to support
 /// reverse offloading.
-static llvm::SmallVector hostEvalInfo;
-static llvm::SmallVector
-sectionsStack;
+class HostEvalInfoStackFrame
+: public mlir::StateStackFrameBase {
+public:
+  MLIR_DEFINE_EXPLICIT_INTERNAL_INLINE_TYPE_ID(HostEvalInfoStackFrame)
+
+  HostEvalInfo info;
+};
+
+static HostEvalInfo *
+getHostEvalInfoStackTop(lower::AbstractConverter &converter) {
+  HostEvalInfoStackFrame *frame =
+  converter.getStateStack().getStackTop();
+  return frame ? &frame->info : nullptr;
+}
+
+/// Stack frame for storing the OpenMPSectionsConstruct currently being
+/// processed so that it can be refered to when lowering the construct.
+class SectionsConstructStackFrame
+: public mlir::StateStackFrameBase {
+public:
+  MLIR_DEFINE_EXPLICIT_INTERNAL_INLINE_TYPE_ID(SectionsConstructStackFrame)
+
+  explicit SectionsConstructStackFrame(
+  const parser::OpenMPSectionsConstruct §ionsConstruct)
+  : sectionsConstruct{sectionsConstruct} {}
+
+  const parser::OpenMPSectionsConstruct §ionsConstruct;
+};
+
+static const parser::OpenMPSectionsConstruct *
+getSectionsConstructStackTop(lower::AbstractConverter &converter) {
+  SectionsConstructStackFrame *frame =
+  converter.getStateStack().getStackTop();
+  return frame ? &frame->sectionsConstruct : nullptr;
+}
 
 /// Bind symbols to their corresponding entry block arguments.
 ///
@@ -537,31 +570,32 @@ static void 
processHostEvalClauses(lower::AbstractConverter &converter,
 if (!ompEval)
   return;
 
-HostEvalInfo &hostInfo = hostEvalInfo.back();
+HostEvalInfo *hostInfo = getHostEvalInfoStackTop(converter);
+assert(hostInfo && "expected HOST_EVAL info structure");
 
 switch (extractOmpDirective(*ompEval)) {
 case OMPD_teams_distribute_parallel_do:
 case OMPD_teams_distribute_parallel_do_simd:
-  cp.processThreadLimit(stmtCtx, hostInfo.ops);
+  cp.processThreadLimit(stmtCtx, hostInfo->ops);
   [[fal

[llvm-branch-commits] [flang] [mlir] [flang][OpenMP][NFC] remove globals with mlir::StateStack (PR #144898)

2025-06-19 Thread Tom Eccles via llvm-branch-commits

tblah wrote:

1. https://github.com/llvm/llvm-project/pull/144897
2. https://github.com/llvm/llvm-project/pull/144898

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


[llvm-branch-commits] [flang] [mlir] [flang][OpenMP][NFC] remove globals with mlir::StateStack (PR #144898)

2025-06-19 Thread Tom Eccles via llvm-branch-commits

https://github.com/tblah created 
https://github.com/llvm/llvm-project/pull/144898

Idea suggested by @skatrak

>From 280e55d4355f100b7d3066fce3c0515b369fecce Mon Sep 17 00:00:00 2001
From: Tom Eccles 
Date: Wed, 18 Jun 2025 21:01:13 +
Subject: [PATCH] [flang][OpenMP][NFC] remove globals with mlir::StateStack

Idea suggested by @skatrak
---
 flang/include/flang/Lower/AbstractConverter.h |   3 +
 flang/lib/Lower/Bridge.cpp|   6 ++
 flang/lib/Lower/OpenMP/OpenMP.cpp | 102 --
 mlir/include/mlir/Support/StateStack.h|  11 ++
 4 files changed, 91 insertions(+), 31 deletions(-)

diff --git a/flang/include/flang/Lower/AbstractConverter.h 
b/flang/include/flang/Lower/AbstractConverter.h
index 8ae68e143cd2f..de3e833f60699 100644
--- a/flang/include/flang/Lower/AbstractConverter.h
+++ b/flang/include/flang/Lower/AbstractConverter.h
@@ -26,6 +26,7 @@
 
 namespace mlir {
 class SymbolTable;
+class StateStack;
 }
 
 namespace fir {
@@ -361,6 +362,8 @@ class AbstractConverter {
   /// functions in order to be in sync).
   virtual mlir::SymbolTable *getMLIRSymbolTable() = 0;
 
+  virtual mlir::StateStack &getStateStack() = 0;
+
 private:
   /// Options controlling lowering behavior.
   const Fortran::lower::LoweringOptions &loweringOptions;
diff --git a/flang/lib/Lower/Bridge.cpp b/flang/lib/Lower/Bridge.cpp
index 64b16b3abe991..462ceb8dff736 100644
--- a/flang/lib/Lower/Bridge.cpp
+++ b/flang/lib/Lower/Bridge.cpp
@@ -78,6 +78,7 @@
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/Path.h"
 #include "llvm/Target/TargetMachine.h"
+#include "mlir/Support/StateStack.h"
 #include 
 
 #define DEBUG_TYPE "flang-lower-bridge"
@@ -1237,6 +1238,8 @@ class FirConverter : public 
Fortran::lower::AbstractConverter {
 
   mlir::SymbolTable *getMLIRSymbolTable() override { return &mlirSymbolTable; }
 
+  mlir::StateStack &getStateStack() override { return stateStack; }
+
   /// Add the symbol to the local map and return `true`. If the symbol is
   /// already in the map and \p forced is `false`, the map is not updated.
   /// Instead the value `false` is returned.
@@ -6552,6 +6555,9 @@ class FirConverter : public 
Fortran::lower::AbstractConverter {
   /// attribute since mlirSymbolTable must pro-actively be maintained when
   /// new Symbol operations are created.
   mlir::SymbolTable mlirSymbolTable;
+
+  /// Used to store context while recursing into regions during lowering.
+  mlir::StateStack stateStack;
 };
 
 } // namespace
diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp 
b/flang/lib/Lower/OpenMP/OpenMP.cpp
index 7ad8869597274..bff3321af2814 100644
--- a/flang/lib/Lower/OpenMP/OpenMP.cpp
+++ b/flang/lib/Lower/OpenMP/OpenMP.cpp
@@ -38,6 +38,7 @@
 #include "flang/Support/OpenMP-utils.h"
 #include "mlir/Dialect/ControlFlow/IR/ControlFlowOps.h"
 #include "mlir/Dialect/OpenMP/OpenMPDialect.h"
+#include "mlir/Support/StateStack.h"
 #include "mlir/Transforms/RegionUtils.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/Frontend/OpenMP/OMPConstants.h"
@@ -200,9 +201,41 @@ class HostEvalInfo {
 /// the handling of the outer region by keeping a stack of information
 /// structures, but it will probably still require some further work to support
 /// reverse offloading.
-static llvm::SmallVector hostEvalInfo;
-static llvm::SmallVector
-sectionsStack;
+class HostEvalInfoStackFrame
+: public mlir::StateStackFrameBase {
+public:
+  MLIR_DEFINE_EXPLICIT_INTERNAL_INLINE_TYPE_ID(HostEvalInfoStackFrame)
+
+  HostEvalInfo info;
+};
+
+static HostEvalInfo *
+getHostEvalInfoStackTop(lower::AbstractConverter &converter) {
+  HostEvalInfoStackFrame *frame =
+  converter.getStateStack().getStackTop();
+  return frame ? &frame->info : nullptr;
+}
+
+/// Stack frame for storing the OpenMPSectionsConstruct currently being
+/// processed so that it can be refered to when lowering the construct.
+class SectionsConstructStackFrame
+: public mlir::StateStackFrameBase {
+public:
+  MLIR_DEFINE_EXPLICIT_INTERNAL_INLINE_TYPE_ID(SectionsConstructStackFrame)
+
+  explicit SectionsConstructStackFrame(
+  const parser::OpenMPSectionsConstruct §ionsConstruct)
+  : sectionsConstruct{sectionsConstruct} {}
+
+  const parser::OpenMPSectionsConstruct §ionsConstruct;
+};
+
+static const parser::OpenMPSectionsConstruct *
+getSectionsConstructStackTop(lower::AbstractConverter &converter) {
+  SectionsConstructStackFrame *frame =
+  converter.getStateStack().getStackTop();
+  return frame ? &frame->sectionsConstruct : nullptr;
+}
 
 /// Bind symbols to their corresponding entry block arguments.
 ///
@@ -537,31 +570,32 @@ static void 
processHostEvalClauses(lower::AbstractConverter &converter,
 if (!ompEval)
   return;
 
-HostEvalInfo &hostInfo = hostEvalInfo.back();
+HostEvalInfo *hostInfo = getHostEvalInfoStackTop(converter);
+assert(hostInfo && "expected HOST_EVAL info structure");
 
 switch (extractOmpDirective(*ompEval)) {
 case OMPD_teams_distr

[llvm-branch-commits] [llvm] [AMDGPU] Improve test coverage for G_INTTOPTR and G_PTRTOINT (PR #142603)

2025-06-19 Thread Pierre van Houtryve via llvm-branch-commits

Pierre-vh wrote:

### Merge activity

* **Jun 19, 7:48 AM UTC**: A user started a stack merge that includes this pull 
request via 
[Graphite](https://app.graphite.dev/github/pr/llvm/llvm-project/142603).


https://github.com/llvm/llvm-project/pull/142603
___
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] New RegBankSelect: Add Ptr32/Ptr64/Ptr128 (PR #142602)

2025-06-19 Thread Pierre van Houtryve via llvm-branch-commits

Pierre-vh wrote:

### Merge activity

* **Jun 19, 7:48 AM UTC**: A user started a stack merge that includes this pull 
request via 
[Graphite](https://app.graphite.dev/github/pr/llvm/llvm-project/142602).


https://github.com/llvm/llvm-project/pull/142602
___
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] New RegBanKSelect: Add S128 types (PR #142601)

2025-06-19 Thread Pierre van Houtryve via llvm-branch-commits

Pierre-vh wrote:

### Merge activity

* **Jun 19, 7:48 AM UTC**: A user started a stack merge that includes this pull 
request via 
[Graphite](https://app.graphite.dev/github/pr/llvm/llvm-project/142601).


https://github.com/llvm/llvm-project/pull/142601
___
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] New RegBankSelect: Add rules for `G_PTRTOINT` and `G_INTTOPTR` (PR #142604)

2025-06-19 Thread Pierre van Houtryve via llvm-branch-commits

Pierre-vh wrote:

### Merge activity

* **Jun 19, 7:48 AM UTC**: A user started a stack merge that includes this pull 
request via 
[Graphite](https://app.graphite.dev/github/pr/llvm/llvm-project/142604).


https://github.com/llvm/llvm-project/pull/142604
___
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] [BOLT] Gadget scanner: detect untrusted LR before tail call (PR #137224)

2025-06-19 Thread Anatoly Trosinenko via llvm-branch-commits

https://github.com/atrosinenko updated 
https://github.com/llvm/llvm-project/pull/137224

>From a0c9617031dd31157686a519743048e12c01ac97 Mon Sep 17 00:00:00 2001
From: Anatoly Trosinenko 
Date: Tue, 22 Apr 2025 21:43:14 +0300
Subject: [PATCH] [BOLT] Gadget scanner: detect untrusted LR before tail call

Implement the detection of tail calls performed with untrusted link
register, which violates the assumption made on entry to every function.

Unlike other pauth gadgets, this one involves some amount of guessing
which branch instructions should be checked as tail calls.
---
 bolt/lib/Passes/PAuthGadgetScanner.cpp|  80 +++
 .../AArch64/gs-pauth-tail-calls.s | 597 ++
 2 files changed, 677 insertions(+)
 create mode 100644 bolt/test/binary-analysis/AArch64/gs-pauth-tail-calls.s

diff --git a/bolt/lib/Passes/PAuthGadgetScanner.cpp 
b/bolt/lib/Passes/PAuthGadgetScanner.cpp
index 05309a47aba40..b5b46390d4586 100644
--- a/bolt/lib/Passes/PAuthGadgetScanner.cpp
+++ b/bolt/lib/Passes/PAuthGadgetScanner.cpp
@@ -1319,6 +1319,83 @@ shouldReportReturnGadget(const BinaryContext &BC, const 
MCInstReference &Inst,
   return make_gadget_report(RetKind, Inst, *RetReg);
 }
 
+/// While BOLT already marks some of the branch instructions as tail calls,
+/// this function tries to improve the coverage by including less obvious cases
+/// when it is possible to do without introducing too many false positives.
+static bool shouldAnalyzeTailCallInst(const BinaryContext &BC,
+  const BinaryFunction &BF,
+  const MCInstReference &Inst) {
+  // Some BC.MIB->isXYZ(Inst) methods simply delegate to MCInstrDesc::isXYZ()
+  // (such as isBranch at the time of writing this comment), some don't (such
+  // as isCall). For that reason, call MCInstrDesc's methods explicitly when
+  // it is important.
+  const MCInstrDesc &Desc =
+  BC.MII->get(static_cast(Inst).getOpcode());
+  // Tail call should be a branch (but not necessarily an indirect one).
+  if (!Desc.isBranch())
+return false;
+
+  // Always analyze the branches already marked as tail calls by BOLT.
+  if (BC.MIB->isTailCall(Inst))
+return true;
+
+  // Try to also check the branches marked as "UNKNOWN CONTROL FLOW" - the
+  // below is a simplified condition from BinaryContext::printInstruction.
+  bool IsUnknownControlFlow =
+  BC.MIB->isIndirectBranch(Inst) && !BC.MIB->getJumpTable(Inst);
+
+  if (BF.hasCFG() && IsUnknownControlFlow)
+return true;
+
+  return false;
+}
+
+static std::optional>
+shouldReportUnsafeTailCall(const BinaryContext &BC, const BinaryFunction &BF,
+   const MCInstReference &Inst, const SrcState &S) {
+  static const GadgetKind UntrustedLRKind(
+  "untrusted link register found before tail call");
+
+  if (!shouldAnalyzeTailCallInst(BC, BF, Inst))
+return std::nullopt;
+
+  // Not only the set of registers returned by getTrustedLiveInRegs() can be
+  // seen as a reasonable target-independent _approximation_ of "the LR", these
+  // are *exactly* those registers used by SrcSafetyAnalysis to initialize the
+  // set of trusted registers on function entry.
+  // Thus, this function basically checks that the precondition expected to be
+  // imposed by a function call instruction (which is hardcoded into the 
target-
+  // specific getTrustedLiveInRegs() function) is also respected on tail calls.
+  SmallVector RegsToCheck = BC.MIB->getTrustedLiveInRegs();
+  LLVM_DEBUG({
+traceInst(BC, "Found tail call inst", Inst);
+traceRegMask(BC, "Trusted regs", S.TrustedRegs);
+  });
+
+  // In musl on AArch64, the _start function sets LR to zero and calls the next
+  // stage initialization function at the end, something along these lines:
+  //
+  //   _start:
+  // mov x30, #0
+  // ; ... other initialization ...
+  // b   _start_c ; performs "exit" system call at some point
+  //
+  // As this would produce a false positive for every executable linked with
+  // such libc, ignore tail calls performed by ELF entry function.
+  if (BC.StartFunctionAddress &&
+  *BC.StartFunctionAddress == Inst.getFunction()->getAddress()) {
+LLVM_DEBUG({ dbgs() << "  Skipping tail call in ELF entry function.\n"; });
+return std::nullopt;
+  }
+
+  // Returns at most one report per instruction - this is probably OK...
+  for (auto Reg : RegsToCheck)
+if (!S.TrustedRegs[Reg])
+  return make_gadget_report(UntrustedLRKind, Inst, Reg);
+
+  return std::nullopt;
+}
+
 static std::optional>
 shouldReportCallGadget(const BinaryContext &BC, const MCInstReference &Inst,
const SrcState &S) {
@@ -1473,6 +1550,9 @@ void FunctionAnalysisContext::findUnsafeUses(
 if (PacRetGadgetsOnly)
   return;
 
+if (auto Report = shouldReportUnsafeTailCall(BC, BF, Inst, S))
+  Reports.push_back(*Report);
+
 if (auto Report = shouldReportCallGadget(BC, Inst, S))

[llvm-branch-commits] [llvm] [BOLT] Introduce helpers to match `MCInst`s one at a time (NFC) (PR #138883)

2025-06-19 Thread Anatoly Trosinenko via llvm-branch-commits

https://github.com/atrosinenko updated 
https://github.com/llvm/llvm-project/pull/138883

>From 70eb080d1bc6be69901ef9457b74bef7917327d8 Mon Sep 17 00:00:00 2001
From: Anatoly Trosinenko 
Date: Wed, 7 May 2025 16:42:00 +0300
Subject: [PATCH] [BOLT] Introduce helpers to match `MCInst`s one at a time
 (NFC)

Introduce matchInst helper function to capture and/or match the operands
of MCInst. Unlike the existing `MCPlusBuilder::MCInstMatcher` machinery,
matchInst is intended for the use cases when precise control over the
instruction order is required. For example, when validating PtrAuth
hardening, all registers are usually considered unsafe after a function
call, even though callee-saved registers should preserve their old
values *under normal operation*.
---
 bolt/include/bolt/Core/MCInstUtils.h  | 128 ++
 .../Target/AArch64/AArch64MCPlusBuilder.cpp   |  90 +---
 2 files changed, 162 insertions(+), 56 deletions(-)

diff --git a/bolt/include/bolt/Core/MCInstUtils.h 
b/bolt/include/bolt/Core/MCInstUtils.h
index 69bf5e6159b74..50b7d56470c99 100644
--- a/bolt/include/bolt/Core/MCInstUtils.h
+++ b/bolt/include/bolt/Core/MCInstUtils.h
@@ -162,6 +162,134 @@ static inline raw_ostream &operator<<(raw_ostream &OS,
   return Ref.print(OS);
 }
 
+/// Instruction-matching helpers operating on a single instruction at a time.
+///
+/// Unlike MCPlusBuilder::MCInstMatcher, this matchInst() function focuses on
+/// the cases where a precise control over the instruction order is important:
+///
+/// // Bring the short names into the local scope:
+/// using namespace MCInstMatcher;
+/// // Declare the registers to capture:
+/// Reg Xn, Xm;
+/// // Capture the 0th and 1st operands, match the 2nd operand against the
+/// // just captured Xm register, match the 3rd operand against literal 0:
+/// if (!matchInst(MaybeAdd, AArch64::ADDXrs, Xm, Xn, Xm, Imm(0))
+///   return AArch64::NoRegister;
+/// // Match the 0th operand against Xm:
+/// if (!matchInst(MaybeBr, AArch64::BR, Xm))
+///   return AArch64::NoRegister;
+/// // Return the matched register:
+/// return Xm.get();
+namespace MCInstMatcher {
+
+// The base class to match an operand of type T.
+//
+// The subclasses of OpMatcher are intended to be allocated on the stack and
+// to only be used by passing them to matchInst() and by calling their get()
+// function, thus the peculiar `mutable` specifiers: to make the calling code
+// compact and readable, the templated matchInst() function has to accept both
+// long-lived Imm/Reg wrappers declared as local variables (intended to capture
+// the first operand's value and match the subsequent operands, whether inside
+// a single instruction or across multiple instructions), as well as temporary
+// wrappers around literal values to match, f.e. Imm(42) or Reg(AArch64::XZR).
+template  class OpMatcher {
+  mutable std::optional Value;
+  mutable std::optional SavedValue;
+
+  // Remember/restore the last Value - to be called by matchInst.
+  void remember() const { SavedValue = Value; }
+  void restore() const { Value = SavedValue; }
+
+  template 
+  friend bool matchInst(const MCInst &, unsigned, const OpMatchers &...);
+
+protected:
+  OpMatcher(std::optional ValueToMatch) : Value(ValueToMatch) {}
+
+  bool matchValue(T OpValue) const {
+// Check that OpValue does not contradict the existing Value.
+bool MatchResult = !Value || *Value == OpValue;
+// If MatchResult is false, all matchers will be reset before returning 
from
+// matchInst, including this one, thus no need to assign conditionally.
+Value = OpValue;
+
+return MatchResult;
+  }
+
+public:
+  /// Returns the captured value.
+  T get() const {
+assert(Value.has_value());
+return *Value;
+  }
+};
+
+class Reg : public OpMatcher {
+  bool matches(const MCOperand &Op) const {
+if (!Op.isReg())
+  return false;
+
+return matchValue(Op.getReg());
+  }
+
+  template 
+  friend bool matchInst(const MCInst &, unsigned, const OpMatchers &...);
+
+public:
+  Reg(std::optional RegToMatch = std::nullopt)
+  : OpMatcher(RegToMatch) {}
+};
+
+class Imm : public OpMatcher {
+  bool matches(const MCOperand &Op) const {
+if (!Op.isImm())
+  return false;
+
+return matchValue(Op.getImm());
+  }
+
+  template 
+  friend bool matchInst(const MCInst &, unsigned, const OpMatchers &...);
+
+public:
+  Imm(std::optional ImmToMatch = std::nullopt)
+  : OpMatcher(ImmToMatch) {}
+};
+
+/// Tries to match Inst and updates Ops on success.
+///
+/// If Inst has the specified Opcode and its operand list prefix matches Ops,
+/// this function returns true and updates Ops, otherwise false is returned and
+/// values of Ops are kept as before matchInst was called.
+///
+/// Please note that while Ops are technically passed by a const reference to
+/// make invocations like `matchInst(MI, Opcode, Imm(42))` possible, all their
+/// fields are marked mut

[llvm-branch-commits] [llvm] [BOLT] Gadget scanner: optionally assume auth traps on failure (PR #139778)

2025-06-19 Thread Anatoly Trosinenko via llvm-branch-commits

https://github.com/atrosinenko updated 
https://github.com/llvm/llvm-project/pull/139778

>From 275344a2d8b93e3426214a09cea5f2243c0e2873 Mon Sep 17 00:00:00 2001
From: Anatoly Trosinenko 
Date: Tue, 13 May 2025 19:50:41 +0300
Subject: [PATCH] [BOLT] Gadget scanner: optionally assume auth traps on
 failure

On AArch64 it is possible for an auth instruction to either return an
invalid address value on failure (without FEAT_FPAC) or generate an
error (with FEAT_FPAC). It thus may be possible to never emit explicit
pointer checks, if the target CPU is known to support FEAT_FPAC.

This commit implements an --auth-traps-on-failure command line option,
which essentially makes "safe-to-dereference" and "trusted" register
properties identical and disables scanning for authentication oracles
completely.
---
 bolt/lib/Passes/PAuthGadgetScanner.cpp| 112 +++
 .../binary-analysis/AArch64/cmdline-args.test |   1 +
 .../AArch64/gs-pauth-authentication-oracles.s |   6 +-
 .../binary-analysis/AArch64/gs-pauth-calls.s  |   5 +-
 .../AArch64/gs-pauth-debug-output.s   | 177 ++---
 .../AArch64/gs-pauth-jump-table.s |   6 +-
 .../AArch64/gs-pauth-signing-oracles.s|  54 ++---
 .../AArch64/gs-pauth-tail-calls.s | 184 +-
 8 files changed, 318 insertions(+), 227 deletions(-)

diff --git a/bolt/lib/Passes/PAuthGadgetScanner.cpp 
b/bolt/lib/Passes/PAuthGadgetScanner.cpp
index 3514c953030a6..b4d2fe150d514 100644
--- a/bolt/lib/Passes/PAuthGadgetScanner.cpp
+++ b/bolt/lib/Passes/PAuthGadgetScanner.cpp
@@ -14,6 +14,7 @@
 #include "bolt/Passes/PAuthGadgetScanner.h"
 #include "bolt/Core/ParallelUtilities.h"
 #include "bolt/Passes/DataflowAnalysis.h"
+#include "bolt/Utils/CommandLineOpts.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/SmallSet.h"
 #include "llvm/MC/MCInst.h"
@@ -26,6 +27,11 @@ namespace llvm {
 namespace bolt {
 namespace PAuthGadgetScanner {
 
+static cl::opt AuthTrapsOnFailure(
+"auth-traps-on-failure",
+cl::desc("Assume authentication instructions always trap on failure"),
+cl::cat(opts::BinaryAnalysisCategory));
+
 [[maybe_unused]] static void traceInst(const BinaryContext &BC, StringRef 
Label,
const MCInst &MI) {
   dbgs() << "  " << Label << ": ";
@@ -364,6 +370,34 @@ class SrcSafetyAnalysis {
 return Clobbered;
   }
 
+  std::optional getRegMadeTrustedByChecking(const MCInst &Inst,
+   SrcState Cur) const {
+// This functions cannot return multiple registers. This is never the case
+// on AArch64.
+std::optional RegCheckedByInst =
+BC.MIB->getAuthCheckedReg(Inst, /*MayOverwrite=*/false);
+if (RegCheckedByInst && Cur.SafeToDerefRegs[*RegCheckedByInst])
+  return *RegCheckedByInst;
+
+auto It = CheckerSequenceInfo.find(&Inst);
+if (It == CheckerSequenceInfo.end())
+  return std::nullopt;
+
+MCPhysReg RegCheckedBySequence = It->second.first;
+const MCInst *FirstCheckerInst = It->second.second;
+
+// FirstCheckerInst should belong to the same basic block (see the
+// assertion in DataflowSrcSafetyAnalysis::run()), meaning it was
+// deterministically processed a few steps before this instruction.
+const SrcState &StateBeforeChecker = getStateBefore(*FirstCheckerInst);
+
+// The sequence checks the register, but it should be authenticated before.
+if (!StateBeforeChecker.SafeToDerefRegs[RegCheckedBySequence])
+  return std::nullopt;
+
+return RegCheckedBySequence;
+  }
+
   // Returns all registers that can be treated as if they are written by an
   // authentication instruction.
   SmallVector getRegsMadeSafeToDeref(const MCInst &Point,
@@ -386,18 +420,38 @@ class SrcSafetyAnalysis {
 Regs.push_back(DstAndSrc->first);
 }
 
+// Make sure explicit checker sequence keeps register safe-to-dereference
+// when the register would be clobbered according to the regular rules:
+//
+//; LR is safe to dereference here
+//mov   x16, x30  ; start of the sequence, LR is s-t-d right before
+//xpaclri ; clobbers LR, LR is not safe anymore
+//cmp   x30, x16
+//b.eq  1f; end of the sequence: LR is marked as trusted
+//brk   0x1234
+//  1:
+//; at this point LR would be marked as trusted,
+//; but not safe-to-dereference
+//
+// or even just
+//
+//; X1 is safe to dereference here
+//ldr x0, [x1, #8]!
+//; X1 is trusted here, but it was clobbered due to address write-back
+if (auto CheckedReg = getRegMadeTrustedByChecking(Point, Cur))
+  Regs.push_back(*CheckedReg);
+
 return Regs;
   }
 
   // Returns all registers made trusted by this instruction.
   SmallVector getRegsMadeTrusted(const MCInst &Point,
 const SrcState &Cur) const {
+assert(!AuthTrapsOnFailure &&

[llvm-branch-commits] [llvm] [BOLT] Gadget scanner: fix LR to be safe in leaf functions without CFG (PR #141824)

2025-06-19 Thread Anatoly Trosinenko via llvm-branch-commits

https://github.com/atrosinenko updated 
https://github.com/llvm/llvm-project/pull/141824

>From e3bef0621e4b78c8a89302acfca9a1360076f269 Mon Sep 17 00:00:00 2001
From: Anatoly Trosinenko 
Date: Wed, 14 May 2025 23:12:13 +0300
Subject: [PATCH] [BOLT] Gadget scanner: fix LR to be safe in leaf functions
 without CFG

After a label in a function without CFG information, use a reasonably
pessimistic estimation of register state (assume that any register that
can be clobbered in this function was actually clobbered) instead of the
most pessimistic "all registers are unsafe". This is the same estimation
as used by the dataflow variant of the analysis when the preceding
instruction is not known for sure.

Without this, leaf functions without CFG information are likely to have
false positive reports about non-protected return instructions, as
1) LR is unlikely to be signed and authenticated in a leaf function and
2) LR is likely to be used by a return instruction near the end of the
   function and
3) the register state is likely to be reset at least once during the
   linear scan through the function
---
 bolt/lib/Passes/PAuthGadgetScanner.cpp| 14 +++--
 .../AArch64/gs-pacret-autiasp.s   | 31 +--
 .../AArch64/gs-pauth-authentication-oracles.s | 20 
 .../AArch64/gs-pauth-debug-output.s   | 30 ++
 .../AArch64/gs-pauth-signing-oracles.s| 27 
 5 files changed, 29 insertions(+), 93 deletions(-)

diff --git a/bolt/lib/Passes/PAuthGadgetScanner.cpp 
b/bolt/lib/Passes/PAuthGadgetScanner.cpp
index e5bdade032488..05309a47aba40 100644
--- a/bolt/lib/Passes/PAuthGadgetScanner.cpp
+++ b/bolt/lib/Passes/PAuthGadgetScanner.cpp
@@ -737,19 +737,14 @@ template  class CFGUnawareAnalysis {
 //
 // Then, a function can be split into a number of disjoint contiguous sequences
 // of instructions without labels in between. These sequences can be processed
-// the same way basic blocks are processed by data-flow analysis, assuming
-// pessimistically that all registers are unsafe at the start of each sequence.
+// the same way basic blocks are processed by data-flow analysis, with the same
+// pessimistic estimation of the initial state at the start of each sequence
+// (except the first instruction of the function).
 class CFGUnawareSrcSafetyAnalysis : public SrcSafetyAnalysis,
 public CFGUnawareAnalysis {
   using SrcSafetyAnalysis::BC;
   BinaryFunction &BF;
 
-  /// Creates a state with all registers marked unsafe (not to be confused
-  /// with empty state).
-  SrcState createUnsafeState() const {
-return SrcState(NumRegs, RegsToTrackInstsFor.getNumTrackedRegisters());
-  }
-
 public:
   CFGUnawareSrcSafetyAnalysis(BinaryFunction &BF,
   MCPlusBuilder::AllocatorIdTy AllocId,
@@ -759,6 +754,7 @@ class CFGUnawareSrcSafetyAnalysis : public 
SrcSafetyAnalysis,
   }
 
   void run() override {
+const SrcState DefaultState = computePessimisticState(BF);
 SrcState S = createEntryState();
 for (auto &I : BF.instrs()) {
   MCInst &Inst = I.second;
@@ -773,7 +769,7 @@ class CFGUnawareSrcSafetyAnalysis : public 
SrcSafetyAnalysis,
 LLVM_DEBUG({
   traceInst(BC, "Due to label, resetting the state before", Inst);
 });
-S = createUnsafeState();
+S = DefaultState;
   }
 
   // Attach the state *before* this instruction executes.
diff --git a/bolt/test/binary-analysis/AArch64/gs-pacret-autiasp.s 
b/bolt/test/binary-analysis/AArch64/gs-pacret-autiasp.s
index df0a83be00986..627f8eb20ab9c 100644
--- a/bolt/test/binary-analysis/AArch64/gs-pacret-autiasp.s
+++ b/bolt/test/binary-analysis/AArch64/gs-pacret-autiasp.s
@@ -224,20 +224,33 @@ f_unreachable_instruction:
 ret
 .size f_unreachable_instruction, .-f_unreachable_instruction
 
-// Expected false positive: without CFG, the state is reset to all-unsafe
-// after an unconditional branch.
-
-.globl  state_is_reset_after_indirect_branch_nocfg
-.type   state_is_reset_after_indirect_branch_nocfg,@function
-state_is_reset_after_indirect_branch_nocfg:
-// CHECK-LABEL: GS-PAUTH: non-protected ret found in function 
state_is_reset_after_indirect_branch_nocfg, at address
-// CHECK-NEXT:  The instruction is {{[0-9a-f]+}}: ret
+// Without CFG, the state is reset at labels, assuming every register that can
+// be clobbered in the function was actually clobbered.
+
+.globl  lr_untouched_nocfg
+.type   lr_untouched_nocfg,@function
+lr_untouched_nocfg:
+// CHECK-NOT: lr_untouched_nocfg
+adr x2, 1f
+br  x2
+1:
+ret
+.size lr_untouched_nocfg, .-lr_untouched_nocfg
+
+.globl  lr_clobbered_nocfg
+.type   lr_clobbered_nocfg,@function
+lr_clobbered_nocfg:
+// CHECK-LABEL: GS-PAUTH: non-protected ret found in function 
lr_clobbered_nocfg, at address
+// CHECK-NEXT:  The instruction is

[llvm-branch-commits] [llvm] [BOLT] Gadget scanner: account for BRK when searching for auth oracles (PR #137975)

2025-06-19 Thread Anatoly Trosinenko via llvm-branch-commits

https://github.com/atrosinenko updated 
https://github.com/llvm/llvm-project/pull/137975

>From 3e9bfcde8cf45cb7cba3b4b4b03cdff2cfc46e99 Mon Sep 17 00:00:00 2001
From: Anatoly Trosinenko 
Date: Wed, 30 Apr 2025 16:08:10 +0300
Subject: [PATCH] [BOLT] Gadget scanner: account for BRK when searching for
 auth oracles

An authenticated pointer can be explicitly checked by the compiler via a
sequence of instructions that executes BRK on failure. It is important
to recognize such BRK instruction as checking every register (as it is
expected to immediately trigger an abnormal program termination) to
prevent false positive reports about authentication oracles:

autia   x2, x3
autia   x0, x1
; neither x0 nor x2 are checked at this point
eor x16, x0, x0, lsl #1
tbz x16, #62, on_success ; marks x0 as checked
; end of BB: for x2 to be checked here, it must be checked in both
; successor basic blocks
  on_failure:
brk 0xc470
  on_success:
; x2 is checked
ldr x1, [x2] ; marks x2 as checked
---
 bolt/include/bolt/Core/MCPlusBuilder.h| 14 ++
 bolt/lib/Passes/PAuthGadgetScanner.cpp| 13 +-
 .../Target/AArch64/AArch64MCPlusBuilder.cpp   | 24 --
 .../AArch64/gs-pauth-address-checks.s | 44 +--
 .../AArch64/gs-pauth-authentication-oracles.s |  9 ++--
 .../AArch64/gs-pauth-signing-oracles.s|  6 +--
 6 files changed, 75 insertions(+), 35 deletions(-)

diff --git a/bolt/include/bolt/Core/MCPlusBuilder.h 
b/bolt/include/bolt/Core/MCPlusBuilder.h
index 804100db80793..c31c9984ed43e 100644
--- a/bolt/include/bolt/Core/MCPlusBuilder.h
+++ b/bolt/include/bolt/Core/MCPlusBuilder.h
@@ -707,6 +707,20 @@ class MCPlusBuilder {
 return false;
   }
 
+  /// Returns true if Inst is a trap instruction.
+  ///
+  /// Tests if Inst is an instruction that immediately causes an abnormal
+  /// program termination, for example when a security violation is detected
+  /// by a compiler-inserted check.
+  ///
+  /// @note An implementation of this method should likely return false for
+  /// calls to library functions like abort(), as it is possible that the
+  /// execution state is partially attacker-controlled at this point.
+  virtual bool isTrap(const MCInst &Inst) const {
+llvm_unreachable("not implemented");
+return false;
+  }
+
   virtual bool isBreakpoint(const MCInst &Inst) const {
 llvm_unreachable("not implemented");
 return false;
diff --git a/bolt/lib/Passes/PAuthGadgetScanner.cpp 
b/bolt/lib/Passes/PAuthGadgetScanner.cpp
index b5b46390d4586..98bb84f6f965d 100644
--- a/bolt/lib/Passes/PAuthGadgetScanner.cpp
+++ b/bolt/lib/Passes/PAuthGadgetScanner.cpp
@@ -1078,6 +1078,15 @@ class DstSafetyAnalysis {
   dbgs() << ")\n";
 });
 
+// If this instruction terminates the program immediately, no
+// authentication oracles are possible past this point.
+if (BC.MIB->isTrap(Point)) {
+  LLVM_DEBUG({ traceInst(BC, "Trap instruction found", Point); });
+  DstState Next(NumRegs, RegsToTrackInstsFor.getNumTrackedRegisters());
+  Next.CannotEscapeUnchecked.set();
+  return Next;
+}
+
 // If this instruction is reachable by the analysis, a non-empty state will
 // be propagated to it sooner or later. Until then, skip computeNext().
 if (Cur.empty()) {
@@ -1185,8 +1194,8 @@ class DataflowDstSafetyAnalysis
 //
 // A basic block without any successors, on the other hand, can be
 // pessimistically initialized to everything-is-unsafe: this will naturally
-// handle both return and tail call instructions and is harmless for
-// internal indirect branch instructions (such as computed gotos).
+// handle return, trap and tail call instructions. At the same time, it is
+// harmless for internal indirect branch instructions, like computed gotos.
 if (BB.succ_empty())
   return createUnsafeState();
 
diff --git a/bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp 
b/bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp
index eb1d9d8a19514..ac454a43e8a59 100644
--- a/bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp
+++ b/bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp
@@ -386,10 +386,9 @@ class AArch64MCPlusBuilder : public MCPlusBuilder {
 // the list of successors of this basic block as appropriate.
 
 // Any of the above code sequences assume the fall-through basic block
-// is a dead-end BRK instruction (any immediate operand is accepted).
+// is a dead-end trap instruction.
 const BinaryBasicBlock *BreakBB = BB.getFallthrough();
-if (!BreakBB || BreakBB->empty() ||
-BreakBB->front().getOpcode() != AArch64::BRK)
+if (!BreakBB || BreakBB->empty() || !isTrap(BreakBB->front()))
   return std::nullopt;
 
 // Iterate over the instructions of BB in reverse order, matching opcodes
@@ -1751,6 +1750,25 @@ class AArch64MCPlusBuilder : public MCPlusBuilder {
 Inst.addOperand(MCOperand::createImm(0));
   }
 

[llvm-branch-commits] [llvm] [BOLT] Factor out MCInstReference from gadget scanner (NFC) (PR #138655)

2025-06-19 Thread Anatoly Trosinenko via llvm-branch-commits

https://github.com/atrosinenko updated 
https://github.com/llvm/llvm-project/pull/138655

>From c5775ce807ce7ee733a2054169c134a5ddd79fbc Mon Sep 17 00:00:00 2001
From: Anatoly Trosinenko 
Date: Thu, 19 Jun 2025 14:03:59 +0300
Subject: [PATCH] [BOLT] Factor out MCInstReference from gadget scanner (NFC)

Move MCInstReference representing a constant reference to an instruction
inside a parent entity - either inside a basic block (which has a
reference to its parent function) or directly to the function (when CFG
information is not available).
---
 bolt/include/bolt/Core/MCInstUtils.h  | 168 +
 bolt/include/bolt/Passes/PAuthGadgetScanner.h | 176 +-
 bolt/lib/Core/CMakeLists.txt  |   1 +
 bolt/lib/Core/MCInstUtils.cpp |  57 ++
 bolt/lib/Passes/PAuthGadgetScanner.cpp| 102 +-
 5 files changed, 269 insertions(+), 235 deletions(-)
 create mode 100644 bolt/include/bolt/Core/MCInstUtils.h
 create mode 100644 bolt/lib/Core/MCInstUtils.cpp

diff --git a/bolt/include/bolt/Core/MCInstUtils.h 
b/bolt/include/bolt/Core/MCInstUtils.h
new file mode 100644
index 0..69bf5e6159b74
--- /dev/null
+++ b/bolt/include/bolt/Core/MCInstUtils.h
@@ -0,0 +1,168 @@
+//===- bolt/Core/MCInstUtils.h --*- C++ 
-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+#ifndef BOLT_CORE_MCINSTUTILS_H
+#define BOLT_CORE_MCINSTUTILS_H
+
+#include "bolt/Core/BinaryBasicBlock.h"
+
+#include 
+#include 
+#include 
+
+namespace llvm {
+namespace bolt {
+
+class BinaryFunction;
+
+/// MCInstReference represents a reference to a constant MCInst as stored 
either
+/// in a BinaryFunction (i.e. before a CFG is created), or in a 
BinaryBasicBlock
+/// (after a CFG is created).
+class MCInstReference {
+  using nocfg_const_iterator = std::map::const_iterator;
+
+  // Two cases are possible:
+  // * functions with CFG reconstructed - a function stores a collection of
+  //   basic blocks, each basic block stores a contiguous vector of MCInst
+  // * functions without CFG - there are no basic blocks created,
+  //   the instructions are directly stored in std::map in BinaryFunction
+  //
+  // In both cases, the direct parent of MCInst is stored together with an
+  // iterator pointing to the instruction.
+
+  // Helper struct: CFG is available, the direct parent is a basic block,
+  // iterator's type is `MCInst *`.
+  struct RefInBB {
+RefInBB(const BinaryBasicBlock *BB, const MCInst *Inst)
+: BB(BB), It(Inst) {}
+RefInBB(const RefInBB &Other) = default;
+RefInBB &operator=(const RefInBB &Other) = default;
+
+const BinaryBasicBlock *BB;
+BinaryBasicBlock::const_iterator It;
+
+bool operator<(const RefInBB &Other) const {
+  return std::tie(BB, It) < std::tie(Other.BB, Other.It);
+}
+
+bool operator==(const RefInBB &Other) const {
+  return BB == Other.BB && It == Other.It;
+}
+  };
+
+  // Helper struct: CFG is *not* available, the direct parent is a function,
+  // iterator's type is std::map::iterator (the mapped value
+  // is an instruction's offset).
+  struct RefInBF {
+RefInBF(const BinaryFunction *BF, nocfg_const_iterator It)
+: BF(BF), It(It) {}
+RefInBF(const RefInBF &Other) = default;
+RefInBF &operator=(const RefInBF &Other) = default;
+
+const BinaryFunction *BF;
+nocfg_const_iterator It;
+
+bool operator<(const RefInBF &Other) const {
+  return std::tie(BF, It->first) < std::tie(Other.BF, Other.It->first);
+}
+
+bool operator==(const RefInBF &Other) const {
+  return BF == Other.BF && It->first == Other.It->first;
+}
+  };
+
+  std::variant Reference;
+
+  // Utility methods to be used like this:
+  //
+  // if (auto *Ref = tryGetRefInBB())
+  //   return Ref->doSomething(...);
+  // return getRefInBF().doSomethingElse(...);
+  const RefInBB *tryGetRefInBB() const {
+assert(std::get_if(&Reference) ||
+   std::get_if(&Reference));
+return std::get_if(&Reference);
+  }
+  const RefInBF &getRefInBF() const {
+assert(std::get_if(&Reference));
+return *std::get_if(&Reference);
+  }
+
+public:
+  /// Constructs an empty reference.
+  MCInstReference() : Reference(RefInBB(nullptr, nullptr)) {}
+  /// Constructs a reference to the instruction inside the basic block.
+  MCInstReference(const BinaryBasicBlock *BB, const MCInst *Inst)
+  : Reference(RefInBB(BB, Inst)) {
+assert(BB && Inst && "Neither BB nor Inst should be nullptr");
+  }
+  /// Constructs a reference to the instruction inside the basic block.
+  MCInstReference(const BinaryBasicBlock *BB, unsigned Index)
+  : Reference(RefInBB(BB, &BB->getInstructionAtIndex(I

[llvm-branch-commits] [llvm] [BOLT] Gadget scanner: make use of C++17 features and LLVM helpers (PR #141665)

2025-06-19 Thread Anatoly Trosinenko via llvm-branch-commits

https://github.com/atrosinenko updated 
https://github.com/llvm/llvm-project/pull/141665

>From e880cb42df70af5112e89c16bffc908274ba5910 Mon Sep 17 00:00:00 2001
From: Anatoly Trosinenko 
Date: Tue, 27 May 2025 21:06:03 +0300
Subject: [PATCH] [BOLT] Gadget scanner: make use of C++17 features and LLVM
 helpers

Perform trivial syntactical cleanups:
* make use of structured binding declarations
* use LLVM utility functions when appropriate
* omit braces around single expression inside single-line LLVM_DEBUG()

This patch is NFC aside from minor debug output changes.
---
 bolt/lib/Passes/PAuthGadgetScanner.cpp| 67 +--
 .../AArch64/gs-pauth-debug-output.s   | 14 ++--
 2 files changed, 38 insertions(+), 43 deletions(-)

diff --git a/bolt/lib/Passes/PAuthGadgetScanner.cpp 
b/bolt/lib/Passes/PAuthGadgetScanner.cpp
index b4d2fe150d514..f455229d9ea7a 100644
--- a/bolt/lib/Passes/PAuthGadgetScanner.cpp
+++ b/bolt/lib/Passes/PAuthGadgetScanner.cpp
@@ -88,8 +88,8 @@ class TrackedRegisters {
   TrackedRegisters(ArrayRef RegsToTrack)
   : Registers(RegsToTrack),
 RegToIndexMapping(getMappingSize(RegsToTrack), NoIndex) {
-for (unsigned I = 0; I < RegsToTrack.size(); ++I)
-  RegToIndexMapping[RegsToTrack[I]] = I;
+for (auto [MappedIndex, Reg] : llvm::enumerate(RegsToTrack))
+  RegToIndexMapping[Reg] = MappedIndex;
   }
 
   ArrayRef getRegisters() const { return Registers; }
@@ -203,9 +203,9 @@ struct SrcState {
 
 SafeToDerefRegs &= StateIn.SafeToDerefRegs;
 TrustedRegs &= StateIn.TrustedRegs;
-for (unsigned I = 0; I < LastInstWritingReg.size(); ++I)
-  for (const MCInst *J : StateIn.LastInstWritingReg[I])
-LastInstWritingReg[I].insert(J);
+for (auto [ThisSet, OtherSet] :
+ llvm::zip_equal(LastInstWritingReg, StateIn.LastInstWritingReg))
+  ThisSet.insert_range(OtherSet);
 return *this;
   }
 
@@ -224,11 +224,9 @@ struct SrcState {
 static void printInstsShort(raw_ostream &OS,
 ArrayRef Insts) {
   OS << "Insts: ";
-  for (unsigned I = 0; I < Insts.size(); ++I) {
-auto &Set = Insts[I];
+  for (auto [I, PtrSet] : llvm::enumerate(Insts)) {
 OS << "[" << I << "](";
-for (const MCInst *MCInstP : Set)
-  OS << MCInstP << " ";
+interleave(PtrSet, OS, " ");
 OS << ")";
   }
 }
@@ -416,8 +414,9 @@ class SrcSafetyAnalysis {
 // ... an address can be updated in a safe manner, producing the result
 // which is as trusted as the input address.
 if (auto DstAndSrc = BC.MIB->analyzeAddressArithmeticsForPtrAuth(Point)) {
-  if (Cur.SafeToDerefRegs[DstAndSrc->second])
-Regs.push_back(DstAndSrc->first);
+  auto [DstReg, SrcReg] = *DstAndSrc;
+  if (Cur.SafeToDerefRegs[SrcReg])
+Regs.push_back(DstReg);
 }
 
 // Make sure explicit checker sequence keeps register safe-to-dereference
@@ -469,8 +468,9 @@ class SrcSafetyAnalysis {
 // ... an address can be updated in a safe manner, producing the result
 // which is as trusted as the input address.
 if (auto DstAndSrc = BC.MIB->analyzeAddressArithmeticsForPtrAuth(Point)) {
-  if (Cur.TrustedRegs[DstAndSrc->second])
-Regs.push_back(DstAndSrc->first);
+  auto [DstReg, SrcReg] = *DstAndSrc;
+  if (Cur.TrustedRegs[SrcReg])
+Regs.push_back(DstReg);
 }
 
 return Regs;
@@ -868,9 +868,9 @@ struct DstState {
   return (*this = StateIn);
 
 CannotEscapeUnchecked &= StateIn.CannotEscapeUnchecked;
-for (unsigned I = 0; I < FirstInstLeakingReg.size(); ++I)
-  for (const MCInst *J : StateIn.FirstInstLeakingReg[I])
-FirstInstLeakingReg[I].insert(J);
+for (auto [ThisSet, OtherSet] :
+ llvm::zip_equal(FirstInstLeakingReg, StateIn.FirstInstLeakingReg))
+  ThisSet.insert_range(OtherSet);
 return *this;
   }
 
@@ -1036,8 +1036,7 @@ class DstSafetyAnalysis {
 
 // ... an address can be updated in a safe manner, or
 if (auto DstAndSrc = BC.MIB->analyzeAddressArithmeticsForPtrAuth(Inst)) {
-  MCPhysReg DstReg, SrcReg;
-  std::tie(DstReg, SrcReg) = *DstAndSrc;
+  auto [DstReg, SrcReg] = *DstAndSrc;
   // Note that *all* registers containing the derived values must be safe,
   // both source and destination ones. No temporaries are supported at now.
   if (Cur.CannotEscapeUnchecked[SrcReg] &&
@@ -1077,7 +1076,7 @@ class DstSafetyAnalysis {
 // If this instruction terminates the program immediately, no
 // authentication oracles are possible past this point.
 if (BC.MIB->isTrap(Point)) {
-  LLVM_DEBUG({ traceInst(BC, "Trap instruction found", Point); });
+  LLVM_DEBUG(traceInst(BC, "Trap instruction found", Point));
   DstState Next(NumRegs, RegsToTrackInstsFor.getNumTrackedRegisters());
   Next.CannotEscapeUnchecked.set();
   return Next;
@@ -1255,7 +1254,7 @@ class CFGUnawareDstSafetyAnalysis : public 
DstSafetyAnalysis,
   // starting to analyze Inst.
   

[llvm-branch-commits] [llvm] [BOLT] Gadget scanner: do not crash on debug-printing CFI instructions (PR #136151)

2025-06-19 Thread Anatoly Trosinenko via llvm-branch-commits

https://github.com/atrosinenko updated 
https://github.com/llvm/llvm-project/pull/136151

>From 9c7da2b0632b21cfe8750faa023d8413ad4664fa Mon Sep 17 00:00:00 2001
From: Anatoly Trosinenko 
Date: Tue, 15 Apr 2025 21:47:18 +0300
Subject: [PATCH] [BOLT] Gadget scanner: do not crash on debug-printing CFI
 instructions

Some instruction-printing code used under LLVM_DEBUG does not handle CFI
instructions well. While CFI instructions seem to be harmless for the
correctness of the analysis results, they do not convey any useful
information to the analysis either, so skip them early.
---
 bolt/lib/Passes/PAuthGadgetScanner.cpp| 16 ++
 .../AArch64/gs-pauth-debug-output.s   | 32 +++
 2 files changed, 48 insertions(+)

diff --git a/bolt/lib/Passes/PAuthGadgetScanner.cpp 
b/bolt/lib/Passes/PAuthGadgetScanner.cpp
index 7682d7fe2c542..95e831fe9c8ca 100644
--- a/bolt/lib/Passes/PAuthGadgetScanner.cpp
+++ b/bolt/lib/Passes/PAuthGadgetScanner.cpp
@@ -430,6 +430,9 @@ class SrcSafetyAnalysis {
   }
 
   SrcState computeNext(const MCInst &Point, const SrcState &Cur) {
+if (BC.MIB->isCFI(Point))
+  return Cur;
+
 SrcStatePrinter P(BC);
 LLVM_DEBUG({
   dbgs() << "  SrcSafetyAnalysis::ComputeNext(";
@@ -704,6 +707,8 @@ class CFGUnawareSrcSafetyAnalysis : public 
SrcSafetyAnalysis,
 SrcState S = createEntryState();
 for (auto &I : BF.instrs()) {
   MCInst &Inst = I.second;
+  if (BC.MIB->isCFI(Inst))
+continue;
 
   // If there is a label before this instruction, it is possible that it
   // can be jumped-to, thus conservatively resetting S. As an exception,
@@ -1010,6 +1015,9 @@ class DstSafetyAnalysis {
   }
 
   DstState computeNext(const MCInst &Point, const DstState &Cur) {
+if (BC.MIB->isCFI(Point))
+  return Cur;
+
 DstStatePrinter P(BC);
 LLVM_DEBUG({
   dbgs() << "  DstSafetyAnalysis::ComputeNext(";
@@ -1177,6 +1185,8 @@ class CFGUnawareDstSafetyAnalysis : public 
DstSafetyAnalysis,
 DstState S = createUnsafeState();
 for (auto &I : llvm::reverse(BF.instrs())) {
   MCInst &Inst = I.second;
+  if (BC.MIB->isCFI(Inst))
+continue;
 
   // If Inst can change the control flow, we cannot be sure that the next
   // instruction (to be executed in analyzed program) is the one processed
@@ -1366,6 +1376,9 @@ void FunctionAnalysisContext::findUnsafeUses(
   });
 
   iterateOverInstrs(BF, [&](MCInstReference Inst) {
+if (BC.MIB->isCFI(Inst))
+  return;
+
 const SrcState &S = Analysis->getStateBefore(Inst);
 
 // If non-empty state was never propagated from the entry basic block
@@ -1429,6 +1442,9 @@ void FunctionAnalysisContext::findUnsafeDefs(
   });
 
   iterateOverInstrs(BF, [&](MCInstReference Inst) {
+if (BC.MIB->isCFI(Inst))
+  return;
+
 const DstState &S = Analysis->getStateAfter(Inst);
 
 if (auto Report = shouldReportAuthOracle(BC, Inst, S))
diff --git a/bolt/test/binary-analysis/AArch64/gs-pauth-debug-output.s 
b/bolt/test/binary-analysis/AArch64/gs-pauth-debug-output.s
index 686557eb1e529..fbb96a63d41ed 100644
--- a/bolt/test/binary-analysis/AArch64/gs-pauth-debug-output.s
+++ b/bolt/test/binary-analysis/AArch64/gs-pauth-debug-output.s
@@ -329,6 +329,38 @@ auth_oracle:
 // PAUTH-EMPTY:
 // PAUTH-NEXT:   Attaching leakage info to: :  autia   x0, x1 
# DataflowDstSafetyAnalysis: dst-state
 
+// Gadget scanner should not crash on CFI instructions, including when 
debug-printing them.
+// Note that the particular debug output is not checked, but BOLT should be
+// compiled with assertions enabled to support -debug-only argument.
+
+.globl  cfi_inst_df
+.type   cfi_inst_df,@function
+cfi_inst_df:
+.cfi_startproc
+sub sp, sp, #16
+.cfi_def_cfa_offset 16
+add sp, sp, #16
+.cfi_def_cfa_offset 0
+ret
+.size   cfi_inst_df, .-cfi_inst_df
+.cfi_endproc
+
+.globl  cfi_inst_nocfg
+.type   cfi_inst_nocfg,@function
+cfi_inst_nocfg:
+.cfi_startproc
+sub sp, sp, #16
+.cfi_def_cfa_offset 16
+
+adr x0, 1f
+br  x0
+1:
+add sp, sp, #16
+.cfi_def_cfa_offset 0
+ret
+.size   cfi_inst_nocfg, .-cfi_inst_nocfg
+.cfi_endproc
+
 // CHECK-LABEL:Analyzing function main, AllocatorId = 1
 .globl  main
 .type   main,@function

___
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] [BOLT] Gadget scanner: fix LR to be safe in leaf functions without CFG (PR #141824)

2025-06-19 Thread Anatoly Trosinenko via llvm-branch-commits

https://github.com/atrosinenko updated 
https://github.com/llvm/llvm-project/pull/141824

>From e3bef0621e4b78c8a89302acfca9a1360076f269 Mon Sep 17 00:00:00 2001
From: Anatoly Trosinenko 
Date: Wed, 14 May 2025 23:12:13 +0300
Subject: [PATCH] [BOLT] Gadget scanner: fix LR to be safe in leaf functions
 without CFG

After a label in a function without CFG information, use a reasonably
pessimistic estimation of register state (assume that any register that
can be clobbered in this function was actually clobbered) instead of the
most pessimistic "all registers are unsafe". This is the same estimation
as used by the dataflow variant of the analysis when the preceding
instruction is not known for sure.

Without this, leaf functions without CFG information are likely to have
false positive reports about non-protected return instructions, as
1) LR is unlikely to be signed and authenticated in a leaf function and
2) LR is likely to be used by a return instruction near the end of the
   function and
3) the register state is likely to be reset at least once during the
   linear scan through the function
---
 bolt/lib/Passes/PAuthGadgetScanner.cpp| 14 +++--
 .../AArch64/gs-pacret-autiasp.s   | 31 +--
 .../AArch64/gs-pauth-authentication-oracles.s | 20 
 .../AArch64/gs-pauth-debug-output.s   | 30 ++
 .../AArch64/gs-pauth-signing-oracles.s| 27 
 5 files changed, 29 insertions(+), 93 deletions(-)

diff --git a/bolt/lib/Passes/PAuthGadgetScanner.cpp 
b/bolt/lib/Passes/PAuthGadgetScanner.cpp
index e5bdade032488..05309a47aba40 100644
--- a/bolt/lib/Passes/PAuthGadgetScanner.cpp
+++ b/bolt/lib/Passes/PAuthGadgetScanner.cpp
@@ -737,19 +737,14 @@ template  class CFGUnawareAnalysis {
 //
 // Then, a function can be split into a number of disjoint contiguous sequences
 // of instructions without labels in between. These sequences can be processed
-// the same way basic blocks are processed by data-flow analysis, assuming
-// pessimistically that all registers are unsafe at the start of each sequence.
+// the same way basic blocks are processed by data-flow analysis, with the same
+// pessimistic estimation of the initial state at the start of each sequence
+// (except the first instruction of the function).
 class CFGUnawareSrcSafetyAnalysis : public SrcSafetyAnalysis,
 public CFGUnawareAnalysis {
   using SrcSafetyAnalysis::BC;
   BinaryFunction &BF;
 
-  /// Creates a state with all registers marked unsafe (not to be confused
-  /// with empty state).
-  SrcState createUnsafeState() const {
-return SrcState(NumRegs, RegsToTrackInstsFor.getNumTrackedRegisters());
-  }
-
 public:
   CFGUnawareSrcSafetyAnalysis(BinaryFunction &BF,
   MCPlusBuilder::AllocatorIdTy AllocId,
@@ -759,6 +754,7 @@ class CFGUnawareSrcSafetyAnalysis : public 
SrcSafetyAnalysis,
   }
 
   void run() override {
+const SrcState DefaultState = computePessimisticState(BF);
 SrcState S = createEntryState();
 for (auto &I : BF.instrs()) {
   MCInst &Inst = I.second;
@@ -773,7 +769,7 @@ class CFGUnawareSrcSafetyAnalysis : public 
SrcSafetyAnalysis,
 LLVM_DEBUG({
   traceInst(BC, "Due to label, resetting the state before", Inst);
 });
-S = createUnsafeState();
+S = DefaultState;
   }
 
   // Attach the state *before* this instruction executes.
diff --git a/bolt/test/binary-analysis/AArch64/gs-pacret-autiasp.s 
b/bolt/test/binary-analysis/AArch64/gs-pacret-autiasp.s
index df0a83be00986..627f8eb20ab9c 100644
--- a/bolt/test/binary-analysis/AArch64/gs-pacret-autiasp.s
+++ b/bolt/test/binary-analysis/AArch64/gs-pacret-autiasp.s
@@ -224,20 +224,33 @@ f_unreachable_instruction:
 ret
 .size f_unreachable_instruction, .-f_unreachable_instruction
 
-// Expected false positive: without CFG, the state is reset to all-unsafe
-// after an unconditional branch.
-
-.globl  state_is_reset_after_indirect_branch_nocfg
-.type   state_is_reset_after_indirect_branch_nocfg,@function
-state_is_reset_after_indirect_branch_nocfg:
-// CHECK-LABEL: GS-PAUTH: non-protected ret found in function 
state_is_reset_after_indirect_branch_nocfg, at address
-// CHECK-NEXT:  The instruction is {{[0-9a-f]+}}: ret
+// Without CFG, the state is reset at labels, assuming every register that can
+// be clobbered in the function was actually clobbered.
+
+.globl  lr_untouched_nocfg
+.type   lr_untouched_nocfg,@function
+lr_untouched_nocfg:
+// CHECK-NOT: lr_untouched_nocfg
+adr x2, 1f
+br  x2
+1:
+ret
+.size lr_untouched_nocfg, .-lr_untouched_nocfg
+
+.globl  lr_clobbered_nocfg
+.type   lr_clobbered_nocfg,@function
+lr_clobbered_nocfg:
+// CHECK-LABEL: GS-PAUTH: non-protected ret found in function 
lr_clobbered_nocfg, at address
+// CHECK-NEXT:  The instruction is

[llvm-branch-commits] [llvm] [BOLT] Gadget scanner: account for BRK when searching for auth oracles (PR #137975)

2025-06-19 Thread Anatoly Trosinenko via llvm-branch-commits

https://github.com/atrosinenko updated 
https://github.com/llvm/llvm-project/pull/137975

>From 3e9bfcde8cf45cb7cba3b4b4b03cdff2cfc46e99 Mon Sep 17 00:00:00 2001
From: Anatoly Trosinenko 
Date: Wed, 30 Apr 2025 16:08:10 +0300
Subject: [PATCH] [BOLT] Gadget scanner: account for BRK when searching for
 auth oracles

An authenticated pointer can be explicitly checked by the compiler via a
sequence of instructions that executes BRK on failure. It is important
to recognize such BRK instruction as checking every register (as it is
expected to immediately trigger an abnormal program termination) to
prevent false positive reports about authentication oracles:

autia   x2, x3
autia   x0, x1
; neither x0 nor x2 are checked at this point
eor x16, x0, x0, lsl #1
tbz x16, #62, on_success ; marks x0 as checked
; end of BB: for x2 to be checked here, it must be checked in both
; successor basic blocks
  on_failure:
brk 0xc470
  on_success:
; x2 is checked
ldr x1, [x2] ; marks x2 as checked
---
 bolt/include/bolt/Core/MCPlusBuilder.h| 14 ++
 bolt/lib/Passes/PAuthGadgetScanner.cpp| 13 +-
 .../Target/AArch64/AArch64MCPlusBuilder.cpp   | 24 --
 .../AArch64/gs-pauth-address-checks.s | 44 +--
 .../AArch64/gs-pauth-authentication-oracles.s |  9 ++--
 .../AArch64/gs-pauth-signing-oracles.s|  6 +--
 6 files changed, 75 insertions(+), 35 deletions(-)

diff --git a/bolt/include/bolt/Core/MCPlusBuilder.h 
b/bolt/include/bolt/Core/MCPlusBuilder.h
index 804100db80793..c31c9984ed43e 100644
--- a/bolt/include/bolt/Core/MCPlusBuilder.h
+++ b/bolt/include/bolt/Core/MCPlusBuilder.h
@@ -707,6 +707,20 @@ class MCPlusBuilder {
 return false;
   }
 
+  /// Returns true if Inst is a trap instruction.
+  ///
+  /// Tests if Inst is an instruction that immediately causes an abnormal
+  /// program termination, for example when a security violation is detected
+  /// by a compiler-inserted check.
+  ///
+  /// @note An implementation of this method should likely return false for
+  /// calls to library functions like abort(), as it is possible that the
+  /// execution state is partially attacker-controlled at this point.
+  virtual bool isTrap(const MCInst &Inst) const {
+llvm_unreachable("not implemented");
+return false;
+  }
+
   virtual bool isBreakpoint(const MCInst &Inst) const {
 llvm_unreachable("not implemented");
 return false;
diff --git a/bolt/lib/Passes/PAuthGadgetScanner.cpp 
b/bolt/lib/Passes/PAuthGadgetScanner.cpp
index b5b46390d4586..98bb84f6f965d 100644
--- a/bolt/lib/Passes/PAuthGadgetScanner.cpp
+++ b/bolt/lib/Passes/PAuthGadgetScanner.cpp
@@ -1078,6 +1078,15 @@ class DstSafetyAnalysis {
   dbgs() << ")\n";
 });
 
+// If this instruction terminates the program immediately, no
+// authentication oracles are possible past this point.
+if (BC.MIB->isTrap(Point)) {
+  LLVM_DEBUG({ traceInst(BC, "Trap instruction found", Point); });
+  DstState Next(NumRegs, RegsToTrackInstsFor.getNumTrackedRegisters());
+  Next.CannotEscapeUnchecked.set();
+  return Next;
+}
+
 // If this instruction is reachable by the analysis, a non-empty state will
 // be propagated to it sooner or later. Until then, skip computeNext().
 if (Cur.empty()) {
@@ -1185,8 +1194,8 @@ class DataflowDstSafetyAnalysis
 //
 // A basic block without any successors, on the other hand, can be
 // pessimistically initialized to everything-is-unsafe: this will naturally
-// handle both return and tail call instructions and is harmless for
-// internal indirect branch instructions (such as computed gotos).
+// handle return, trap and tail call instructions. At the same time, it is
+// harmless for internal indirect branch instructions, like computed gotos.
 if (BB.succ_empty())
   return createUnsafeState();
 
diff --git a/bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp 
b/bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp
index eb1d9d8a19514..ac454a43e8a59 100644
--- a/bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp
+++ b/bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp
@@ -386,10 +386,9 @@ class AArch64MCPlusBuilder : public MCPlusBuilder {
 // the list of successors of this basic block as appropriate.
 
 // Any of the above code sequences assume the fall-through basic block
-// is a dead-end BRK instruction (any immediate operand is accepted).
+// is a dead-end trap instruction.
 const BinaryBasicBlock *BreakBB = BB.getFallthrough();
-if (!BreakBB || BreakBB->empty() ||
-BreakBB->front().getOpcode() != AArch64::BRK)
+if (!BreakBB || BreakBB->empty() || !isTrap(BreakBB->front()))
   return std::nullopt;
 
 // Iterate over the instructions of BB in reverse order, matching opcodes
@@ -1751,6 +1750,25 @@ class AArch64MCPlusBuilder : public MCPlusBuilder {
 Inst.addOperand(MCOperand::createImm(0));
   }
 

[llvm-branch-commits] [llvm] [BOLT] Gadget scanner: make use of C++17 features and LLVM helpers (PR #141665)

2025-06-19 Thread Anatoly Trosinenko via llvm-branch-commits

https://github.com/atrosinenko updated 
https://github.com/llvm/llvm-project/pull/141665

>From e880cb42df70af5112e89c16bffc908274ba5910 Mon Sep 17 00:00:00 2001
From: Anatoly Trosinenko 
Date: Tue, 27 May 2025 21:06:03 +0300
Subject: [PATCH] [BOLT] Gadget scanner: make use of C++17 features and LLVM
 helpers

Perform trivial syntactical cleanups:
* make use of structured binding declarations
* use LLVM utility functions when appropriate
* omit braces around single expression inside single-line LLVM_DEBUG()

This patch is NFC aside from minor debug output changes.
---
 bolt/lib/Passes/PAuthGadgetScanner.cpp| 67 +--
 .../AArch64/gs-pauth-debug-output.s   | 14 ++--
 2 files changed, 38 insertions(+), 43 deletions(-)

diff --git a/bolt/lib/Passes/PAuthGadgetScanner.cpp 
b/bolt/lib/Passes/PAuthGadgetScanner.cpp
index b4d2fe150d514..f455229d9ea7a 100644
--- a/bolt/lib/Passes/PAuthGadgetScanner.cpp
+++ b/bolt/lib/Passes/PAuthGadgetScanner.cpp
@@ -88,8 +88,8 @@ class TrackedRegisters {
   TrackedRegisters(ArrayRef RegsToTrack)
   : Registers(RegsToTrack),
 RegToIndexMapping(getMappingSize(RegsToTrack), NoIndex) {
-for (unsigned I = 0; I < RegsToTrack.size(); ++I)
-  RegToIndexMapping[RegsToTrack[I]] = I;
+for (auto [MappedIndex, Reg] : llvm::enumerate(RegsToTrack))
+  RegToIndexMapping[Reg] = MappedIndex;
   }
 
   ArrayRef getRegisters() const { return Registers; }
@@ -203,9 +203,9 @@ struct SrcState {
 
 SafeToDerefRegs &= StateIn.SafeToDerefRegs;
 TrustedRegs &= StateIn.TrustedRegs;
-for (unsigned I = 0; I < LastInstWritingReg.size(); ++I)
-  for (const MCInst *J : StateIn.LastInstWritingReg[I])
-LastInstWritingReg[I].insert(J);
+for (auto [ThisSet, OtherSet] :
+ llvm::zip_equal(LastInstWritingReg, StateIn.LastInstWritingReg))
+  ThisSet.insert_range(OtherSet);
 return *this;
   }
 
@@ -224,11 +224,9 @@ struct SrcState {
 static void printInstsShort(raw_ostream &OS,
 ArrayRef Insts) {
   OS << "Insts: ";
-  for (unsigned I = 0; I < Insts.size(); ++I) {
-auto &Set = Insts[I];
+  for (auto [I, PtrSet] : llvm::enumerate(Insts)) {
 OS << "[" << I << "](";
-for (const MCInst *MCInstP : Set)
-  OS << MCInstP << " ";
+interleave(PtrSet, OS, " ");
 OS << ")";
   }
 }
@@ -416,8 +414,9 @@ class SrcSafetyAnalysis {
 // ... an address can be updated in a safe manner, producing the result
 // which is as trusted as the input address.
 if (auto DstAndSrc = BC.MIB->analyzeAddressArithmeticsForPtrAuth(Point)) {
-  if (Cur.SafeToDerefRegs[DstAndSrc->second])
-Regs.push_back(DstAndSrc->first);
+  auto [DstReg, SrcReg] = *DstAndSrc;
+  if (Cur.SafeToDerefRegs[SrcReg])
+Regs.push_back(DstReg);
 }
 
 // Make sure explicit checker sequence keeps register safe-to-dereference
@@ -469,8 +468,9 @@ class SrcSafetyAnalysis {
 // ... an address can be updated in a safe manner, producing the result
 // which is as trusted as the input address.
 if (auto DstAndSrc = BC.MIB->analyzeAddressArithmeticsForPtrAuth(Point)) {
-  if (Cur.TrustedRegs[DstAndSrc->second])
-Regs.push_back(DstAndSrc->first);
+  auto [DstReg, SrcReg] = *DstAndSrc;
+  if (Cur.TrustedRegs[SrcReg])
+Regs.push_back(DstReg);
 }
 
 return Regs;
@@ -868,9 +868,9 @@ struct DstState {
   return (*this = StateIn);
 
 CannotEscapeUnchecked &= StateIn.CannotEscapeUnchecked;
-for (unsigned I = 0; I < FirstInstLeakingReg.size(); ++I)
-  for (const MCInst *J : StateIn.FirstInstLeakingReg[I])
-FirstInstLeakingReg[I].insert(J);
+for (auto [ThisSet, OtherSet] :
+ llvm::zip_equal(FirstInstLeakingReg, StateIn.FirstInstLeakingReg))
+  ThisSet.insert_range(OtherSet);
 return *this;
   }
 
@@ -1036,8 +1036,7 @@ class DstSafetyAnalysis {
 
 // ... an address can be updated in a safe manner, or
 if (auto DstAndSrc = BC.MIB->analyzeAddressArithmeticsForPtrAuth(Inst)) {
-  MCPhysReg DstReg, SrcReg;
-  std::tie(DstReg, SrcReg) = *DstAndSrc;
+  auto [DstReg, SrcReg] = *DstAndSrc;
   // Note that *all* registers containing the derived values must be safe,
   // both source and destination ones. No temporaries are supported at now.
   if (Cur.CannotEscapeUnchecked[SrcReg] &&
@@ -1077,7 +1076,7 @@ class DstSafetyAnalysis {
 // If this instruction terminates the program immediately, no
 // authentication oracles are possible past this point.
 if (BC.MIB->isTrap(Point)) {
-  LLVM_DEBUG({ traceInst(BC, "Trap instruction found", Point); });
+  LLVM_DEBUG(traceInst(BC, "Trap instruction found", Point));
   DstState Next(NumRegs, RegsToTrackInstsFor.getNumTrackedRegisters());
   Next.CannotEscapeUnchecked.set();
   return Next;
@@ -1255,7 +1254,7 @@ class CFGUnawareDstSafetyAnalysis : public 
DstSafetyAnalysis,
   // starting to analyze Inst.
   

[llvm-branch-commits] [llvm] [BOLT] Gadget scanner: optionally assume auth traps on failure (PR #139778)

2025-06-19 Thread Anatoly Trosinenko via llvm-branch-commits

https://github.com/atrosinenko updated 
https://github.com/llvm/llvm-project/pull/139778

>From 275344a2d8b93e3426214a09cea5f2243c0e2873 Mon Sep 17 00:00:00 2001
From: Anatoly Trosinenko 
Date: Tue, 13 May 2025 19:50:41 +0300
Subject: [PATCH] [BOLT] Gadget scanner: optionally assume auth traps on
 failure

On AArch64 it is possible for an auth instruction to either return an
invalid address value on failure (without FEAT_FPAC) or generate an
error (with FEAT_FPAC). It thus may be possible to never emit explicit
pointer checks, if the target CPU is known to support FEAT_FPAC.

This commit implements an --auth-traps-on-failure command line option,
which essentially makes "safe-to-dereference" and "trusted" register
properties identical and disables scanning for authentication oracles
completely.
---
 bolt/lib/Passes/PAuthGadgetScanner.cpp| 112 +++
 .../binary-analysis/AArch64/cmdline-args.test |   1 +
 .../AArch64/gs-pauth-authentication-oracles.s |   6 +-
 .../binary-analysis/AArch64/gs-pauth-calls.s  |   5 +-
 .../AArch64/gs-pauth-debug-output.s   | 177 ++---
 .../AArch64/gs-pauth-jump-table.s |   6 +-
 .../AArch64/gs-pauth-signing-oracles.s|  54 ++---
 .../AArch64/gs-pauth-tail-calls.s | 184 +-
 8 files changed, 318 insertions(+), 227 deletions(-)

diff --git a/bolt/lib/Passes/PAuthGadgetScanner.cpp 
b/bolt/lib/Passes/PAuthGadgetScanner.cpp
index 3514c953030a6..b4d2fe150d514 100644
--- a/bolt/lib/Passes/PAuthGadgetScanner.cpp
+++ b/bolt/lib/Passes/PAuthGadgetScanner.cpp
@@ -14,6 +14,7 @@
 #include "bolt/Passes/PAuthGadgetScanner.h"
 #include "bolt/Core/ParallelUtilities.h"
 #include "bolt/Passes/DataflowAnalysis.h"
+#include "bolt/Utils/CommandLineOpts.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/SmallSet.h"
 #include "llvm/MC/MCInst.h"
@@ -26,6 +27,11 @@ namespace llvm {
 namespace bolt {
 namespace PAuthGadgetScanner {
 
+static cl::opt AuthTrapsOnFailure(
+"auth-traps-on-failure",
+cl::desc("Assume authentication instructions always trap on failure"),
+cl::cat(opts::BinaryAnalysisCategory));
+
 [[maybe_unused]] static void traceInst(const BinaryContext &BC, StringRef 
Label,
const MCInst &MI) {
   dbgs() << "  " << Label << ": ";
@@ -364,6 +370,34 @@ class SrcSafetyAnalysis {
 return Clobbered;
   }
 
+  std::optional getRegMadeTrustedByChecking(const MCInst &Inst,
+   SrcState Cur) const {
+// This functions cannot return multiple registers. This is never the case
+// on AArch64.
+std::optional RegCheckedByInst =
+BC.MIB->getAuthCheckedReg(Inst, /*MayOverwrite=*/false);
+if (RegCheckedByInst && Cur.SafeToDerefRegs[*RegCheckedByInst])
+  return *RegCheckedByInst;
+
+auto It = CheckerSequenceInfo.find(&Inst);
+if (It == CheckerSequenceInfo.end())
+  return std::nullopt;
+
+MCPhysReg RegCheckedBySequence = It->second.first;
+const MCInst *FirstCheckerInst = It->second.second;
+
+// FirstCheckerInst should belong to the same basic block (see the
+// assertion in DataflowSrcSafetyAnalysis::run()), meaning it was
+// deterministically processed a few steps before this instruction.
+const SrcState &StateBeforeChecker = getStateBefore(*FirstCheckerInst);
+
+// The sequence checks the register, but it should be authenticated before.
+if (!StateBeforeChecker.SafeToDerefRegs[RegCheckedBySequence])
+  return std::nullopt;
+
+return RegCheckedBySequence;
+  }
+
   // Returns all registers that can be treated as if they are written by an
   // authentication instruction.
   SmallVector getRegsMadeSafeToDeref(const MCInst &Point,
@@ -386,18 +420,38 @@ class SrcSafetyAnalysis {
 Regs.push_back(DstAndSrc->first);
 }
 
+// Make sure explicit checker sequence keeps register safe-to-dereference
+// when the register would be clobbered according to the regular rules:
+//
+//; LR is safe to dereference here
+//mov   x16, x30  ; start of the sequence, LR is s-t-d right before
+//xpaclri ; clobbers LR, LR is not safe anymore
+//cmp   x30, x16
+//b.eq  1f; end of the sequence: LR is marked as trusted
+//brk   0x1234
+//  1:
+//; at this point LR would be marked as trusted,
+//; but not safe-to-dereference
+//
+// or even just
+//
+//; X1 is safe to dereference here
+//ldr x0, [x1, #8]!
+//; X1 is trusted here, but it was clobbered due to address write-back
+if (auto CheckedReg = getRegMadeTrustedByChecking(Point, Cur))
+  Regs.push_back(*CheckedReg);
+
 return Regs;
   }
 
   // Returns all registers made trusted by this instruction.
   SmallVector getRegsMadeTrusted(const MCInst &Point,
 const SrcState &Cur) const {
+assert(!AuthTrapsOnFailure &&

[llvm-branch-commits] [llvm] [BOLT] Gadget scanner: prevent false positives due to jump tables (PR #138884)

2025-06-19 Thread Anatoly Trosinenko via llvm-branch-commits

https://github.com/atrosinenko updated 
https://github.com/llvm/llvm-project/pull/138884

>From e72572049530d58764cff1ce1081c1765838188a Mon Sep 17 00:00:00 2001
From: Anatoly Trosinenko 
Date: Tue, 6 May 2025 11:31:03 +0300
Subject: [PATCH] [BOLT] Gadget scanner: prevent false positives due to jump
 tables

As part of PAuth hardening, AArch64 LLVM backend can use a special
BR_JumpTable pseudo (enabled by -faarch64-jump-table-hardening
Clang option) which is expanded in the AsmPrinter into a contiguous
sequence without unsafe instructions in the middle.

This commit adds another target-specific callback to MCPlusBuilder
to make it possible to inhibit false positives for known-safe jump
table dispatch sequences. Without special handling, the branch
instruction is likely to be reported as a non-protected call (as its
destination is not produced by an auth instruction, PC-relative address
materialization, etc.) and possibly as a tail call being performed with
unsafe link register (as the detection whether the branch instruction
is a tail call is an heuristic).

For now, only the specific instruction sequence used by the AArch64
LLVM backend is matched.
---
 bolt/include/bolt/Core/MCInstUtils.h  |   9 +
 bolt/include/bolt/Core/MCPlusBuilder.h|  14 +
 bolt/lib/Core/MCInstUtils.cpp |  20 +
 bolt/lib/Passes/PAuthGadgetScanner.cpp|  10 +
 .../Target/AArch64/AArch64MCPlusBuilder.cpp   |  73 ++
 .../AArch64/gs-pauth-jump-table.s | 703 ++
 6 files changed, 829 insertions(+)
 create mode 100644 bolt/test/binary-analysis/AArch64/gs-pauth-jump-table.s

diff --git a/bolt/include/bolt/Core/MCInstUtils.h 
b/bolt/include/bolt/Core/MCInstUtils.h
index 50b7d56470c99..33d36cccbcfff 100644
--- a/bolt/include/bolt/Core/MCInstUtils.h
+++ b/bolt/include/bolt/Core/MCInstUtils.h
@@ -154,6 +154,15 @@ class MCInstReference {
 return nullptr;
   }
 
+  /// Returns the only preceding instruction, or std::nullopt if multiple or no
+  /// predecessors are possible.
+  ///
+  /// If CFG information is available, basic block boundary can be crossed,
+  /// provided there is exactly one predecessor. If CFG is not available, the
+  /// preceding instruction in the offset order is returned, unless this is the
+  /// first instruction of the function.
+  std::optional getSinglePredecessor();
+
   raw_ostream &print(raw_ostream &OS) const;
 };
 
diff --git a/bolt/include/bolt/Core/MCPlusBuilder.h 
b/bolt/include/bolt/Core/MCPlusBuilder.h
index c31c9984ed43e..b6f70fc831fca 100644
--- a/bolt/include/bolt/Core/MCPlusBuilder.h
+++ b/bolt/include/bolt/Core/MCPlusBuilder.h
@@ -14,6 +14,7 @@
 #ifndef BOLT_CORE_MCPLUSBUILDER_H
 #define BOLT_CORE_MCPLUSBUILDER_H
 
+#include "bolt/Core/MCInstUtils.h"
 #include "bolt/Core/MCPlus.h"
 #include "bolt/Core/Relocation.h"
 #include "llvm/ADT/ArrayRef.h"
@@ -700,6 +701,19 @@ class MCPlusBuilder {
 return std::nullopt;
   }
 
+  /// Tests if BranchInst corresponds to an instruction sequence which is known
+  /// to be a safe dispatch via jump table.
+  ///
+  /// The target can decide which instruction sequences to consider "safe" from
+  /// the Pointer Authentication point of view, such as any jump table dispatch
+  /// sequence without function calls inside, any sequence which is contiguous,
+  /// or only some specific well-known sequences.
+  virtual bool
+  isSafeJumpTableBranchForPtrAuth(MCInstReference BranchInst) const {
+llvm_unreachable("not implemented");
+return false;
+  }
+
   virtual bool isTerminator(const MCInst &Inst) const;
 
   virtual bool isNoop(const MCInst &Inst) const {
diff --git a/bolt/lib/Core/MCInstUtils.cpp b/bolt/lib/Core/MCInstUtils.cpp
index 40f6edd59135c..b7c6d898988af 100644
--- a/bolt/lib/Core/MCInstUtils.cpp
+++ b/bolt/lib/Core/MCInstUtils.cpp
@@ -55,3 +55,23 @@ raw_ostream &MCInstReference::print(raw_ostream &OS) const {
   OS << ">";
   return OS;
 }
+
+std::optional MCInstReference::getSinglePredecessor() {
+  if (const RefInBB *Ref = tryGetRefInBB()) {
+if (Ref->It != Ref->BB->begin())
+  return MCInstReference(Ref->BB, &*std::prev(Ref->It));
+
+if (Ref->BB->pred_size() != 1)
+  return std::nullopt;
+
+BinaryBasicBlock *PredBB = *Ref->BB->pred_begin();
+assert(!PredBB->empty() && "Empty basic blocks are not supported yet");
+return MCInstReference(PredBB, &*PredBB->rbegin());
+  }
+
+  const RefInBF &Ref = getRefInBF();
+  if (Ref.It == Ref.BF->instrs().begin())
+return std::nullopt;
+
+  return MCInstReference(Ref.BF, std::prev(Ref.It));
+}
diff --git a/bolt/lib/Passes/PAuthGadgetScanner.cpp 
b/bolt/lib/Passes/PAuthGadgetScanner.cpp
index ee873f7c2c21d..3514c953030a6 100644
--- a/bolt/lib/Passes/PAuthGadgetScanner.cpp
+++ b/bolt/lib/Passes/PAuthGadgetScanner.cpp
@@ -1363,6 +1363,11 @@ shouldReportUnsafeTailCall(const BinaryContext &BC, 
const BinaryFunction &BF,
 return std::nullopt;
   }
 
+  if (BC.MIB->isSafeJumpTableBranchForPtrAuth(Inst)) {
+LL

[llvm-branch-commits] [llvm] [BOLT] Introduce helpers to match `MCInst`s one at a time (NFC) (PR #138883)

2025-06-19 Thread Anatoly Trosinenko via llvm-branch-commits

https://github.com/atrosinenko updated 
https://github.com/llvm/llvm-project/pull/138883

>From 70eb080d1bc6be69901ef9457b74bef7917327d8 Mon Sep 17 00:00:00 2001
From: Anatoly Trosinenko 
Date: Wed, 7 May 2025 16:42:00 +0300
Subject: [PATCH] [BOLT] Introduce helpers to match `MCInst`s one at a time
 (NFC)

Introduce matchInst helper function to capture and/or match the operands
of MCInst. Unlike the existing `MCPlusBuilder::MCInstMatcher` machinery,
matchInst is intended for the use cases when precise control over the
instruction order is required. For example, when validating PtrAuth
hardening, all registers are usually considered unsafe after a function
call, even though callee-saved registers should preserve their old
values *under normal operation*.
---
 bolt/include/bolt/Core/MCInstUtils.h  | 128 ++
 .../Target/AArch64/AArch64MCPlusBuilder.cpp   |  90 +---
 2 files changed, 162 insertions(+), 56 deletions(-)

diff --git a/bolt/include/bolt/Core/MCInstUtils.h 
b/bolt/include/bolt/Core/MCInstUtils.h
index 69bf5e6159b74..50b7d56470c99 100644
--- a/bolt/include/bolt/Core/MCInstUtils.h
+++ b/bolt/include/bolt/Core/MCInstUtils.h
@@ -162,6 +162,134 @@ static inline raw_ostream &operator<<(raw_ostream &OS,
   return Ref.print(OS);
 }
 
+/// Instruction-matching helpers operating on a single instruction at a time.
+///
+/// Unlike MCPlusBuilder::MCInstMatcher, this matchInst() function focuses on
+/// the cases where a precise control over the instruction order is important:
+///
+/// // Bring the short names into the local scope:
+/// using namespace MCInstMatcher;
+/// // Declare the registers to capture:
+/// Reg Xn, Xm;
+/// // Capture the 0th and 1st operands, match the 2nd operand against the
+/// // just captured Xm register, match the 3rd operand against literal 0:
+/// if (!matchInst(MaybeAdd, AArch64::ADDXrs, Xm, Xn, Xm, Imm(0))
+///   return AArch64::NoRegister;
+/// // Match the 0th operand against Xm:
+/// if (!matchInst(MaybeBr, AArch64::BR, Xm))
+///   return AArch64::NoRegister;
+/// // Return the matched register:
+/// return Xm.get();
+namespace MCInstMatcher {
+
+// The base class to match an operand of type T.
+//
+// The subclasses of OpMatcher are intended to be allocated on the stack and
+// to only be used by passing them to matchInst() and by calling their get()
+// function, thus the peculiar `mutable` specifiers: to make the calling code
+// compact and readable, the templated matchInst() function has to accept both
+// long-lived Imm/Reg wrappers declared as local variables (intended to capture
+// the first operand's value and match the subsequent operands, whether inside
+// a single instruction or across multiple instructions), as well as temporary
+// wrappers around literal values to match, f.e. Imm(42) or Reg(AArch64::XZR).
+template  class OpMatcher {
+  mutable std::optional Value;
+  mutable std::optional SavedValue;
+
+  // Remember/restore the last Value - to be called by matchInst.
+  void remember() const { SavedValue = Value; }
+  void restore() const { Value = SavedValue; }
+
+  template 
+  friend bool matchInst(const MCInst &, unsigned, const OpMatchers &...);
+
+protected:
+  OpMatcher(std::optional ValueToMatch) : Value(ValueToMatch) {}
+
+  bool matchValue(T OpValue) const {
+// Check that OpValue does not contradict the existing Value.
+bool MatchResult = !Value || *Value == OpValue;
+// If MatchResult is false, all matchers will be reset before returning 
from
+// matchInst, including this one, thus no need to assign conditionally.
+Value = OpValue;
+
+return MatchResult;
+  }
+
+public:
+  /// Returns the captured value.
+  T get() const {
+assert(Value.has_value());
+return *Value;
+  }
+};
+
+class Reg : public OpMatcher {
+  bool matches(const MCOperand &Op) const {
+if (!Op.isReg())
+  return false;
+
+return matchValue(Op.getReg());
+  }
+
+  template 
+  friend bool matchInst(const MCInst &, unsigned, const OpMatchers &...);
+
+public:
+  Reg(std::optional RegToMatch = std::nullopt)
+  : OpMatcher(RegToMatch) {}
+};
+
+class Imm : public OpMatcher {
+  bool matches(const MCOperand &Op) const {
+if (!Op.isImm())
+  return false;
+
+return matchValue(Op.getImm());
+  }
+
+  template 
+  friend bool matchInst(const MCInst &, unsigned, const OpMatchers &...);
+
+public:
+  Imm(std::optional ImmToMatch = std::nullopt)
+  : OpMatcher(ImmToMatch) {}
+};
+
+/// Tries to match Inst and updates Ops on success.
+///
+/// If Inst has the specified Opcode and its operand list prefix matches Ops,
+/// this function returns true and updates Ops, otherwise false is returned and
+/// values of Ops are kept as before matchInst was called.
+///
+/// Please note that while Ops are technically passed by a const reference to
+/// make invocations like `matchInst(MI, Opcode, Imm(42))` possible, all their
+/// fields are marked mut

[llvm-branch-commits] [llvm] AMDGPU/GlobalISel: Improve readanylane combines in regbanklegalize (PR #142789)

2025-06-19 Thread Petar Avramovic via llvm-branch-commits

https://github.com/petar-avramovic updated 
https://github.com/llvm/llvm-project/pull/142789

>From 28f0f171b27aaf707706db71978d525c12e21491 Mon Sep 17 00:00:00 2001
From: Petar Avramovic 
Date: Thu, 5 Jun 2025 12:17:13 +0200
Subject: [PATCH] AMDGPU/GlobalISel: Improve readanylane combines in
 regbanklegalize

---
 .../Target/AMDGPU/AMDGPURegBankLegalize.cpp   | 122 +++---
 .../AMDGPU/GlobalISel/readanylane-combines.ll |  25 +---
 .../GlobalISel/readanylane-combines.mir   |  78 +++
 3 files changed, 125 insertions(+), 100 deletions(-)

diff --git a/llvm/lib/Target/AMDGPU/AMDGPURegBankLegalize.cpp 
b/llvm/lib/Target/AMDGPU/AMDGPURegBankLegalize.cpp
index ba661348ca5b5..6707b641b0d25 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPURegBankLegalize.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPURegBankLegalize.cpp
@@ -23,6 +23,7 @@
 #include "GCNSubtarget.h"
 #include "llvm/CodeGen/GlobalISel/CSEInfo.h"
 #include "llvm/CodeGen/GlobalISel/CSEMIRBuilder.h"
+#include "llvm/CodeGen/GlobalISel/GenericMachineInstrs.h"
 #include "llvm/CodeGen/MachineFunctionPass.h"
 #include "llvm/CodeGen/MachineUniformityAnalysis.h"
 #include "llvm/CodeGen/TargetPassConfig.h"
@@ -137,7 +138,109 @@ class AMDGPURegBankLegalizeCombiner {
 return {MatchMI, MatchMI->getOperand(1).getReg()};
   }
 
+  std::pair tryMatchRALFromUnmerge(Register Src) {
+MachineInstr *ReadAnyLane = MRI.getVRegDef(Src);
+if (ReadAnyLane->getOpcode() == AMDGPU::G_AMDGPU_READANYLANE) {
+  Register RALSrc = ReadAnyLane->getOperand(1).getReg();
+  if (auto *UnMerge = getOpcodeDef(RALSrc, MRI))
+return {UnMerge, UnMerge->findRegisterDefOperandIdx(RALSrc, nullptr)};
+}
+return {nullptr, -1};
+  }
+
+  Register getReadAnyLaneSrc(Register Src) {
+// Src = G_AMDGPU_READANYLANE RALSrc
+auto [RAL, RALSrc] = tryMatch(Src, AMDGPU::G_AMDGPU_READANYLANE);
+if (RAL)
+  return RALSrc;
+
+// LoVgpr, HiVgpr = G_UNMERGE_VALUES UnmergeSrc
+// LoSgpr = G_AMDGPU_READANYLANE LoVgpr
+// HiSgpr = G_AMDGPU_READANYLANE HiVgpr
+// Src G_MERGE_VALUES LoSgpr, HiSgpr
+auto *Merge = getOpcodeDef(Src, MRI);
+if (Merge) {
+  unsigned NumElts = Merge->getNumSources();
+  auto [Unmerge, Idx] = tryMatchRALFromUnmerge(Merge->getSourceReg(0));
+  if (!Unmerge || Unmerge->getNumDefs() != NumElts || Idx != 0)
+return {};
+
+  // check if all elements are from same unmerge and there is no shuffling
+  for (unsigned i = 1; i < NumElts; ++i) {
+auto [UnmergeI, IdxI] = tryMatchRALFromUnmerge(Merge->getSourceReg(i));
+if (UnmergeI != Unmerge || (unsigned)IdxI != i)
+  return {};
+  }
+  return Unmerge->getSourceReg();
+}
+
+// ..., VgprI, ... = G_UNMERGE_VALUES VgprLarge
+// SgprI = G_AMDGPU_READANYLANE VgprI
+// SgprLarge G_MERGE_VALUES ..., SgprI, ...
+// ..., Src, ... = G_UNMERGE_VALUES SgprLarge
+auto *UnMerge = getOpcodeDef(Src, MRI);
+if (UnMerge) {
+  int Idx = UnMerge->findRegisterDefOperandIdx(Src, nullptr);
+  auto *Merge = getOpcodeDef(UnMerge->getSourceReg(), 
MRI);
+  if (Merge) {
+auto [RAL, RALSrc] =
+tryMatch(Merge->getSourceReg(Idx), AMDGPU::G_AMDGPU_READANYLANE);
+if (RAL)
+  return RALSrc;
+  }
+}
+
+return {};
+  }
+
+  void replaceRegWithOrBuildCopy(Register Dst, Register Src) {
+if (Dst.isVirtual())
+  MRI.replaceRegWith(Dst, Src);
+else
+  B.buildCopy(Dst, Src);
+  }
+
+  bool tryEliminateReadAnyLane(MachineInstr &Copy) {
+Register Dst = Copy.getOperand(0).getReg();
+Register Src = Copy.getOperand(1).getReg();
+if (!Src.isVirtual())
+  return false;
+
+Register RALDst = Src;
+MachineInstr &SrcMI = *MRI.getVRegDef(Src);
+if (SrcMI.getOpcode() == AMDGPU::G_BITCAST)
+  RALDst = SrcMI.getOperand(1).getReg();
+
+Register RALSrc = getReadAnyLaneSrc(RALDst);
+if (!RALSrc)
+  return false;
+
+B.setInstr(Copy);
+if (SrcMI.getOpcode() != AMDGPU::G_BITCAST) {
+  // Src = READANYLANE RALSrc Src = READANYLANE RALSrc
+  // Dst = Copy Src   $Dst = Copy Src
+  // ->   ->
+  // Dst = RALSrc $Dst = Copy RALSrc
+  replaceRegWithOrBuildCopy(Dst, RALSrc);
+} else {
+  // RALDst = READANYLANE RALSrc  RALDst = READANYLANE RALSrc
+  // Src = G_BITCAST RALDst   Src = G_BITCAST RALDst
+  // Dst = Copy Src   Dst = Copy Src
+  // ->  ->
+  // NewVgpr = G_BITCAST RALDst   NewVgpr = G_BITCAST RALDst
+  // Dst = NewVgpr$Dst = Copy NewVgpr
+  auto Bitcast = B.buildBitcast({VgprRB, MRI.getType(Src)}, RALSrc);
+  replaceRegWithOrBuildCopy(Dst, Bitcast.getReg(0));
+}
+
+eraseInstr(Copy, MRI, nullptr);
+return true;
+  }
+
   void tryCombineCopy(MachineInstr &MI) {
+if (tryEliminateReadAnyLane(MI))
+  return;
+
 Register Dst = MI.get

[llvm-branch-commits] [llvm] AMDGPU/GlobalISel: Add waterfall lowering in regbanklegalize (PR #142790)

2025-06-19 Thread Petar Avramovic via llvm-branch-commits

https://github.com/petar-avramovic updated 
https://github.com/llvm/llvm-project/pull/142790

>From ec14c19baccfeb87380bf99f728b213db3db05e2 Mon Sep 17 00:00:00 2001
From: Petar Avramovic 
Date: Thu, 5 Jun 2025 12:43:04 +0200
Subject: [PATCH] AMDGPU/GlobalISel: Add waterfall lowering in regbanklegalize

Add rules for G_AMDGPU_BUFFER_LOAD and implement waterfall lowering
for divergent operands that must be sgpr.
---
 .../Target/AMDGPU/AMDGPUGlobalISelUtils.cpp   |  53 +++-
 .../lib/Target/AMDGPU/AMDGPUGlobalISelUtils.h |   2 +
 .../Target/AMDGPU/AMDGPURegBankLegalize.cpp   |  17 +-
 .../AMDGPU/AMDGPURegBankLegalizeHelper.cpp| 239 +-
 .../AMDGPU/AMDGPURegBankLegalizeHelper.h  |   1 +
 .../AMDGPU/AMDGPURegBankLegalizeRules.cpp |  22 +-
 .../AMDGPU/AMDGPURegBankLegalizeRules.h   |   6 +-
 .../AMDGPU/GlobalISel/buffer-schedule.ll  |   2 +-
 .../llvm.amdgcn.make.buffer.rsrc.ll   |   2 +-
 .../regbankselect-amdgcn.raw.buffer.load.ll   |  59 ++---
 ...egbankselect-amdgcn.raw.ptr.buffer.load.ll |  59 ++---
 ...regbankselect-amdgcn.struct.buffer.load.ll |  59 ++---
 ...ankselect-amdgcn.struct.ptr.buffer.load.ll |  59 ++---
 .../llvm.amdgcn.buffer.load-last-use.ll   |   2 +-
 .../llvm.amdgcn.raw.atomic.buffer.load.ll |  42 +--
 .../llvm.amdgcn.raw.ptr.atomic.buffer.load.ll |  42 +--
 .../llvm.amdgcn.struct.atomic.buffer.load.ll  |  48 ++--
 ...vm.amdgcn.struct.ptr.atomic.buffer.load.ll |  48 ++--
 .../CodeGen/AMDGPU/swizzle.bit.extract.ll |   4 +-
 19 files changed, 523 insertions(+), 243 deletions(-)

diff --git a/llvm/lib/Target/AMDGPU/AMDGPUGlobalISelUtils.cpp 
b/llvm/lib/Target/AMDGPU/AMDGPUGlobalISelUtils.cpp
index 00979f44f9d34..d8be3aee1f410 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUGlobalISelUtils.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUGlobalISelUtils.cpp
@@ -117,45 +117,72 @@ static LLT getReadAnyLaneSplitTy(LLT Ty) {
   return LLT::scalar(32);
 }
 
-static Register buildReadAnyLane(MachineIRBuilder &B, Register VgprSrc,
- const RegisterBankInfo &RBI);
+using ReadLaneFnTy =
+function_ref;
+
+static Register buildReadLane(MachineIRBuilder &, Register,
+  const RegisterBankInfo &, ReadLaneFnTy);
 
 static void unmergeReadAnyLane(MachineIRBuilder &B,
SmallVectorImpl &SgprDstParts,
LLT UnmergeTy, Register VgprSrc,
-   const RegisterBankInfo &RBI) {
+   const RegisterBankInfo &RBI,
+   ReadLaneFnTy BuildRL) {
   const RegisterBank *VgprRB = &RBI.getRegBank(AMDGPU::VGPRRegBankID);
   auto Unmerge = B.buildUnmerge({VgprRB, UnmergeTy}, VgprSrc);
   for (unsigned i = 0; i < Unmerge->getNumOperands() - 1; ++i) {
-SgprDstParts.push_back(buildReadAnyLane(B, Unmerge.getReg(i), RBI));
+SgprDstParts.push_back(buildReadLane(B, Unmerge.getReg(i), RBI, BuildRL));
   }
 }
 
-static Register buildReadAnyLane(MachineIRBuilder &B, Register VgprSrc,
- const RegisterBankInfo &RBI) {
+static Register buildReadLane(MachineIRBuilder &B, Register VgprSrc,
+  const RegisterBankInfo &RBI,
+  ReadLaneFnTy BuildRL) {
   LLT Ty = B.getMRI()->getType(VgprSrc);
   const RegisterBank *SgprRB = &RBI.getRegBank(AMDGPU::SGPRRegBankID);
   if (Ty.getSizeInBits() == 32) {
-return B.buildInstr(AMDGPU::G_AMDGPU_READANYLANE, {{SgprRB, Ty}}, 
{VgprSrc})
-.getReg(0);
+Register SgprDst = B.getMRI()->createVirtualRegister({SgprRB, Ty});
+return BuildRL(B, SgprDst, VgprSrc).getReg(0);
   }
 
   SmallVector SgprDstParts;
-  unmergeReadAnyLane(B, SgprDstParts, getReadAnyLaneSplitTy(Ty), VgprSrc, RBI);
+  unmergeReadAnyLane(B, SgprDstParts, getReadAnyLaneSplitTy(Ty), VgprSrc, RBI,
+ BuildRL);
 
   return B.buildMergeLikeInstr({SgprRB, Ty}, SgprDstParts).getReg(0);
 }
 
-void AMDGPU::buildReadAnyLane(MachineIRBuilder &B, Register SgprDst,
-  Register VgprSrc, const RegisterBankInfo &RBI) {
+static void buildReadLane(MachineIRBuilder &B, Register SgprDst,
+  Register VgprSrc, const RegisterBankInfo &RBI,
+  ReadLaneFnTy BuildReadLane) {
   LLT Ty = B.getMRI()->getType(VgprSrc);
   if (Ty.getSizeInBits() == 32) {
-B.buildInstr(AMDGPU::G_AMDGPU_READANYLANE, {SgprDst}, {VgprSrc});
+BuildReadLane(B, SgprDst, VgprSrc);
 return;
   }
 
   SmallVector SgprDstParts;
-  unmergeReadAnyLane(B, SgprDstParts, getReadAnyLaneSplitTy(Ty), VgprSrc, RBI);
+  unmergeReadAnyLane(B, SgprDstParts, getReadAnyLaneSplitTy(Ty), VgprSrc, RBI,
+ BuildReadLane);
 
   B.buildMergeLikeInstr(SgprDst, SgprDstParts).getReg(0);
 }
+
+void AMDGPU::buildReadAnyLane(MachineIRBuilder &B, Register SgprDst,
+  Register VgprSrc, const RegisterBankInfo &RBI) {
+  return bu

[llvm-branch-commits] [llvm] AMDGPU/GlobalISel: Add waterfall lowering in regbanklegalize (PR #142790)

2025-06-19 Thread Petar Avramovic via llvm-branch-commits

https://github.com/petar-avramovic updated 
https://github.com/llvm/llvm-project/pull/142790

>From ec14c19baccfeb87380bf99f728b213db3db05e2 Mon Sep 17 00:00:00 2001
From: Petar Avramovic 
Date: Thu, 5 Jun 2025 12:43:04 +0200
Subject: [PATCH] AMDGPU/GlobalISel: Add waterfall lowering in regbanklegalize

Add rules for G_AMDGPU_BUFFER_LOAD and implement waterfall lowering
for divergent operands that must be sgpr.
---
 .../Target/AMDGPU/AMDGPUGlobalISelUtils.cpp   |  53 +++-
 .../lib/Target/AMDGPU/AMDGPUGlobalISelUtils.h |   2 +
 .../Target/AMDGPU/AMDGPURegBankLegalize.cpp   |  17 +-
 .../AMDGPU/AMDGPURegBankLegalizeHelper.cpp| 239 +-
 .../AMDGPU/AMDGPURegBankLegalizeHelper.h  |   1 +
 .../AMDGPU/AMDGPURegBankLegalizeRules.cpp |  22 +-
 .../AMDGPU/AMDGPURegBankLegalizeRules.h   |   6 +-
 .../AMDGPU/GlobalISel/buffer-schedule.ll  |   2 +-
 .../llvm.amdgcn.make.buffer.rsrc.ll   |   2 +-
 .../regbankselect-amdgcn.raw.buffer.load.ll   |  59 ++---
 ...egbankselect-amdgcn.raw.ptr.buffer.load.ll |  59 ++---
 ...regbankselect-amdgcn.struct.buffer.load.ll |  59 ++---
 ...ankselect-amdgcn.struct.ptr.buffer.load.ll |  59 ++---
 .../llvm.amdgcn.buffer.load-last-use.ll   |   2 +-
 .../llvm.amdgcn.raw.atomic.buffer.load.ll |  42 +--
 .../llvm.amdgcn.raw.ptr.atomic.buffer.load.ll |  42 +--
 .../llvm.amdgcn.struct.atomic.buffer.load.ll  |  48 ++--
 ...vm.amdgcn.struct.ptr.atomic.buffer.load.ll |  48 ++--
 .../CodeGen/AMDGPU/swizzle.bit.extract.ll |   4 +-
 19 files changed, 523 insertions(+), 243 deletions(-)

diff --git a/llvm/lib/Target/AMDGPU/AMDGPUGlobalISelUtils.cpp 
b/llvm/lib/Target/AMDGPU/AMDGPUGlobalISelUtils.cpp
index 00979f44f9d34..d8be3aee1f410 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUGlobalISelUtils.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUGlobalISelUtils.cpp
@@ -117,45 +117,72 @@ static LLT getReadAnyLaneSplitTy(LLT Ty) {
   return LLT::scalar(32);
 }
 
-static Register buildReadAnyLane(MachineIRBuilder &B, Register VgprSrc,
- const RegisterBankInfo &RBI);
+using ReadLaneFnTy =
+function_ref;
+
+static Register buildReadLane(MachineIRBuilder &, Register,
+  const RegisterBankInfo &, ReadLaneFnTy);
 
 static void unmergeReadAnyLane(MachineIRBuilder &B,
SmallVectorImpl &SgprDstParts,
LLT UnmergeTy, Register VgprSrc,
-   const RegisterBankInfo &RBI) {
+   const RegisterBankInfo &RBI,
+   ReadLaneFnTy BuildRL) {
   const RegisterBank *VgprRB = &RBI.getRegBank(AMDGPU::VGPRRegBankID);
   auto Unmerge = B.buildUnmerge({VgprRB, UnmergeTy}, VgprSrc);
   for (unsigned i = 0; i < Unmerge->getNumOperands() - 1; ++i) {
-SgprDstParts.push_back(buildReadAnyLane(B, Unmerge.getReg(i), RBI));
+SgprDstParts.push_back(buildReadLane(B, Unmerge.getReg(i), RBI, BuildRL));
   }
 }
 
-static Register buildReadAnyLane(MachineIRBuilder &B, Register VgprSrc,
- const RegisterBankInfo &RBI) {
+static Register buildReadLane(MachineIRBuilder &B, Register VgprSrc,
+  const RegisterBankInfo &RBI,
+  ReadLaneFnTy BuildRL) {
   LLT Ty = B.getMRI()->getType(VgprSrc);
   const RegisterBank *SgprRB = &RBI.getRegBank(AMDGPU::SGPRRegBankID);
   if (Ty.getSizeInBits() == 32) {
-return B.buildInstr(AMDGPU::G_AMDGPU_READANYLANE, {{SgprRB, Ty}}, 
{VgprSrc})
-.getReg(0);
+Register SgprDst = B.getMRI()->createVirtualRegister({SgprRB, Ty});
+return BuildRL(B, SgprDst, VgprSrc).getReg(0);
   }
 
   SmallVector SgprDstParts;
-  unmergeReadAnyLane(B, SgprDstParts, getReadAnyLaneSplitTy(Ty), VgprSrc, RBI);
+  unmergeReadAnyLane(B, SgprDstParts, getReadAnyLaneSplitTy(Ty), VgprSrc, RBI,
+ BuildRL);
 
   return B.buildMergeLikeInstr({SgprRB, Ty}, SgprDstParts).getReg(0);
 }
 
-void AMDGPU::buildReadAnyLane(MachineIRBuilder &B, Register SgprDst,
-  Register VgprSrc, const RegisterBankInfo &RBI) {
+static void buildReadLane(MachineIRBuilder &B, Register SgprDst,
+  Register VgprSrc, const RegisterBankInfo &RBI,
+  ReadLaneFnTy BuildReadLane) {
   LLT Ty = B.getMRI()->getType(VgprSrc);
   if (Ty.getSizeInBits() == 32) {
-B.buildInstr(AMDGPU::G_AMDGPU_READANYLANE, {SgprDst}, {VgprSrc});
+BuildReadLane(B, SgprDst, VgprSrc);
 return;
   }
 
   SmallVector SgprDstParts;
-  unmergeReadAnyLane(B, SgprDstParts, getReadAnyLaneSplitTy(Ty), VgprSrc, RBI);
+  unmergeReadAnyLane(B, SgprDstParts, getReadAnyLaneSplitTy(Ty), VgprSrc, RBI,
+ BuildReadLane);
 
   B.buildMergeLikeInstr(SgprDst, SgprDstParts).getReg(0);
 }
+
+void AMDGPU::buildReadAnyLane(MachineIRBuilder &B, Register SgprDst,
+  Register VgprSrc, const RegisterBankInfo &RBI) {
+  return bu

[llvm-branch-commits] [llvm] MC: Move ExceptionHandling enum to Support (PR #144692)

2025-06-19 Thread Matt Arsenault via llvm-branch-commits

arsenm wrote:

### Merge activity

* **Jun 19, 9:57 AM UTC**: A user started a stack merge that includes this pull 
request via 
[Graphite](https://app.graphite.dev/github/pr/llvm/llvm-project/144692).


https://github.com/llvm/llvm-project/pull/144692
___
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] RuntimeLibcalls: Pass in exception handling type (PR #144696)

2025-06-19 Thread Nikita Popov via llvm-branch-commits

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

LGTM

https://github.com/llvm/llvm-project/pull/144696
___
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: Improve readanylane combines in regbanklegalize (PR #142789)

2025-06-19 Thread Petar Avramovic via llvm-branch-commits

https://github.com/petar-avramovic updated 
https://github.com/llvm/llvm-project/pull/142789

>From 28f0f171b27aaf707706db71978d525c12e21491 Mon Sep 17 00:00:00 2001
From: Petar Avramovic 
Date: Thu, 5 Jun 2025 12:17:13 +0200
Subject: [PATCH] AMDGPU/GlobalISel: Improve readanylane combines in
 regbanklegalize

---
 .../Target/AMDGPU/AMDGPURegBankLegalize.cpp   | 122 +++---
 .../AMDGPU/GlobalISel/readanylane-combines.ll |  25 +---
 .../GlobalISel/readanylane-combines.mir   |  78 +++
 3 files changed, 125 insertions(+), 100 deletions(-)

diff --git a/llvm/lib/Target/AMDGPU/AMDGPURegBankLegalize.cpp 
b/llvm/lib/Target/AMDGPU/AMDGPURegBankLegalize.cpp
index ba661348ca5b5..6707b641b0d25 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPURegBankLegalize.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPURegBankLegalize.cpp
@@ -23,6 +23,7 @@
 #include "GCNSubtarget.h"
 #include "llvm/CodeGen/GlobalISel/CSEInfo.h"
 #include "llvm/CodeGen/GlobalISel/CSEMIRBuilder.h"
+#include "llvm/CodeGen/GlobalISel/GenericMachineInstrs.h"
 #include "llvm/CodeGen/MachineFunctionPass.h"
 #include "llvm/CodeGen/MachineUniformityAnalysis.h"
 #include "llvm/CodeGen/TargetPassConfig.h"
@@ -137,7 +138,109 @@ class AMDGPURegBankLegalizeCombiner {
 return {MatchMI, MatchMI->getOperand(1).getReg()};
   }
 
+  std::pair tryMatchRALFromUnmerge(Register Src) {
+MachineInstr *ReadAnyLane = MRI.getVRegDef(Src);
+if (ReadAnyLane->getOpcode() == AMDGPU::G_AMDGPU_READANYLANE) {
+  Register RALSrc = ReadAnyLane->getOperand(1).getReg();
+  if (auto *UnMerge = getOpcodeDef(RALSrc, MRI))
+return {UnMerge, UnMerge->findRegisterDefOperandIdx(RALSrc, nullptr)};
+}
+return {nullptr, -1};
+  }
+
+  Register getReadAnyLaneSrc(Register Src) {
+// Src = G_AMDGPU_READANYLANE RALSrc
+auto [RAL, RALSrc] = tryMatch(Src, AMDGPU::G_AMDGPU_READANYLANE);
+if (RAL)
+  return RALSrc;
+
+// LoVgpr, HiVgpr = G_UNMERGE_VALUES UnmergeSrc
+// LoSgpr = G_AMDGPU_READANYLANE LoVgpr
+// HiSgpr = G_AMDGPU_READANYLANE HiVgpr
+// Src G_MERGE_VALUES LoSgpr, HiSgpr
+auto *Merge = getOpcodeDef(Src, MRI);
+if (Merge) {
+  unsigned NumElts = Merge->getNumSources();
+  auto [Unmerge, Idx] = tryMatchRALFromUnmerge(Merge->getSourceReg(0));
+  if (!Unmerge || Unmerge->getNumDefs() != NumElts || Idx != 0)
+return {};
+
+  // check if all elements are from same unmerge and there is no shuffling
+  for (unsigned i = 1; i < NumElts; ++i) {
+auto [UnmergeI, IdxI] = tryMatchRALFromUnmerge(Merge->getSourceReg(i));
+if (UnmergeI != Unmerge || (unsigned)IdxI != i)
+  return {};
+  }
+  return Unmerge->getSourceReg();
+}
+
+// ..., VgprI, ... = G_UNMERGE_VALUES VgprLarge
+// SgprI = G_AMDGPU_READANYLANE VgprI
+// SgprLarge G_MERGE_VALUES ..., SgprI, ...
+// ..., Src, ... = G_UNMERGE_VALUES SgprLarge
+auto *UnMerge = getOpcodeDef(Src, MRI);
+if (UnMerge) {
+  int Idx = UnMerge->findRegisterDefOperandIdx(Src, nullptr);
+  auto *Merge = getOpcodeDef(UnMerge->getSourceReg(), 
MRI);
+  if (Merge) {
+auto [RAL, RALSrc] =
+tryMatch(Merge->getSourceReg(Idx), AMDGPU::G_AMDGPU_READANYLANE);
+if (RAL)
+  return RALSrc;
+  }
+}
+
+return {};
+  }
+
+  void replaceRegWithOrBuildCopy(Register Dst, Register Src) {
+if (Dst.isVirtual())
+  MRI.replaceRegWith(Dst, Src);
+else
+  B.buildCopy(Dst, Src);
+  }
+
+  bool tryEliminateReadAnyLane(MachineInstr &Copy) {
+Register Dst = Copy.getOperand(0).getReg();
+Register Src = Copy.getOperand(1).getReg();
+if (!Src.isVirtual())
+  return false;
+
+Register RALDst = Src;
+MachineInstr &SrcMI = *MRI.getVRegDef(Src);
+if (SrcMI.getOpcode() == AMDGPU::G_BITCAST)
+  RALDst = SrcMI.getOperand(1).getReg();
+
+Register RALSrc = getReadAnyLaneSrc(RALDst);
+if (!RALSrc)
+  return false;
+
+B.setInstr(Copy);
+if (SrcMI.getOpcode() != AMDGPU::G_BITCAST) {
+  // Src = READANYLANE RALSrc Src = READANYLANE RALSrc
+  // Dst = Copy Src   $Dst = Copy Src
+  // ->   ->
+  // Dst = RALSrc $Dst = Copy RALSrc
+  replaceRegWithOrBuildCopy(Dst, RALSrc);
+} else {
+  // RALDst = READANYLANE RALSrc  RALDst = READANYLANE RALSrc
+  // Src = G_BITCAST RALDst   Src = G_BITCAST RALDst
+  // Dst = Copy Src   Dst = Copy Src
+  // ->  ->
+  // NewVgpr = G_BITCAST RALDst   NewVgpr = G_BITCAST RALDst
+  // Dst = NewVgpr$Dst = Copy NewVgpr
+  auto Bitcast = B.buildBitcast({VgprRB, MRI.getType(Src)}, RALSrc);
+  replaceRegWithOrBuildCopy(Dst, Bitcast.getReg(0));
+}
+
+eraseInstr(Copy, MRI, nullptr);
+return true;
+  }
+
   void tryCombineCopy(MachineInstr &MI) {
+if (tryEliminateReadAnyLane(MI))
+  return;
+
 Register Dst = MI.get

[llvm-branch-commits] [clang] 366be49 - Revert "[CUDA][HIP] Add a __device__ version of std::__glibcxx_assert_fail() …"

2025-06-19 Thread via llvm-branch-commits

Author: Juan Manuel Martinez Caamaño
Date: 2025-06-19T09:11:36+02:00
New Revision: 366be49837a1fa669d836cc167b1b6dbf2725110

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

LOG: Revert "[CUDA][HIP] Add a __device__ version of 
std::__glibcxx_assert_fail() …"

This reverts commit cb011d3199e1160ad2706cb5b1d43692fa4784d8.

Added: 


Modified: 
clang/lib/Headers/CMakeLists.txt

Removed: 
clang/lib/Headers/cuda_wrappers/bits/c++config.h



diff  --git a/clang/lib/Headers/CMakeLists.txt 
b/clang/lib/Headers/CMakeLists.txt
index c96d209c1fc0c..c1c9d2e8c7b79 100644
--- a/clang/lib/Headers/CMakeLists.txt
+++ b/clang/lib/Headers/CMakeLists.txt
@@ -341,7 +341,6 @@ set(cuda_wrapper_files
 )
 
 set(cuda_wrapper_bits_files
-  cuda_wrappers/bits/c++config.h
   cuda_wrappers/bits/shared_ptr_base.h
   cuda_wrappers/bits/basic_string.h
   cuda_wrappers/bits/basic_string.tcc

diff  --git a/clang/lib/Headers/cuda_wrappers/bits/c++config.h 
b/clang/lib/Headers/cuda_wrappers/bits/c++config.h
deleted file mode 100644
index eafa13a9cc640..0
--- a/clang/lib/Headers/cuda_wrappers/bits/c++config.h
+++ /dev/null
@@ -1,51 +0,0 @@
-// libstdc++ uses the non-constexpr function std::__glibcxx_assert_fail()
-// to trigger compilation errors when the __glibcxx_assert(cond) macro
-// is used in a constexpr context.
-// Compilation fails when using code from the libstdc++ (such as std::array) on
-// device code, since these assertions invoke a non-constexpr host function 
from
-// device code.
-//
-// To work around this issue, we declare our own device version of the function
-
-#ifndef __CLANG_CUDA_WRAPPERS_BITS_CPP_CONFIG
-#define __CLANG_CUDA_WRAPPERS_BITS_CPP_CONFIG
-
-#include_next 
-
-#ifdef _LIBCPP_BEGIN_NAMESPACE_STD
-_LIBCPP_BEGIN_NAMESPACE_STD
-#else
-namespace std {
-#ifdef _GLIBCXX_BEGIN_NAMESPACE_VERSION
-_GLIBCXX_BEGIN_NAMESPACE_VERSION
-#endif
-
-#ifdef _GLIBCXX_VERBOSE_ASSERT
-__attribute__((device, noreturn)) inline void
-__glibcxx_assert_fail(const char *file, int line, const char *function,
-  const char *condition) noexcept {
-  if (file && function && condition)
-__builtin_printf("%s:%d: %s: Assertion '%s' failed.\n", file, line,
- function, condition);
-  else if (function)
-__builtin_printf("%s: Undefined behavior detected.\n", function);
-  __builtin_abort();
-}
-#endif
-
-#endif
-__attribute__((device, noreturn, __always_inline__,
-   __visibility__("default"))) inline void
-__glibcxx_assert_fail(...) noexcept {
-  __builtin_abort();
-}
-#ifdef _LIBCPP_END_NAMESPACE_STD
-_LIBCPP_END_NAMESPACE_STD
-#else
-#ifdef _GLIBCXX_BEGIN_NAMESPACE_VERSION
-_GLIBCXX_END_NAMESPACE_VERSION
-#endif
-} // namespace std
-#endif
-
-#endif



___
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] MC: Move ExceptionHandling enum to Support (PR #144692)

2025-06-19 Thread Nikita Popov via llvm-branch-commits

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

LGTM

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