Skip to content

Commit

Permalink
[BOLT] Skip optimization of functions with alt instructions (llvm#95172)
Browse files Browse the repository at this point in the history
Alternative instructions in the Linux kernel may modify control flow in
a function. As such, it is unsafe to optimize functions with alternative
instructions until we properly support CFG alternatives.

Previously, we marked functions with alt instructions before the
emission, but that could be too late if we remove or replace
instructions with alternatives. We could have marked functions as
non-simple immediately after reading .altinstructions, but it's nice to
be able to view functions after CFG is built. Thus assign the non-simple
status after building CFG.
  • Loading branch information
maksfb authored Jun 18, 2024
1 parent 0863bd8 commit ad2905e
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 15 deletions.
16 changes: 7 additions & 9 deletions bolt/lib/Rewrite/LinuxKernelRewriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -273,9 +273,9 @@ class LinuxKernelRewriter final : public MetadataRewriter {

/// Handle alternative instruction info from .altinstructions.
Error readAltInstructions();
void processAltInstructionsPostCFG();
Error tryReadAltInstructions(uint32_t AltInstFeatureSize,
bool AltInstHasPadLen, bool ParseOnly);
Error rewriteAltInstructions();

/// Read .pci_fixup
Error readPCIFixupTable();
Expand Down Expand Up @@ -326,6 +326,8 @@ class LinuxKernelRewriter final : public MetadataRewriter {
if (Error E = processORCPostCFG())
return E;

processAltInstructionsPostCFG();

return Error::success();
}

Expand All @@ -335,9 +337,6 @@ class LinuxKernelRewriter final : public MetadataRewriter {
if (Error E = rewriteExceptionTable())
return E;

if (Error E = rewriteAltInstructions())
return E;

if (Error E = rewriteParaInstructions())
return E;

Expand Down Expand Up @@ -1486,12 +1485,11 @@ Error LinuxKernelRewriter::tryReadAltInstructions(uint32_t AltInstFeatureSize,
return Error::success();
}

Error LinuxKernelRewriter::rewriteAltInstructions() {
// Disable output of functions with alt instructions before the rewrite
// support is complete.
void LinuxKernelRewriter::processAltInstructionsPostCFG() {
// Disable optimization and output of functions with alt instructions before
// the rewrite support is complete. Alt instructions can modify the control
// flow, hence we may end up deleting seemingly unreachable code.
skipFunctionsWithAnnotation("AltInst");

return Error::success();
}

/// When the Linux kernel needs to handle an error associated with a given PCI
Expand Down
12 changes: 6 additions & 6 deletions bolt/test/X86/linux-alt-instruction.s
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-unknown %s -o %t.o
# RUN: %clang %cflags -nostdlib %t.o -o %t.exe \
# RUN: -Wl,--image-base=0xffffffff80000000,--no-dynamic-linker,--no-eh-frame-hdr,--no-pie
# RUN: llvm-bolt %t.exe --print-normalized --alt-inst-feature-size=2 -o %t.out \
# RUN: llvm-bolt %t.exe --print-cfg --alt-inst-feature-size=2 -o %t.out \
# RUN: | FileCheck %s

## Older kernels used to have padlen field in alt_instr. Check compatibility.
Expand All @@ -15,7 +15,7 @@
# RUN: %s -o %t.padlen.o
# RUN: %clang %cflags -nostdlib %t.padlen.o -o %t.padlen.exe \
# RUN: -Wl,--image-base=0xffffffff80000000,--no-dynamic-linker,--no-eh-frame-hdr,--no-pie
# RUN: llvm-bolt %t.padlen.exe --print-normalized --alt-inst-has-padlen -o %t.padlen.out \
# RUN: llvm-bolt %t.padlen.exe --print-cfg --alt-inst-has-padlen -o %t.padlen.out \
# RUN: | FileCheck %s

## Check with a larger size of "feature" field in alt_instr.
Expand All @@ -24,7 +24,7 @@
# RUN: --defsym FEATURE_SIZE_4=1 %s -o %t.fs4.o
# RUN: %clang %cflags -nostdlib %t.fs4.o -o %t.fs4.exe \
# RUN: -Wl,--image-base=0xffffffff80000000,--no-dynamic-linker,--no-eh-frame-hdr,--no-pie
# RUN: llvm-bolt %t.fs4.exe --print-normalized --alt-inst-feature-size=4 -o %t.fs4.out \
# RUN: llvm-bolt %t.fs4.exe --print-cfg --alt-inst-feature-size=4 -o %t.fs4.out \
# RUN: | FileCheck %s

## Check that out-of-bounds read is handled properly.
Expand All @@ -33,9 +33,9 @@

## Check that BOLT automatically detects structure fields in .altinstructions.

# RUN: llvm-bolt %t.exe --print-normalized -o %t.out | FileCheck %s
# RUN: llvm-bolt %t.exe --print-normalized -o %t.padlen.out | FileCheck %s
# RUN: llvm-bolt %t.exe --print-normalized -o %t.fs4.out | FileCheck %s
# RUN: llvm-bolt %t.exe --print-cfg -o %t.out | FileCheck %s
# RUN: llvm-bolt %t.exe --print-cfg -o %t.padlen.out | FileCheck %s
# RUN: llvm-bolt %t.exe --print-cfg -o %t.fs4.out | FileCheck %s

# CHECK: BOLT-INFO: Linux kernel binary detected
# CHECK: BOLT-INFO: parsed 2 alternative instruction entries
Expand Down

0 comments on commit ad2905e

Please sign in to comment.