Skip to content

Commit ea86400

Browse files
committed
Merge commit '56daf026ba60bc07599c05201db057eb8108caec' into llvmspirv_pulldown
2 parents 272bdd6 + 56daf02 commit ea86400

File tree

158 files changed

+5650
-2036
lines changed

Some content is hidden

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

158 files changed

+5650
-2036
lines changed

bolt/include/bolt/Core/BinaryFunction.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -319,10 +319,6 @@ class BinaryFunction {
319319
/// Execution halts whenever this function is entered.
320320
bool TrapsOnEntry{false};
321321

322-
/// True if the function had an indirect branch with a fixed internal
323-
/// destination.
324-
bool HasFixedIndirectBranch{false};
325-
326322
/// True if the function is a fragment of another function. This means that
327323
/// this function could only be entered via its parent or one of its sibling
328324
/// fragments. It could be entered at any basic block. It can also return

bolt/lib/Core/BinaryContext.cpp

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1926,10 +1926,27 @@ BinaryContext::getBaseAddressForMapping(uint64_t MMapAddress,
19261926
// Find a segment with a matching file offset.
19271927
for (auto &KV : SegmentMapInfo) {
19281928
const SegmentInfo &SegInfo = KV.second;
1929-
if (alignDown(SegInfo.FileOffset, SegInfo.Alignment) == FileOffset) {
1930-
// Use segment's aligned memory offset to calculate the base address.
1931-
const uint64_t MemOffset = alignDown(SegInfo.Address, SegInfo.Alignment);
1932-
return MMapAddress - MemOffset;
1929+
// FileOffset is got from perf event,
1930+
// and it is equal to alignDown(SegInfo.FileOffset, pagesize).
1931+
// If the pagesize is not equal to SegInfo.Alignment.
1932+
// FileOffset and SegInfo.FileOffset should be aligned first,
1933+
// and then judge whether they are equal.
1934+
if (alignDown(SegInfo.FileOffset, SegInfo.Alignment) ==
1935+
alignDown(FileOffset, SegInfo.Alignment)) {
1936+
// The function's offset from base address in VAS is aligned by pagesize
1937+
// instead of SegInfo.Alignment. Pagesize can't be got from perf events.
1938+
// However, The ELF document says that SegInfo.FileOffset should equal
1939+
// to SegInfo.Address, modulo the pagesize.
1940+
// Reference: https://refspecs.linuxfoundation.org/elf/elf.pdf
1941+
1942+
// So alignDown(SegInfo.Address, pagesize) can be calculated by:
1943+
// alignDown(SegInfo.Address, pagesize)
1944+
// = SegInfo.Address - (SegInfo.Address % pagesize)
1945+
// = SegInfo.Address - (SegInfo.FileOffset % pagesize)
1946+
// = SegInfo.Address - SegInfo.FileOffset +
1947+
// alignDown(SegInfo.FileOffset, pagesize)
1948+
// = SegInfo.Address - SegInfo.FileOffset + FileOffset
1949+
return MMapAddress - (SegInfo.Address - SegInfo.FileOffset + FileOffset);
19331950
}
19341951
}
19351952

bolt/lib/Core/BinaryFunction.cpp

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -432,8 +432,6 @@ void BinaryFunction::print(raw_ostream &OS, std::string Annotation) {
432432
OS << "\n IsSplit : " << isSplit();
433433
OS << "\n BB Count : " << size();
434434

435-
if (HasFixedIndirectBranch)
436-
OS << "\n HasFixedIndirectBranch : true";
437435
if (HasUnknownControlFlow)
438436
OS << "\n Unknown CF : true";
439437
if (getPersonalityFunction())
@@ -1118,7 +1116,7 @@ void BinaryFunction::handleIndirectBranch(MCInst &Instruction, uint64_t Size,
11181116
Instruction.clear();
11191117
MIB->createUncondBranch(Instruction, TargetSymbol, BC.Ctx.get());
11201118
TakenBranches.emplace_back(Offset, IndirectTarget - getAddress());
1121-
HasFixedIndirectBranch = true;
1119+
addEntryPointAtOffset(IndirectTarget - getAddress());
11221120
} else {
11231121
MIB->convertJmpToTailCall(Instruction);
11241122
BC.addInterproceduralReference(this, IndirectTarget);
@@ -1894,9 +1892,6 @@ bool BinaryFunction::postProcessIndirectBranches(
18941892
LastIndirectJumpBB->updateJumpTableSuccessors();
18951893
}
18961894

1897-
if (HasFixedIndirectBranch)
1898-
return false;
1899-
19001895
// Validate that all data references to function offsets are claimed by
19011896
// recognized jump tables. Register externally referenced blocks as entry
19021897
// points.
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
#include <stdio.h>
2+
#include <stdlib.h>
3+
#include <unistd.h>
4+
5+
int add(int a, int b) { return a + b; }
6+
int minus(int a, int b) { return a - b; }
7+
int multiple(int a, int b) { return a * b; }
8+
int divide(int a, int b) {
9+
if (b == 0)
10+
return 0;
11+
return a / b;
12+
}
13+
14+
int main() {
15+
int a = 16;
16+
int b = 8;
17+
18+
for (int i = 1; i < 100000; i++) {
19+
add(a, b);
20+
minus(a, b);
21+
multiple(a, b);
22+
divide(a, b);
23+
}
24+
25+
return 0;
26+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
SECTIONS {
2+
. = SIZEOF_HEADERS;
3+
.interp : { *(.interp) }
4+
.note.gnu.build-id : { *(.note.gnu.build-id) }
5+
. = 0x212e8;
6+
.dynsym : { *(.dynsym) }
7+
. = 0x31860;
8+
.text : { *(.text*) }
9+
. = 0x41c20;
10+
.fini_array : { *(.fini_array) }
11+
. = 0x54e18;
12+
.data : { *(.data) }
13+
}

bolt/test/perf2bolt/lit.local.cfg

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
import shutil
2+
3+
if shutil.which("perf") != None:
4+
config.available_features.add("perf")

bolt/test/perf2bolt/perf_test.test

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# Check perf2bolt binary function which was compiled with pie
2+
3+
REQUIRES: system-linux, perf
4+
5+
RUN: %clang %S/Inputs/perf_test.c -fuse-ld=lld -Wl,--script=%S/Inputs/perf_test.lds -o %t
6+
RUN: perf record -e cycles:u -o %t2 -- %t
7+
RUN: perf2bolt %t -p=%t2 -o %t3 -nl -ignore-build-id 2>&1 | FileCheck %s
8+
9+
CHECK-NOT: PERF2BOLT-ERROR
10+
CHECK-NOT: !! WARNING !! This high mismatch ratio indicates the input binary is probably not the same binary used during profiling collection.
11+
12+
RUN: %clang %S/Inputs/perf_test.c -no-pie -fuse-ld=lld -o %t4
13+
RUN: perf record -e cycles:u -o %t5 -- %t4
14+
RUN: perf2bolt %t4 -p=%t5 -o %t6 -nl -ignore-build-id 2>&1 | FileCheck %s --check-prefix=CHECK-NO-PIE
15+
16+
CHECK-NO-PIE-NOT: PERF2BOLT-ERROR
17+
CHECK-NO-PIE-NOT: !! WARNING !! This high mismatch ratio indicates the input binary is probably not the same binary used during profiling collection.

bolt/unittests/Core/BinaryContext.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,3 +123,24 @@ TEST_P(BinaryContextTester, BaseAddress) {
123123
BaseAddress = BC->getBaseAddressForMapping(0x7f13f5556000, 0x137a000);
124124
ASSERT_FALSE(BaseAddress.has_value());
125125
}
126+
127+
TEST_P(BinaryContextTester, BaseAddress2) {
128+
// Check that base address calculation is correct for a binary if the
129+
// alignment in ELF file are different from pagesize.
130+
// The segment layout is as follows:
131+
BC->SegmentMapInfo[0] = SegmentInfo{0, 0x2177c, 0, 0x2177c, 0x10000};
132+
BC->SegmentMapInfo[0x31860] =
133+
SegmentInfo{0x31860, 0x370, 0x21860, 0x370, 0x10000};
134+
BC->SegmentMapInfo[0x41c20] =
135+
SegmentInfo{0x41c20, 0x1f8, 0x21c20, 0x1f8, 0x10000};
136+
BC->SegmentMapInfo[0x54e18] =
137+
SegmentInfo{0x54e18, 0x51, 0x24e18, 0x51, 0x10000};
138+
139+
std::optional<uint64_t> BaseAddress =
140+
BC->getBaseAddressForMapping(0xaaaaea444000, 0x21000);
141+
ASSERT_TRUE(BaseAddress.has_value());
142+
ASSERT_EQ(*BaseAddress, 0xaaaaea413000ULL);
143+
144+
BaseAddress = BC->getBaseAddressForMapping(0xaaaaea444000, 0x11000);
145+
ASSERT_FALSE(BaseAddress.has_value());
146+
}

clang-tools-extra/clang-tidy/bugprone/AssertSideEffectCheck.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,18 @@ AST_MATCHER_P2(Expr, hasSideEffect, bool, CheckFunctionCalls,
4141
}
4242

4343
if (const auto *OpCallExpr = dyn_cast<CXXOperatorCallExpr>(E)) {
44+
if (const auto *MethodDecl =
45+
dyn_cast_or_null<CXXMethodDecl>(OpCallExpr->getDirectCallee()))
46+
if (MethodDecl->isConst())
47+
return false;
48+
4449
OverloadedOperatorKind OpKind = OpCallExpr->getOperator();
4550
return OpKind == OO_Equal || OpKind == OO_PlusEqual ||
4651
OpKind == OO_MinusEqual || OpKind == OO_StarEqual ||
4752
OpKind == OO_SlashEqual || OpKind == OO_AmpEqual ||
4853
OpKind == OO_PipeEqual || OpKind == OO_CaretEqual ||
4954
OpKind == OO_LessLessEqual || OpKind == OO_GreaterGreaterEqual ||
55+
OpKind == OO_LessLess || OpKind == OO_GreaterGreater ||
5056
OpKind == OO_PlusPlus || OpKind == OO_MinusMinus ||
5157
OpKind == OO_PercentEqual || OpKind == OO_New ||
5258
OpKind == OO_Delete || OpKind == OO_Array_New ||

clang-tools-extra/docs/ReleaseNotes.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,11 @@ Changes in existing checks
212212
<clang-tidy/checks/abseil/string-find-startswith>` check to also consider
213213
``std::basic_string_view`` in addition to ``std::basic_string`` by default.
214214

215+
- Improved :doc:`bugprone-assert-side-effect
216+
<clang-tidy/checks/bugprone/assert-side-effect>` check to report usage of
217+
non-const ``<<`` and ``>>`` operators in assertions and fixed some false-positives
218+
with const operators.
219+
215220
- Improved :doc:`bugprone-dangling-handle
216221
<clang-tidy/checks/bugprone/dangling-handle>` check to support functional
217222
casting during type conversions at variable initialization, now with improved

0 commit comments

Comments
 (0)