Skip to content

Commit e7c692d

Browse files
SC llvm teamSC llvm team
SC llvm team
authored and
SC llvm team
committed
Merged main:cf128305bdada3ffb34054813a855d80b3948025 into amd-gfx:6b7061457387
Local branch amd-gfx 6b70614 Merged main:79a32609759af317a62184c2c7b1300263a336c8 into amd-gfx:aaa80328586e Remote branch main cf12830 [SDAG] Dont treat ISD::SHL as a uniform binary operator in `ShrinkDemandedOp` (llvm#92753)
2 parents 6b70614 + cf12830 commit e7c692d

File tree

347 files changed

+6351
-2882
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

347 files changed

+6351
-2882
lines changed

bolt/include/bolt/Core/BinaryContext.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -677,6 +677,9 @@ class BinaryContext {
677677
/// have an origin file name available.
678678
bool HasSymbolsWithFileName{false};
679679

680+
/// Does the binary have BAT section.
681+
bool HasBATSection{false};
682+
680683
/// Sum of execution count of all functions
681684
uint64_t SumExecutionCount{0};
682685

bolt/include/bolt/Passes/BinaryPasses.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include "bolt/Core/BinaryContext.h"
1717
#include "bolt/Core/BinaryFunction.h"
1818
#include "bolt/Core/DynoStats.h"
19+
#include "bolt/Profile/BoltAddressTranslation.h"
1920
#include "llvm/Support/CommandLine.h"
2021
#include <atomic>
2122
#include <set>
@@ -399,8 +400,11 @@ class PrintProfileStats : public BinaryFunctionPass {
399400
/// Prints a list of the top 100 functions sorted by a set of
400401
/// dyno stats categories.
401402
class PrintProgramStats : public BinaryFunctionPass {
403+
BoltAddressTranslation *BAT = nullptr;
404+
402405
public:
403-
explicit PrintProgramStats() : BinaryFunctionPass(false) {}
406+
explicit PrintProgramStats(BoltAddressTranslation *BAT = nullptr)
407+
: BinaryFunctionPass(false), BAT(BAT) {}
404408

405409
const char *getName() const override { return "print-stats"; }
406410
bool shouldPrint(const BinaryFunction &) const override { return false; }

bolt/include/bolt/Profile/DataAggregator.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#define BOLT_PROFILE_DATA_AGGREGATOR_H
1616

1717
#include "bolt/Profile/DataReader.h"
18+
#include "bolt/Profile/YAMLProfileWriter.h"
1819
#include "llvm/ADT/StringRef.h"
1920
#include "llvm/Support/Error.h"
2021
#include "llvm/Support/Program.h"
@@ -248,7 +249,7 @@ class DataAggregator : public DataReader {
248249
BinaryFunction *getBATParentFunction(const BinaryFunction &Func) const;
249250

250251
/// Retrieve the location name to be used for samples recorded in \p Func.
251-
StringRef getLocationName(const BinaryFunction &Func) const;
252+
static StringRef getLocationName(const BinaryFunction &Func, bool BAT);
252253

253254
/// Semantic actions - parser hooks to interpret parsed perf samples
254255
/// Register a sample (non-LBR mode), i.e. a new hit at \p Address
@@ -490,6 +491,8 @@ class DataAggregator : public DataReader {
490491
/// Parse the output generated by "perf buildid-list" to extract build-ids
491492
/// and return a file name matching a given \p FileBuildID.
492493
std::optional<StringRef> getFileNameForBuildID(StringRef FileBuildID);
494+
495+
friend class YAMLProfileWriter;
493496
};
494497
} // namespace bolt
495498
} // namespace llvm

bolt/lib/Core/BinaryContext.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1322,7 +1322,9 @@ void BinaryContext::processInterproceduralReferences() {
13221322
InterproceduralReferences) {
13231323
BinaryFunction &Function = *It.first;
13241324
uint64_t Address = It.second;
1325-
if (!Address || Function.isIgnored())
1325+
// Process interprocedural references from ignored functions in BAT mode
1326+
// (non-simple in non-relocation mode) to properly register entry points
1327+
if (!Address || (Function.isIgnored() && !HasBATSection))
13261328
continue;
13271329

13281330
BinaryFunction *TargetFunction =

bolt/lib/Core/BinaryFunction.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1666,7 +1666,8 @@ void BinaryFunction::postProcessEntryPoints() {
16661666
// In non-relocation mode there's potentially an external undetectable
16671667
// reference to the entry point and hence we cannot move this entry
16681668
// point. Optimizing without moving could be difficult.
1669-
if (!BC.HasRelocations)
1669+
// In BAT mode, register any known entry points for CFG construction.
1670+
if (!BC.HasRelocations && !BC.HasBATSection)
16701671
setSimple(false);
16711672

16721673
const uint32_t Offset = KV.first;

bolt/lib/Passes/BinaryPasses.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1390,9 +1390,19 @@ Error PrintProgramStats::runOnFunctions(BinaryContext &BC) {
13901390
if (Function.isPLTFunction())
13911391
continue;
13921392

1393+
// Adjustment for BAT mode: the profile for BOLT split fragments is combined
1394+
// so only count the hot fragment.
1395+
const uint64_t Address = Function.getAddress();
1396+
bool IsHotParentOfBOLTSplitFunction = !Function.getFragments().empty() &&
1397+
BAT && BAT->isBATFunction(Address) &&
1398+
!BAT->fetchParentAddress(Address);
1399+
13931400
++NumRegularFunctions;
13941401

1395-
if (!Function.isSimple()) {
1402+
// In BOLTed binaries split functions are non-simple (due to non-relocation
1403+
// mode), but the original function is known to be simple and we have a
1404+
// valid profile for it.
1405+
if (!Function.isSimple() && !IsHotParentOfBOLTSplitFunction) {
13961406
if (Function.hasProfile())
13971407
++NumNonSimpleProfiledFunctions;
13981408
continue;

bolt/lib/Profile/DataAggregator.cpp

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -613,7 +613,8 @@ Error DataAggregator::readProfile(BinaryContext &BC) {
613613
if (std::error_code EC = writeBATYAML(BC, opts::SaveProfile))
614614
report_error("cannot create output data file", EC);
615615
}
616-
BC.logBOLTErrorsAndQuitOnFatal(PrintProgramStats().runOnFunctions(BC));
616+
PrintProgramStats PPS(BAT);
617+
BC.logBOLTErrorsAndQuitOnFatal(PPS.runOnFunctions(BC));
617618
}
618619

619620
return Error::success();
@@ -673,7 +674,8 @@ DataAggregator::getBATParentFunction(const BinaryFunction &Func) const {
673674
return nullptr;
674675
}
675676

676-
StringRef DataAggregator::getLocationName(const BinaryFunction &Func) const {
677+
StringRef DataAggregator::getLocationName(const BinaryFunction &Func,
678+
bool BAT) {
677679
if (!BAT)
678680
return Func.getOneName();
679681

@@ -702,7 +704,7 @@ bool DataAggregator::doSample(BinaryFunction &OrigFunc, uint64_t Address,
702704
auto I = NamesToSamples.find(Func.getOneName());
703705
if (I == NamesToSamples.end()) {
704706
bool Success;
705-
StringRef LocName = getLocationName(Func);
707+
StringRef LocName = getLocationName(Func, BAT);
706708
std::tie(I, Success) = NamesToSamples.insert(
707709
std::make_pair(Func.getOneName(),
708710
FuncSampleData(LocName, FuncSampleData::ContainerTy())));
@@ -722,7 +724,7 @@ bool DataAggregator::doIntraBranch(BinaryFunction &Func, uint64_t From,
722724
FuncBranchData *AggrData = getBranchData(Func);
723725
if (!AggrData) {
724726
AggrData = &NamesToBranches[Func.getOneName()];
725-
AggrData->Name = getLocationName(Func);
727+
AggrData->Name = getLocationName(Func, BAT);
726728
setBranchData(Func, AggrData);
727729
}
728730

@@ -741,7 +743,7 @@ bool DataAggregator::doInterBranch(BinaryFunction *FromFunc,
741743
StringRef SrcFunc;
742744
StringRef DstFunc;
743745
if (FromFunc) {
744-
SrcFunc = getLocationName(*FromFunc);
746+
SrcFunc = getLocationName(*FromFunc, BAT);
745747
FromAggrData = getBranchData(*FromFunc);
746748
if (!FromAggrData) {
747749
FromAggrData = &NamesToBranches[FromFunc->getOneName()];
@@ -752,7 +754,7 @@ bool DataAggregator::doInterBranch(BinaryFunction *FromFunc,
752754
recordExit(*FromFunc, From, Mispreds, Count);
753755
}
754756
if (ToFunc) {
755-
DstFunc = getLocationName(*ToFunc);
757+
DstFunc = getLocationName(*ToFunc, BAT);
756758
ToAggrData = getBranchData(*ToFunc);
757759
if (!ToAggrData) {
758760
ToAggrData = &NamesToBranches[ToFunc->getOneName()];
@@ -2340,7 +2342,7 @@ std::error_code DataAggregator::writeBATYAML(BinaryContext &BC,
23402342
continue;
23412343
BinaryFunction *BF = BC.getBinaryFunctionAtAddress(FuncAddress);
23422344
assert(BF);
2343-
YamlBF.Name = getLocationName(*BF);
2345+
YamlBF.Name = getLocationName(*BF, BAT);
23442346
YamlBF.Id = BF->getFunctionNumber();
23452347
YamlBF.Hash = BAT->getBFHash(FuncAddress);
23462348
YamlBF.ExecCount = BF->getKnownExecutionCount();

bolt/lib/Profile/YAMLProfileWriter.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include "bolt/Core/BinaryBasicBlock.h"
1111
#include "bolt/Core/BinaryFunction.h"
1212
#include "bolt/Profile/BoltAddressTranslation.h"
13+
#include "bolt/Profile/DataAggregator.h"
1314
#include "bolt/Profile/ProfileReaderBase.h"
1415
#include "bolt/Rewrite/RewriteInstance.h"
1516
#include "llvm/Support/CommandLine.h"
@@ -39,6 +40,10 @@ const BinaryFunction *YAMLProfileWriter::setCSIDestination(
3940
BC.getFunctionForSymbol(Symbol, &EntryID)) {
4041
if (BAT && BAT->isBATFunction(Callee->getAddress()))
4142
std::tie(Callee, EntryID) = BAT->translateSymbol(BC, *Symbol, Offset);
43+
else if (const BinaryBasicBlock *BB =
44+
Callee->getBasicBlockContainingOffset(Offset))
45+
BC.getFunctionForSymbol(Callee->getSecondaryEntryPointSymbol(*BB),
46+
&EntryID);
4247
CSI.DestId = Callee->getFunctionNumber();
4348
CSI.EntryDiscriminator = EntryID;
4449
return Callee;
@@ -59,7 +64,7 @@ YAMLProfileWriter::convert(const BinaryFunction &BF, bool UseDFS,
5964
BF.computeHash(UseDFS);
6065
BF.computeBlockHashes();
6166

62-
YamlBF.Name = BF.getPrintName();
67+
YamlBF.Name = DataAggregator::getLocationName(BF, BAT);
6368
YamlBF.Id = BF.getFunctionNumber();
6469
YamlBF.Hash = BF.getHash();
6570
YamlBF.NumBasicBlocks = BF.size();

bolt/lib/Rewrite/RewriteInstance.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1988,6 +1988,7 @@ Error RewriteInstance::readSpecialSections() {
19881988

19891989
if (ErrorOr<BinarySection &> BATSec =
19901990
BC->getUniqueSectionByName(BoltAddressTranslation::SECTION_NAME)) {
1991+
BC->HasBATSection = true;
19911992
// Do not read BAT when plotting a heatmap
19921993
if (!opts::HeatmapMode) {
19931994
if (std::error_code EC = BAT->parse(BC->outs(), BATSec->getContents())) {

bolt/test/X86/bolt-address-translation-yaml.test

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@ RUN: perf2bolt %t.out --pa -p %p/Inputs/blarge_new_bat.preagg.txt -w %t.yaml -o
3131
RUN: 2>&1 | FileCheck --check-prefix READ-BAT-CHECK %s
3232
RUN: FileCheck --input-file %t.yaml --check-prefix YAML-BAT-CHECK %s
3333
# Check that YAML converted from fdata matches YAML created directly with BAT.
34-
RUN: llvm-bolt %t.exe -data %t.fdata -w %t.yaml-fdata -o /dev/null
34+
RUN: llvm-bolt %t.exe -data %t.fdata -w %t.yaml-fdata -o /dev/null \
35+
RUN: 2>&1 | FileCheck --check-prefix READ-BAT-FDATA-CHECK %s
3536
RUN: FileCheck --input-file %t.yaml-fdata --check-prefix YAML-BAT-CHECK %s
3637

3738
# Test resulting YAML profile with the original binary (no-stale mode)
@@ -45,6 +46,8 @@ WRITE-BAT-CHECK: BOLT-INFO: BAT section size (bytes): 384
4546
READ-BAT-CHECK-NOT: BOLT-ERROR: unable to save profile in YAML format for input file processed by BOLT
4647
READ-BAT-CHECK: BOLT-INFO: Parsed 5 BAT entries
4748
READ-BAT-CHECK: PERF2BOLT: read 79 aggregated LBR entries
49+
READ-BAT-CHECK: BOLT-INFO: 5 out of 21 functions in the binary (23.8%) have non-empty execution profile
50+
READ-BAT-FDATA-CHECK: BOLT-INFO: 5 out of 16 functions in the binary (31.2%) have non-empty execution profile
4851

4952
YAML-BAT-CHECK: functions:
5053
# Function not covered by BAT - has insns in basic block
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
# This reproduces a bug with not processing interprocedural references from
2+
# ignored functions.
3+
4+
# REQUIRES: system-linux
5+
6+
# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-unknown %s -o %t.o
7+
# RUN: %clang %cflags %t.o -o %t.exe -nostdlib -Wl,-q
8+
# RUN: llvm-bolt %t.exe -o %t.out --enable-bat -funcs=main
9+
# RUN: link_fdata %s %t.out %t.preagg PREAGG
10+
# RUN: perf2bolt %t.out -p %t.preagg --pa -o %t.fdata -w %t.yaml
11+
# RUN: FileCheck %s --input-file=%t.fdata --check-prefix=CHECK-FDATA
12+
# RUN: FileCheck %s --input-file=%t.yaml --check-prefix=CHECK-YAML
13+
14+
# CHECK-FDATA: 1 main 0 1 foo a 1 1
15+
# CHECK-YAML: name: main
16+
# CHECK-YAML: calls: {{.*}} disc: 1
17+
18+
# PREAGG: B #main# #foo_secondary# 1 1
19+
# main calls foo at valid instruction offset past nops that are to be stripped.
20+
.globl main
21+
main:
22+
.cfi_startproc
23+
call foo_secondary
24+
ret
25+
.cfi_endproc
26+
.size main,.-main
27+
28+
# Placeholder cold fragment to force main to be ignored in non-relocation mode.
29+
.globl main.cold
30+
main.cold:
31+
.cfi_startproc
32+
ud2
33+
.cfi_endproc
34+
.size main.cold,.-main.cold
35+
36+
# foo is set up to contain a valid instruction at called offset, and trapping
37+
# instructions past that.
38+
.globl foo
39+
foo:
40+
.cfi_startproc
41+
.nops 10
42+
.globl foo_secondary
43+
foo_secondary:
44+
ret
45+
.rept 20
46+
int3
47+
.endr
48+
.cfi_endproc
49+
.size foo,.-foo

bolt/test/X86/register-fragments-bolt-symbols.s

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,11 @@
1818
# RUN: FileCheck --input-file %t.bat.fdata --check-prefix=CHECK-FDATA %s
1919
# RUN: FileCheck --input-file %t.bat.yaml --check-prefix=CHECK-YAML %s
2020

21+
# RUN: link_fdata --no-redefine %s %t.bolt %t.preagg2 PREAGG2
22+
# PREAGG2: B X:0 #chain# 1 0
23+
# RUN: perf2bolt %t.bolt -p %t.preagg2 --pa -o %t.bat2.fdata -w %t.bat2.yaml
24+
# RUN: FileCheck %s --input-file %t.bat2.yaml --check-prefix=CHECK-YAML2
25+
2126
# CHECK-SYMS: l df *ABS* [[#]] chain.s
2227
# CHECK-SYMS: l F .bolt.org.text [[#]] chain
2328
# CHECK-SYMS: l F .text.cold [[#]] chain.cold.0
@@ -28,6 +33,9 @@
2833

2934
# CHECK-FDATA: 0 [unknown] 0 1 chain/chain.s/2 10 0 1
3035
# CHECK-YAML: - name: 'chain/chain.s/2'
36+
# CHECK-YAML2: - name: 'chain/chain.s/1'
37+
## non-BAT function has non-zero insns:
38+
# CHECK-YAML2: insns: 1
3139

3240
.file "chain.s"
3341
.text

bolt/test/link_fdata.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
parser.add_argument("prefix", nargs="?", default="FDATA", help="Custom FDATA prefix")
2020
parser.add_argument("--nmtool", default="nm", help="Path to nm tool")
2121
parser.add_argument("--no-lbr", action="store_true")
22+
parser.add_argument("--no-redefine", action="store_true")
2223

2324
args = parser.parse_args()
2425

@@ -90,6 +91,8 @@
9091
symbols = {}
9192
for symline in nm_output.splitlines():
9293
symval, _, symname = symline.split(maxsplit=2)
94+
if symname in symbols and args.no_redefine:
95+
continue
9396
symbols[symname] = symval
9497

9598

clang-tools-extra/clangd/unittests/FindTargetTests.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -836,7 +836,9 @@ TEST_F(TargetDeclTest, OverloadExpr) {
836836
[[delete]] x;
837837
}
838838
)cpp";
839-
EXPECT_DECLS("CXXDeleteExpr", "void operator delete(void *) noexcept");
839+
// Sized deallocation is enabled by default in C++14 onwards.
840+
EXPECT_DECLS("CXXDeleteExpr",
841+
"void operator delete(void *, unsigned long) noexcept");
840842
}
841843

842844
TEST_F(TargetDeclTest, DependentExprs) {

clang-tools-extra/test/clang-tidy/checkers/misc/new-delete-overloads.cpp

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,6 @@ struct S {
1212
// CHECK-MESSAGES: :[[@LINE+1]]:7: warning: declaration of 'operator new' has no matching declaration of 'operator delete' at the same scope
1313
void *operator new(size_t size) noexcept(false);
1414

15-
struct T {
16-
// Sized deallocations are not enabled by default, and so this new/delete pair
17-
// does not match. However, we expect only one warning, for the new, because
18-
// the operator delete is a placement delete and we do not warn on mismatching
19-
// placement operations.
20-
// CHECK-MESSAGES: :[[@LINE+1]]:9: warning: declaration of 'operator new' has no matching declaration of 'operator delete' at the same scope
21-
void *operator new(size_t size) noexcept;
22-
void operator delete(void *ptr, size_t) noexcept; // ok only if sized deallocation is enabled
23-
};
24-
2515
struct U {
2616
void *operator new(size_t size) noexcept;
2717
void operator delete(void *ptr) noexcept;

clang/docs/ReleaseNotes.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,11 @@ C++17 Feature Support
155155
files because they may not be stable across multiple TUs (the values may vary
156156
based on compiler version as well as CPU tuning). #GH60174
157157

158+
C++14 Feature Support
159+
^^^^^^^^^^^^^^^^^^^^^
160+
- Sized deallocation is enabled by default in C++14 onwards. The user may specify
161+
``-fno-sized-deallocation`` to disable it if there are some regressions.
162+
158163
C++20 Feature Support
159164
^^^^^^^^^^^^^^^^^^^^^
160165

clang/docs/analyzer/checkers.rst

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1179,6 +1179,47 @@ security.insecureAPI.DeprecatedOrUnsafeBufferHandling (C)
11791179
strncpy(buf, "a", 1); // warn
11801180
}
11811181
1182+
security.SetgidSetuidOrder (C)
1183+
""""""""""""""""""""""""""""""
1184+
When dropping user-level and group-level privileges in a program by using
1185+
``setuid`` and ``setgid`` calls, it is important to reset the group-level
1186+
privileges (with ``setgid``) first. Function ``setgid`` will likely fail if
1187+
the superuser privileges are already dropped.
1188+
1189+
The checker checks for sequences of ``setuid(getuid())`` and
1190+
``setgid(getgid())`` calls (in this order). If such a sequence is found and
1191+
there is no other privilege-changing function call (``seteuid``, ``setreuid``,
1192+
``setresuid`` and the GID versions of these) in between, a warning is
1193+
generated. The checker finds only exactly ``setuid(getuid())`` calls (and the
1194+
GID versions), not for example if the result of ``getuid()`` is stored in a
1195+
variable.
1196+
1197+
.. code-block:: c
1198+
1199+
void test1() {
1200+
// ...
1201+
// end of section with elevated privileges
1202+
// reset privileges (user and group) to normal user
1203+
if (setuid(getuid()) != 0) {
1204+
handle_error();
1205+
return;
1206+
}
1207+
if (setgid(getgid()) != 0) { // warning: A 'setgid(getgid())' call following a 'setuid(getuid())' call is likely to fail
1208+
handle_error();
1209+
return;
1210+
}
1211+
// user-ID and group-ID are reset to normal user now
1212+
// ...
1213+
}
1214+
1215+
In the code above the problem is that ``setuid(getuid())`` removes superuser
1216+
privileges before ``setgid(getgid())`` is called. To fix the problem the
1217+
``setgid(getgid())`` should be called first. Further attention is needed to
1218+
avoid code like ``setgid(getuid())`` (this checker does not detect bugs like
1219+
this) and always check the return value of these calls.
1220+
1221+
This check corresponds to SEI CERT Rule `POS36-C <https://wiki.sei.cmu.edu/confluence/display/c/POS36-C.+Observe+correct+revocation+order+while+relinquishing+privileges>`_.
1222+
11821223
.. _unix-checkers:
11831224
11841225
unix

0 commit comments

Comments
 (0)