llvm.org GIT mirror llvm / 960a40e
Re-commit r301040 "X86: Don't emit zero-byte functions on Windows" 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 Hans Wennborg 3 years ago
18 changed file(s) with 55 addition(s) and 36 deletion(s). Raw diff Collapse all Expand all
11071107
11081108
11091109 /// Return the noop instruction to use for a noop.
1110 virtual void getNoopForMachoTarget(MCInst &NopInst) const;
1110 virtual void getNoop(MCInst &NopInst) const;
11111111
11121112 /// Return true for post-incremented instructions.
11131113 virtual bool isPostIncrement(const MachineInstr &MI) const {
10451045 // If the function is empty and the object file uses .subsections_via_symbols,
10461046 // then we need to emit *something* to the function body to prevent the
10471047 // labels from collapsing together. Just emit a noop.
1048 if ((MAI->hasSubsectionsViaSymbols() && !HasAnyRealCode)) {
1048 // Similarly, don't emit empty functions on Windows either. It can lead to
1049 // duplicate entries (two functions with the same RVA) in the Guard CF Table
1050 // after linking, causing the kernel not to load the binary:
1051 // https://developercommunity.visualstudio.com/content/problem/45366/vc-linker-creates-invalid-dll-with-clang-cl.html
1052 // FIXME: Hide this behind some API in e.g. MCAsmInfo or MCTargetStreamer.
1053 const Triple &TT = TM.getTargetTriple();
1054 if (!HasAnyRealCode && (MAI->hasSubsectionsViaSymbols() ||
1055 (TT.isOSWindows() && TT.isOSBinFormatCOFF()))) {
10491056 MCInst Noop;
1050 MF->getSubtarget().getInstrInfo()->getNoopForMachoTarget(Noop);
1057 MF->getSubtarget().getInstrInfo()->getNoop(Noop);
10511058 OutStreamer->AddComment("avoids zero-length function");
1052
1053 // Targets can opt-out of emitting the noop here by leaving the opcode
1054 // unspecified.
1055 if (Noop.getOpcode())
1056 OutStreamer->EmitInstruction(Noop, getSubtargetInfo());
1059 OutStreamer->EmitInstruction(Noop, getSubtargetInfo());
10571060 }
10581061
10591062 const Function *F = MF->getFunction();
427427 return nullptr;
428428 }
429429
430 void TargetInstrInfo::getNoopForMachoTarget(MCInst &NopInst) const {
431 llvm_unreachable("Not a MachO target");
430 void TargetInstrInfo::getNoop(MCInst &NopInst) const {
431 llvm_unreachable("Not implemented");
432432 }
433433
434434 static MachineInstr *foldPatchpoint(MachineFunction &MF, MachineInstr &MI,
30243024 return false;
30253025 }
30263026
3027 void AArch64InstrInfo::getNoopForMachoTarget(MCInst &NopInst) const {
3027 void AArch64InstrInfo::getNoop(MCInst &NopInst) const {
30283028 NopInst.setOpcode(AArch64::HINT);
30293029 NopInst.addOperand(MCOperand::createImm(0));
30303030 }
204204 const DebugLoc &DL, unsigned DstReg,
205205 ArrayRef Cond, unsigned TrueReg,
206206 unsigned FalseReg) const override;
207 void getNoopForMachoTarget(MCInst &NopInst) const override;
207 void getNoop(MCInst &NopInst) const override;
208208
209209 /// analyzeCompare - For a comparison instruction, return the source registers
210210 /// in SrcReg and SrcReg2, and the value it compares against in CmpValue.
103103 public:
104104 // Return whether the target has an explicit NOP encoding.
105105 bool hasNOP() const;
106
107 virtual void getNoopForElfTarget(MCInst &NopInst) const {
108 getNoopForMachoTarget(NopInst);
109 }
110106
111107 // Return the non-pre/post incrementing version of 'Opc'. Return 0
112108 // if there is not such an opcode.
3131 ARMInstrInfo::ARMInstrInfo(const ARMSubtarget &STI)
3232 : ARMBaseInstrInfo(STI), RI() {}
3333
34 /// getNoopForMachoTarget - Return the noop instruction to use for a noop.
35 void ARMInstrInfo::getNoopForMachoTarget(MCInst &NopInst) const {
34 /// Return the noop instruction to use for a noop.
35 void ARMInstrInfo::getNoop(MCInst &NopInst) const {
3636 if (hasNOP()) {
3737 NopInst.setOpcode(ARM::HINT);
3838 NopInst.addOperand(MCOperand::createImm(0));
2424 public:
2525 explicit ARMInstrInfo(const ARMSubtarget &STI);
2626
27 /// getNoopForMachoTarget - Return the noop instruction to use for a noop.
28 void getNoopForMachoTarget(MCInst &NopInst) const override;
27 /// Return the noop instruction to use for a noop.
28 void getNoop(MCInst &NopInst) const override;
2929
3030 // Return the non-pre/post incrementing version of 'Opc'. Return 0
3131 // if there is not such an opcode.
210210 .addImm(ARMCC::AL).addReg(0));
211211
212212 MCInst Noop;
213 Subtarget->getInstrInfo()->getNoopForElfTarget(Noop);
213 Subtarget->getInstrInfo()->getNoop(Noop);
214214 for (int8_t I = 0; I < NoopsInSledCount; I++)
215 {
216215 OutStreamer->EmitInstruction(Noop, getSubtargetInfo());
217 }
218216
219217 OutStreamer->EmitLabel(Target);
220218 recordSled(CurSled, MI, Kind);
2323 Thumb1InstrInfo::Thumb1InstrInfo(const ARMSubtarget &STI)
2424 : ARMBaseInstrInfo(STI), RI() {}
2525
26 /// getNoopForMachoTarget - Return the noop instruction to use for a noop.
27 void Thumb1InstrInfo::getNoopForMachoTarget(MCInst &NopInst) const {
26 /// Return the noop instruction to use for a noop.
27 void Thumb1InstrInfo::getNoop(MCInst &NopInst) const {
2828 NopInst.setOpcode(ARM::tMOVr);
2929 NopInst.addOperand(MCOperand::createReg(ARM::R8));
3030 NopInst.addOperand(MCOperand::createReg(ARM::R8));
2424 public:
2525 explicit Thumb1InstrInfo(const ARMSubtarget &STI);
2626
27 /// getNoopForMachoTarget - Return the noop instruction to use for a noop.
28 void getNoopForMachoTarget(MCInst &NopInst) const override;
27 /// Return the noop instruction to use for a noop.
28 void getNoop(MCInst &NopInst) const override;
2929
3030 // Return the non-pre/post incrementing version of 'Opc'. Return 0
3131 // if there is not such an opcode.
3131 Thumb2InstrInfo::Thumb2InstrInfo(const ARMSubtarget &STI)
3232 : ARMBaseInstrInfo(STI), RI() {}
3333
34 /// getNoopForMachoTarget - Return the noop instruction to use for a noop.
35 void Thumb2InstrInfo::getNoopForMachoTarget(MCInst &NopInst) const {
34 /// Return the noop instruction to use for a noop.
35 void Thumb2InstrInfo::getNoop(MCInst &NopInst) const {
3636 NopInst.setOpcode(ARM::tHINT);
3737 NopInst.addOperand(MCOperand::createImm(0));
3838 NopInst.addOperand(MCOperand::createImm(ARMCC::AL));
2525 public:
2626 explicit Thumb2InstrInfo(const ARMSubtarget &STI);
2727
28 /// getNoopForMachoTarget - Return the noop instruction to use for a noop.
29 void getNoopForMachoTarget(MCInst &NopInst) const override;
28 /// Return the noop instruction to use for a noop.
29 void getNoop(MCInst &NopInst) const override;
3030
3131 // Return the non-pre/post incrementing version of 'Opc'. Return 0
3232 // if there is not such an opcode.
439439 BuildMI(MBB, MI, DL, get(Opcode));
440440 }
441441
442 /// getNoopForMachoTarget - Return the noop instruction to use for a noop.
443 void PPCInstrInfo::getNoopForMachoTarget(MCInst &NopInst) const {
442 /// Return the noop instruction to use for a noop.
443 void PPCInstrInfo::getNoop(MCInst &NopInst) const {
444444 NopInst.setOpcode(PPC::NOP);
445445 }
446446
268268 ///
269269 unsigned getInstSizeInBytes(const MachineInstr &MI) const override;
270270
271 void getNoopForMachoTarget(MCInst &NopInst) const override;
271 void getNoop(MCInst &NopInst) const override;
272272
273273 std::pair
274274 decomposeMachineOperandsTargetFlags(unsigned TF) const override;
95139513 }
95149514
95159515 /// Return the noop instruction to use for a noop.
9516 void X86InstrInfo::getNoopForMachoTarget(MCInst &NopInst) const {
9516 void X86InstrInfo::getNoop(MCInst &NopInst) const {
95179517 NopInst.setOpcode(X86::NOOP);
95189518 }
95199519
456456 int64_t Offset1, int64_t Offset2,
457457 unsigned NumLoads) const override;
458458
459 void getNoopForMachoTarget(MCInst &NopInst) const override;
459 void getNoop(MCInst &NopInst) const override;
460460
461461 bool
462462 reverseBranchCondition(SmallVectorImpl &Cond) const override;
0 ; RUN: llc < %s -mtriple=i686-pc-win32 | FileCheck -check-prefix=CHECK -check-prefix=WIN32 %s
1 ; RUN: llc < %s -mtriple=x86_64-pc-win32 | FileCheck -check-prefix=CHECK -check-prefix=WIN64 %s
2 ; RUN: llc < %s -mtriple=i386-linux-gnu | FileCheck -check-prefix=LINUX %s
3
4 target datalayout = "e-m:x-p:32:32-i64:64-f80:32-n8:16:32-a:0:32-S32"
5 target triple = "i686-pc-windows-msvc18.0.0"
6
7 ; Don't emit empty functions on Windows; it can lead to duplicate entries
8 ; (multiple functions sharing the same RVA) in the Guard CF Function Table which
9 ; the kernel refuses to load.
10
11 define void @f() {
12 entry:
13 unreachable
14
15 ; CHECK-LABEL: f:
16 ; WIN32: nop
17 ; WIN64: ud2
18 ; LINUX-NOT: nop
19 ; LINUX-NOT: ud2
20
21 }