Skip to content

Commit

Permalink
Re-commit r301040 "X86: Don't emit zero-byte functions on Windows"
Browse files Browse the repository at this point in the history
In addition to the original commit, tighten the condition for when to
pad empty functions to COFF Windows.  This avoids running into problems
when targeting e.g. Win32 AMDGPU, which caused test failures when this
was committed initially.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@301047 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
zmodem committed Apr 21, 2017
1 parent 94f347b commit 960a40e
Show file tree
Hide file tree
Showing 18 changed files with 55 additions and 36 deletions.
2 changes: 1 addition & 1 deletion include/llvm/Target/TargetInstrInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -1108,7 +1108,7 @@ class TargetInstrInfo : public MCInstrInfo {


/// Return the noop instruction to use for a noop.
virtual void getNoopForMachoTarget(MCInst &NopInst) const;
virtual void getNoop(MCInst &NopInst) const;

/// Return true for post-incremented instructions.
virtual bool isPostIncrement(const MachineInstr &MI) const {
Expand Down
17 changes: 10 additions & 7 deletions lib/CodeGen/AsmPrinter/AsmPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1046,15 +1046,18 @@ void AsmPrinter::EmitFunctionBody() {
// If the function is empty and the object file uses .subsections_via_symbols,
// then we need to emit *something* to the function body to prevent the
// labels from collapsing together. Just emit a noop.
if ((MAI->hasSubsectionsViaSymbols() && !HasAnyRealCode)) {
// Similarly, don't emit empty functions on Windows either. It can lead to
// duplicate entries (two functions with the same RVA) in the Guard CF Table
// after linking, causing the kernel not to load the binary:
// https://developercommunity.visualstudio.com/content/problem/45366/vc-linker-creates-invalid-dll-with-clang-cl.html
// FIXME: Hide this behind some API in e.g. MCAsmInfo or MCTargetStreamer.
const Triple &TT = TM.getTargetTriple();
if (!HasAnyRealCode && (MAI->hasSubsectionsViaSymbols() ||
(TT.isOSWindows() && TT.isOSBinFormatCOFF()))) {
MCInst Noop;
MF->getSubtarget().getInstrInfo()->getNoopForMachoTarget(Noop);
MF->getSubtarget().getInstrInfo()->getNoop(Noop);
OutStreamer->AddComment("avoids zero-length function");

// Targets can opt-out of emitting the noop here by leaving the opcode
// unspecified.
if (Noop.getOpcode())
OutStreamer->EmitInstruction(Noop, getSubtargetInfo());
OutStreamer->EmitInstruction(Noop, getSubtargetInfo());
}

const Function *F = MF->getFunction();
Expand Down
4 changes: 2 additions & 2 deletions lib/CodeGen/TargetInstrInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -428,8 +428,8 @@ static const TargetRegisterClass *canFoldCopy(const MachineInstr &MI,
return nullptr;
}

void TargetInstrInfo::getNoopForMachoTarget(MCInst &NopInst) const {
llvm_unreachable("Not a MachO target");
void TargetInstrInfo::getNoop(MCInst &NopInst) const {
llvm_unreachable("Not implemented");
}

static MachineInstr *foldPatchpoint(MachineFunction &MF, MachineInstr &MI,
Expand Down
2 changes: 1 addition & 1 deletion lib/Target/AArch64/AArch64InstrInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3025,7 +3025,7 @@ bool llvm::rewriteAArch64FrameIndex(MachineInstr &MI, unsigned FrameRegIdx,
return false;
}

void AArch64InstrInfo::getNoopForMachoTarget(MCInst &NopInst) const {
void AArch64InstrInfo::getNoop(MCInst &NopInst) const {
NopInst.setOpcode(AArch64::HINT);
NopInst.addOperand(MCOperand::createImm(0));
}
Expand Down
2 changes: 1 addition & 1 deletion lib/Target/AArch64/AArch64InstrInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ class AArch64InstrInfo final : public AArch64GenInstrInfo {
const DebugLoc &DL, unsigned DstReg,
ArrayRef<MachineOperand> Cond, unsigned TrueReg,
unsigned FalseReg) const override;
void getNoopForMachoTarget(MCInst &NopInst) const override;
void getNoop(MCInst &NopInst) const override;

/// analyzeCompare - For a comparison instruction, return the source registers
/// in SrcReg and SrcReg2, and the value it compares against in CmpValue.
Expand Down
4 changes: 0 additions & 4 deletions lib/Target/ARM/ARMBaseInstrInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,10 +105,6 @@ class ARMBaseInstrInfo : public ARMGenInstrInfo {
// Return whether the target has an explicit NOP encoding.
bool hasNOP() const;

virtual void getNoopForElfTarget(MCInst &NopInst) const {
getNoopForMachoTarget(NopInst);
}

// Return the non-pre/post incrementing version of 'Opc'. Return 0
// if there is not such an opcode.
virtual unsigned getUnindexedOpcode(unsigned Opc) const = 0;
Expand Down
4 changes: 2 additions & 2 deletions lib/Target/ARM/ARMInstrInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ using namespace llvm;
ARMInstrInfo::ARMInstrInfo(const ARMSubtarget &STI)
: ARMBaseInstrInfo(STI), RI() {}

/// getNoopForMachoTarget - Return the noop instruction to use for a noop.
void ARMInstrInfo::getNoopForMachoTarget(MCInst &NopInst) const {
/// Return the noop instruction to use for a noop.
void ARMInstrInfo::getNoop(MCInst &NopInst) const {
if (hasNOP()) {
NopInst.setOpcode(ARM::HINT);
NopInst.addOperand(MCOperand::createImm(0));
Expand Down
4 changes: 2 additions & 2 deletions lib/Target/ARM/ARMInstrInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ class ARMInstrInfo : public ARMBaseInstrInfo {
public:
explicit ARMInstrInfo(const ARMSubtarget &STI);

/// getNoopForMachoTarget - Return the noop instruction to use for a noop.
void getNoopForMachoTarget(MCInst &NopInst) const override;
/// Return the noop instruction to use for a noop.
void getNoop(MCInst &NopInst) const override;

// Return the non-pre/post incrementing version of 'Opc'. Return 0
// if there is not such an opcode.
Expand Down
4 changes: 1 addition & 3 deletions lib/Target/ARM/ARMMCInstLower.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -211,11 +211,9 @@ void ARMAsmPrinter::EmitSled(const MachineInstr &MI, SledKind Kind)
.addImm(ARMCC::AL).addReg(0));

MCInst Noop;
Subtarget->getInstrInfo()->getNoopForElfTarget(Noop);
Subtarget->getInstrInfo()->getNoop(Noop);
for (int8_t I = 0; I < NoopsInSledCount; I++)
{
OutStreamer->EmitInstruction(Noop, getSubtargetInfo());
}

OutStreamer->EmitLabel(Target);
recordSled(CurSled, MI, Kind);
Expand Down
4 changes: 2 additions & 2 deletions lib/Target/ARM/Thumb1InstrInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ using namespace llvm;
Thumb1InstrInfo::Thumb1InstrInfo(const ARMSubtarget &STI)
: ARMBaseInstrInfo(STI), RI() {}

/// getNoopForMachoTarget - Return the noop instruction to use for a noop.
void Thumb1InstrInfo::getNoopForMachoTarget(MCInst &NopInst) const {
/// Return the noop instruction to use for a noop.
void Thumb1InstrInfo::getNoop(MCInst &NopInst) const {
NopInst.setOpcode(ARM::tMOVr);
NopInst.addOperand(MCOperand::createReg(ARM::R8));
NopInst.addOperand(MCOperand::createReg(ARM::R8));
Expand Down
4 changes: 2 additions & 2 deletions lib/Target/ARM/Thumb1InstrInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ class Thumb1InstrInfo : public ARMBaseInstrInfo {
public:
explicit Thumb1InstrInfo(const ARMSubtarget &STI);

/// getNoopForMachoTarget - Return the noop instruction to use for a noop.
void getNoopForMachoTarget(MCInst &NopInst) const override;
/// Return the noop instruction to use for a noop.
void getNoop(MCInst &NopInst) const override;

// Return the non-pre/post incrementing version of 'Opc'. Return 0
// if there is not such an opcode.
Expand Down
4 changes: 2 additions & 2 deletions lib/Target/ARM/Thumb2InstrInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ OldT2IfCvt("old-thumb2-ifcvt", cl::Hidden,
Thumb2InstrInfo::Thumb2InstrInfo(const ARMSubtarget &STI)
: ARMBaseInstrInfo(STI), RI() {}

/// getNoopForMachoTarget - Return the noop instruction to use for a noop.
void Thumb2InstrInfo::getNoopForMachoTarget(MCInst &NopInst) const {
/// Return the noop instruction to use for a noop.
void Thumb2InstrInfo::getNoop(MCInst &NopInst) const {
NopInst.setOpcode(ARM::tHINT);
NopInst.addOperand(MCOperand::createImm(0));
NopInst.addOperand(MCOperand::createImm(ARMCC::AL));
Expand Down
4 changes: 2 additions & 2 deletions lib/Target/ARM/Thumb2InstrInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ class Thumb2InstrInfo : public ARMBaseInstrInfo {
public:
explicit Thumb2InstrInfo(const ARMSubtarget &STI);

/// getNoopForMachoTarget - Return the noop instruction to use for a noop.
void getNoopForMachoTarget(MCInst &NopInst) const override;
/// Return the noop instruction to use for a noop.
void getNoop(MCInst &NopInst) const override;

// Return the non-pre/post incrementing version of 'Opc'. Return 0
// if there is not such an opcode.
Expand Down
4 changes: 2 additions & 2 deletions lib/Target/PowerPC/PPCInstrInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -440,8 +440,8 @@ void PPCInstrInfo::insertNoop(MachineBasicBlock &MBB,
BuildMI(MBB, MI, DL, get(Opcode));
}

/// getNoopForMachoTarget - Return the noop instruction to use for a noop.
void PPCInstrInfo::getNoopForMachoTarget(MCInst &NopInst) const {
/// Return the noop instruction to use for a noop.
void PPCInstrInfo::getNoop(MCInst &NopInst) const {
NopInst.setOpcode(PPC::NOP);
}

Expand Down
2 changes: 1 addition & 1 deletion lib/Target/PowerPC/PPCInstrInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,7 @@ class PPCInstrInfo : public PPCGenInstrInfo {
///
unsigned getInstSizeInBytes(const MachineInstr &MI) const override;

void getNoopForMachoTarget(MCInst &NopInst) const override;
void getNoop(MCInst &NopInst) const override;

std::pair<unsigned, unsigned>
decomposeMachineOperandsTargetFlags(unsigned TF) const override;
Expand Down
2 changes: 1 addition & 1 deletion lib/Target/X86/X86InstrInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9514,7 +9514,7 @@ void X86InstrInfo::setExecutionDomain(MachineInstr &MI, unsigned Domain) const {
}

/// Return the noop instruction to use for a noop.
void X86InstrInfo::getNoopForMachoTarget(MCInst &NopInst) const {
void X86InstrInfo::getNoop(MCInst &NopInst) const {
NopInst.setOpcode(X86::NOOP);
}

Expand Down
2 changes: 1 addition & 1 deletion lib/Target/X86/X86InstrInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -457,7 +457,7 @@ class X86InstrInfo final : public X86GenInstrInfo {
int64_t Offset1, int64_t Offset2,
unsigned NumLoads) const override;

void getNoopForMachoTarget(MCInst &NopInst) const override;
void getNoop(MCInst &NopInst) const override;

bool
reverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const override;
Expand Down
22 changes: 22 additions & 0 deletions test/CodeGen/X86/empty-function.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
; RUN: llc < %s -mtriple=i686-pc-win32 | FileCheck -check-prefix=CHECK -check-prefix=WIN32 %s
; RUN: llc < %s -mtriple=x86_64-pc-win32 | FileCheck -check-prefix=CHECK -check-prefix=WIN64 %s
; RUN: llc < %s -mtriple=i386-linux-gnu | FileCheck -check-prefix=LINUX %s

target datalayout = "e-m:x-p:32:32-i64:64-f80:32-n8:16:32-a:0:32-S32"
target triple = "i686-pc-windows-msvc18.0.0"

; Don't emit empty functions on Windows; it can lead to duplicate entries
; (multiple functions sharing the same RVA) in the Guard CF Function Table which
; the kernel refuses to load.

define void @f() {
entry:
unreachable

; CHECK-LABEL: f:
; WIN32: nop
; WIN64: ud2
; LINUX-NOT: nop
; LINUX-NOT: ud2

}

0 comments on commit 960a40e

Please sign in to comment.