Skip to content

Commit 4610bf5

Browse files
committed
Merge branch 'main' into ckoparkar/161036
* main: (63 commits) [libc++] Inline vector::__append into resize (llvm#162086) [Flang][OpenMP] Move char box bounds generation for Maps to DirectiveCommons.h (llvm#165918) RuntimeLibcalls: Add entries for vector sincospi functions (llvm#166981) [X86] _mm_addsub_pd is not valid for constexpr (llvm#167363) [CIR] Re-land: Recognize constant aggregate initialization of auto vars (llvm#167033) [gn build] Port d2521f1 [gn build] Port caed089 [gn build] Port 315d705 [gn build] Port 2345b7d [PowerPC] convert memmove to milicode call .___memmove64[PR] in 64-bit mode (llvm#167334) [HLSL] Add internal linkage attribute to resources (llvm#166844) AMDGPU: Update test after e95f6fa [bazel] Port llvm#166980: TLI/VectorLibrary refactor (llvm#167354) [libc++] Split macros related to hardening into their own header (llvm#167069) [libc++][NFC] Remove unused imports from generate_feature_test_macro_components.py (llvm#159591) [CIR][NFC] Add test for Complex imag with GUN extension (llvm#167215) [BOLT][AArch64] Add more heuristics on epilogue determination (llvm#167077) RegisterCoalescer: Enable terminal rule by default for AMDGPU (llvm#161621) Revert "[clang] Refactor option-related code from clangDriver into new clangOptions library" (llvm#167348) [libc++][docs] Update to refer to P3355R2 (llvm#167267) ...
2 parents b3579ab + 0d97f43 commit 4610bf5

File tree

292 files changed

+12003
-13084
lines changed

Some content is hidden

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

292 files changed

+12003
-13084
lines changed

.github/workflows/build-ci-container-tooling.yml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@ jobs:
3636
test-command: 'cd $HOME && clang-format --version | grep version && git-clang-format -h | grep usage && black --version | grep black'
3737
- container-name: lint
3838
test-command: 'cd $HOME && clang-tidy --version | grep version && clang-tidy-diff.py -h | grep usage'
39+
- container-name: abi-tests
40+
test-command: 'cd $HOME && abi-compliance-checker --help'
41+
target: abi-tests
3942
steps:
4043
- name: Checkout LLVM
4144
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
@@ -52,7 +55,7 @@ jobs:
5255
with:
5356
container-name: ci-ubuntu-24.04-${{ matrix.container-name }}
5457
dockerfile: .github/workflows/containers/github-action-ci-tooling/Dockerfile
55-
target: ci-container-code-${{ matrix.container-name }}
58+
target: ci-container-${{ matrix.target || format('code-{0}', matrix.container-name) }}
5659
test-command: ${{ matrix.test-command }}
5760

5861
push-ci-container:

.github/workflows/containers/github-action-ci-tooling/Dockerfile

Lines changed: 42 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,28 @@ RUN echo '%sudo ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers
4747
# as root in 'ci-container-code-format' and 'ci-container-code-lint' containers
4848

4949

50+
FROM base AS ci-container-build-tools
51+
ARG LLVM_VERSION
52+
ARG LLVM_VERSION_MAJOR
53+
54+
COPY --from=llvm-downloader /llvm-extract/LLVM-${LLVM_VERSION}-Linux-X64/bin/clang-${LLVM_VERSION_MAJOR} \
55+
${LLVM_SYSROOT}/bin/
56+
COPY --from=llvm-downloader /llvm-extract/LLVM-${LLVM_VERSION}-Linux-X64/lib/clang/${LLVM_VERSION_MAJOR}/include \
57+
${LLVM_SYSROOT}/lib/clang/${LLVM_VERSION_MAJOR}/include
58+
RUN ln -s ${LLVM_SYSROOT}/bin/clang-${LLVM_VERSION_MAJOR} ${LLVM_SYSROOT}/bin/clang && \
59+
ln -s ${LLVM_SYSROOT}/bin/clang ${LLVM_SYSROOT}/bin/clang++
60+
61+
RUN apt-get update && \
62+
DEBIAN_FRONTEND=noninteractive apt-get install -y \
63+
cmake \
64+
ninja-build && \
65+
apt-get clean && \
66+
rm -rf /var/lib/apt/lists/*
67+
68+
ENV CC=${LLVM_SYSROOT}/bin/clang
69+
ENV CXX=${LLVM_SYSROOT}/bin/clang++
70+
71+
5072
FROM base AS ci-container-code-format
5173
ARG LLVM_VERSION
5274

@@ -63,31 +85,37 @@ USER gha
6385
WORKDIR /home/gha
6486

6587

66-
FROM base AS ci-container-code-lint
88+
FROM ci-container-build-tools AS ci-container-code-lint
6789
ARG LLVM_VERSION
6890
ARG LLVM_VERSION_MAJOR
6991

7092
COPY --from=llvm-downloader /llvm-extract/LLVM-${LLVM_VERSION}-Linux-X64/bin/clang-tidy \
71-
/llvm-extract/LLVM-${LLVM_VERSION}-Linux-X64/bin/clang-${LLVM_VERSION_MAJOR} \
7293
${LLVM_SYSROOT}/bin/
73-
COPY --from=llvm-downloader /llvm-extract/LLVM-${LLVM_VERSION}-Linux-X64/lib/clang/${LLVM_VERSION_MAJOR}/include \
74-
${LLVM_SYSROOT}/lib/clang/${LLVM_VERSION_MAJOR}/include
7594
COPY clang-tools-extra/clang-tidy/tool/clang-tidy-diff.py ${LLVM_SYSROOT}/bin/clang-tidy-diff.py
7695

77-
RUN ln -s ${LLVM_SYSROOT}/bin/clang-${LLVM_VERSION_MAJOR} ${LLVM_SYSROOT}/bin/clang && \
78-
ln -s ${LLVM_SYSROOT}/bin/clang ${LLVM_SYSROOT}/bin/clang++
96+
# Install dependencies for 'pr-code-lint.yml' job
97+
COPY llvm/utils/git/requirements_linting.txt requirements_linting.txt
98+
RUN pip install -r requirements_linting.txt --break-system-packages && \
99+
rm requirements_linting.txt
100+
USER gha
101+
WORKDIR /home/gha
102+
79103

104+
FROM ci-container-build-tools as ci-container-abi-tests
80105

81106
RUN apt-get update && \
82107
DEBIAN_FRONTEND=noninteractive apt-get install -y \
83-
cmake \
84-
ninja-build && \
108+
abi-compliance-checker \
109+
abi-dumper \
110+
autoconf \
111+
pkg-config && \
85112
apt-get clean && \
86113
rm -rf /var/lib/apt/lists/*
87114

88-
# Install dependencies for 'pr-code-lint.yml' job
89-
COPY llvm/utils/git/requirements_linting.txt requirements_linting.txt
90-
RUN pip install -r requirements_linting.txt --break-system-packages && \
91-
rm requirements_linting.txt
92-
USER gha
93-
WORKDIR /home/gha
115+
RUN git clone https://github.com/universal-ctags/ctags.git && \
116+
cd ctags && \
117+
./autogen.sh && \
118+
./configure && \
119+
sudo make install && \
120+
rm -Rf ../ctags
121+

bolt/include/bolt/Core/MCPlusBuilder.h

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -784,6 +784,11 @@ class MCPlusBuilder {
784784

785785
virtual bool isPop(const MCInst &Inst) const { return false; }
786786

787+
/// Determine if a basic block looks like an epilogue. For now it is only
788+
/// called at the final stage of building CFG to check basic block ending
789+
/// with an indirect call that has unknown control flow attribute.
790+
virtual bool isEpilogue(const BinaryBasicBlock &BB) const { return false; }
791+
787792
/// Return true if the instruction is used to terminate an indirect branch.
788793
virtual bool isTerminateBranch(const MCInst &Inst) const {
789794
llvm_unreachable("not implemented");
@@ -1371,20 +1376,13 @@ class MCPlusBuilder {
13711376
/// Return true if \p Inst has RestoreState annotation.
13721377
bool hasRestoreState(const MCInst &Inst) const;
13731378

1374-
/// Stores RA Signed annotation on \p Inst.
1375-
void setRASigned(MCInst &Inst) const;
1376-
1377-
/// Return true if \p Inst has Signed RA annotation.
1378-
bool isRASigned(const MCInst &Inst) const;
1379-
1380-
/// Stores RA Unsigned annotation on \p Inst.
1381-
void setRAUnsigned(MCInst &Inst) const;
1382-
1383-
/// Return true if \p Inst has Unsigned RA annotation.
1384-
bool isRAUnsigned(const MCInst &Inst) const;
1379+
/// Sets kRASigned or kRAUnsigned annotation on \p Inst.
1380+
/// Fails if \p Inst has either annotation already set.
1381+
void setRAState(MCInst &Inst, bool State) const;
13851382

1386-
/// Return true if \p Inst doesn't have any annotation related to RA state.
1387-
bool isRAStateUnknown(const MCInst &Inst) const;
1383+
/// Return true if \p Inst has kRASigned annotation, false if it has
1384+
/// kRAUnsigned annotation, and std::nullopt if neither annotation is set.
1385+
std::optional<bool> getRAState(const MCInst &Inst) const;
13881386

13891387
/// Return true if the instruction is a call with an exception handling info.
13901388
virtual bool isInvoke(const MCInst &Inst) const {

bolt/lib/Core/BinaryFunction.cpp

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2167,13 +2167,10 @@ bool BinaryFunction::postProcessIndirectBranches(
21672167
continue;
21682168
}
21692169

2170-
// If this block contains an epilogue code and has an indirect branch,
2171-
// then most likely it's a tail call. Otherwise, we cannot tell for sure
2172-
// what it is and conservatively reject the function's CFG.
2173-
bool IsEpilogue = llvm::any_of(BB, [&](const MCInst &Instr) {
2174-
return BC.MIB->isLeave(Instr) || BC.MIB->isPop(Instr);
2175-
});
2176-
if (IsEpilogue) {
2170+
// If this block contains epilogue code and has an indirect branch,
2171+
// then most likely it's a tail call. Otherwise, we cannot tell for
2172+
// sure what it is and conservatively reject the function's CFG.
2173+
if (BC.MIB->isEpilogue(BB)) {
21772174
BC.MIB->convertJmpToTailCall(Instr);
21782175
BB.removeAllSuccessors();
21792176
continue;

bolt/lib/Core/MCPlusBuilder.cpp

Lines changed: 11 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -186,26 +186,21 @@ bool MCPlusBuilder::hasRestoreState(const MCInst &Inst) const {
186186
return hasAnnotation(Inst, MCAnnotation::kRestoreState);
187187
}
188188

189-
void MCPlusBuilder::setRASigned(MCInst &Inst) const {
189+
void MCPlusBuilder::setRAState(MCInst &Inst, bool State) const {
190190
assert(!hasAnnotation(Inst, MCAnnotation::kRASigned));
191-
setAnnotationOpValue(Inst, MCAnnotation::kRASigned, true);
192-
}
193-
194-
bool MCPlusBuilder::isRASigned(const MCInst &Inst) const {
195-
return hasAnnotation(Inst, MCAnnotation::kRASigned);
196-
}
197-
198-
void MCPlusBuilder::setRAUnsigned(MCInst &Inst) const {
199191
assert(!hasAnnotation(Inst, MCAnnotation::kRAUnsigned));
200-
setAnnotationOpValue(Inst, MCAnnotation::kRAUnsigned, true);
192+
if (State)
193+
setAnnotationOpValue(Inst, MCAnnotation::kRASigned, true);
194+
else
195+
setAnnotationOpValue(Inst, MCAnnotation::kRAUnsigned, true);
201196
}
202197

203-
bool MCPlusBuilder::isRAUnsigned(const MCInst &Inst) const {
204-
return hasAnnotation(Inst, MCAnnotation::kRAUnsigned);
205-
}
206-
207-
bool MCPlusBuilder::isRAStateUnknown(const MCInst &Inst) const {
208-
return !(isRAUnsigned(Inst) || isRASigned(Inst));
198+
std::optional<bool> MCPlusBuilder::getRAState(const MCInst &Inst) const {
199+
if (hasAnnotation(Inst, MCAnnotation::kRASigned))
200+
return true;
201+
if (hasAnnotation(Inst, MCAnnotation::kRAUnsigned))
202+
return false;
203+
return std::nullopt;
209204
}
210205

211206
std::optional<MCLandingPad> MCPlusBuilder::getEHInfo(const MCInst &Inst) const {

bolt/lib/Passes/InsertNegateRAStatePass.cpp

Lines changed: 39 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,12 @@ using namespace llvm;
2121
namespace llvm {
2222
namespace bolt {
2323

24+
static bool PassFailed = false;
25+
2426
void InsertNegateRAState::runOnFunction(BinaryFunction &BF) {
27+
if (PassFailed)
28+
return;
29+
2530
BinaryContext &BC = BF.getBinaryContext();
2631

2732
if (BF.getState() == BinaryFunction::State::Empty)
@@ -39,26 +44,31 @@ void InsertNegateRAState::runOnFunction(BinaryFunction &BF) {
3944
for (FunctionFragment &FF : BF.getLayout().fragments()) {
4045
coverFunctionFragmentStart(BF, FF);
4146
bool FirstIter = true;
42-
MCInst PrevInst;
47+
bool PrevRAState = false;
4348
// As this pass runs after function splitting, we should only check
4449
// consecutive instructions inside FunctionFragments.
4550
for (BinaryBasicBlock *BB : FF) {
4651
for (auto It = BB->begin(); It != BB->end(); ++It) {
4752
MCInst &Inst = *It;
4853
if (BC.MIB->isCFI(Inst))
4954
continue;
55+
auto RAState = BC.MIB->getRAState(Inst);
56+
if (!RAState) {
57+
BC.errs() << "BOLT-ERROR: unknown RAState after inferUnknownStates "
58+
<< " in function " << BF.getPrintName() << "\n";
59+
PassFailed = true;
60+
return;
61+
}
5062
if (!FirstIter) {
5163
// Consecutive instructions with different RAState means we need to
5264
// add a OpNegateRAState.
53-
if ((BC.MIB->isRASigned(PrevInst) && BC.MIB->isRAUnsigned(Inst)) ||
54-
(BC.MIB->isRAUnsigned(PrevInst) && BC.MIB->isRASigned(Inst))) {
65+
if (*RAState != PrevRAState)
5566
It = BF.addCFIInstruction(
5667
BB, It, MCCFIInstruction::createNegateRAState(nullptr));
57-
}
5868
} else {
5969
FirstIter = false;
6070
}
61-
PrevInst = *It;
71+
PrevRAState = *RAState;
6272
}
6373
}
6474
}
@@ -81,10 +91,17 @@ void InsertNegateRAState::coverFunctionFragmentStart(BinaryFunction &BF,
8191
});
8292
// If a function is already split in the input, the first FF can also start
8393
// with Signed state. This covers that scenario as well.
84-
if (BC.MIB->isRASigned(*((*FirstNonEmpty)->begin()))) {
85-
BF.addCFIInstruction(*FirstNonEmpty, (*FirstNonEmpty)->begin(),
86-
MCCFIInstruction::createNegateRAState(nullptr));
94+
auto II = (*FirstNonEmpty)->getFirstNonPseudo();
95+
auto RAState = BC.MIB->getRAState(*II);
96+
if (!RAState) {
97+
BC.errs() << "BOLT-ERROR: unknown RAState after inferUnknownStates "
98+
<< " in function " << BF.getPrintName() << "\n";
99+
PassFailed = true;
100+
return;
87101
}
102+
if (*RAState)
103+
BF.addCFIInstruction(*FirstNonEmpty, II,
104+
MCCFIInstruction::createNegateRAState(nullptr));
88105
}
89106

90107
void InsertNegateRAState::inferUnknownStates(BinaryFunction &BF) {
@@ -96,15 +113,21 @@ void InsertNegateRAState::inferUnknownStates(BinaryFunction &BF) {
96113
if (BC.MIB->isCFI(Inst))
97114
continue;
98115

99-
if (!FirstIter && BC.MIB->isRAStateUnknown(Inst)) {
100-
if (BC.MIB->isRASigned(PrevInst) || BC.MIB->isPSignOnLR(PrevInst)) {
101-
BC.MIB->setRASigned(Inst);
102-
} else if (BC.MIB->isRAUnsigned(PrevInst) ||
103-
BC.MIB->isPAuthOnLR(PrevInst)) {
104-
BC.MIB->setRAUnsigned(Inst);
116+
auto RAState = BC.MIB->getRAState(Inst);
117+
if (!FirstIter && !RAState) {
118+
if (BC.MIB->isPSignOnLR(PrevInst))
119+
RAState = true;
120+
else if (BC.MIB->isPAuthOnLR(PrevInst))
121+
RAState = false;
122+
else {
123+
auto PrevRAState = BC.MIB->getRAState(PrevInst);
124+
RAState = PrevRAState ? *PrevRAState : false;
105125
}
126+
BC.MIB->setRAState(Inst, *RAState);
106127
} else {
107128
FirstIter = false;
129+
if (!RAState)
130+
BC.MIB->setRAState(Inst, BF.getInitialRAState());
108131
}
109132
PrevInst = Inst;
110133
}
@@ -135,6 +158,8 @@ Error InsertNegateRAState::runOnFunctions(BinaryContext &BC) {
135158
<< " functions "
136159
<< format("(%.2lf%%).\n", (100.0 * FunctionsModified) /
137160
BC.getBinaryFunctions().size());
161+
if (PassFailed)
162+
return createFatalBOLTError("");
138163
return Error::success();
139164
}
140165

bolt/lib/Passes/MarkRAStates.cpp

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -72,9 +72,6 @@ bool MarkRAStates::runOnFunction(BinaryFunction &BF) {
7272
BF.setIgnored();
7373
return false;
7474
}
75-
// The signing instruction itself is unsigned, the next will be
76-
// signed.
77-
BC.MIB->setRAUnsigned(Inst);
7875
} else if (BC.MIB->isPAuthOnLR(Inst)) {
7976
if (!RAState) {
8077
// RA authenticating instructions should only follow signed RA state.
@@ -86,15 +83,10 @@ bool MarkRAStates::runOnFunction(BinaryFunction &BF) {
8683
BF.setIgnored();
8784
return false;
8885
}
89-
// The authenticating instruction itself is signed, but the next will be
90-
// unsigned.
91-
BC.MIB->setRASigned(Inst);
92-
} else if (RAState) {
93-
BC.MIB->setRASigned(Inst);
94-
} else {
95-
BC.MIB->setRAUnsigned(Inst);
9686
}
9787

88+
BC.MIB->setRAState(Inst, RAState);
89+
9890
// Updating RAState. All updates are valid from the next instruction.
9991
// Because the same instruction can have remember and restore, the order
10092
// here is relevant. This is the reason to loop over Annotations instead

bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -164,11 +164,53 @@ class AArch64MCPlusBuilder : public MCPlusBuilder {
164164

165165
bool isPush(const MCInst &Inst) const override {
166166
return isStoreToStack(Inst);
167-
};
167+
}
168168

169169
bool isPop(const MCInst &Inst) const override {
170170
return isLoadFromStack(Inst);
171-
};
171+
}
172+
173+
// We look for instructions that load from stack or make stack pointer
174+
// adjustment, and assume the basic block is an epilogue if and only if
175+
// such instructions are present and also immediately precede the branch
176+
// instruction that ends the basic block.
177+
bool isEpilogue(const BinaryBasicBlock &BB) const override {
178+
if (BB.succ_size())
179+
return false;
180+
181+
bool SeenLoadFromStack = false;
182+
bool SeenStackPointerAdjustment = false;
183+
for (const MCInst &Instr : BB) {
184+
// Skip CFI pseudo instruction.
185+
if (isCFI(Instr))
186+
continue;
187+
188+
bool IsPop = isPop(Instr);
189+
// A load from stack instruction could do SP adjustment in pre-index or
190+
// post-index form, which we can skip to check for epilogue recognition
191+
// purpose.
192+
bool IsSPAdj = (isADD(Instr) || isMOVW(Instr)) &&
193+
Instr.getOperand(0).isReg() &&
194+
Instr.getOperand(0).getReg() == AArch64::SP;
195+
SeenLoadFromStack |= IsPop;
196+
SeenStackPointerAdjustment |= IsSPAdj;
197+
198+
if (!SeenLoadFromStack && !SeenStackPointerAdjustment)
199+
continue;
200+
if (IsPop || IsSPAdj || isPAuthOnLR(Instr))
201+
continue;
202+
if (isReturn(Instr))
203+
return true;
204+
if (isBranch(Instr))
205+
break;
206+
207+
// Any previously seen load from stack or stack adjustment instruction
208+
// is definitely not part of epilogue code sequence, so reset these two.
209+
SeenLoadFromStack = false;
210+
SeenStackPointerAdjustment = false;
211+
}
212+
return SeenLoadFromStack || SeenStackPointerAdjustment;
213+
}
172214

173215
void createCall(MCInst &Inst, const MCSymbol *Target,
174216
MCContext *Ctx) override {

bolt/lib/Target/X86/X86MCPlusBuilder.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,12 @@ class X86MCPlusBuilder : public MCPlusBuilder {
219219
return getPopSize(Inst) == 0 ? false : true;
220220
}
221221

222+
bool isEpilogue(const BinaryBasicBlock &BB) const override {
223+
return ::llvm::any_of(BB, [&](const MCInst &Instr) {
224+
return isLeave(Instr) || isPop(Instr);
225+
});
226+
}
227+
222228
bool isTerminateBranch(const MCInst &Inst) const override {
223229
return Inst.getOpcode() == X86::ENDBR32 || Inst.getOpcode() == X86::ENDBR64;
224230
}

0 commit comments

Comments
 (0)