[llvm-branch-commits] [flang] [mlir] [MLIR][OpenMP] Add lowering support for AUTOMAP modifier (PR #151513)
https://github.com/TIFitis updated
https://github.com/llvm/llvm-project/pull/151513
>From 6dd4d9d7aa2c6b15761b9a135b6571c08947ad40 Mon Sep 17 00:00:00 2001
From: Akash Banerjee
Date: Thu, 31 Jul 2025 13:41:59 +0100
Subject: [PATCH 1/2] [MLIR][OpenMP] Add lowering support for AUTOMAP modifier
Add Automap modifier to the MLIR op definition for the DeclareTarget
directive's Enter clause.
Also add lowering support in Flang.
Automap Ref: OpenMP 6.0 section 7.9.7.
---
flang/include/flang/Lower/OpenMP.h| 1 +
flang/lib/Lower/OpenMP/ClauseProcessor.cpp| 13 +---
flang/lib/Lower/OpenMP/OpenMP.cpp | 33 +--
flang/lib/Lower/OpenMP/Utils.cpp | 5 +--
flang/lib/Lower/OpenMP/Utils.h| 14 ++--
.../Optimizer/OpenMP/FunctionFiltering.cpp| 5 +--
.../Optimizer/OpenMP/MarkDeclareTarget.cpp| 21 +++-
.../Lower/OpenMP/declare-target-automap.f90 | 8 +
.../mlir/Dialect/OpenMP/OpenMPAttrDefs.td | 8 ++---
.../Dialect/OpenMP/OpenMPOpsInterfaces.td | 19 +--
10 files changed, 83 insertions(+), 44 deletions(-)
create mode 100644 flang/test/Lower/OpenMP/declare-target-automap.f90
diff --git a/flang/include/flang/Lower/OpenMP.h
b/flang/include/flang/Lower/OpenMP.h
index 6e150ef4e8e82..581c93f76d627 100644
--- a/flang/include/flang/Lower/OpenMP.h
+++ b/flang/include/flang/Lower/OpenMP.h
@@ -57,6 +57,7 @@ struct Variable;
struct OMPDeferredDeclareTargetInfo {
mlir::omp::DeclareTargetCaptureClause declareTargetCaptureClause;
mlir::omp::DeclareTargetDeviceType declareTargetDeviceType;
+ bool automap = false;
const Fortran::semantics::Symbol &sym;
};
diff --git a/flang/lib/Lower/OpenMP/ClauseProcessor.cpp
b/flang/lib/Lower/OpenMP/ClauseProcessor.cpp
index 8eabf4f499604..ab33e089cc9e8 100644
--- a/flang/lib/Lower/OpenMP/ClauseProcessor.cpp
+++ b/flang/lib/Lower/OpenMP/ClauseProcessor.cpp
@@ -1184,7 +1184,8 @@ bool ClauseProcessor::processLink(
[&](const omp::clause::Link &clause, const parser::CharBlock &) {
// Case: declare target link(var1, var2)...
gatherFuncAndVarSyms(
-clause.v, mlir::omp::DeclareTargetCaptureClause::link, result);
+clause.v, mlir::omp::DeclareTargetCaptureClause::link, result,
+/*automap=*/false);
});
}
@@ -1512,7 +1513,8 @@ bool ClauseProcessor::processTo(
[&](const omp::clause::To &clause, const parser::CharBlock &) {
// Case: declare target to(func, var1, var2)...
gatherFuncAndVarSyms(std::get(clause.t),
- mlir::omp::DeclareTargetCaptureClause::to,
result);
+ mlir::omp::DeclareTargetCaptureClause::to, result,
+ /*automap=*/false);
});
}
@@ -1521,12 +1523,13 @@ bool ClauseProcessor::processEnter(
return findRepeatableClause(
[&](const omp::clause::Enter &clause, const parser::CharBlock &source) {
mlir::Location currentLocation = converter.genLocation(source);
-if (std::get>(clause.t))
- TODO(currentLocation, "Declare target enter AUTOMAP modifier");
+bool automap =
+std::get>(clause.t)
+.has_value();
// Case: declare target enter(func, var1, var2)...
gatherFuncAndVarSyms(std::get(clause.t),
mlir::omp::DeclareTargetCaptureClause::enter,
- result);
+ result, automap);
});
}
diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp
b/flang/lib/Lower/OpenMP/OpenMP.cpp
index 12089d6caa5fe..de44bfa87562b 100644
--- a/flang/lib/Lower/OpenMP/OpenMP.cpp
+++ b/flang/lib/Lower/OpenMP/OpenMP.cpp
@@ -773,7 +773,7 @@ static void getDeclareTargetInfo(
ObjectList objects{makeObjects(*objectList, semaCtx)};
// Case: declare target(func, var1, var2)
gatherFuncAndVarSyms(objects, mlir::omp::DeclareTargetCaptureClause::to,
- symbolAndClause);
+ symbolAndClause, /*automap=*/false);
} else if (const auto *clauseList{
parser::Unwrap(spec.u)}) {
List clauses = makeClauses(*clauseList, semaCtx);
@@ -814,13 +814,12 @@ static void collectDeferredDeclareTargets(
mlir::ModuleOp mod = converter.getFirOpBuilder().getModule();
for (const DeclareTargetCapturePair &symClause : symbolAndClause) {
-mlir::Operation *op = mod.lookupSymbol(
-converter.mangleName(std::get(symClause)));
+mlir::Operation *op =
+mod.lookupSymbol(converter.mangleName(symClause.symbol));
if (!op) {
- deferredDeclareTarget.push_back({std::get<0>(symClause),
- clauseOps.deviceType,
- std::get<1>(symClause)});
+ deferredDeclareTarget.push_back({symClause.clause, clauseOps.deviceType,
+ symClause.automap, symClause.symbol});
[llvm-branch-commits] [clang] [clang] callee_type metadata for indirect calls (PR #117036)
https://github.com/Prabhuk updated
https://github.com/llvm/llvm-project/pull/117036
>From b7fbe09b32ff02d4f7c52d82fbf8b5cd28138852 Mon Sep 17 00:00:00 2001
From: prabhukr
Date: Wed, 23 Apr 2025 04:05:47 +
Subject: [PATCH] Address review comments.
Created using spr 1.3.6-beta.1
---
clang/lib/CodeGen/CGCall.cpp| 8
clang/lib/CodeGen/CodeGenModule.cpp | 10 +-
clang/lib/CodeGen/CodeGenModule.h | 4 ++--
3 files changed, 11 insertions(+), 11 deletions(-)
diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp
index 185ee1a970aac..d8ab7140f7943 100644
--- a/clang/lib/CodeGen/CGCall.cpp
+++ b/clang/lib/CodeGen/CGCall.cpp
@@ -5780,19 +5780,19 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo
&CallInfo,
if (callOrInvoke) {
*callOrInvoke = CI;
if (CGM.getCodeGenOpts().CallGraphSection) {
- assert((TargetDecl && TargetDecl->getFunctionType() ||
- Callee.getAbstractInfo().getCalleeFunctionProtoType()) &&
- "cannot find callsite type");
QualType CST;
if (TargetDecl && TargetDecl->getFunctionType())
CST = QualType(TargetDecl->getFunctionType(), 0);
else if (const auto *FPT =
Callee.getAbstractInfo().getCalleeFunctionProtoType())
CST = QualType(FPT, 0);
+ else
+llvm_unreachable(
+"Cannot find the callee type to generate callee_type metadata.");
// Set type identifier metadata of indirect calls for call graph section.
if (!CST.isNull())
-CGM.CreateCalleeTypeMetadataForIcall(CST, *callOrInvoke);
+CGM.createCalleeTypeMetadataForIcall(CST, *callOrInvoke);
}
}
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp
b/clang/lib/CodeGen/CodeGenModule.cpp
index 43cd2405571cf..2fc99639a75cb 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -2654,7 +2654,7 @@ void
CodeGenModule::SetLLVMFunctionAttributesForDefinition(const Decl *D,
// Skip available_externally functions. They won't be codegen'ed in the
// current module anyway.
if (getContext().GetGVALinkageForFunction(FD) != GVA_AvailableExternally)
-CreateFunctionTypeMetadataForIcall(FD, F);
+createFunctionTypeMetadataForIcall(FD, F);
}
}
@@ -2868,7 +2868,7 @@ static bool hasExistingGeneralizedTypeMD(llvm::Function
*F) {
return MD->hasGeneralizedMDString();
}
-void CodeGenModule::CreateFunctionTypeMetadataForIcall(const FunctionDecl *FD,
+void CodeGenModule::createFunctionTypeMetadataForIcall(const FunctionDecl *FD,
llvm::Function *F) {
if (CodeGenOpts.CallGraphSection && !hasExistingGeneralizedTypeMD(F) &&
(!F->hasLocalLinkage() ||
@@ -2898,7 +2898,7 @@ void
CodeGenModule::CreateFunctionTypeMetadataForIcall(const FunctionDecl *FD,
F->addTypeMetadata(0, llvm::ConstantAsMetadata::get(CrossDsoTypeId));
}
-void CodeGenModule::CreateCalleeTypeMetadataForIcall(const QualType &QT,
+void CodeGenModule::createCalleeTypeMetadataForIcall(const QualType &QT,
llvm::CallBase *CB) {
// Only if needed for call graph section and only for indirect calls.
if (!CodeGenOpts.CallGraphSection || !CB->isIndirectCall())
@@ -2909,7 +2909,7 @@ void
CodeGenModule::CreateCalleeTypeMetadataForIcall(const QualType &QT,
getLLVMContext(), {llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(
llvm::Type::getInt64Ty(getLLVMContext()), 0)),
TypeIdMD});
- llvm::MDTuple *MDN = llvm::MDNode::get(getLLVMContext(), { TypeTuple });
+ llvm::MDTuple *MDN = llvm::MDNode::get(getLLVMContext(), {TypeTuple});
CB->setMetadata(llvm::LLVMContext::MD_callee_type, MDN);
}
@@ -3041,7 +3041,7 @@ void CodeGenModule::SetFunctionAttributes(GlobalDecl GD,
llvm::Function *F,
// jump table.
if (!CodeGenOpts.SanitizeCfiCrossDso ||
!CodeGenOpts.SanitizeCfiCanonicalJumpTables)
-CreateFunctionTypeMetadataForIcall(FD, F);
+createFunctionTypeMetadataForIcall(FD, F);
if (LangOpts.Sanitize.has(SanitizerKind::KCFI))
setKCFIType(FD, F);
diff --git a/clang/lib/CodeGen/CodeGenModule.h
b/clang/lib/CodeGen/CodeGenModule.h
index dfbe4388349dd..4b53f0f241b52 100644
--- a/clang/lib/CodeGen/CodeGenModule.h
+++ b/clang/lib/CodeGen/CodeGenModule.h
@@ -1619,11 +1619,11 @@ class CodeGenModule : public CodeGenTypeCache {
llvm::Metadata *CreateMetadataIdentifierGeneralized(QualType T);
/// Create and attach type metadata to the given function.
- void CreateFunctionTypeMetadataForIcall(const FunctionDecl *FD,
+ void createFunctionTypeMetadataForIcall(const FunctionDecl *FD,
llvm::Function *F);
/// Create and attach type metadata to the given call.
- void CreateCalleeTypeMetadataForIcall(const QualType &QT, llvm::CallBase
*CB);
+ void createCa
[llvm-branch-commits] callgraph make flag experimental (PR #151402)
https://github.com/Prabhuk updated https://github.com/llvm/llvm-project/pull/151402 ___ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] callgraph make flag experimental (PR #151402)
https://github.com/Prabhuk updated https://github.com/llvm/llvm-project/pull/151402 ___ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] callee_type metadata for indirect calls (PR #117036)
https://github.com/Prabhuk updated
https://github.com/llvm/llvm-project/pull/117036
>From b7fbe09b32ff02d4f7c52d82fbf8b5cd28138852 Mon Sep 17 00:00:00 2001
From: prabhukr
Date: Wed, 23 Apr 2025 04:05:47 +
Subject: [PATCH] Address review comments.
Created using spr 1.3.6-beta.1
---
clang/lib/CodeGen/CGCall.cpp| 8
clang/lib/CodeGen/CodeGenModule.cpp | 10 +-
clang/lib/CodeGen/CodeGenModule.h | 4 ++--
3 files changed, 11 insertions(+), 11 deletions(-)
diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp
index 185ee1a970aac..d8ab7140f7943 100644
--- a/clang/lib/CodeGen/CGCall.cpp
+++ b/clang/lib/CodeGen/CGCall.cpp
@@ -5780,19 +5780,19 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo
&CallInfo,
if (callOrInvoke) {
*callOrInvoke = CI;
if (CGM.getCodeGenOpts().CallGraphSection) {
- assert((TargetDecl && TargetDecl->getFunctionType() ||
- Callee.getAbstractInfo().getCalleeFunctionProtoType()) &&
- "cannot find callsite type");
QualType CST;
if (TargetDecl && TargetDecl->getFunctionType())
CST = QualType(TargetDecl->getFunctionType(), 0);
else if (const auto *FPT =
Callee.getAbstractInfo().getCalleeFunctionProtoType())
CST = QualType(FPT, 0);
+ else
+llvm_unreachable(
+"Cannot find the callee type to generate callee_type metadata.");
// Set type identifier metadata of indirect calls for call graph section.
if (!CST.isNull())
-CGM.CreateCalleeTypeMetadataForIcall(CST, *callOrInvoke);
+CGM.createCalleeTypeMetadataForIcall(CST, *callOrInvoke);
}
}
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp
b/clang/lib/CodeGen/CodeGenModule.cpp
index 43cd2405571cf..2fc99639a75cb 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -2654,7 +2654,7 @@ void
CodeGenModule::SetLLVMFunctionAttributesForDefinition(const Decl *D,
// Skip available_externally functions. They won't be codegen'ed in the
// current module anyway.
if (getContext().GetGVALinkageForFunction(FD) != GVA_AvailableExternally)
-CreateFunctionTypeMetadataForIcall(FD, F);
+createFunctionTypeMetadataForIcall(FD, F);
}
}
@@ -2868,7 +2868,7 @@ static bool hasExistingGeneralizedTypeMD(llvm::Function
*F) {
return MD->hasGeneralizedMDString();
}
-void CodeGenModule::CreateFunctionTypeMetadataForIcall(const FunctionDecl *FD,
+void CodeGenModule::createFunctionTypeMetadataForIcall(const FunctionDecl *FD,
llvm::Function *F) {
if (CodeGenOpts.CallGraphSection && !hasExistingGeneralizedTypeMD(F) &&
(!F->hasLocalLinkage() ||
@@ -2898,7 +2898,7 @@ void
CodeGenModule::CreateFunctionTypeMetadataForIcall(const FunctionDecl *FD,
F->addTypeMetadata(0, llvm::ConstantAsMetadata::get(CrossDsoTypeId));
}
-void CodeGenModule::CreateCalleeTypeMetadataForIcall(const QualType &QT,
+void CodeGenModule::createCalleeTypeMetadataForIcall(const QualType &QT,
llvm::CallBase *CB) {
// Only if needed for call graph section and only for indirect calls.
if (!CodeGenOpts.CallGraphSection || !CB->isIndirectCall())
@@ -2909,7 +2909,7 @@ void
CodeGenModule::CreateCalleeTypeMetadataForIcall(const QualType &QT,
getLLVMContext(), {llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(
llvm::Type::getInt64Ty(getLLVMContext()), 0)),
TypeIdMD});
- llvm::MDTuple *MDN = llvm::MDNode::get(getLLVMContext(), { TypeTuple });
+ llvm::MDTuple *MDN = llvm::MDNode::get(getLLVMContext(), {TypeTuple});
CB->setMetadata(llvm::LLVMContext::MD_callee_type, MDN);
}
@@ -3041,7 +3041,7 @@ void CodeGenModule::SetFunctionAttributes(GlobalDecl GD,
llvm::Function *F,
// jump table.
if (!CodeGenOpts.SanitizeCfiCrossDso ||
!CodeGenOpts.SanitizeCfiCanonicalJumpTables)
-CreateFunctionTypeMetadataForIcall(FD, F);
+createFunctionTypeMetadataForIcall(FD, F);
if (LangOpts.Sanitize.has(SanitizerKind::KCFI))
setKCFIType(FD, F);
diff --git a/clang/lib/CodeGen/CodeGenModule.h
b/clang/lib/CodeGen/CodeGenModule.h
index dfbe4388349dd..4b53f0f241b52 100644
--- a/clang/lib/CodeGen/CodeGenModule.h
+++ b/clang/lib/CodeGen/CodeGenModule.h
@@ -1619,11 +1619,11 @@ class CodeGenModule : public CodeGenTypeCache {
llvm::Metadata *CreateMetadataIdentifierGeneralized(QualType T);
/// Create and attach type metadata to the given function.
- void CreateFunctionTypeMetadataForIcall(const FunctionDecl *FD,
+ void createFunctionTypeMetadataForIcall(const FunctionDecl *FD,
llvm::Function *F);
/// Create and attach type metadata to the given call.
- void CreateCalleeTypeMetadataForIcall(const QualType &QT, llvm::CallBase
*CB);
+ void createCa
[llvm-branch-commits] [clang] [clang] Introduce CallGraphSection option (PR #117037)
https://github.com/Prabhuk updated https://github.com/llvm/llvm-project/pull/117037 >From 6a12be2c5b60a95a06875b0b2c4f14228d1fa882 Mon Sep 17 00:00:00 2001 From: prabhukr Date: Wed, 12 Mar 2025 23:30:01 + Subject: [PATCH 1/2] Fix EOF newlines. Created using spr 1.3.6-beta.1 --- clang/test/Driver/call-graph-section.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/test/Driver/call-graph-section.c b/clang/test/Driver/call-graph-section.c index 108446729d857..5832aa6754137 100644 --- a/clang/test/Driver/call-graph-section.c +++ b/clang/test/Driver/call-graph-section.c @@ -2,4 +2,4 @@ // RUN: %clang -### -S -fcall-graph-section -fno-call-graph-section %s 2>&1 | FileCheck --check-prefix=NO-CALL-GRAPH-SECTION %s // CALL-GRAPH-SECTION: "-fcall-graph-section" -// NO-CALL-GRAPH-SECTION-NOT: "-fcall-graph-section" \ No newline at end of file +// NO-CALL-GRAPH-SECTION-NOT: "-fcall-graph-section" >From c67f714eaab9a7f1e4d2d76da28641b05710231d Mon Sep 17 00:00:00 2001 From: prabhukr Date: Mon, 21 Jul 2025 23:53:52 + Subject: [PATCH 2/2] Fix review comment on test file. Created using spr 1.3.6-beta.1 --- clang/test/Driver/call-graph-section.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/clang/test/Driver/call-graph-section.c b/clang/test/Driver/call-graph-section.c index 5832aa6754137..563f36de4119e 100644 --- a/clang/test/Driver/call-graph-section.c +++ b/clang/test/Driver/call-graph-section.c @@ -1,5 +1,5 @@ -// RUN: %clang -### -S -fcall-graph-section %s 2>&1 | FileCheck --check-prefix=CALL-GRAPH-SECTION %s -// RUN: %clang -### -S -fcall-graph-section -fno-call-graph-section %s 2>&1 | FileCheck --check-prefix=NO-CALL-GRAPH-SECTION %s +// RUN: %clang -### -fcall-graph-section %s 2>&1 | FileCheck --check-prefix=CALL-GRAPH-SECTION %s +// RUN: %clang -### -fcall-graph-section -fno-call-graph-section %s 2>&1 | FileCheck --check-prefix=NO-CALL-GRAPH-SECTION %s // CALL-GRAPH-SECTION: "-fcall-graph-section" // NO-CALL-GRAPH-SECTION-NOT: "-fcall-graph-section" ___ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [LoopPeel] Fix branch weights' effect on block frequencies (PR #128785)
https://github.com/jdenny-ornl closed https://github.com/llvm/llvm-project/pull/128785 ___ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Introduce CallGraphSection option (PR #117037)
https://github.com/Prabhuk updated https://github.com/llvm/llvm-project/pull/117037 >From 6a12be2c5b60a95a06875b0b2c4f14228d1fa882 Mon Sep 17 00:00:00 2001 From: prabhukr Date: Wed, 12 Mar 2025 23:30:01 + Subject: [PATCH 1/2] Fix EOF newlines. Created using spr 1.3.6-beta.1 --- clang/test/Driver/call-graph-section.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/test/Driver/call-graph-section.c b/clang/test/Driver/call-graph-section.c index 108446729d857..5832aa6754137 100644 --- a/clang/test/Driver/call-graph-section.c +++ b/clang/test/Driver/call-graph-section.c @@ -2,4 +2,4 @@ // RUN: %clang -### -S -fcall-graph-section -fno-call-graph-section %s 2>&1 | FileCheck --check-prefix=NO-CALL-GRAPH-SECTION %s // CALL-GRAPH-SECTION: "-fcall-graph-section" -// NO-CALL-GRAPH-SECTION-NOT: "-fcall-graph-section" \ No newline at end of file +// NO-CALL-GRAPH-SECTION-NOT: "-fcall-graph-section" >From c67f714eaab9a7f1e4d2d76da28641b05710231d Mon Sep 17 00:00:00 2001 From: prabhukr Date: Mon, 21 Jul 2025 23:53:52 + Subject: [PATCH 2/2] Fix review comment on test file. Created using spr 1.3.6-beta.1 --- clang/test/Driver/call-graph-section.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/clang/test/Driver/call-graph-section.c b/clang/test/Driver/call-graph-section.c index 5832aa6754137..563f36de4119e 100644 --- a/clang/test/Driver/call-graph-section.c +++ b/clang/test/Driver/call-graph-section.c @@ -1,5 +1,5 @@ -// RUN: %clang -### -S -fcall-graph-section %s 2>&1 | FileCheck --check-prefix=CALL-GRAPH-SECTION %s -// RUN: %clang -### -S -fcall-graph-section -fno-call-graph-section %s 2>&1 | FileCheck --check-prefix=NO-CALL-GRAPH-SECTION %s +// RUN: %clang -### -fcall-graph-section %s 2>&1 | FileCheck --check-prefix=CALL-GRAPH-SECTION %s +// RUN: %clang -### -fcall-graph-section -fno-call-graph-section %s 2>&1 | FileCheck --check-prefix=NO-CALL-GRAPH-SECTION %s // CALL-GRAPH-SECTION: "-fcall-graph-section" // NO-CALL-GRAPH-SECTION-NOT: "-fcall-graph-section" ___ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] callee_type metadata for indirect calls (PR #117036)
https://github.com/Prabhuk updated
https://github.com/llvm/llvm-project/pull/117036
>From b7fbe09b32ff02d4f7c52d82fbf8b5cd28138852 Mon Sep 17 00:00:00 2001
From: prabhukr
Date: Wed, 23 Apr 2025 04:05:47 +
Subject: [PATCH] Address review comments.
Created using spr 1.3.6-beta.1
---
clang/lib/CodeGen/CGCall.cpp| 8
clang/lib/CodeGen/CodeGenModule.cpp | 10 +-
clang/lib/CodeGen/CodeGenModule.h | 4 ++--
3 files changed, 11 insertions(+), 11 deletions(-)
diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp
index 185ee1a970aac..d8ab7140f7943 100644
--- a/clang/lib/CodeGen/CGCall.cpp
+++ b/clang/lib/CodeGen/CGCall.cpp
@@ -5780,19 +5780,19 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo
&CallInfo,
if (callOrInvoke) {
*callOrInvoke = CI;
if (CGM.getCodeGenOpts().CallGraphSection) {
- assert((TargetDecl && TargetDecl->getFunctionType() ||
- Callee.getAbstractInfo().getCalleeFunctionProtoType()) &&
- "cannot find callsite type");
QualType CST;
if (TargetDecl && TargetDecl->getFunctionType())
CST = QualType(TargetDecl->getFunctionType(), 0);
else if (const auto *FPT =
Callee.getAbstractInfo().getCalleeFunctionProtoType())
CST = QualType(FPT, 0);
+ else
+llvm_unreachable(
+"Cannot find the callee type to generate callee_type metadata.");
// Set type identifier metadata of indirect calls for call graph section.
if (!CST.isNull())
-CGM.CreateCalleeTypeMetadataForIcall(CST, *callOrInvoke);
+CGM.createCalleeTypeMetadataForIcall(CST, *callOrInvoke);
}
}
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp
b/clang/lib/CodeGen/CodeGenModule.cpp
index 43cd2405571cf..2fc99639a75cb 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -2654,7 +2654,7 @@ void
CodeGenModule::SetLLVMFunctionAttributesForDefinition(const Decl *D,
// Skip available_externally functions. They won't be codegen'ed in the
// current module anyway.
if (getContext().GetGVALinkageForFunction(FD) != GVA_AvailableExternally)
-CreateFunctionTypeMetadataForIcall(FD, F);
+createFunctionTypeMetadataForIcall(FD, F);
}
}
@@ -2868,7 +2868,7 @@ static bool hasExistingGeneralizedTypeMD(llvm::Function
*F) {
return MD->hasGeneralizedMDString();
}
-void CodeGenModule::CreateFunctionTypeMetadataForIcall(const FunctionDecl *FD,
+void CodeGenModule::createFunctionTypeMetadataForIcall(const FunctionDecl *FD,
llvm::Function *F) {
if (CodeGenOpts.CallGraphSection && !hasExistingGeneralizedTypeMD(F) &&
(!F->hasLocalLinkage() ||
@@ -2898,7 +2898,7 @@ void
CodeGenModule::CreateFunctionTypeMetadataForIcall(const FunctionDecl *FD,
F->addTypeMetadata(0, llvm::ConstantAsMetadata::get(CrossDsoTypeId));
}
-void CodeGenModule::CreateCalleeTypeMetadataForIcall(const QualType &QT,
+void CodeGenModule::createCalleeTypeMetadataForIcall(const QualType &QT,
llvm::CallBase *CB) {
// Only if needed for call graph section and only for indirect calls.
if (!CodeGenOpts.CallGraphSection || !CB->isIndirectCall())
@@ -2909,7 +2909,7 @@ void
CodeGenModule::CreateCalleeTypeMetadataForIcall(const QualType &QT,
getLLVMContext(), {llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(
llvm::Type::getInt64Ty(getLLVMContext()), 0)),
TypeIdMD});
- llvm::MDTuple *MDN = llvm::MDNode::get(getLLVMContext(), { TypeTuple });
+ llvm::MDTuple *MDN = llvm::MDNode::get(getLLVMContext(), {TypeTuple});
CB->setMetadata(llvm::LLVMContext::MD_callee_type, MDN);
}
@@ -3041,7 +3041,7 @@ void CodeGenModule::SetFunctionAttributes(GlobalDecl GD,
llvm::Function *F,
// jump table.
if (!CodeGenOpts.SanitizeCfiCrossDso ||
!CodeGenOpts.SanitizeCfiCanonicalJumpTables)
-CreateFunctionTypeMetadataForIcall(FD, F);
+createFunctionTypeMetadataForIcall(FD, F);
if (LangOpts.Sanitize.has(SanitizerKind::KCFI))
setKCFIType(FD, F);
diff --git a/clang/lib/CodeGen/CodeGenModule.h
b/clang/lib/CodeGen/CodeGenModule.h
index dfbe4388349dd..4b53f0f241b52 100644
--- a/clang/lib/CodeGen/CodeGenModule.h
+++ b/clang/lib/CodeGen/CodeGenModule.h
@@ -1619,11 +1619,11 @@ class CodeGenModule : public CodeGenTypeCache {
llvm::Metadata *CreateMetadataIdentifierGeneralized(QualType T);
/// Create and attach type metadata to the given function.
- void CreateFunctionTypeMetadataForIcall(const FunctionDecl *FD,
+ void createFunctionTypeMetadataForIcall(const FunctionDecl *FD,
llvm::Function *F);
/// Create and attach type metadata to the given call.
- void CreateCalleeTypeMetadataForIcall(const QualType &QT, llvm::CallBase
*CB);
+ void createCa
[llvm-branch-commits] [clang] [clang] Introduce CallGraphSection option (PR #117037)
https://github.com/Prabhuk updated https://github.com/llvm/llvm-project/pull/117037 >From 6a12be2c5b60a95a06875b0b2c4f14228d1fa882 Mon Sep 17 00:00:00 2001 From: prabhukr Date: Wed, 12 Mar 2025 23:30:01 + Subject: [PATCH 1/2] Fix EOF newlines. Created using spr 1.3.6-beta.1 --- clang/test/Driver/call-graph-section.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/test/Driver/call-graph-section.c b/clang/test/Driver/call-graph-section.c index 108446729d857..5832aa6754137 100644 --- a/clang/test/Driver/call-graph-section.c +++ b/clang/test/Driver/call-graph-section.c @@ -2,4 +2,4 @@ // RUN: %clang -### -S -fcall-graph-section -fno-call-graph-section %s 2>&1 | FileCheck --check-prefix=NO-CALL-GRAPH-SECTION %s // CALL-GRAPH-SECTION: "-fcall-graph-section" -// NO-CALL-GRAPH-SECTION-NOT: "-fcall-graph-section" \ No newline at end of file +// NO-CALL-GRAPH-SECTION-NOT: "-fcall-graph-section" >From c67f714eaab9a7f1e4d2d76da28641b05710231d Mon Sep 17 00:00:00 2001 From: prabhukr Date: Mon, 21 Jul 2025 23:53:52 + Subject: [PATCH 2/2] Fix review comment on test file. Created using spr 1.3.6-beta.1 --- clang/test/Driver/call-graph-section.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/clang/test/Driver/call-graph-section.c b/clang/test/Driver/call-graph-section.c index 5832aa6754137..563f36de4119e 100644 --- a/clang/test/Driver/call-graph-section.c +++ b/clang/test/Driver/call-graph-section.c @@ -1,5 +1,5 @@ -// RUN: %clang -### -S -fcall-graph-section %s 2>&1 | FileCheck --check-prefix=CALL-GRAPH-SECTION %s -// RUN: %clang -### -S -fcall-graph-section -fno-call-graph-section %s 2>&1 | FileCheck --check-prefix=NO-CALL-GRAPH-SECTION %s +// RUN: %clang -### -fcall-graph-section %s 2>&1 | FileCheck --check-prefix=CALL-GRAPH-SECTION %s +// RUN: %clang -### -fcall-graph-section -fno-call-graph-section %s 2>&1 | FileCheck --check-prefix=NO-CALL-GRAPH-SECTION %s // CALL-GRAPH-SECTION: "-fcall-graph-section" // NO-CALL-GRAPH-SECTION-NOT: "-fcall-graph-section" ___ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] callgraph make flag experimental (PR #151402)
https://github.com/Prabhuk updated https://github.com/llvm/llvm-project/pull/151402 ___ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] callgraph make flag experimental (PR #151402)
https://github.com/Prabhuk updated https://github.com/llvm/llvm-project/pull/151402 ___ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] callee_type metadata for indirect calls (PR #117036)
https://github.com/Prabhuk updated
https://github.com/llvm/llvm-project/pull/117036
>From b7fbe09b32ff02d4f7c52d82fbf8b5cd28138852 Mon Sep 17 00:00:00 2001
From: prabhukr
Date: Wed, 23 Apr 2025 04:05:47 +
Subject: [PATCH] Address review comments.
Created using spr 1.3.6-beta.1
---
clang/lib/CodeGen/CGCall.cpp| 8
clang/lib/CodeGen/CodeGenModule.cpp | 10 +-
clang/lib/CodeGen/CodeGenModule.h | 4 ++--
3 files changed, 11 insertions(+), 11 deletions(-)
diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp
index 185ee1a970aac..d8ab7140f7943 100644
--- a/clang/lib/CodeGen/CGCall.cpp
+++ b/clang/lib/CodeGen/CGCall.cpp
@@ -5780,19 +5780,19 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo
&CallInfo,
if (callOrInvoke) {
*callOrInvoke = CI;
if (CGM.getCodeGenOpts().CallGraphSection) {
- assert((TargetDecl && TargetDecl->getFunctionType() ||
- Callee.getAbstractInfo().getCalleeFunctionProtoType()) &&
- "cannot find callsite type");
QualType CST;
if (TargetDecl && TargetDecl->getFunctionType())
CST = QualType(TargetDecl->getFunctionType(), 0);
else if (const auto *FPT =
Callee.getAbstractInfo().getCalleeFunctionProtoType())
CST = QualType(FPT, 0);
+ else
+llvm_unreachable(
+"Cannot find the callee type to generate callee_type metadata.");
// Set type identifier metadata of indirect calls for call graph section.
if (!CST.isNull())
-CGM.CreateCalleeTypeMetadataForIcall(CST, *callOrInvoke);
+CGM.createCalleeTypeMetadataForIcall(CST, *callOrInvoke);
}
}
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp
b/clang/lib/CodeGen/CodeGenModule.cpp
index 43cd2405571cf..2fc99639a75cb 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -2654,7 +2654,7 @@ void
CodeGenModule::SetLLVMFunctionAttributesForDefinition(const Decl *D,
// Skip available_externally functions. They won't be codegen'ed in the
// current module anyway.
if (getContext().GetGVALinkageForFunction(FD) != GVA_AvailableExternally)
-CreateFunctionTypeMetadataForIcall(FD, F);
+createFunctionTypeMetadataForIcall(FD, F);
}
}
@@ -2868,7 +2868,7 @@ static bool hasExistingGeneralizedTypeMD(llvm::Function
*F) {
return MD->hasGeneralizedMDString();
}
-void CodeGenModule::CreateFunctionTypeMetadataForIcall(const FunctionDecl *FD,
+void CodeGenModule::createFunctionTypeMetadataForIcall(const FunctionDecl *FD,
llvm::Function *F) {
if (CodeGenOpts.CallGraphSection && !hasExistingGeneralizedTypeMD(F) &&
(!F->hasLocalLinkage() ||
@@ -2898,7 +2898,7 @@ void
CodeGenModule::CreateFunctionTypeMetadataForIcall(const FunctionDecl *FD,
F->addTypeMetadata(0, llvm::ConstantAsMetadata::get(CrossDsoTypeId));
}
-void CodeGenModule::CreateCalleeTypeMetadataForIcall(const QualType &QT,
+void CodeGenModule::createCalleeTypeMetadataForIcall(const QualType &QT,
llvm::CallBase *CB) {
// Only if needed for call graph section and only for indirect calls.
if (!CodeGenOpts.CallGraphSection || !CB->isIndirectCall())
@@ -2909,7 +2909,7 @@ void
CodeGenModule::CreateCalleeTypeMetadataForIcall(const QualType &QT,
getLLVMContext(), {llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(
llvm::Type::getInt64Ty(getLLVMContext()), 0)),
TypeIdMD});
- llvm::MDTuple *MDN = llvm::MDNode::get(getLLVMContext(), { TypeTuple });
+ llvm::MDTuple *MDN = llvm::MDNode::get(getLLVMContext(), {TypeTuple});
CB->setMetadata(llvm::LLVMContext::MD_callee_type, MDN);
}
@@ -3041,7 +3041,7 @@ void CodeGenModule::SetFunctionAttributes(GlobalDecl GD,
llvm::Function *F,
// jump table.
if (!CodeGenOpts.SanitizeCfiCrossDso ||
!CodeGenOpts.SanitizeCfiCanonicalJumpTables)
-CreateFunctionTypeMetadataForIcall(FD, F);
+createFunctionTypeMetadataForIcall(FD, F);
if (LangOpts.Sanitize.has(SanitizerKind::KCFI))
setKCFIType(FD, F);
diff --git a/clang/lib/CodeGen/CodeGenModule.h
b/clang/lib/CodeGen/CodeGenModule.h
index dfbe4388349dd..4b53f0f241b52 100644
--- a/clang/lib/CodeGen/CodeGenModule.h
+++ b/clang/lib/CodeGen/CodeGenModule.h
@@ -1619,11 +1619,11 @@ class CodeGenModule : public CodeGenTypeCache {
llvm::Metadata *CreateMetadataIdentifierGeneralized(QualType T);
/// Create and attach type metadata to the given function.
- void CreateFunctionTypeMetadataForIcall(const FunctionDecl *FD,
+ void createFunctionTypeMetadataForIcall(const FunctionDecl *FD,
llvm::Function *F);
/// Create and attach type metadata to the given call.
- void CreateCalleeTypeMetadataForIcall(const QualType &QT, llvm::CallBase
*CB);
+ void createCa
[llvm-branch-commits] [clang] release/21.x: [CMake][Release] Build with -ffat-lto-objects (#140381) (PR #151245)
tstellar wrote: The failures aren't related to this change. The Linux failures are due to test failures which was already happening with -rc1. The MacOS failures are happening because the PR testing uses the free runners and they always timeout before they finish. https://github.com/llvm/llvm-project/pull/151245 ___ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [libunwind] release/21.x: [libunwind] Fix return type of `DwarfFDECache::findFDE()` in definition (#146308) (PR #150126)
alexrp wrote: Looks like the CI needs to be retried? https://github.com/llvm/llvm-project/pull/150126 ___ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [mlir] [OpenMP][OMPIRBuilder] Use device shared memory for arg structures (PR #150925)
https://github.com/Meinersbur commented: Passing callbacks around significantly adds complexity. Did you consider deriving a new class from CodeExtractor and overriding some method `createAlloca` for use by OpenMPIRBuilder? https://github.com/llvm/llvm-project/pull/150925 ___ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [mlir] [OpenMP][OMPIRBuilder] Use device shared memory for arg structures (PR #150925)
@@ -1614,6 +1650,50 @@ OpenMPIRBuilder::InsertPointOrErrorTy
OpenMPIRBuilder::createParallel(
IfCondition, NumThreads, PrivTID, PrivTIDAddr,
ThreadID, ToBeDeletedVec);
};
+
+std::optional ExecMode =
+getTargetKernelExecMode(*OuterFn);
+
+// If OuterFn is not a Generic kernel, skip custom allocation. This causes
+// the CodeExtractor to follow its default behavior. Otherwise, we need to
+// use device shared memory to allocate argument structures.
+if (ExecMode && *ExecMode & OMP_TGT_EXEC_MODE_GENERIC) {
+ OI.CustomArgAllocatorCB = [this,
+ EntryBB](BasicBlock *, BasicBlock::iterator,
+ Type *ArgTy, const Twine &Name) {
+// Instead of using the insertion point provided by the CodeExtractor,
+// here we need to use the block that eventually calls the outlined
+// function for the `parallel` construct.
+//
+// The reason is that the explicit deallocation call will be inserted
+// within the outlined function, whereas the alloca insertion point
+// might actually be located somewhere else in the caller. This becomes
+// a problem when e.g. `parallel` is inside of a `distribute`
construct,
+// because the deallocation would be executed multiple times and the
+// allocation just once (outside of the loop).
+//
+// TODO: Ideally, we'd want to do the allocation and deallocation
+// outside of the `parallel` outlined function, hence using here the
+// insertion point provided by the CodeExtractor. We can't do this at
+// the moment because there is currently no way of passing an eligible
+// insertion point for the explicit deallocation to the CodeExtractor,
+// as that block is created (at least when nested inside of
+// `distribute`) sometime after createParallel() completed, so it can't
+// be stored in the OutlineInfo structure here.
Meinersbur wrote:
Could a temporary block be created that is then connected to the CFG later?
https://github.com/llvm/llvm-project/pull/150925
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [mlir] [OpenMP][OMPIRBuilder] Use device shared memory for arg structures (PR #150925)
@@ -133,6 +137,25 @@ class CodeExtractorAnalysisCache {
// space.
bool ArgsInZeroAddressSpace;
+// If set, this callback will be used to allocate the arguments in the
+// caller before passing it to the outlined function holding the extracted
+// piece of code.
Meinersbur wrote:
```suggestion
/// If set, this callback will be used to allocate the arguments in the
/// caller before passing it to the outlined function holding the extracted
/// piece of code.
```
These can be doxygen comments
https://github.com/llvm/llvm-project/pull/150925
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [mlir] [OpenMP][OMPIRBuilder] Use device shared memory for arg structures (PR #150925)
https://github.com/Meinersbur edited https://github.com/llvm/llvm-project/pull/150925 ___ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [llvm] [OpenMP][clang] 6.0: num_threads strict (part 3: codegen) (PR #146405)
@@ -1874,6 +1874,10 @@ class OMPMessageClause final : public OMPClause {
// Expression of the 'message' clause.
Stmt *MessageString = nullptr;
+ // The message as a StringLiteral in case it is as string literal. This might
+ // be needed during compile time.
+ StringLiteral *MessageStringLiteral = nullptr;
+
ro-i wrote:
We need a string literal when we want to print the error during compilation.
Then we need the `StringLiteral::getString()` method, see my changes for
`SemaOpenMP::ActOnOpenMPErrorDirective()`.
https://github.com/llvm/llvm-project/pull/146405
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Introduce CallGraphSection option (PR #117037)
https://github.com/Prabhuk updated https://github.com/llvm/llvm-project/pull/117037 >From 6a12be2c5b60a95a06875b0b2c4f14228d1fa882 Mon Sep 17 00:00:00 2001 From: prabhukr Date: Wed, 12 Mar 2025 23:30:01 + Subject: [PATCH 1/2] Fix EOF newlines. Created using spr 1.3.6-beta.1 --- clang/test/Driver/call-graph-section.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/test/Driver/call-graph-section.c b/clang/test/Driver/call-graph-section.c index 108446729d857..5832aa6754137 100644 --- a/clang/test/Driver/call-graph-section.c +++ b/clang/test/Driver/call-graph-section.c @@ -2,4 +2,4 @@ // RUN: %clang -### -S -fcall-graph-section -fno-call-graph-section %s 2>&1 | FileCheck --check-prefix=NO-CALL-GRAPH-SECTION %s // CALL-GRAPH-SECTION: "-fcall-graph-section" -// NO-CALL-GRAPH-SECTION-NOT: "-fcall-graph-section" \ No newline at end of file +// NO-CALL-GRAPH-SECTION-NOT: "-fcall-graph-section" >From c67f714eaab9a7f1e4d2d76da28641b05710231d Mon Sep 17 00:00:00 2001 From: prabhukr Date: Mon, 21 Jul 2025 23:53:52 + Subject: [PATCH 2/2] Fix review comment on test file. Created using spr 1.3.6-beta.1 --- clang/test/Driver/call-graph-section.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/clang/test/Driver/call-graph-section.c b/clang/test/Driver/call-graph-section.c index 5832aa6754137..563f36de4119e 100644 --- a/clang/test/Driver/call-graph-section.c +++ b/clang/test/Driver/call-graph-section.c @@ -1,5 +1,5 @@ -// RUN: %clang -### -S -fcall-graph-section %s 2>&1 | FileCheck --check-prefix=CALL-GRAPH-SECTION %s -// RUN: %clang -### -S -fcall-graph-section -fno-call-graph-section %s 2>&1 | FileCheck --check-prefix=NO-CALL-GRAPH-SECTION %s +// RUN: %clang -### -fcall-graph-section %s 2>&1 | FileCheck --check-prefix=CALL-GRAPH-SECTION %s +// RUN: %clang -### -fcall-graph-section -fno-call-graph-section %s 2>&1 | FileCheck --check-prefix=NO-CALL-GRAPH-SECTION %s // CALL-GRAPH-SECTION: "-fcall-graph-section" // NO-CALL-GRAPH-SECTION-NOT: "-fcall-graph-section" ___ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [lldb] release/21.x: [lldb][AArch64][Linux] Show MTE store only setting in mte_ctrl (#145033) (PR #151111)
DavidSpickett wrote: Release note is https://github.com/llvm/llvm-project/pull/151548. https://github.com/llvm/llvm-project/pull/15 ___ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [llvm][docs] Add release note for LLDB MTE changes (PR #151548)
https://github.com/DavidSpickett created https://github.com/llvm/llvm-project/pull/151548 Goes with https://github.com/llvm/llvm-project/pull/15. >From 7cc104eb0363522f2be1d5be0697498c697c61b0 Mon Sep 17 00:00:00 2001 From: David Spickett Date: Thu, 31 Jul 2025 16:56:39 +0100 Subject: [PATCH] [llvm][docs] Add release note for LLDB MTE changes Goes with https://github.com/llvm/llvm-project/pull/15. --- llvm/docs/ReleaseNotes.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/llvm/docs/ReleaseNotes.md b/llvm/docs/ReleaseNotes.md index de6b1181158d2..a126d7ae1ab4a 100644 --- a/llvm/docs/ReleaseNotes.md +++ b/llvm/docs/ReleaseNotes.md @@ -326,6 +326,9 @@ Changes to LLDB RISC-V code with `disassemble`'s `--byte` option. * LLDB added native support for the Model Context Protocol (MCP). An MCP server can be started with the `protocol-server start MCP` command. +* On AArch64 Linux, LLDB will now show the state of the `STORE_ONLY` field of + `mte_ctrl`. This will only be shown on hardware that has the + `FEAT_MTE_STORE_ONLY` architecture feature. ### Changes to lldb-dap ___ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [llvm][docs] Add release note for LLDB MTE changes (PR #151548)
https://github.com/DavidSpickett milestoned https://github.com/llvm/llvm-project/pull/151548 ___ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [llvm] [AMDGPU] v_cvt_sr_pk_f16_f32 gfx1250 instruction (PR #151482)
https://github.com/shiltian approved this pull request. https://github.com/llvm/llvm-project/pull/151482 ___ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [llvm] [OpenMP][clang] 6.0: num_threads strict (part 3: codegen) (PR #146405)
@@ -1874,6 +1874,10 @@ class OMPMessageClause final : public OMPClause {
// Expression of the 'message' clause.
Stmt *MessageString = nullptr;
+ // The message as a StringLiteral in case it is as string literal. This might
+ // be needed during compile time.
+ StringLiteral *MessageStringLiteral = nullptr;
+
alexey-bataev wrote:
Why do you need this? MessageString should be enough. Just generate a cast to
`const char *` for StringLiteral
https://github.com/llvm/llvm-project/pull/146405
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [AMDGPU] Handle direct loads to LDS in memory model (PR #142018)
https://github.com/kerbowa closed https://github.com/llvm/llvm-project/pull/142018 ___ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [llvm] [OpenMP][clang] 6.0: num_threads strict (part 3: codegen) (PR #146405)
@@ -1874,6 +1874,10 @@ class OMPMessageClause final : public OMPClause {
// Expression of the 'message' clause.
Stmt *MessageString = nullptr;
+ // The message as a StringLiteral in case it is as string literal. This might
+ // be needed during compile time.
+ StringLiteral *MessageStringLiteral = nullptr;
+
ro-i wrote:
Oh, I see, thanks for the hint!
done
https://github.com/llvm/llvm-project/pull/146405
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [mlir] [mlir][linalg] Enable scalable vectorization of linalg.unpack (PR #149293)
https://github.com/banach-space edited https://github.com/llvm/llvm-project/pull/149293 ___ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [llvm] [OpenMP][clang] 6.0: num_threads strict (part 3: codegen) (PR #146405)
@@ -2718,11 +2718,14 @@ void CGOpenMPRuntime::emitNumThreadsClause(
// as if sev-level is fatal."
Args.push_back(llvm::ConstantInt::get(
CGM.Int32Ty, Severity == OMPC_SEVERITY_warning ? 1 : 2));
-if (Message)
- Args.push_back(CGF.EmitStringLiteralLValue(cast(Message))
- .getPointer(CGF));
-else
+if (Message) {
+ if (const StringLiteral *Msg = dyn_cast(Message))
+Args.push_back(CGF.EmitStringLiteralLValue(Msg).getPointer(CGF));
+ else
ro-i wrote:
done. This took me some time due to this bug:
https://github.com/llvm/llvm-project/blob/2c00df3c938a99a85f5b0abebbb541d2e003af2c/clang/lib/Sema/TreeTransform.h#L10940-L10949
(`C->getMessageString()` instead of `E.get()`)
I also adapted the error codegen and the corresponding test so that the whole
thing gets enough testing. Otherwise, I think things might get confusing.
https://github.com/llvm/llvm-project/pull/146405
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [mlir] [mlir][linalg] Enable scalable vectorization of linalg.unpack (PR #149293)
banach-space wrote: **UPDATE: 31/7/25** * Implemented https://github.com/llvm/llvm-project/pull/151503 (effectively NFC) and rebased this PR on top of it to help keep the noise level contained. * The latest [commit](https://github.com/llvm/llvm-project/pull/149293/commits/97fbccdc118f1f3da28b91be129ada6fe4f9b0ea) updates `vectorizeAsTensorUnpackOp` to only require "read-vector-sizes". I’m quite happy with the current state - `vectorizeAsTensorUnpackOp` is much simpler now. Many thanks for the discussion, @hanhanW 🙏🏻 Also, kudos to @egebeysel - your [comment](https://github.com/llvm/llvm-project/pull/149293#discussion_r2237499014) prompted me to rethink the approach. That's the kind of review feedback every contributor hopes for! https://github.com/llvm/llvm-project/pull/149293 ___ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [flang] [mlir] [MLIR][OpenMP] Add lowering support for AUTOMAP modifier (PR #151513)
https://github.com/TIFitis created
https://github.com/llvm/llvm-project/pull/151513
Add Automap modifier to the MLIR op definition for the DeclareTarget
directive's Enter clause. Also add lowering support in Flang.
Automap Ref: OpenMP 6.0 section 7.9.7.
>From 6dd4d9d7aa2c6b15761b9a135b6571c08947ad40 Mon Sep 17 00:00:00 2001
From: Akash Banerjee
Date: Thu, 31 Jul 2025 13:41:59 +0100
Subject: [PATCH] [MLIR][OpenMP] Add lowering support for AUTOMAP modifier
Add Automap modifier to the MLIR op definition for the DeclareTarget
directive's Enter clause.
Also add lowering support in Flang.
Automap Ref: OpenMP 6.0 section 7.9.7.
---
flang/include/flang/Lower/OpenMP.h| 1 +
flang/lib/Lower/OpenMP/ClauseProcessor.cpp| 13 +---
flang/lib/Lower/OpenMP/OpenMP.cpp | 33 +--
flang/lib/Lower/OpenMP/Utils.cpp | 5 +--
flang/lib/Lower/OpenMP/Utils.h| 14 ++--
.../Optimizer/OpenMP/FunctionFiltering.cpp| 5 +--
.../Optimizer/OpenMP/MarkDeclareTarget.cpp| 21 +++-
.../Lower/OpenMP/declare-target-automap.f90 | 8 +
.../mlir/Dialect/OpenMP/OpenMPAttrDefs.td | 8 ++---
.../Dialect/OpenMP/OpenMPOpsInterfaces.td | 19 +--
10 files changed, 83 insertions(+), 44 deletions(-)
create mode 100644 flang/test/Lower/OpenMP/declare-target-automap.f90
diff --git a/flang/include/flang/Lower/OpenMP.h
b/flang/include/flang/Lower/OpenMP.h
index 6e150ef4e8e82..581c93f76d627 100644
--- a/flang/include/flang/Lower/OpenMP.h
+++ b/flang/include/flang/Lower/OpenMP.h
@@ -57,6 +57,7 @@ struct Variable;
struct OMPDeferredDeclareTargetInfo {
mlir::omp::DeclareTargetCaptureClause declareTargetCaptureClause;
mlir::omp::DeclareTargetDeviceType declareTargetDeviceType;
+ bool automap = false;
const Fortran::semantics::Symbol &sym;
};
diff --git a/flang/lib/Lower/OpenMP/ClauseProcessor.cpp
b/flang/lib/Lower/OpenMP/ClauseProcessor.cpp
index 8eabf4f499604..ab33e089cc9e8 100644
--- a/flang/lib/Lower/OpenMP/ClauseProcessor.cpp
+++ b/flang/lib/Lower/OpenMP/ClauseProcessor.cpp
@@ -1184,7 +1184,8 @@ bool ClauseProcessor::processLink(
[&](const omp::clause::Link &clause, const parser::CharBlock &) {
// Case: declare target link(var1, var2)...
gatherFuncAndVarSyms(
-clause.v, mlir::omp::DeclareTargetCaptureClause::link, result);
+clause.v, mlir::omp::DeclareTargetCaptureClause::link, result,
+/*automap=*/false);
});
}
@@ -1512,7 +1513,8 @@ bool ClauseProcessor::processTo(
[&](const omp::clause::To &clause, const parser::CharBlock &) {
// Case: declare target to(func, var1, var2)...
gatherFuncAndVarSyms(std::get(clause.t),
- mlir::omp::DeclareTargetCaptureClause::to,
result);
+ mlir::omp::DeclareTargetCaptureClause::to, result,
+ /*automap=*/false);
});
}
@@ -1521,12 +1523,13 @@ bool ClauseProcessor::processEnter(
return findRepeatableClause(
[&](const omp::clause::Enter &clause, const parser::CharBlock &source) {
mlir::Location currentLocation = converter.genLocation(source);
-if (std::get>(clause.t))
- TODO(currentLocation, "Declare target enter AUTOMAP modifier");
+bool automap =
+std::get>(clause.t)
+.has_value();
// Case: declare target enter(func, var1, var2)...
gatherFuncAndVarSyms(std::get(clause.t),
mlir::omp::DeclareTargetCaptureClause::enter,
- result);
+ result, automap);
});
}
diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp
b/flang/lib/Lower/OpenMP/OpenMP.cpp
index 12089d6caa5fe..de44bfa87562b 100644
--- a/flang/lib/Lower/OpenMP/OpenMP.cpp
+++ b/flang/lib/Lower/OpenMP/OpenMP.cpp
@@ -773,7 +773,7 @@ static void getDeclareTargetInfo(
ObjectList objects{makeObjects(*objectList, semaCtx)};
// Case: declare target(func, var1, var2)
gatherFuncAndVarSyms(objects, mlir::omp::DeclareTargetCaptureClause::to,
- symbolAndClause);
+ symbolAndClause, /*automap=*/false);
} else if (const auto *clauseList{
parser::Unwrap(spec.u)}) {
List clauses = makeClauses(*clauseList, semaCtx);
@@ -814,13 +814,12 @@ static void collectDeferredDeclareTargets(
mlir::ModuleOp mod = converter.getFirOpBuilder().getModule();
for (const DeclareTargetCapturePair &symClause : symbolAndClause) {
-mlir::Operation *op = mod.lookupSymbol(
-converter.mangleName(std::get(symClause)));
+mlir::Operation *op =
+mod.lookupSymbol(converter.mangleName(symClause.symbol));
if (!op) {
- deferredDeclareTarget.push_back({std::get<0>(symClause),
- clauseOps.deviceType,
- std::get<1>(symC
[llvm-branch-commits] [flang] [mlir] [MLIR][OpenMP] Add lowering support for AUTOMAP modifier (PR #151513)
llvmbot wrote:
@llvm/pr-subscribers-mlir
Author: Akash Banerjee (TIFitis)
Changes
Add Automap modifier to the MLIR op definition for the DeclareTarget
directive's Enter clause. Also add lowering support in Flang.
Automap Ref: OpenMP 6.0 section 7.9.7.
---
Full diff: https://github.com/llvm/llvm-project/pull/151513.diff
10 Files Affected:
- (modified) flang/include/flang/Lower/OpenMP.h (+1)
- (modified) flang/lib/Lower/OpenMP/ClauseProcessor.cpp (+8-5)
- (modified) flang/lib/Lower/OpenMP/OpenMP.cpp (+15-18)
- (modified) flang/lib/Lower/OpenMP/Utils.cpp (+3-2)
- (modified) flang/lib/Lower/OpenMP/Utils.h (+11-3)
- (modified) flang/lib/Optimizer/OpenMP/FunctionFiltering.cpp (+3-2)
- (modified) flang/lib/Optimizer/OpenMP/MarkDeclareTarget.cpp (+13-8)
- (added) flang/test/Lower/OpenMP/declare-target-automap.f90 (+8)
- (modified) mlir/include/mlir/Dialect/OpenMP/OpenMPAttrDefs.td (+4-4)
- (modified) mlir/include/mlir/Dialect/OpenMP/OpenMPOpsInterfaces.td (+17-2)
``diff
diff --git a/flang/include/flang/Lower/OpenMP.h
b/flang/include/flang/Lower/OpenMP.h
index 6e150ef4e8e82..581c93f76d627 100644
--- a/flang/include/flang/Lower/OpenMP.h
+++ b/flang/include/flang/Lower/OpenMP.h
@@ -57,6 +57,7 @@ struct Variable;
struct OMPDeferredDeclareTargetInfo {
mlir::omp::DeclareTargetCaptureClause declareTargetCaptureClause;
mlir::omp::DeclareTargetDeviceType declareTargetDeviceType;
+ bool automap = false;
const Fortran::semantics::Symbol &sym;
};
diff --git a/flang/lib/Lower/OpenMP/ClauseProcessor.cpp
b/flang/lib/Lower/OpenMP/ClauseProcessor.cpp
index 8eabf4f499604..ab33e089cc9e8 100644
--- a/flang/lib/Lower/OpenMP/ClauseProcessor.cpp
+++ b/flang/lib/Lower/OpenMP/ClauseProcessor.cpp
@@ -1184,7 +1184,8 @@ bool ClauseProcessor::processLink(
[&](const omp::clause::Link &clause, const parser::CharBlock &) {
// Case: declare target link(var1, var2)...
gatherFuncAndVarSyms(
-clause.v, mlir::omp::DeclareTargetCaptureClause::link, result);
+clause.v, mlir::omp::DeclareTargetCaptureClause::link, result,
+/*automap=*/false);
});
}
@@ -1512,7 +1513,8 @@ bool ClauseProcessor::processTo(
[&](const omp::clause::To &clause, const parser::CharBlock &) {
// Case: declare target to(func, var1, var2)...
gatherFuncAndVarSyms(std::get(clause.t),
- mlir::omp::DeclareTargetCaptureClause::to,
result);
+ mlir::omp::DeclareTargetCaptureClause::to, result,
+ /*automap=*/false);
});
}
@@ -1521,12 +1523,13 @@ bool ClauseProcessor::processEnter(
return findRepeatableClause(
[&](const omp::clause::Enter &clause, const parser::CharBlock &source) {
mlir::Location currentLocation = converter.genLocation(source);
-if (std::get>(clause.t))
- TODO(currentLocation, "Declare target enter AUTOMAP modifier");
+bool automap =
+std::get>(clause.t)
+.has_value();
// Case: declare target enter(func, var1, var2)...
gatherFuncAndVarSyms(std::get(clause.t),
mlir::omp::DeclareTargetCaptureClause::enter,
- result);
+ result, automap);
});
}
diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp
b/flang/lib/Lower/OpenMP/OpenMP.cpp
index 12089d6caa5fe..de44bfa87562b 100644
--- a/flang/lib/Lower/OpenMP/OpenMP.cpp
+++ b/flang/lib/Lower/OpenMP/OpenMP.cpp
@@ -773,7 +773,7 @@ static void getDeclareTargetInfo(
ObjectList objects{makeObjects(*objectList, semaCtx)};
// Case: declare target(func, var1, var2)
gatherFuncAndVarSyms(objects, mlir::omp::DeclareTargetCaptureClause::to,
- symbolAndClause);
+ symbolAndClause, /*automap=*/false);
} else if (const auto *clauseList{
parser::Unwrap(spec.u)}) {
List clauses = makeClauses(*clauseList, semaCtx);
@@ -814,13 +814,12 @@ static void collectDeferredDeclareTargets(
mlir::ModuleOp mod = converter.getFirOpBuilder().getModule();
for (const DeclareTargetCapturePair &symClause : symbolAndClause) {
-mlir::Operation *op = mod.lookupSymbol(
-converter.mangleName(std::get(symClause)));
+mlir::Operation *op =
+mod.lookupSymbol(converter.mangleName(symClause.symbol));
if (!op) {
- deferredDeclareTarget.push_back({std::get<0>(symClause),
- clauseOps.deviceType,
- std::get<1>(symClause)});
+ deferredDeclareTarget.push_back({symClause.clause, clauseOps.deviceType,
+ symClause.automap, symClause.symbol});
}
}
}
@@ -839,8 +838,8 @@ getDeclareTargetFunctionDevice(
// directive is a function or subroutine
mlir::ModuleOp mod = converter.getFirOpBuilder().getModule();
for (const De
[llvm-branch-commits] [flang] [mlir] [MLIR][OpenMP] Add lowering support for AUTOMAP modifier (PR #151513)
llvmbot wrote:
@llvm/pr-subscribers-mlir-openmp
Author: Akash Banerjee (TIFitis)
Changes
Add Automap modifier to the MLIR op definition for the DeclareTarget
directive's Enter clause. Also add lowering support in Flang.
Automap Ref: OpenMP 6.0 section 7.9.7.
---
Full diff: https://github.com/llvm/llvm-project/pull/151513.diff
10 Files Affected:
- (modified) flang/include/flang/Lower/OpenMP.h (+1)
- (modified) flang/lib/Lower/OpenMP/ClauseProcessor.cpp (+8-5)
- (modified) flang/lib/Lower/OpenMP/OpenMP.cpp (+15-18)
- (modified) flang/lib/Lower/OpenMP/Utils.cpp (+3-2)
- (modified) flang/lib/Lower/OpenMP/Utils.h (+11-3)
- (modified) flang/lib/Optimizer/OpenMP/FunctionFiltering.cpp (+3-2)
- (modified) flang/lib/Optimizer/OpenMP/MarkDeclareTarget.cpp (+13-8)
- (added) flang/test/Lower/OpenMP/declare-target-automap.f90 (+8)
- (modified) mlir/include/mlir/Dialect/OpenMP/OpenMPAttrDefs.td (+4-4)
- (modified) mlir/include/mlir/Dialect/OpenMP/OpenMPOpsInterfaces.td (+17-2)
``diff
diff --git a/flang/include/flang/Lower/OpenMP.h
b/flang/include/flang/Lower/OpenMP.h
index 6e150ef4e8e82..581c93f76d627 100644
--- a/flang/include/flang/Lower/OpenMP.h
+++ b/flang/include/flang/Lower/OpenMP.h
@@ -57,6 +57,7 @@ struct Variable;
struct OMPDeferredDeclareTargetInfo {
mlir::omp::DeclareTargetCaptureClause declareTargetCaptureClause;
mlir::omp::DeclareTargetDeviceType declareTargetDeviceType;
+ bool automap = false;
const Fortran::semantics::Symbol &sym;
};
diff --git a/flang/lib/Lower/OpenMP/ClauseProcessor.cpp
b/flang/lib/Lower/OpenMP/ClauseProcessor.cpp
index 8eabf4f499604..ab33e089cc9e8 100644
--- a/flang/lib/Lower/OpenMP/ClauseProcessor.cpp
+++ b/flang/lib/Lower/OpenMP/ClauseProcessor.cpp
@@ -1184,7 +1184,8 @@ bool ClauseProcessor::processLink(
[&](const omp::clause::Link &clause, const parser::CharBlock &) {
// Case: declare target link(var1, var2)...
gatherFuncAndVarSyms(
-clause.v, mlir::omp::DeclareTargetCaptureClause::link, result);
+clause.v, mlir::omp::DeclareTargetCaptureClause::link, result,
+/*automap=*/false);
});
}
@@ -1512,7 +1513,8 @@ bool ClauseProcessor::processTo(
[&](const omp::clause::To &clause, const parser::CharBlock &) {
// Case: declare target to(func, var1, var2)...
gatherFuncAndVarSyms(std::get(clause.t),
- mlir::omp::DeclareTargetCaptureClause::to,
result);
+ mlir::omp::DeclareTargetCaptureClause::to, result,
+ /*automap=*/false);
});
}
@@ -1521,12 +1523,13 @@ bool ClauseProcessor::processEnter(
return findRepeatableClause(
[&](const omp::clause::Enter &clause, const parser::CharBlock &source) {
mlir::Location currentLocation = converter.genLocation(source);
-if (std::get>(clause.t))
- TODO(currentLocation, "Declare target enter AUTOMAP modifier");
+bool automap =
+std::get>(clause.t)
+.has_value();
// Case: declare target enter(func, var1, var2)...
gatherFuncAndVarSyms(std::get(clause.t),
mlir::omp::DeclareTargetCaptureClause::enter,
- result);
+ result, automap);
});
}
diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp
b/flang/lib/Lower/OpenMP/OpenMP.cpp
index 12089d6caa5fe..de44bfa87562b 100644
--- a/flang/lib/Lower/OpenMP/OpenMP.cpp
+++ b/flang/lib/Lower/OpenMP/OpenMP.cpp
@@ -773,7 +773,7 @@ static void getDeclareTargetInfo(
ObjectList objects{makeObjects(*objectList, semaCtx)};
// Case: declare target(func, var1, var2)
gatherFuncAndVarSyms(objects, mlir::omp::DeclareTargetCaptureClause::to,
- symbolAndClause);
+ symbolAndClause, /*automap=*/false);
} else if (const auto *clauseList{
parser::Unwrap(spec.u)}) {
List clauses = makeClauses(*clauseList, semaCtx);
@@ -814,13 +814,12 @@ static void collectDeferredDeclareTargets(
mlir::ModuleOp mod = converter.getFirOpBuilder().getModule();
for (const DeclareTargetCapturePair &symClause : symbolAndClause) {
-mlir::Operation *op = mod.lookupSymbol(
-converter.mangleName(std::get(symClause)));
+mlir::Operation *op =
+mod.lookupSymbol(converter.mangleName(symClause.symbol));
if (!op) {
- deferredDeclareTarget.push_back({std::get<0>(symClause),
- clauseOps.deviceType,
- std::get<1>(symClause)});
+ deferredDeclareTarget.push_back({symClause.clause, clauseOps.deviceType,
+ symClause.automap, symClause.symbol});
}
}
}
@@ -839,8 +838,8 @@ getDeclareTargetFunctionDevice(
// directive is a function or subroutine
mlir::ModuleOp mod = converter.getFirOpBuilder().getModule();
for (c
[llvm-branch-commits] [mlir] [mlir][linalg] Enable scalable vectorization of linalg.unpack (PR #149293)
egebeysel wrote: > Also, kudos to @egebeysel - your > [comment](https://github.com/llvm/llvm-project/pull/149293#discussion_r2237499014) > prompted me to rethink the approach. That's the kind of review feedback > every contributor hopes for! I'm glad to have helped and thanks for the updates! 😄 I'm back from a break, I'll try and take another look at this tomorrow, if not today. https://github.com/llvm/llvm-project/pull/149293 ___ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [llvm] [OpenMP][clang] 6.0: num_threads strict (part 3: codegen) (PR #146405)
@@ -1874,6 +1874,10 @@ class OMPMessageClause final : public OMPClause {
// Expression of the 'message' clause.
Stmt *MessageString = nullptr;
+ // The message as a StringLiteral in case it is as string literal. This might
+ // be needed during compile time.
+ StringLiteral *MessageStringLiteral = nullptr;
+
alexey-bataev wrote:
You do not need string literal for this, you need a string, evaluatable at
compile time using something like `Expr->tryEvaluateString()`
https://github.com/llvm/llvm-project/pull/146405
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [LoopPeel] Fix branch weights' effect on block frequencies (PR #128785)
https://github.com/jdenny-ornl reopened https://github.com/llvm/llvm-project/pull/128785 ___ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [BOLT] Gadget scanner: make use of C++17 features and LLVM helpers (PR #141665)
https://github.com/atrosinenko updated
https://github.com/llvm/llvm-project/pull/141665
>From 3491782bc06da3bd1d40b2471c6b8c585ea871e6 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 af911ba829ca5..01ffb2ddb0c78 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] Introduce helpers to match `MCInst`s one at a time (NFC) (PR #138883)
https://github.com/atrosinenko updated
https://github.com/llvm/llvm-project/pull/138883
>From d9aaf1b4d5e44c7248b2a1cbc0b516e908733d31 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] Factor out MCInstReference from gadget scanner (NFC) (PR #138655)
https://github.com/atrosinenko updated
https://github.com/llvm/llvm-project/pull/138655
>From e400b2291786002dae1dddbd96c456a5e9dd5087 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: prevent false positives due to jump tables (PR #138884)
https://github.com/atrosinenko updated
https://github.com/llvm/llvm-project/pull/138884
>From d888f459d05eb0b6d0943eee5a956134c91ba01c Mon Sep 17 00:00:00 2001
From: Anatoly Trosinenko
Date: Tue, 6 May 2025 11:31:03 +0300
Subject: [PATCH 1/2] [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 d79174f13f502..beceb125161b8 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"
@@ -711,6 +712,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 d33244d47dcbc..0fb4b161abdbb 100644
--- a/bolt/lib/Passes/PAuthGadgetScanner.cpp
+++ b/bolt/lib/Passes/PAuthGadgetScanner.cpp
@@ -1370,6 +1370,11 @@ shouldReportUnsafeTailCall(const BinaryContext &BC,
const BinaryFunction &BF,
return std::nullopt;
}
+ if (BC.MIB->isSafeJumpTableBranchForPtrAuth(Inst)) {
+
[llvm-branch-commits] [llvm] [BOLT] Gadget scanner: make use of C++17 features and LLVM helpers (PR #141665)
https://github.com/atrosinenko updated
https://github.com/llvm/llvm-project/pull/141665
>From 3491782bc06da3bd1d40b2471c6b8c585ea871e6 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 af911ba829ca5..01ffb2ddb0c78 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)
https://github.com/atrosinenko updated
https://github.com/llvm/llvm-project/pull/139778
>From 47a8b85c8355ee8f63876d5948b35c6e2a169ae0 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 0fb4b161abdbb..af911ba829ca5 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] Factor out MCInstReference from gadget scanner (NFC) (PR #138655)
https://github.com/atrosinenko updated
https://github.com/llvm/llvm-project/pull/138655
>From e400b2291786002dae1dddbd96c456a5e9dd5087 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: optionally assume auth traps on failure (PR #139778)
https://github.com/atrosinenko updated
https://github.com/llvm/llvm-project/pull/139778
>From 47a8b85c8355ee8f63876d5948b35c6e2a169ae0 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 0fb4b161abdbb..af911ba829ca5 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)
https://github.com/atrosinenko updated
https://github.com/llvm/llvm-project/pull/138884
>From d888f459d05eb0b6d0943eee5a956134c91ba01c Mon Sep 17 00:00:00 2001
From: Anatoly Trosinenko
Date: Tue, 6 May 2025 11:31:03 +0300
Subject: [PATCH 1/2] [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 d79174f13f502..beceb125161b8 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"
@@ -711,6 +712,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 d33244d47dcbc..0fb4b161abdbb 100644
--- a/bolt/lib/Passes/PAuthGadgetScanner.cpp
+++ b/bolt/lib/Passes/PAuthGadgetScanner.cpp
@@ -1370,6 +1370,11 @@ shouldReportUnsafeTailCall(const BinaryContext &BC,
const BinaryFunction &BF,
return std::nullopt;
}
+ if (BC.MIB->isSafeJumpTableBranchForPtrAuth(Inst)) {
+
[llvm-branch-commits] [llvm] [BOLT] Introduce helpers to match `MCInst`s one at a time (NFC) (PR #138883)
https://github.com/atrosinenko updated
https://github.com/llvm/llvm-project/pull/138883
>From d9aaf1b4d5e44c7248b2a1cbc0b516e908733d31 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] Ignore FileCheck when profcheck is enabled (PR #151214)
mtrofin wrote: ### Merge activity * **Aug 1, 5:19 AM UTC**: A user started a stack merge that includes this pull request via [Graphite](https://app.graphite.dev/github/pr/llvm/llvm-project/151214). https://github.com/llvm/llvm-project/pull/151214 ___ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [lld] ELF: Introduce R_AARCH64_FUNCINIT64 relocation type. (PR #133531)
https://github.com/pcc updated https://github.com/llvm/llvm-project/pull/133531
>From 96e7da9a083888683c2ba00d97f886fd748ea10b Mon Sep 17 00:00:00 2001
From: Peter Collingbourne
Date: Wed, 9 Apr 2025 20:30:57 -0700
Subject: [PATCH] Undo unnecessary change
Created using spr 1.3.6-beta.1
---
lld/ELF/SyntheticSections.cpp | 2 +-
lld/ELF/SyntheticSections.h | 2 +-
lld/ELF/Writer.cpp| 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp
index 8cab71c4c8d94..106749e90a82b 100644
--- a/lld/ELF/SyntheticSections.cpp
+++ b/lld/ELF/SyntheticSections.cpp
@@ -1696,7 +1696,7 @@ void
RelocationBaseSection::addAddendOnlyRelocIfNonPreemptible(
sym, 0, R_ABS, addendRelType);
}
-void RelocationBaseSection::mergeRels(Ctx &ctx) {
+void RelocationBaseSection::mergeRels() {
size_t newSize = relocs.size();
for (const auto &v : relocsVec)
newSize += v.size();
diff --git a/lld/ELF/SyntheticSections.h b/lld/ELF/SyntheticSections.h
index 7a85906e8601d..2dd4b80eb85bf 100644
--- a/lld/ELF/SyntheticSections.h
+++ b/lld/ELF/SyntheticSections.h
@@ -553,7 +553,7 @@ class RelocationBaseSection : public SyntheticSection {
}
size_t getSize() const override { return relocs.size() * this->entsize; }
size_t getRelativeRelocCount() const { return numRelativeRelocs; }
- void mergeRels(Ctx &ctx);
+ void mergeRels();
void partitionRels();
void finalizeContents() override;
diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp
index 67004055f1af5..28b24f90716b8 100644
--- a/lld/ELF/Writer.cpp
+++ b/lld/ELF/Writer.cpp
@@ -2076,7 +2076,7 @@ template void
Writer::finalizeSections() {
// symbol table section (dynSymTab) must be the first one.
for (Partition &part : ctx.partitions) {
if (part.relaDyn) {
-part.relaDyn->mergeRels(ctx);
+part.relaDyn->mergeRels();
// Compute DT_RELACOUNT to be used by part.dynamic.
part.relaDyn->partitionRels();
finalizeSynthetic(ctx, part.relaDyn.get());
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] ELF: Introduce R_AARCH64_PATCHINST relocation type. (PR #133534)
https://github.com/pcc updated https://github.com/llvm/llvm-project/pull/133534 ___ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] Add deactivation symbol operand to ConstantPtrAuth. (PR #133537)
https://github.com/pcc edited https://github.com/llvm/llvm-project/pull/133537 ___ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] Add deactivation symbol operand to ConstantPtrAuth. (PR #133537)
https://github.com/pcc updated https://github.com/llvm/llvm-project/pull/133537 ___ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] ELF: Introduce R_AARCH64_PATCHINST relocation type. (PR #133534)
https://github.com/pcc updated https://github.com/llvm/llvm-project/pull/133534 ___ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [lld] ELF: Introduce R_AARCH64_FUNCINIT64 relocation type. (PR #133531)
https://github.com/pcc updated https://github.com/llvm/llvm-project/pull/133531
>From 96e7da9a083888683c2ba00d97f886fd748ea10b Mon Sep 17 00:00:00 2001
From: Peter Collingbourne
Date: Wed, 9 Apr 2025 20:30:57 -0700
Subject: [PATCH] Undo unnecessary change
Created using spr 1.3.6-beta.1
---
lld/ELF/SyntheticSections.cpp | 2 +-
lld/ELF/SyntheticSections.h | 2 +-
lld/ELF/Writer.cpp| 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp
index 8cab71c4c8d94..106749e90a82b 100644
--- a/lld/ELF/SyntheticSections.cpp
+++ b/lld/ELF/SyntheticSections.cpp
@@ -1696,7 +1696,7 @@ void
RelocationBaseSection::addAddendOnlyRelocIfNonPreemptible(
sym, 0, R_ABS, addendRelType);
}
-void RelocationBaseSection::mergeRels(Ctx &ctx) {
+void RelocationBaseSection::mergeRels() {
size_t newSize = relocs.size();
for (const auto &v : relocsVec)
newSize += v.size();
diff --git a/lld/ELF/SyntheticSections.h b/lld/ELF/SyntheticSections.h
index 7a85906e8601d..2dd4b80eb85bf 100644
--- a/lld/ELF/SyntheticSections.h
+++ b/lld/ELF/SyntheticSections.h
@@ -553,7 +553,7 @@ class RelocationBaseSection : public SyntheticSection {
}
size_t getSize() const override { return relocs.size() * this->entsize; }
size_t getRelativeRelocCount() const { return numRelativeRelocs; }
- void mergeRels(Ctx &ctx);
+ void mergeRels();
void partitionRels();
void finalizeContents() override;
diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp
index 67004055f1af5..28b24f90716b8 100644
--- a/lld/ELF/Writer.cpp
+++ b/lld/ELF/Writer.cpp
@@ -2076,7 +2076,7 @@ template void
Writer::finalizeSections() {
// symbol table section (dynSymTab) must be the first one.
for (Partition &part : ctx.partitions) {
if (part.relaDyn) {
-part.relaDyn->mergeRels(ctx);
+part.relaDyn->mergeRels();
// Compute DT_RELACOUNT to be used by part.dynamic.
part.relaDyn->partitionRels();
finalizeSynthetic(ctx, part.relaDyn.get());
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] CodeGen: Optionally emit PAuth relocations as IRELATIVE relocations. (PR #133533)
https://github.com/pcc updated https://github.com/llvm/llvm-project/pull/133533 ___ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] CodeGen: Optionally emit PAuth relocations as IRELATIVE relocations. (PR #133533)
https://github.com/pcc updated https://github.com/llvm/llvm-project/pull/133533 ___ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] Add IR and codegen support for deactivation symbols. (PR #133536)
https://github.com/pcc updated https://github.com/llvm/llvm-project/pull/133536 ___ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] Add IR and codegen support for deactivation symbols. (PR #133536)
https://github.com/pcc updated https://github.com/llvm/llvm-project/pull/133536 ___ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] Ignore FileCheck when profcheck is enabled (PR #151214)
https://github.com/mtrofin updated https://github.com/llvm/llvm-project/pull/151214 >From e6467e2025cf473486313319115a839efdc35ea4 Mon Sep 17 00:00:00 2001 From: Mircea Trofin Date: Tue, 29 Jul 2025 12:55:59 -0700 Subject: [PATCH] fixes --- llvm/test/lit.cfg.py | 14 -- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/llvm/test/lit.cfg.py b/llvm/test/lit.cfg.py index 1d190fd20e573..43c7cf677a913 100644 --- a/llvm/test/lit.cfg.py +++ b/llvm/test/lit.cfg.py @@ -18,7 +18,17 @@ config.name = "LLVM" # testFormat: The test format to use to interpret tests. -config.test_format = lit.formats.ShTest(not llvm_config.use_lit_shell) +extra_substitutions = extra_substitutions = ( +[ +(r"\| not FileCheck .*", "| tee /dev/null"), +(r"\| FileCheck .*", "| tee /dev/null"), +] +if config.enable_profcheck +else [] +) +config.test_format = lit.formats.ShTest( +not llvm_config.use_lit_shell, extra_substitutions +) # suffixes: A list of file extensions to treat as test files. This is overriden # by individual lit.local.cfg files in the test subdirectories. @@ -278,6 +288,7 @@ def get_asan_rtlib(): ] ) + # Find (major, minor) version of ptxas def ptxas_version(ptxas): ptxas_cmd = subprocess.Popen([ptxas, "--version"], stdout=subprocess.PIPE) @@ -602,7 +613,6 @@ def host_unwind_supports_jit(): # compact-unwind only, and JIT'd registration is not available before # macOS 14.0. if platform.system() == "Darwin": - assert "arm64" in config.host_triple or "x86_64" in config.host_triple if "x86_64" in config.host_triple: ___ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] Ignore FileCheck when profcheck is enabled (PR #151214)
https://github.com/mtrofin updated https://github.com/llvm/llvm-project/pull/151214 >From 57a17d34eda45e885b1c6ca173fea93bbf4c236e Mon Sep 17 00:00:00 2001 From: Mircea Trofin Date: Tue, 29 Jul 2025 12:55:59 -0700 Subject: [PATCH] fixes --- llvm/test/lit.cfg.py | 14 -- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/llvm/test/lit.cfg.py b/llvm/test/lit.cfg.py index 1d190fd20e573..43c7cf677a913 100644 --- a/llvm/test/lit.cfg.py +++ b/llvm/test/lit.cfg.py @@ -18,7 +18,17 @@ config.name = "LLVM" # testFormat: The test format to use to interpret tests. -config.test_format = lit.formats.ShTest(not llvm_config.use_lit_shell) +extra_substitutions = extra_substitutions = ( +[ +(r"\| not FileCheck .*", "| tee /dev/null"), +(r"\| FileCheck .*", "| tee /dev/null"), +] +if config.enable_profcheck +else [] +) +config.test_format = lit.formats.ShTest( +not llvm_config.use_lit_shell, extra_substitutions +) # suffixes: A list of file extensions to treat as test files. This is overriden # by individual lit.local.cfg files in the test subdirectories. @@ -278,6 +288,7 @@ def get_asan_rtlib(): ] ) + # Find (major, minor) version of ptxas def ptxas_version(ptxas): ptxas_cmd = subprocess.Popen([ptxas, "--version"], stdout=subprocess.PIPE) @@ -602,7 +613,6 @@ def host_unwind_supports_jit(): # compact-unwind only, and JIT'd registration is not available before # macOS 14.0. if platform.system() == "Darwin": - assert "arm64" in config.host_triple or "x86_64" in config.host_triple if "x86_64" in config.host_triple: ___ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] Ignore FileCheck when profcheck is enabled (PR #151214)
https://github.com/mtrofin updated https://github.com/llvm/llvm-project/pull/151214 >From 57a17d34eda45e885b1c6ca173fea93bbf4c236e Mon Sep 17 00:00:00 2001 From: Mircea Trofin Date: Tue, 29 Jul 2025 12:55:59 -0700 Subject: [PATCH] fixes --- llvm/test/lit.cfg.py | 14 -- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/llvm/test/lit.cfg.py b/llvm/test/lit.cfg.py index 1d190fd20e573..43c7cf677a913 100644 --- a/llvm/test/lit.cfg.py +++ b/llvm/test/lit.cfg.py @@ -18,7 +18,17 @@ config.name = "LLVM" # testFormat: The test format to use to interpret tests. -config.test_format = lit.formats.ShTest(not llvm_config.use_lit_shell) +extra_substitutions = extra_substitutions = ( +[ +(r"\| not FileCheck .*", "| tee /dev/null"), +(r"\| FileCheck .*", "| tee /dev/null"), +] +if config.enable_profcheck +else [] +) +config.test_format = lit.formats.ShTest( +not llvm_config.use_lit_shell, extra_substitutions +) # suffixes: A list of file extensions to treat as test files. This is overriden # by individual lit.local.cfg files in the test subdirectories. @@ -278,6 +288,7 @@ def get_asan_rtlib(): ] ) + # Find (major, minor) version of ptxas def ptxas_version(ptxas): ptxas_cmd = subprocess.Popen([ptxas, "--version"], stdout=subprocess.PIPE) @@ -602,7 +613,6 @@ def host_unwind_supports_jit(): # compact-unwind only, and JIT'd registration is not available before # macOS 14.0. if platform.system() == "Darwin": - assert "arm64" in config.host_triple or "x86_64" in config.host_triple if "x86_64" in config.host_triple: ___ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [BOLT] Factor out MCInstReference from gadget scanner (NFC) (PR #138655)
https://github.com/atrosinenko edited https://github.com/llvm/llvm-project/pull/138655 ___ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [libunwind] release/21.x: [libunwind] Fix return type of `DwarfFDECache::findFDE()` in definition (#146308) (PR #150126)
https://github.com/tru updated https://github.com/llvm/llvm-project/pull/150126
>From 75a6a3c1f565a63837bdaf9cad01bf976f3c4842 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Alex=20R=C3=B8nne=20Petersen?=
Date: Wed, 23 Jul 2025 00:03:19 +0200
Subject: [PATCH] [libunwind] Fix return type of `DwarfFDECache::findFDE()` in
definition (#146308)
Needed to resolve this compilation error on some systems:
lib/libunwind/src/UnwindCursor.hpp:153:38: error: return type of
out-of-line definition of 'libunwind::DwarfFDECache::findFDE' differs
from that in the declaration
typename A::pint_t DwarfFDECache::findFDE(pint_t mh, pint_t pc) {
~^
lib/libunwind/src/libunwind.cpp:31:10: note: in file included from
lib/libunwind/src/libunwind.cpp:31:
#include "UnwindCursor.hpp"
^
lib/libunwind/src/UnwindCursor.hpp:100:17: note: previous declaration is
here
static pint_t findFDE(pint_t mh, pint_t pc);
~~~^
(cherry picked from commit eb0d8f9272f7c734cdaf31bc33a18e1619e021e4)
---
libunwind/src/UnwindCursor.hpp | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/libunwind/src/UnwindCursor.hpp b/libunwind/src/UnwindCursor.hpp
index 55db035e62040..9a1afd3721f5a 100644
--- a/libunwind/src/UnwindCursor.hpp
+++ b/libunwind/src/UnwindCursor.hpp
@@ -173,7 +173,8 @@ bool DwarfFDECache::_registeredForDyldUnloads = false;
#endif
template
-typename A::pint_t DwarfFDECache::findFDE(pint_t mh, pint_t pc) {
+typename DwarfFDECache::pint_t DwarfFDECache::findFDE(pint_t mh,
+pint_t pc) {
pint_t result = 0;
_LIBUNWIND_LOG_IF_FALSE(_lock.lock_shared());
for (entry *p = _buffer; p < _bufferUsed; ++p) {
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] release/21.x: [clang][Driver] Prefer non-Linux emulations for baremetal Arm/AArch64 targets (#149235) (PR #151052)
tru wrote: @petrhosek can you review? https://github.com/llvm/llvm-project/pull/151052 ___ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] release/21.x: [X86][AVX10.2] Fix VNNIINT16 maskz intrinsics arguments order (#151077) (PR #151092)
tru wrote: @RKSimon can you review? https://github.com/llvm/llvm-project/pull/151092 ___ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [lld] 7e51c08 - [LLD][COFF] Allow symbols with empty chunks to have no associated output section in the PDB writer (#149523)
Author: Jacek Caban
Date: 2025-08-01T08:54:34+02:00
New Revision: 7e51c08c82c50afc75cd3adb50ffa60aee832fb4
URL:
https://github.com/llvm/llvm-project/commit/7e51c08c82c50afc75cd3adb50ffa60aee832fb4
DIFF:
https://github.com/llvm/llvm-project/commit/7e51c08c82c50afc75cd3adb50ffa60aee832fb4.diff
LOG: [LLD][COFF] Allow symbols with empty chunks to have no associated output
section in the PDB writer (#149523)
If a chunk is empty and there are no other non-empty chunks in the same
section, `removeEmptySections()` will remove the entire section. In this
case, use a section index of 0, as the MSVC linker does, instead of
asserting.
(cherry picked from commit 1ab04fc94c5f68ad0dc6755e3914f2895b85e720)
Added:
lld/test/COFF/pdb-empty-sec.s
Modified:
lld/COFF/PDB.cpp
Removed:
diff --git a/lld/COFF/PDB.cpp b/lld/COFF/PDB.cpp
index a54ea403ba2ec..94eeae2797971 100644
--- a/lld/COFF/PDB.cpp
+++ b/lld/COFF/PDB.cpp
@@ -1135,9 +1135,12 @@ static pdb::BulkPublic createPublic(COFFLinkerContext
&ctx, Defined *def) {
pub.setFlags(flags);
OutputSection *os = ctx.getOutputSection(def->getChunk());
- assert(os && "all publics should be in final image");
- pub.Offset = def->getRVA() - os->getRVA();
- pub.Segment = os->sectionIndex;
+ assert((os || !def->getChunk()->getSize()) &&
+ "all publics should be in final image");
+ if (os) {
+pub.Offset = def->getRVA() - os->getRVA();
+pub.Segment = os->sectionIndex;
+ }
return pub;
}
diff --git a/lld/test/COFF/pdb-empty-sec.s b/lld/test/COFF/pdb-empty-sec.s
new file mode 100644
index 0..0d61447b76651
--- /dev/null
+++ b/lld/test/COFF/pdb-empty-sec.s
@@ -0,0 +1,19 @@
+// REQUIRES: x86
+
+// RUN: llvm-mc -filetype=obj -triple=x86_64-windows %s -o %t.obj
+// RUN: lld-link -dll -noentry -debug %t.obj -out:%t.dll
+// RUN: llvm-pdbutil dump -publics %t.pdb | FileCheck %s
+
+// CHECK: Records
+// CHECK-NEXT: 0 | S_PUB32 [size = 20] `func`
+// CHECK-NEXT: flags = none, addr = 0001:
+// CHECK-NEXT: 20 | S_PUB32 [size = 20] `sym`
+// CHECK-NEXT: flags = none, addr = :
+
+.globl sym
+.data
+sym:
+.text
+.globl func
+func:
+ret
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [lld] release/21.x: [LLD][COFF] Allow symbols with empty chunks to have no associated output section in the PDB writer (#149523) (PR #150969)
https://github.com/tru updated https://github.com/llvm/llvm-project/pull/150969
>From 7e51c08c82c50afc75cd3adb50ffa60aee832fb4 Mon Sep 17 00:00:00 2001
From: Jacek Caban
Date: Mon, 28 Jul 2025 08:01:26 -0700
Subject: [PATCH] [LLD][COFF] Allow symbols with empty chunks to have no
associated output section in the PDB writer (#149523)
If a chunk is empty and there are no other non-empty chunks in the same
section, `removeEmptySections()` will remove the entire section. In this
case, use a section index of 0, as the MSVC linker does, instead of
asserting.
(cherry picked from commit 1ab04fc94c5f68ad0dc6755e3914f2895b85e720)
---
lld/COFF/PDB.cpp | 9 ++---
lld/test/COFF/pdb-empty-sec.s | 19 +++
2 files changed, 25 insertions(+), 3 deletions(-)
create mode 100644 lld/test/COFF/pdb-empty-sec.s
diff --git a/lld/COFF/PDB.cpp b/lld/COFF/PDB.cpp
index a54ea403ba2ec..94eeae2797971 100644
--- a/lld/COFF/PDB.cpp
+++ b/lld/COFF/PDB.cpp
@@ -1135,9 +1135,12 @@ static pdb::BulkPublic createPublic(COFFLinkerContext
&ctx, Defined *def) {
pub.setFlags(flags);
OutputSection *os = ctx.getOutputSection(def->getChunk());
- assert(os && "all publics should be in final image");
- pub.Offset = def->getRVA() - os->getRVA();
- pub.Segment = os->sectionIndex;
+ assert((os || !def->getChunk()->getSize()) &&
+ "all publics should be in final image");
+ if (os) {
+pub.Offset = def->getRVA() - os->getRVA();
+pub.Segment = os->sectionIndex;
+ }
return pub;
}
diff --git a/lld/test/COFF/pdb-empty-sec.s b/lld/test/COFF/pdb-empty-sec.s
new file mode 100644
index 0..0d61447b76651
--- /dev/null
+++ b/lld/test/COFF/pdb-empty-sec.s
@@ -0,0 +1,19 @@
+// REQUIRES: x86
+
+// RUN: llvm-mc -filetype=obj -triple=x86_64-windows %s -o %t.obj
+// RUN: lld-link -dll -noentry -debug %t.obj -out:%t.dll
+// RUN: llvm-pdbutil dump -publics %t.pdb | FileCheck %s
+
+// CHECK: Records
+// CHECK-NEXT: 0 | S_PUB32 [size = 20] `func`
+// CHECK-NEXT: flags = none, addr = 0001:
+// CHECK-NEXT: 20 | S_PUB32 [size = 20] `sym`
+// CHECK-NEXT: flags = none, addr = :
+
+.globl sym
+.data
+sym:
+.text
+.globl func
+func:
+ret
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [lld] release/21.x: [LLD][COFF] Allow symbols with empty chunks to have no associated output section in the PDB writer (#149523) (PR #150969)
https://github.com/tru closed https://github.com/llvm/llvm-project/pull/150969 ___ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] release/21.x: [[gnu::nonstring]] should work on pointers too (#150974) (PR #150980)
https://github.com/tru updated https://github.com/llvm/llvm-project/pull/150980
>From 4ca9a4bb351a723f746738384ef785e104f19dbc Mon Sep 17 00:00:00 2001
From: Aaron Ballman
Date: Mon, 28 Jul 2025 11:53:33 -0400
Subject: [PATCH] [[gnu::nonstring]] should work on pointers too (#150974)
Clang's current implementation only works on array types, but GCC (which
is where we got this attribute) supports it on pointers as well as
arrays.
Fixes #150951
(cherry picked from commit 837b2d464ff16fe0d892dcf2827747c97dd5465e)
---
clang/include/clang/Basic/AttrDocs.td | 6 +++---
clang/lib/Sema/SemaDeclAttr.cpp | 6 +++---
clang/test/Sema/attr-nonstring.c | 8
3 files changed, 14 insertions(+), 6 deletions(-)
diff --git a/clang/include/clang/Basic/AttrDocs.td
b/clang/include/clang/Basic/AttrDocs.td
index fefdaba7f8bf5..76747d2b11811 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -9417,9 +9417,9 @@ def NonStringDocs : Documentation {
let Category = DocCatDecl;
let Content = [{
The ``nonstring`` attribute can be applied to the declaration of a variable or
-a field whose type is a character array to specify that the character array is
-not intended to behave like a null-terminated string. This will silence
-diagnostics with code like:
+a field whose type is a character pointer or character array to specify that
+the buffer is not intended to behave like a null-terminated string. This will
+silence diagnostics with code like:
.. code-block:: c
diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index 5f481ed1f7139..eff5f9568236a 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -5011,10 +5011,10 @@ void Sema::AddModeAttr(Decl *D, const
AttributeCommonInfo &CI,
static void handleNonStringAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
// This only applies to fields and variable declarations which have an array
- // type.
+ // type or pointer type, with character elements.
QualType QT = cast(D)->getType();
- if (!QT->isArrayType() ||
- !QT->getBaseElementTypeUnsafe()->isAnyCharacterType()) {
+ if ((!QT->isArrayType() && !QT->isPointerType()) ||
+ !QT->getPointeeOrArrayElementType()->isAnyCharacterType()) {
S.Diag(D->getBeginLoc(), diag::warn_attribute_non_character_array)
<< AL << AL.isRegularKeywordAttribute() << QT << AL.getRange();
return;
diff --git a/clang/test/Sema/attr-nonstring.c b/clang/test/Sema/attr-nonstring.c
index 3838aa3bbee15..fe7b6d259dd79 100644
--- a/clang/test/Sema/attr-nonstring.c
+++ b/clang/test/Sema/attr-nonstring.c
@@ -229,3 +229,11 @@ struct Outer o2[] = {
}
}
};
+
+// The attribute also works with a pointer type, not just an array type.
+__attribute__((nonstring)) char *ptr1;
+__attribute__((nonstring)) const unsigned char *ptr2;
+struct GH150951 {
+ __attribute__((nonstring)) char *ptr1;
+ __attribute__((nonstring)) const unsigned char *ptr2;
+};
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] release/21.x: [[gnu::nonstring]] should work on pointers too (#150974) (PR #150980)
https://github.com/tru closed https://github.com/llvm/llvm-project/pull/150980 ___ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] 4ca9a4b - [[gnu::nonstring]] should work on pointers too (#150974)
Author: Aaron Ballman
Date: 2025-08-01T08:55:21+02:00
New Revision: 4ca9a4bb351a723f746738384ef785e104f19dbc
URL:
https://github.com/llvm/llvm-project/commit/4ca9a4bb351a723f746738384ef785e104f19dbc
DIFF:
https://github.com/llvm/llvm-project/commit/4ca9a4bb351a723f746738384ef785e104f19dbc.diff
LOG: [[gnu::nonstring]] should work on pointers too (#150974)
Clang's current implementation only works on array types, but GCC (which
is where we got this attribute) supports it on pointers as well as
arrays.
Fixes #150951
(cherry picked from commit 837b2d464ff16fe0d892dcf2827747c97dd5465e)
Added:
Modified:
clang/include/clang/Basic/AttrDocs.td
clang/lib/Sema/SemaDeclAttr.cpp
clang/test/Sema/attr-nonstring.c
Removed:
diff --git a/clang/include/clang/Basic/AttrDocs.td
b/clang/include/clang/Basic/AttrDocs.td
index fefdaba7f8bf5..76747d2b11811 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -9417,9 +9417,9 @@ def NonStringDocs : Documentation {
let Category = DocCatDecl;
let Content = [{
The ``nonstring`` attribute can be applied to the declaration of a variable or
-a field whose type is a character array to specify that the character array is
-not intended to behave like a null-terminated string. This will silence
-diagnostics with code like:
+a field whose type is a character pointer or character array to specify that
+the buffer is not intended to behave like a null-terminated string. This will
+silence diagnostics with code like:
.. code-block:: c
diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index 5f481ed1f7139..eff5f9568236a 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -5011,10 +5011,10 @@ void Sema::AddModeAttr(Decl *D, const
AttributeCommonInfo &CI,
static void handleNonStringAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
// This only applies to fields and variable declarations which have an array
- // type.
+ // type or pointer type, with character elements.
QualType QT = cast(D)->getType();
- if (!QT->isArrayType() ||
- !QT->getBaseElementTypeUnsafe()->isAnyCharacterType()) {
+ if ((!QT->isArrayType() && !QT->isPointerType()) ||
+ !QT->getPointeeOrArrayElementType()->isAnyCharacterType()) {
S.Diag(D->getBeginLoc(), diag::warn_attribute_non_character_array)
<< AL << AL.isRegularKeywordAttribute() << QT << AL.getRange();
return;
diff --git a/clang/test/Sema/attr-nonstring.c
b/clang/test/Sema/attr-nonstring.c
index 3838aa3bbee15..fe7b6d259dd79 100644
--- a/clang/test/Sema/attr-nonstring.c
+++ b/clang/test/Sema/attr-nonstring.c
@@ -229,3 +229,11 @@ struct Outer o2[] = {
}
}
};
+
+// The attribute also works with a pointer type, not just an array type.
+__attribute__((nonstring)) char *ptr1;
+__attribute__((nonstring)) const unsigned char *ptr2;
+struct GH150951 {
+ __attribute__((nonstring)) char *ptr1;
+ __attribute__((nonstring)) const unsigned char *ptr2;
+};
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [lld] release/21.x: [LLD][COFF] Allow symbols with empty chunks to have no associated output section in the PDB writer (#149523) (PR #150969)
github-actions[bot] wrote: @cjacek (or anyone else). If you would like to add a note about this fix in the release notes (completely optional). Please reply to this comment with a one or two sentence description of the fix. When you are done, please add the release:note label to this PR. https://github.com/llvm/llvm-project/pull/150969 ___ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] release/21.x: [[gnu::nonstring]] should work on pointers too (#150974) (PR #150980)
github-actions[bot] wrote: @AaronBallman (or anyone else). If you would like to add a note about this fix in the release notes (completely optional). Please reply to this comment with a one or two sentence description of the fix. When you are done, please add the release:note label to this PR. https://github.com/llvm/llvm-project/pull/150980 ___ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang][DebugInfo] Disable VTable debug info (#130255) on COFF platforms (PR #150938)
https://github.com/tru updated https://github.com/llvm/llvm-project/pull/150938
>From 4cc5f4e94f7e87026418c2965e2e0a699e431cf8 Mon Sep 17 00:00:00 2001
From: kikairoya
Date: Mon, 28 Jul 2025 22:02:55 +0900
Subject: [PATCH 1/3] [clang][DebugInfo] Disable VTable debug info (#130255) on
COFF platforms
On COFF platform, d1b0cbff806b50d399826e79b9a53e4726c21302 generates
a debug info linked with VTable even if that is dllimport-ed. That
causes an access violation while performing runtime pseudo-relocation
if the debug section is stripped.
For the release branch, we simply disable VTable debug info on COFF
platform to avoid this problem.
Fixes #149639
---
clang/lib/CodeGen/CGDebugInfo.cpp | 3 ++-
.../vtable-debug-info-inheritance-simple.cpp | 11 ---
2 files changed, 10 insertions(+), 4 deletions(-)
diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp
b/clang/lib/CodeGen/CGDebugInfo.cpp
index 0dde045453e3a..ec28bd259e8e1 100644
--- a/clang/lib/CodeGen/CGDebugInfo.cpp
+++ b/clang/lib/CodeGen/CGDebugInfo.cpp
@@ -2645,7 +2645,8 @@ StringRef CGDebugInfo::getVTableName(const CXXRecordDecl
*RD) {
// existing information in the DWARF. The type is assumed to be 'void *'.
void CGDebugInfo::emitVTableSymbol(llvm::GlobalVariable *VTable,
const CXXRecordDecl *RD) {
- if (!CGM.getTarget().getCXXABI().isItaniumFamily())
+ if (!CGM.getTarget().getCXXABI().isItaniumFamily() ||
+ CGM.getTarget().getTriple().isOSBinFormatCOFF())
return;
ASTContext &Context = CGM.getContext();
diff --git a/clang/test/CodeGenCXX/vtable-debug-info-inheritance-simple.cpp
b/clang/test/CodeGenCXX/vtable-debug-info-inheritance-simple.cpp
index 249586f5991f1..b24ece1598327 100644
--- a/clang/test/CodeGenCXX/vtable-debug-info-inheritance-simple.cpp
+++ b/clang/test/CodeGenCXX/vtable-debug-info-inheritance-simple.cpp
@@ -1,5 +1,3 @@
-// REQUIRES: target={{x86_64.*-linux.*}}
-
// Simple inheritance case:
// For CBase and CDerived we check:
// - Generation of their vtables (including attributes).
@@ -30,13 +28,20 @@ int main() {
return 0;
}
-// RUN: %clang --target=x86_64-linux -Xclang -disable-O0-optnone -Xclang
-disable-llvm-passes -emit-llvm -S -g %s -o - | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-linux -emit-llvm -mrelocation-model pic
-pic-is-pie -debug-info-kind=limited -dwarf-version=5 -disable-O0-optnone
-disable-llvm-passes %s -o - | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-windows-gnu -emit-llvm -mrelocation-model
pic -pic-is-pie -debug-info-kind=limited -dwarf-version=5 -disable-O0-optnone
-disable-llvm-passes %s -o - | FileCheck %s --check-prefix=COFF
// CHECK: $_ZTVN3NSP5CBaseE = comdat any
// CHECK: $_ZTV8CDerived = comdat any
// CHECK: @_ZTVN3NSP5CBaseE = linkonce_odr {{dso_local|hidden}} unnamed_addr
constant {{.*}}, comdat, align 8, !dbg [[BASE_VTABLE_VAR:![0-9]*]]
// CHECK: @_ZTV8CDerived = linkonce_odr {{dso_local|hidden}} unnamed_addr
constant {{.*}}, comdat, align 8, !dbg [[DERIVED_VTABLE_VAR:![0-9]*]]
+// COFF: @_ZTVN3NSP5CBaseE = linkonce_odr {{dso_local|hidden}} unnamed_addr
constant {{.*}}, comdat, align 8
+// COFF-NOT: !dbg
+// COFF-SAME: {{$}}
+// COFF: @_ZTV8CDerived = linkonce_odr {{dso_local|hidden}} unnamed_addr
constant {{.*}}, comdat, align 8
+// COFF-NOT: !dbg
+// COFF-SAME: {{$}}
// CHECK: [[BASE_VTABLE_VAR]] = !DIGlobalVariableExpression(var:
[[BASE_VTABLE:![0-9]*]], expr: !DIExpression())
// CHECK-NEXT: [[BASE_VTABLE]] = distinct !DIGlobalVariable(name: "_vtable$",
linkageName: "_ZTVN3NSP5CBaseE"
>From b4c42dc666953919cb6e90ed424c7964351f981a Mon Sep 17 00:00:00 2001
From: kikairoya
Date: Mon, 28 Jul 2025 22:48:04 +0900
Subject: [PATCH 2/3] fix test debug-info-class
---
clang/test/CodeGenCXX/debug-info-class.cpp | 46 ++
1 file changed, 29 insertions(+), 17 deletions(-)
diff --git a/clang/test/CodeGenCXX/debug-info-class.cpp
b/clang/test/CodeGenCXX/debug-info-class.cpp
index 0bc4fdaa565c3..aa24a63c58cb8 100644
--- a/clang/test/CodeGenCXX/debug-info-class.cpp
+++ b/clang/test/CodeGenCXX/debug-info-class.cpp
@@ -99,12 +99,12 @@ int main(int argc, char **argv) {
return 0;
}
-// RUN: %clang_cc1 -triple x86_64-unknown_unknown -emit-llvm
-debug-info-kind=limited -fexceptions -std=c++98 %s -o - | FileCheck
-check-prefix=CHECK98 -check-prefix=CHECK %s
-// RUN: %clang_cc1 -triple i686-cygwin -emit-llvm -debug-info-kind=limited
-fexceptions -std=c++98 %s -o - | FileCheck -check-prefix=CHECK98
-check-prefix=CHECK %s
-// RUN: %clang_cc1 -triple armv7l-unknown-linux-gnueabihf -emit-llvm
-debug-info-kind=limited -fexceptions -std=c++98 %s -o - | FileCheck
-check-prefix=CHECK98 -check-prefix=CHECK %s
-// RUN: %clang_cc1 -triple x86_64-unknown_unknown -emit-llvm
-debug-info-kind=limited -fexceptions -std=c++11 %s -o - | FileCheck
-check-prefix=CHECK11 -check-prefix=CHECK %s
-// RUN: %clang_cc1 -triple i686-cygwin -emit-llvm -debug-info-kind=limited
-fexce
[llvm-branch-commits] [clang][DebugInfo] Disable VTable debug info (#130255) on COFF platforms (PR #150938)
https://github.com/tru closed https://github.com/llvm/llvm-project/pull/150938 ___ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang][DebugInfo] Disable VTable debug info (#130255) on COFF platforms (PR #150938)
https://github.com/tru updated https://github.com/llvm/llvm-project/pull/150938 ___ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang][CodeGen] Remove CWD fallback in compilation directory (PR #150130)
https://github.com/cachemeifyoucan updated https://github.com/llvm/llvm-project/pull/150130 ___ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang][CodeGen] Remove CWD fallback in compilation directory (PR #150130)
https://github.com/cachemeifyoucan updated https://github.com/llvm/llvm-project/pull/150130 ___ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [BOLT] Gadget scanner: make use of C++17 features and LLVM helpers (PR #141665)
https://github.com/atrosinenko updated
https://github.com/llvm/llvm-project/pull/141665
>From 5f0ba9059ee626f6a317add10451ed8902d46164 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 af911ba829ca5..01ffb2ddb0c78 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] Introduce helpers to match `MCInst`s one at a time (NFC) (PR #138883)
https://github.com/atrosinenko updated
https://github.com/llvm/llvm-project/pull/138883
>From 52148333034882554e897a768110222d5821d132 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 7b04ce7134e3e..1617ef726ea87 100644
--- a/bolt/include/bolt/Core/MCInstUtils.h
+++ b/bolt/include/bolt/Core/MCInstUtils.h
@@ -149,6 +149,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] Introduce helpers to match `MCInst`s one at a time (NFC) (PR #138883)
https://github.com/atrosinenko updated
https://github.com/llvm/llvm-project/pull/138883
>From 52148333034882554e897a768110222d5821d132 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 7b04ce7134e3e..1617ef726ea87 100644
--- a/bolt/include/bolt/Core/MCInstUtils.h
+++ b/bolt/include/bolt/Core/MCInstUtils.h
@@ -149,6 +149,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: prevent false positives due to jump tables (PR #138884)
https://github.com/atrosinenko updated
https://github.com/llvm/llvm-project/pull/138884
>From 8e44004d43f8f888a9609efa661ee50c5bba1277 Mon Sep 17 00:00:00 2001
From: Anatoly Trosinenko
Date: Tue, 6 May 2025 11:31:03 +0300
Subject: [PATCH 1/2] [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 1617ef726ea87..cc623065f112c 100644
--- a/bolt/include/bolt/Core/MCInstUtils.h
+++ b/bolt/include/bolt/Core/MCInstUtils.h
@@ -141,6 +141,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 d79174f13f502..beceb125161b8 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"
@@ -711,6 +712,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 3cdb9673d4dc0..39bc96f087f8e 100644
--- a/bolt/lib/Core/MCInstUtils.cpp
+++ b/bolt/lib/Core/MCInstUtils.cpp
@@ -54,3 +54,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 d33244d47dcbc..0fb4b161abdbb 100644
--- a/bolt/lib/Passes/PAuthGadgetScanner.cpp
+++ b/bolt/lib/Passes/PAuthGadgetScanner.cpp
@@ -1370,6 +1370,11 @@ shouldReportUnsafeTailCall(const BinaryContext &BC,
const BinaryFunction &BF,
return std::nullopt;
}
+ if (BC.MIB->isSafeJumpTableBranchForPtrAuth(Inst)) {
+
[llvm-branch-commits] [llvm] [BOLT] Gadget scanner: optionally assume auth traps on failure (PR #139778)
https://github.com/atrosinenko updated
https://github.com/llvm/llvm-project/pull/139778
>From 6f64ed049a56c2356c75ab085a9fc6e2baeb6052 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 0fb4b161abdbb..af911ba829ca5 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] Refactor MCInstReference and move it to Core (NFC) (PR #138655)
https://github.com/atrosinenko updated
https://github.com/llvm/llvm-project/pull/138655
>From e400b2291786002dae1dddbd96c456a5e9dd5087 Mon Sep 17 00:00:00 2001
From: Anatoly Trosinenko
Date: Thu, 19 Jun 2025 14:03:59 +0300
Subject: [PATCH 1/2] [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->getInstructionAtIn
[llvm-branch-commits] [llvm] [BOLT] Gadget scanner: make use of C++17 features and LLVM helpers (PR #141665)
https://github.com/atrosinenko updated
https://github.com/llvm/llvm-project/pull/141665
>From 5f0ba9059ee626f6a317add10451ed8902d46164 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 af911ba829ca5..01ffb2ddb0c78 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] [lldb] [llvm] Backport Wasm Debugging changes to the LLVM 21.x Release (PR #151559)
llvmbot wrote: @llvm/pr-subscribers-lldb Author: Jonas Devlieghere (JDevlieghere) Changes #151439 --- Patch is 99.21 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/151559.diff 34 Files Affected: - (modified) lldb/docs/resources/lldbgdbremote.md (+67) - (modified) lldb/include/lldb/Expression/DWARFExpression.h (+8-4) - (modified) lldb/packages/Python/lldbsuite/test/lldbgdbclient.py (+2-2) - (modified) lldb/source/Expression/DWARFExpression.cpp (+6-4) - (modified) lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.cpp (+5-1) - (modified) lldb/source/Plugins/Process/CMakeLists.txt (+1) - (modified) lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp (+7-2) - (modified) lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h (+2) - (added) lldb/source/Plugins/Process/wasm/CMakeLists.txt (+11) - (added) lldb/source/Plugins/Process/wasm/ProcessWasm.cpp (+166) - (added) lldb/source/Plugins/Process/wasm/ProcessWasm.h (+99) - (added) lldb/source/Plugins/Process/wasm/RegisterContextWasm.cpp (+109) - (added) lldb/source/Plugins/Process/wasm/RegisterContextWasm.h (+69) - (added) lldb/source/Plugins/Process/wasm/ThreadWasm.cpp (+51) - (added) lldb/source/Plugins/Process/wasm/ThreadWasm.h (+41) - (added) lldb/source/Plugins/Process/wasm/UnwindWasm.cpp (+85) - (added) lldb/source/Plugins/Process/wasm/UnwindWasm.h (+51) - (modified) lldb/source/Plugins/SymbolFile/DWARF/CMakeLists.txt (+1) - (modified) lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp (+3-1) - (modified) lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h (+5-3) - (modified) lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp (+4) - (modified) lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h (+3) - (modified) lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp (+5-3) - (modified) lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h (+2-1) - (added) lldb/source/Plugins/SymbolFile/DWARF/SymbolFileWasm.cpp (+100) - (added) lldb/source/Plugins/SymbolFile/DWARF/SymbolFileWasm.h (+34) - (modified) lldb/source/Target/Platform.cpp (+7) - (added) lldb/source/Utility/WasmVirtualRegisters.h (+53) - (modified) lldb/test/API/functionalities/gdb_remote_client/TestWasm.py (+165-58) - (added) lldb/test/API/functionalities/gdb_remote_client/simple.c (+10) - (added) lldb/test/API/functionalities/gdb_remote_client/simple.yaml (+228) - (modified) lldb/unittests/Expression/CMakeLists.txt (+2) - (modified) lldb/unittests/Expression/DWARFExpressionTest.cpp (+428-152) - (modified) llvm/docs/ReleaseNotes.md (+2) ``diff diff --git a/lldb/docs/resources/lldbgdbremote.md b/lldb/docs/resources/lldbgdbremote.md index 80c68091ecd07..36b95f1073ebc 100644 --- a/lldb/docs/resources/lldbgdbremote.md +++ b/lldb/docs/resources/lldbgdbremote.md @@ -2463,3 +2463,70 @@ omitting them will work fine; these numbers are always base 16. The length of the payload is not provided. A reliable, 8-bit clean, transport layer is assumed. + +## Wasm Packets + +The packet below are supported by the +[WAMR](https://github.com/bytecodealliance/wasm-micro-runtime) and +[V8](https://v8.dev) Wasm runtimes. + + +### qWasmCallStack + +Get the Wasm call stack for the given thread id. This returns a hex-encoded +list of PC values, one for each frame of the call stack. To match the Wasm +specification, the addresses are encoded in little endian byte order, even if +the endian of the Wasm runtime's host is not little endian. + +``` +send packet: $qWasmCallStack:202dbe040#08 +read packet: $9c010040e5010040fe010040# +``` + +**Priority to Implement:** Only required for Wasm support. Necessary to show +stack traces. + +### qWasmGlobal + +Get the value of a Wasm global variable for the given frame index at the given +variable index. The indexes are encoded as base 10. The result is a hex-encoded +address from where to read the value. + +``` +send packet: $qWasmGlobal:0;2#cb +read packet: $e0030100#b9 +``` + +**Priority to Implement:** Only required for Wasm support. Necessary to show +variables. + + +### qWasmLocal + +Get the value of a Wasm function argument or local variable for the given frame +index at the given variable index. The indexes are encoded as base 10. The +result is a hex-encoded address from where to read the value. + + +``` +send packet: $qWasmLocal:0;2#cb +read packet: $e0030100#b9 +``` + +**Priority to Implement:** Only required for Wasm support. Necessary to show +variables. + + +### qWasmStackValue + +Get the value of a Wasm local variable from the Wasm operand stack, for the +given frame index at the given variable index. The indexes are encoded as base +10. The result is a hex-encoded address from where to read value. + +``` +send packet: $qWasmStackValue:0;2#cb +read packet: $e0030100#b9 +``` + +**Priority to Implement:** Only required for Wasm support. Necessary to show +variables. diff --git a/lldb/include/lldb/Expression/DWARFExpress
[llvm-branch-commits] [clang][ScanDeps] Clear compilation directory if needed (PR #150129)
https://github.com/cachemeifyoucan updated https://github.com/llvm/llvm-project/pull/150129 ___ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang][ScanDeps] Clear compilation directory if needed (PR #150129)
https://github.com/cachemeifyoucan updated https://github.com/llvm/llvm-project/pull/150129 ___ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] callee_type metadata for indirect calls (PR #117036)
https://github.com/Prabhuk updated
https://github.com/llvm/llvm-project/pull/117036
>From b7fbe09b32ff02d4f7c52d82fbf8b5cd28138852 Mon Sep 17 00:00:00 2001
From: prabhukr
Date: Wed, 23 Apr 2025 04:05:47 +
Subject: [PATCH] Address review comments.
Created using spr 1.3.6-beta.1
---
clang/lib/CodeGen/CGCall.cpp| 8
clang/lib/CodeGen/CodeGenModule.cpp | 10 +-
clang/lib/CodeGen/CodeGenModule.h | 4 ++--
3 files changed, 11 insertions(+), 11 deletions(-)
diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp
index 185ee1a970aac..d8ab7140f7943 100644
--- a/clang/lib/CodeGen/CGCall.cpp
+++ b/clang/lib/CodeGen/CGCall.cpp
@@ -5780,19 +5780,19 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo
&CallInfo,
if (callOrInvoke) {
*callOrInvoke = CI;
if (CGM.getCodeGenOpts().CallGraphSection) {
- assert((TargetDecl && TargetDecl->getFunctionType() ||
- Callee.getAbstractInfo().getCalleeFunctionProtoType()) &&
- "cannot find callsite type");
QualType CST;
if (TargetDecl && TargetDecl->getFunctionType())
CST = QualType(TargetDecl->getFunctionType(), 0);
else if (const auto *FPT =
Callee.getAbstractInfo().getCalleeFunctionProtoType())
CST = QualType(FPT, 0);
+ else
+llvm_unreachable(
+"Cannot find the callee type to generate callee_type metadata.");
// Set type identifier metadata of indirect calls for call graph section.
if (!CST.isNull())
-CGM.CreateCalleeTypeMetadataForIcall(CST, *callOrInvoke);
+CGM.createCalleeTypeMetadataForIcall(CST, *callOrInvoke);
}
}
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp
b/clang/lib/CodeGen/CodeGenModule.cpp
index 43cd2405571cf..2fc99639a75cb 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -2654,7 +2654,7 @@ void
CodeGenModule::SetLLVMFunctionAttributesForDefinition(const Decl *D,
// Skip available_externally functions. They won't be codegen'ed in the
// current module anyway.
if (getContext().GetGVALinkageForFunction(FD) != GVA_AvailableExternally)
-CreateFunctionTypeMetadataForIcall(FD, F);
+createFunctionTypeMetadataForIcall(FD, F);
}
}
@@ -2868,7 +2868,7 @@ static bool hasExistingGeneralizedTypeMD(llvm::Function
*F) {
return MD->hasGeneralizedMDString();
}
-void CodeGenModule::CreateFunctionTypeMetadataForIcall(const FunctionDecl *FD,
+void CodeGenModule::createFunctionTypeMetadataForIcall(const FunctionDecl *FD,
llvm::Function *F) {
if (CodeGenOpts.CallGraphSection && !hasExistingGeneralizedTypeMD(F) &&
(!F->hasLocalLinkage() ||
@@ -2898,7 +2898,7 @@ void
CodeGenModule::CreateFunctionTypeMetadataForIcall(const FunctionDecl *FD,
F->addTypeMetadata(0, llvm::ConstantAsMetadata::get(CrossDsoTypeId));
}
-void CodeGenModule::CreateCalleeTypeMetadataForIcall(const QualType &QT,
+void CodeGenModule::createCalleeTypeMetadataForIcall(const QualType &QT,
llvm::CallBase *CB) {
// Only if needed for call graph section and only for indirect calls.
if (!CodeGenOpts.CallGraphSection || !CB->isIndirectCall())
@@ -2909,7 +2909,7 @@ void
CodeGenModule::CreateCalleeTypeMetadataForIcall(const QualType &QT,
getLLVMContext(), {llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(
llvm::Type::getInt64Ty(getLLVMContext()), 0)),
TypeIdMD});
- llvm::MDTuple *MDN = llvm::MDNode::get(getLLVMContext(), { TypeTuple });
+ llvm::MDTuple *MDN = llvm::MDNode::get(getLLVMContext(), {TypeTuple});
CB->setMetadata(llvm::LLVMContext::MD_callee_type, MDN);
}
@@ -3041,7 +3041,7 @@ void CodeGenModule::SetFunctionAttributes(GlobalDecl GD,
llvm::Function *F,
// jump table.
if (!CodeGenOpts.SanitizeCfiCrossDso ||
!CodeGenOpts.SanitizeCfiCanonicalJumpTables)
-CreateFunctionTypeMetadataForIcall(FD, F);
+createFunctionTypeMetadataForIcall(FD, F);
if (LangOpts.Sanitize.has(SanitizerKind::KCFI))
setKCFIType(FD, F);
diff --git a/clang/lib/CodeGen/CodeGenModule.h
b/clang/lib/CodeGen/CodeGenModule.h
index dfbe4388349dd..4b53f0f241b52 100644
--- a/clang/lib/CodeGen/CodeGenModule.h
+++ b/clang/lib/CodeGen/CodeGenModule.h
@@ -1619,11 +1619,11 @@ class CodeGenModule : public CodeGenTypeCache {
llvm::Metadata *CreateMetadataIdentifierGeneralized(QualType T);
/// Create and attach type metadata to the given function.
- void CreateFunctionTypeMetadataForIcall(const FunctionDecl *FD,
+ void createFunctionTypeMetadataForIcall(const FunctionDecl *FD,
llvm::Function *F);
/// Create and attach type metadata to the given call.
- void CreateCalleeTypeMetadataForIcall(const QualType &QT, llvm::CallBase
*CB);
+ void createCa
[llvm-branch-commits] [clang] [clang] callee_type metadata for indirect calls (PR #117036)
https://github.com/Prabhuk updated
https://github.com/llvm/llvm-project/pull/117036
>From b7fbe09b32ff02d4f7c52d82fbf8b5cd28138852 Mon Sep 17 00:00:00 2001
From: prabhukr
Date: Wed, 23 Apr 2025 04:05:47 +
Subject: [PATCH] Address review comments.
Created using spr 1.3.6-beta.1
---
clang/lib/CodeGen/CGCall.cpp| 8
clang/lib/CodeGen/CodeGenModule.cpp | 10 +-
clang/lib/CodeGen/CodeGenModule.h | 4 ++--
3 files changed, 11 insertions(+), 11 deletions(-)
diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp
index 185ee1a970aac..d8ab7140f7943 100644
--- a/clang/lib/CodeGen/CGCall.cpp
+++ b/clang/lib/CodeGen/CGCall.cpp
@@ -5780,19 +5780,19 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo
&CallInfo,
if (callOrInvoke) {
*callOrInvoke = CI;
if (CGM.getCodeGenOpts().CallGraphSection) {
- assert((TargetDecl && TargetDecl->getFunctionType() ||
- Callee.getAbstractInfo().getCalleeFunctionProtoType()) &&
- "cannot find callsite type");
QualType CST;
if (TargetDecl && TargetDecl->getFunctionType())
CST = QualType(TargetDecl->getFunctionType(), 0);
else if (const auto *FPT =
Callee.getAbstractInfo().getCalleeFunctionProtoType())
CST = QualType(FPT, 0);
+ else
+llvm_unreachable(
+"Cannot find the callee type to generate callee_type metadata.");
// Set type identifier metadata of indirect calls for call graph section.
if (!CST.isNull())
-CGM.CreateCalleeTypeMetadataForIcall(CST, *callOrInvoke);
+CGM.createCalleeTypeMetadataForIcall(CST, *callOrInvoke);
}
}
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp
b/clang/lib/CodeGen/CodeGenModule.cpp
index 43cd2405571cf..2fc99639a75cb 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -2654,7 +2654,7 @@ void
CodeGenModule::SetLLVMFunctionAttributesForDefinition(const Decl *D,
// Skip available_externally functions. They won't be codegen'ed in the
// current module anyway.
if (getContext().GetGVALinkageForFunction(FD) != GVA_AvailableExternally)
-CreateFunctionTypeMetadataForIcall(FD, F);
+createFunctionTypeMetadataForIcall(FD, F);
}
}
@@ -2868,7 +2868,7 @@ static bool hasExistingGeneralizedTypeMD(llvm::Function
*F) {
return MD->hasGeneralizedMDString();
}
-void CodeGenModule::CreateFunctionTypeMetadataForIcall(const FunctionDecl *FD,
+void CodeGenModule::createFunctionTypeMetadataForIcall(const FunctionDecl *FD,
llvm::Function *F) {
if (CodeGenOpts.CallGraphSection && !hasExistingGeneralizedTypeMD(F) &&
(!F->hasLocalLinkage() ||
@@ -2898,7 +2898,7 @@ void
CodeGenModule::CreateFunctionTypeMetadataForIcall(const FunctionDecl *FD,
F->addTypeMetadata(0, llvm::ConstantAsMetadata::get(CrossDsoTypeId));
}
-void CodeGenModule::CreateCalleeTypeMetadataForIcall(const QualType &QT,
+void CodeGenModule::createCalleeTypeMetadataForIcall(const QualType &QT,
llvm::CallBase *CB) {
// Only if needed for call graph section and only for indirect calls.
if (!CodeGenOpts.CallGraphSection || !CB->isIndirectCall())
@@ -2909,7 +2909,7 @@ void
CodeGenModule::CreateCalleeTypeMetadataForIcall(const QualType &QT,
getLLVMContext(), {llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(
llvm::Type::getInt64Ty(getLLVMContext()), 0)),
TypeIdMD});
- llvm::MDTuple *MDN = llvm::MDNode::get(getLLVMContext(), { TypeTuple });
+ llvm::MDTuple *MDN = llvm::MDNode::get(getLLVMContext(), {TypeTuple});
CB->setMetadata(llvm::LLVMContext::MD_callee_type, MDN);
}
@@ -3041,7 +3041,7 @@ void CodeGenModule::SetFunctionAttributes(GlobalDecl GD,
llvm::Function *F,
// jump table.
if (!CodeGenOpts.SanitizeCfiCrossDso ||
!CodeGenOpts.SanitizeCfiCanonicalJumpTables)
-CreateFunctionTypeMetadataForIcall(FD, F);
+createFunctionTypeMetadataForIcall(FD, F);
if (LangOpts.Sanitize.has(SanitizerKind::KCFI))
setKCFIType(FD, F);
diff --git a/clang/lib/CodeGen/CodeGenModule.h
b/clang/lib/CodeGen/CodeGenModule.h
index dfbe4388349dd..4b53f0f241b52 100644
--- a/clang/lib/CodeGen/CodeGenModule.h
+++ b/clang/lib/CodeGen/CodeGenModule.h
@@ -1619,11 +1619,11 @@ class CodeGenModule : public CodeGenTypeCache {
llvm::Metadata *CreateMetadataIdentifierGeneralized(QualType T);
/// Create and attach type metadata to the given function.
- void CreateFunctionTypeMetadataForIcall(const FunctionDecl *FD,
+ void createFunctionTypeMetadataForIcall(const FunctionDecl *FD,
llvm::Function *F);
/// Create and attach type metadata to the given call.
- void CreateCalleeTypeMetadataForIcall(const QualType &QT, llvm::CallBase
*CB);
+ void createCa
[llvm-branch-commits] [llvm] llvm-reduce: Add new pass to inline call sites (PR #134223)
https://github.com/arsenm updated
https://github.com/llvm/llvm-project/pull/134223
>From 5408369ff5ebc372458f5528acbf93674c4359b0 Mon Sep 17 00:00:00 2001
From: Matt Arsenault
Date: Sun, 30 Mar 2025 09:34:09 +0700
Subject: [PATCH] llvm-reduce: Add new pass to inline call sites
Added a primitive heuristic to avoid blowing up the code size
which could use more thought.
This helps cleanup some basic examples I've been looking at where
there is a worse result when just running a bug through the full
optimization pipeline vs. running just a single pass at the point
of failure.
---
.../llvm-reduce/inline-call-sites-cost.ll | 95 +++
.../tools/llvm-reduce/inline-call-sites.ll| 765 ++
llvm/tools/llvm-reduce/CMakeLists.txt | 1 +
llvm/tools/llvm-reduce/DeltaManager.cpp | 1 +
llvm/tools/llvm-reduce/DeltaPasses.def| 2 +-
.../deltas/ReduceInlineCallSites.cpp | 103 +++
.../deltas/ReduceInlineCallSites.h| 18 +
7 files changed, 984 insertions(+), 1 deletion(-)
create mode 100644 llvm/test/tools/llvm-reduce/inline-call-sites-cost.ll
create mode 100644 llvm/test/tools/llvm-reduce/inline-call-sites.ll
create mode 100644 llvm/tools/llvm-reduce/deltas/ReduceInlineCallSites.cpp
create mode 100644 llvm/tools/llvm-reduce/deltas/ReduceInlineCallSites.h
diff --git a/llvm/test/tools/llvm-reduce/inline-call-sites-cost.ll
b/llvm/test/tools/llvm-reduce/inline-call-sites-cost.ll
new file mode 100644
index 0..fc25ca45824dc
--- /dev/null
+++ b/llvm/test/tools/llvm-reduce/inline-call-sites-cost.ll
@@ -0,0 +1,95 @@
+; RUN: llvm-reduce --abort-on-invalid-reduction
--delta-passes=inline-call-sites -reduce-callsite-inline-threshold=3 --test
FileCheck --test-arg --check-prefix=CHECK --test-arg %s --test-arg --input-file
%s -o %t
+; RUN: FileCheck -check-prefixes=RESULT,CHECK %s < %t
+
+declare void @extern_b()
+declare void @extern_a()
+
+; RESULT: @gv_init = global ptr @no_inline_noncall_user
+@gv_init = global ptr @no_inline_noncall_user
+
+
+; CHECK-LABEL: define void @no_inline_noncall_user(
+define void @no_inline_noncall_user() {
+ call void @extern_a()
+ call void @extern_a()
+ call void @extern_a()
+ call void @extern_a()
+ ret void
+}
+
+; RESULT-LABEL: define void @noncall_user_call() {
+; RESULT-NEXT: call void @no_inline_noncall_user()
+; RESULT-NEXT: ret void
+define void @noncall_user_call() {
+ call void @no_inline_noncall_user()
+ ret void
+}
+
+; RESULT-LABEL: define void @big_callee_small_caller_callee() {
+define void @big_callee_small_caller_callee() {
+ call void @extern_a()
+ call void @extern_a()
+ call void @extern_a()
+ call void @extern_a()
+ ret void
+}
+
+; RESULT-LABEL: define void @big_callee_small_caller_caller() {
+; RESULT-NEXT: call void @extern_b()
+; RESULT-NEXT: call void @extern_a()
+; RESULT-NEXT: call void @extern_a()
+; RESULT-NEXT: call void @extern_a()
+; RESULT-NEXT: call void @extern_a()
+; RESULT-NEXT: ret void
+define void @big_callee_small_caller_caller() {
+ call void @extern_b()
+ call void @big_callee_small_caller_callee()
+ ret void
+}
+
+; RESULT-LABEL: define void @small_callee_big_caller_callee() {
+; RESULT-NEXT: call void @extern_a()
+; RESULT-NEXT: ret void
+define void @small_callee_big_caller_callee() {
+ call void @extern_a()
+ ret void
+}
+
+; RESULT-LABEL: define void @small_callee_big_caller_caller() {
+; RESULT-NEXT: call void @extern_b()
+; RESULT-NEXT: call void @extern_a()
+; RESULT-NEXT: call void @extern_b()
+; RESULT-NEXT: call void @extern_b()
+; RESULT-NEXT: ret void
+define void @small_callee_big_caller_caller() {
+ call void @extern_b()
+ call void @small_callee_big_caller_callee()
+ call void @extern_b()
+ call void @extern_b()
+ ret void
+}
+
+; RESULT-LABEL: define void @big_callee_big_caller_callee() {
+define void @big_callee_big_caller_callee() {
+ call void @extern_a()
+ call void @extern_a()
+ call void @extern_a()
+ call void @extern_a()
+ ret void
+}
+
+; RESULT-LABEL: define void @big_callee_big_caller_caller() {
+; RESULT-NEXT: call void @extern_b()
+; RESULT-NEXT: call void @big_callee_big_caller_callee()
+; RESULT-NEXT: call void @extern_b()
+; RESULT-NEXT: call void @extern_b()
+; RESULT-NEXT: call void @extern_b()
+; RESULT-NEXT: ret void
+define void @big_callee_big_caller_caller() {
+ call void @extern_b()
+ call void @big_callee_big_caller_callee()
+ call void @extern_b()
+ call void @extern_b()
+ call void @extern_b()
+ ret void
+}
diff --git a/llvm/test/tools/llvm-reduce/inline-call-sites.ll
b/llvm/test/tools/llvm-reduce/inline-call-sites.ll
new file mode 100644
index 0..0e7cf79df784c
--- /dev/null
+++ b/llvm/test/tools/llvm-reduce/inline-call-sites.ll
@@ -0,0 +1,765 @@
+; RUN: llvm-reduce --abort-on-invalid-reduction
--delta-passes=inline-call-sites -reduce-callsite-inline-threshold=-1 --test
FileCheck --test-arg --check-prefixes=CHECK,INTERESTING --test-arg %s
--test-arg --input-file %s -o %t
[llvm-branch-commits] [llvm] llvm-reduce: Add new pass to inline call sites (PR #134223)
https://github.com/arsenm updated
https://github.com/llvm/llvm-project/pull/134223
>From 5408369ff5ebc372458f5528acbf93674c4359b0 Mon Sep 17 00:00:00 2001
From: Matt Arsenault
Date: Sun, 30 Mar 2025 09:34:09 +0700
Subject: [PATCH] llvm-reduce: Add new pass to inline call sites
Added a primitive heuristic to avoid blowing up the code size
which could use more thought.
This helps cleanup some basic examples I've been looking at where
there is a worse result when just running a bug through the full
optimization pipeline vs. running just a single pass at the point
of failure.
---
.../llvm-reduce/inline-call-sites-cost.ll | 95 +++
.../tools/llvm-reduce/inline-call-sites.ll| 765 ++
llvm/tools/llvm-reduce/CMakeLists.txt | 1 +
llvm/tools/llvm-reduce/DeltaManager.cpp | 1 +
llvm/tools/llvm-reduce/DeltaPasses.def| 2 +-
.../deltas/ReduceInlineCallSites.cpp | 103 +++
.../deltas/ReduceInlineCallSites.h| 18 +
7 files changed, 984 insertions(+), 1 deletion(-)
create mode 100644 llvm/test/tools/llvm-reduce/inline-call-sites-cost.ll
create mode 100644 llvm/test/tools/llvm-reduce/inline-call-sites.ll
create mode 100644 llvm/tools/llvm-reduce/deltas/ReduceInlineCallSites.cpp
create mode 100644 llvm/tools/llvm-reduce/deltas/ReduceInlineCallSites.h
diff --git a/llvm/test/tools/llvm-reduce/inline-call-sites-cost.ll
b/llvm/test/tools/llvm-reduce/inline-call-sites-cost.ll
new file mode 100644
index 0..fc25ca45824dc
--- /dev/null
+++ b/llvm/test/tools/llvm-reduce/inline-call-sites-cost.ll
@@ -0,0 +1,95 @@
+; RUN: llvm-reduce --abort-on-invalid-reduction
--delta-passes=inline-call-sites -reduce-callsite-inline-threshold=3 --test
FileCheck --test-arg --check-prefix=CHECK --test-arg %s --test-arg --input-file
%s -o %t
+; RUN: FileCheck -check-prefixes=RESULT,CHECK %s < %t
+
+declare void @extern_b()
+declare void @extern_a()
+
+; RESULT: @gv_init = global ptr @no_inline_noncall_user
+@gv_init = global ptr @no_inline_noncall_user
+
+
+; CHECK-LABEL: define void @no_inline_noncall_user(
+define void @no_inline_noncall_user() {
+ call void @extern_a()
+ call void @extern_a()
+ call void @extern_a()
+ call void @extern_a()
+ ret void
+}
+
+; RESULT-LABEL: define void @noncall_user_call() {
+; RESULT-NEXT: call void @no_inline_noncall_user()
+; RESULT-NEXT: ret void
+define void @noncall_user_call() {
+ call void @no_inline_noncall_user()
+ ret void
+}
+
+; RESULT-LABEL: define void @big_callee_small_caller_callee() {
+define void @big_callee_small_caller_callee() {
+ call void @extern_a()
+ call void @extern_a()
+ call void @extern_a()
+ call void @extern_a()
+ ret void
+}
+
+; RESULT-LABEL: define void @big_callee_small_caller_caller() {
+; RESULT-NEXT: call void @extern_b()
+; RESULT-NEXT: call void @extern_a()
+; RESULT-NEXT: call void @extern_a()
+; RESULT-NEXT: call void @extern_a()
+; RESULT-NEXT: call void @extern_a()
+; RESULT-NEXT: ret void
+define void @big_callee_small_caller_caller() {
+ call void @extern_b()
+ call void @big_callee_small_caller_callee()
+ ret void
+}
+
+; RESULT-LABEL: define void @small_callee_big_caller_callee() {
+; RESULT-NEXT: call void @extern_a()
+; RESULT-NEXT: ret void
+define void @small_callee_big_caller_callee() {
+ call void @extern_a()
+ ret void
+}
+
+; RESULT-LABEL: define void @small_callee_big_caller_caller() {
+; RESULT-NEXT: call void @extern_b()
+; RESULT-NEXT: call void @extern_a()
+; RESULT-NEXT: call void @extern_b()
+; RESULT-NEXT: call void @extern_b()
+; RESULT-NEXT: ret void
+define void @small_callee_big_caller_caller() {
+ call void @extern_b()
+ call void @small_callee_big_caller_callee()
+ call void @extern_b()
+ call void @extern_b()
+ ret void
+}
+
+; RESULT-LABEL: define void @big_callee_big_caller_callee() {
+define void @big_callee_big_caller_callee() {
+ call void @extern_a()
+ call void @extern_a()
+ call void @extern_a()
+ call void @extern_a()
+ ret void
+}
+
+; RESULT-LABEL: define void @big_callee_big_caller_caller() {
+; RESULT-NEXT: call void @extern_b()
+; RESULT-NEXT: call void @big_callee_big_caller_callee()
+; RESULT-NEXT: call void @extern_b()
+; RESULT-NEXT: call void @extern_b()
+; RESULT-NEXT: call void @extern_b()
+; RESULT-NEXT: ret void
+define void @big_callee_big_caller_caller() {
+ call void @extern_b()
+ call void @big_callee_big_caller_callee()
+ call void @extern_b()
+ call void @extern_b()
+ call void @extern_b()
+ ret void
+}
diff --git a/llvm/test/tools/llvm-reduce/inline-call-sites.ll
b/llvm/test/tools/llvm-reduce/inline-call-sites.ll
new file mode 100644
index 0..0e7cf79df784c
--- /dev/null
+++ b/llvm/test/tools/llvm-reduce/inline-call-sites.ll
@@ -0,0 +1,765 @@
+; RUN: llvm-reduce --abort-on-invalid-reduction
--delta-passes=inline-call-sites -reduce-callsite-inline-threshold=-1 --test
FileCheck --test-arg --check-prefixes=CHECK,INTERESTING --test-arg %s
--test-arg --input-file %s -o %t
[llvm-branch-commits] MachineInstrBuilder: Introduce copyMIMetadata() function. (PR #133535)
https://github.com/pcc updated https://github.com/llvm/llvm-project/pull/133535 ___ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [NFC] test/lit.cfg.py formatting (PR #151218)
https://github.com/mtrofin updated
https://github.com/llvm/llvm-project/pull/151218
>From 9e08971351e80d1af1f861364a7cbc3ed028457e Mon Sep 17 00:00:00 2001
From: Mircea Trofin
Date: Tue, 29 Jul 2025 13:01:10 -0700
Subject: [PATCH] [NFC] test/lit.cfg.py formatting
---
llvm/test/lit.cfg.py | 11 +--
1 file changed, 5 insertions(+), 6 deletions(-)
diff --git a/llvm/test/lit.cfg.py b/llvm/test/lit.cfg.py
index 143cc3817bd08..1d190fd20e573 100644
--- a/llvm/test/lit.cfg.py
+++ b/llvm/test/lit.cfg.py
@@ -451,7 +451,7 @@ def version_int(ver):
"%llvmdylib",
"{}/libLLVM{}.{}".format(
config.llvm_shlib_dir, config.llvm_shlib_ext,
config.llvm_dylib_version
-)
+),
)
)
@@ -582,6 +582,7 @@ def have_ld64_plugin_support():
if have_ld64_plugin_support():
config.available_features.add("ld64_plugin")
+
def host_unwind_supports_jit():
# Do we expect the host machine to support JIT registration of clang's
# default unwind info format for the host (e.g. eh-frames, compact-unwind,
@@ -589,7 +590,7 @@ def host_unwind_supports_jit():
# Linux and the BSDs use DWARF eh-frames and all known unwinders support
# register_frame at minimum.
-if platform.system() in [ "Linux", "FreeBSD", "NetBSD" ]:
+if platform.system() in ["Linux", "FreeBSD", "NetBSD"]:
return True
# Windows does not support frame info without the ORC runtime.
@@ -602,10 +603,7 @@ def host_unwind_supports_jit():
# macOS 14.0.
if platform.system() == "Darwin":
-assert (
-"arm64" in config.host_triple
-or "x86_64" in config.host_triple
-)
+assert "arm64" in config.host_triple or "x86_64" in config.host_triple
if "x86_64" in config.host_triple:
return True
@@ -627,6 +625,7 @@ def host_unwind_supports_jit():
return False
+
if host_unwind_supports_jit():
config.available_features.add("host-unwind-supports-jit")
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] Ignore FileCheck when profcheck is enabled (PR #151214)
https://github.com/mtrofin updated https://github.com/llvm/llvm-project/pull/151214 >From 60275ac82364dd936e5d35902c1bf9872d5371ef Mon Sep 17 00:00:00 2001 From: Mircea Trofin Date: Tue, 29 Jul 2025 12:55:59 -0700 Subject: [PATCH] fixes --- llvm/test/lit.cfg.py | 14 -- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/llvm/test/lit.cfg.py b/llvm/test/lit.cfg.py index 1d190fd20e573..43c7cf677a913 100644 --- a/llvm/test/lit.cfg.py +++ b/llvm/test/lit.cfg.py @@ -18,7 +18,17 @@ config.name = "LLVM" # testFormat: The test format to use to interpret tests. -config.test_format = lit.formats.ShTest(not llvm_config.use_lit_shell) +extra_substitutions = extra_substitutions = ( +[ +(r"\| not FileCheck .*", "| tee /dev/null"), +(r"\| FileCheck .*", "| tee /dev/null"), +] +if config.enable_profcheck +else [] +) +config.test_format = lit.formats.ShTest( +not llvm_config.use_lit_shell, extra_substitutions +) # suffixes: A list of file extensions to treat as test files. This is overriden # by individual lit.local.cfg files in the test subdirectories. @@ -278,6 +288,7 @@ def get_asan_rtlib(): ] ) + # Find (major, minor) version of ptxas def ptxas_version(ptxas): ptxas_cmd = subprocess.Popen([ptxas, "--version"], stdout=subprocess.PIPE) @@ -602,7 +613,6 @@ def host_unwind_supports_jit(): # compact-unwind only, and JIT'd registration is not available before # macOS 14.0. if platform.system() == "Darwin": - assert "arm64" in config.host_triple or "x86_64" in config.host_triple if "x86_64" in config.host_triple: ___ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] Ignore FileCheck when profcheck is enabled (PR #151214)
https://github.com/mtrofin updated https://github.com/llvm/llvm-project/pull/151214 >From 60275ac82364dd936e5d35902c1bf9872d5371ef Mon Sep 17 00:00:00 2001 From: Mircea Trofin Date: Tue, 29 Jul 2025 12:55:59 -0700 Subject: [PATCH] fixes --- llvm/test/lit.cfg.py | 14 -- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/llvm/test/lit.cfg.py b/llvm/test/lit.cfg.py index 1d190fd20e573..43c7cf677a913 100644 --- a/llvm/test/lit.cfg.py +++ b/llvm/test/lit.cfg.py @@ -18,7 +18,17 @@ config.name = "LLVM" # testFormat: The test format to use to interpret tests. -config.test_format = lit.formats.ShTest(not llvm_config.use_lit_shell) +extra_substitutions = extra_substitutions = ( +[ +(r"\| not FileCheck .*", "| tee /dev/null"), +(r"\| FileCheck .*", "| tee /dev/null"), +] +if config.enable_profcheck +else [] +) +config.test_format = lit.formats.ShTest( +not llvm_config.use_lit_shell, extra_substitutions +) # suffixes: A list of file extensions to treat as test files. This is overriden # by individual lit.local.cfg files in the test subdirectories. @@ -278,6 +288,7 @@ def get_asan_rtlib(): ] ) + # Find (major, minor) version of ptxas def ptxas_version(ptxas): ptxas_cmd = subprocess.Popen([ptxas, "--version"], stdout=subprocess.PIPE) @@ -602,7 +613,6 @@ def host_unwind_supports_jit(): # compact-unwind only, and JIT'd registration is not available before # macOS 14.0. if platform.system() == "Darwin": - assert "arm64" in config.host_triple or "x86_64" in config.host_triple if "x86_64" in config.host_triple: ___ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [NFC] test/lit.cfg.py formatting (PR #151218)
https://github.com/mtrofin updated
https://github.com/llvm/llvm-project/pull/151218
>From 9e08971351e80d1af1f861364a7cbc3ed028457e Mon Sep 17 00:00:00 2001
From: Mircea Trofin
Date: Tue, 29 Jul 2025 13:01:10 -0700
Subject: [PATCH] [NFC] test/lit.cfg.py formatting
---
llvm/test/lit.cfg.py | 11 +--
1 file changed, 5 insertions(+), 6 deletions(-)
diff --git a/llvm/test/lit.cfg.py b/llvm/test/lit.cfg.py
index 143cc3817bd08..1d190fd20e573 100644
--- a/llvm/test/lit.cfg.py
+++ b/llvm/test/lit.cfg.py
@@ -451,7 +451,7 @@ def version_int(ver):
"%llvmdylib",
"{}/libLLVM{}.{}".format(
config.llvm_shlib_dir, config.llvm_shlib_ext,
config.llvm_dylib_version
-)
+),
)
)
@@ -582,6 +582,7 @@ def have_ld64_plugin_support():
if have_ld64_plugin_support():
config.available_features.add("ld64_plugin")
+
def host_unwind_supports_jit():
# Do we expect the host machine to support JIT registration of clang's
# default unwind info format for the host (e.g. eh-frames, compact-unwind,
@@ -589,7 +590,7 @@ def host_unwind_supports_jit():
# Linux and the BSDs use DWARF eh-frames and all known unwinders support
# register_frame at minimum.
-if platform.system() in [ "Linux", "FreeBSD", "NetBSD" ]:
+if platform.system() in ["Linux", "FreeBSD", "NetBSD"]:
return True
# Windows does not support frame info without the ORC runtime.
@@ -602,10 +603,7 @@ def host_unwind_supports_jit():
# macOS 14.0.
if platform.system() == "Darwin":
-assert (
-"arm64" in config.host_triple
-or "x86_64" in config.host_triple
-)
+assert "arm64" in config.host_triple or "x86_64" in config.host_triple
if "x86_64" in config.host_triple:
return True
@@ -627,6 +625,7 @@ def host_unwind_supports_jit():
return False
+
if host_unwind_supports_jit():
config.available_features.add("host-unwind-supports-jit")
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [BOLT] Factor out MCInstReference from gadget scanner (PR #138655)
https://github.com/atrosinenko edited https://github.com/llvm/llvm-project/pull/138655 ___ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [BOLT] Factor out MCInstReference from gadget scanner (NFC) (PR #138655)
https://github.com/atrosinenko edited https://github.com/llvm/llvm-project/pull/138655 ___ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [libcxx] [libcxxabi] [llvm] release/21.x: [libc++][hardening] Introduce assertion semantics. (#149459) (PR #151095)
var-const wrote: @tru Friendly ping. :) Sorry for the nuisance -- I just want to make sure this patch doesn't miss the current RC deadline. https://github.com/llvm/llvm-project/pull/151095 ___ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
