forked from OSchip/llvm-project
Revert "[X86] Support the "ms-hotpatch" attribute."
This reverts commit r278048. Something changed between the last time I built this--it takes awhile on my ridiculously slow and ancient computer--and now that broke this. llvm-svn: 278053
This commit is contained in:
parent
0e37911334
commit
e9c32c7ed3
|
@ -1448,7 +1448,7 @@ example:
|
||||||
generated for this function needs to follow certain conventions that
|
generated for this function needs to follow certain conventions that
|
||||||
make it possible for a runtime function to patch over it later.
|
make it possible for a runtime function to patch over it later.
|
||||||
The exact effect of this attribute depends on its string value,
|
The exact effect of this attribute depends on its string value,
|
||||||
for which there currently are two legal possiblities:
|
for which there currently is one legal possibility:
|
||||||
|
|
||||||
* ``"prologue-short-redirect"`` - This style of patchable
|
* ``"prologue-short-redirect"`` - This style of patchable
|
||||||
function is intended to support patching a function prologue to
|
function is intended to support patching a function prologue to
|
||||||
|
@ -1464,24 +1464,6 @@ example:
|
||||||
|
|
||||||
``"prologue-short-redirect"`` is currently only supported on
|
``"prologue-short-redirect"`` is currently only supported on
|
||||||
x86-64.
|
x86-64.
|
||||||
* ``"ms-hotpatch"`` - This style of patchable function is similar to
|
|
||||||
``"prologue-short-redirect"``, but it also imposes several additional
|
|
||||||
guarantees to support the style of hotpatching used on Windows. On
|
|
||||||
32-bit x86, the first instruction will be a ``mov %edi, %edi``
|
|
||||||
instruction; this is frequently used as a magic value indicating a
|
|
||||||
hotpatchable function. On other architectures, however, the first
|
|
||||||
instruction can be anything allowed in a Windows-style prologue;
|
|
||||||
this is because all functions on the non-i386 architectures Windows
|
|
||||||
supports are assumed to be hotpatchable. Additionally, when not
|
|
||||||
targeting a Visual C++-style toolchain, patch space will be provided
|
|
||||||
prior to the function's entry point of an architecturally specific
|
|
||||||
size. These sizes are compatible with GCC: on 32-bit x86, the patch
|
|
||||||
space is 64 bytes long; on x86-64, it is 128 bytes long. The patch
|
|
||||||
space is not provided for MSVC toolchains because the
|
|
||||||
`/FUNCTIONPADMIN <https://msdn.microsoft.com/en-us/library/ms173524.aspx>`_
|
|
||||||
option, which provides this space, is expected to be used there.
|
|
||||||
|
|
||||||
``"ms-hotpatch"`` is currently only supported on x86 and x86-64.
|
|
||||||
|
|
||||||
This attribute by itself does not imply restrictions on
|
This attribute by itself does not imply restrictions on
|
||||||
inter-procedural optimizations. All of the semantic effects the
|
inter-procedural optimizations. All of the semantic effects the
|
||||||
|
|
|
@ -23,8 +23,6 @@
|
||||||
#define LLVM_ANALYSIS_TARGETTRANSFORMINFO_H
|
#define LLVM_ANALYSIS_TARGETTRANSFORMINFO_H
|
||||||
|
|
||||||
#include "llvm/ADT/Optional.h"
|
#include "llvm/ADT/Optional.h"
|
||||||
#include "llvm/ADT/StringRef.h"
|
|
||||||
#include "llvm/CodeGen/MachineBasicBlock.h"
|
|
||||||
#include "llvm/IR/IntrinsicInst.h"
|
#include "llvm/IR/IntrinsicInst.h"
|
||||||
#include "llvm/IR/Intrinsics.h"
|
#include "llvm/IR/Intrinsics.h"
|
||||||
#include "llvm/IR/Operator.h"
|
#include "llvm/IR/Operator.h"
|
||||||
|
@ -297,18 +295,6 @@ public:
|
||||||
/// target-independent defaults.
|
/// target-independent defaults.
|
||||||
void getUnrollingPreferences(Loop *L, UnrollingPreferences &UP) const;
|
void getUnrollingPreferences(Loop *L, UnrollingPreferences &UP) const;
|
||||||
|
|
||||||
/// \brief Emit a patchable operation in the given basic block at the
|
|
||||||
/// given insertion point.
|
|
||||||
///
|
|
||||||
/// Most of the time, this will be a straight-up \c TargetOpcode::PATCHABLE_OP
|
|
||||||
/// instruction, which will be lowered by the target to a no-op that can
|
|
||||||
/// be safely replaced with a short jump. However, some targets under certain
|
|
||||||
/// conditions can have peculiar requirements for this instruction; these
|
|
||||||
/// targets can provide their own implementation of this to emit the correct
|
|
||||||
/// instruction.
|
|
||||||
void emitPatchableOp(StringRef PatchType, MachineBasicBlock &MBB,
|
|
||||||
MachineBasicBlock::iterator &MBBI) const;
|
|
||||||
|
|
||||||
/// @}
|
/// @}
|
||||||
|
|
||||||
/// \name Scalar Target Information
|
/// \name Scalar Target Information
|
||||||
|
@ -661,9 +647,6 @@ public:
|
||||||
virtual bool isSourceOfDivergence(const Value *V) = 0;
|
virtual bool isSourceOfDivergence(const Value *V) = 0;
|
||||||
virtual bool isLoweredToCall(const Function *F) = 0;
|
virtual bool isLoweredToCall(const Function *F) = 0;
|
||||||
virtual void getUnrollingPreferences(Loop *L, UnrollingPreferences &UP) = 0;
|
virtual void getUnrollingPreferences(Loop *L, UnrollingPreferences &UP) = 0;
|
||||||
virtual void emitPatchableOp(StringRef Kind,
|
|
||||||
MachineBasicBlock &MBB,
|
|
||||||
MachineBasicBlock::iterator &MBBI) const = 0;
|
|
||||||
virtual bool isLegalAddImmediate(int64_t Imm) = 0;
|
virtual bool isLegalAddImmediate(int64_t Imm) = 0;
|
||||||
virtual bool isLegalICmpImmediate(int64_t Imm) = 0;
|
virtual bool isLegalICmpImmediate(int64_t Imm) = 0;
|
||||||
virtual bool isLegalAddressingMode(Type *Ty, GlobalValue *BaseGV,
|
virtual bool isLegalAddressingMode(Type *Ty, GlobalValue *BaseGV,
|
||||||
|
@ -809,10 +792,6 @@ public:
|
||||||
void getUnrollingPreferences(Loop *L, UnrollingPreferences &UP) override {
|
void getUnrollingPreferences(Loop *L, UnrollingPreferences &UP) override {
|
||||||
return Impl.getUnrollingPreferences(L, UP);
|
return Impl.getUnrollingPreferences(L, UP);
|
||||||
}
|
}
|
||||||
void emitPatchableOp(StringRef Kind, MachineBasicBlock &MBB,
|
|
||||||
MachineBasicBlock::iterator &MBBI) const override {
|
|
||||||
return Impl.emitPatchableOp(Kind, MBB, MBBI);
|
|
||||||
}
|
|
||||||
bool isLegalAddImmediate(int64_t Imm) override {
|
bool isLegalAddImmediate(int64_t Imm) override {
|
||||||
return Impl.isLegalAddImmediate(Imm);
|
return Impl.isLegalAddImmediate(Imm);
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,10 +23,6 @@
|
||||||
#include "llvm/IR/Operator.h"
|
#include "llvm/IR/Operator.h"
|
||||||
#include "llvm/IR/Type.h"
|
#include "llvm/IR/Type.h"
|
||||||
#include "llvm/Analysis/VectorUtils.h"
|
#include "llvm/Analysis/VectorUtils.h"
|
||||||
#include "llvm/CodeGen/MachineBasicBlock.h"
|
|
||||||
#include "llvm/CodeGen/MachineInstrBuilder.h"
|
|
||||||
#include "llvm/Target/TargetInstrInfo.h"
|
|
||||||
#include "llvm/Target/TargetSubtargetInfo.h"
|
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
|
|
||||||
|
@ -210,20 +206,6 @@ public:
|
||||||
|
|
||||||
void getUnrollingPreferences(Loop *, TTI::UnrollingPreferences &) {}
|
void getUnrollingPreferences(Loop *, TTI::UnrollingPreferences &) {}
|
||||||
|
|
||||||
void emitPatchableOp(StringRef, MachineBasicBlock &MBB,
|
|
||||||
MachineBasicBlock::iterator &MBBI) const {
|
|
||||||
auto *TII = MBB.getParent()->getSubtarget().getInstrInfo();
|
|
||||||
auto MIB = BuildMI(MBB, MBBI, MBBI->getDebugLoc(),
|
|
||||||
TII->get(TargetOpcode::PATCHABLE_OP))
|
|
||||||
.addImm(2)
|
|
||||||
.addImm(MBBI->getOpcode());
|
|
||||||
|
|
||||||
for (auto &MO : MBBI->operands())
|
|
||||||
MIB.addOperand(MO);
|
|
||||||
|
|
||||||
MBBI->eraseFromParent();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isLegalAddImmediate(int64_t Imm) { return false; }
|
bool isLegalAddImmediate(int64_t Imm) { return false; }
|
||||||
|
|
||||||
bool isLegalICmpImmediate(int64_t Imm) { return false; }
|
bool isLegalICmpImmediate(int64_t Imm) { return false; }
|
||||||
|
|
|
@ -106,12 +106,6 @@ void TargetTransformInfo::getUnrollingPreferences(
|
||||||
return TTIImpl->getUnrollingPreferences(L, UP);
|
return TTIImpl->getUnrollingPreferences(L, UP);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TargetTransformInfo::emitPatchableOp(
|
|
||||||
StringRef PatchType, MachineBasicBlock &MBB,
|
|
||||||
MachineBasicBlock::iterator &MBBI) const {
|
|
||||||
return TTIImpl->emitPatchableOp(PatchType, MBB, MBBI);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool TargetTransformInfo::isLegalAddImmediate(int64_t Imm) const {
|
bool TargetTransformInfo::isLegalAddImmediate(int64_t Imm) const {
|
||||||
return TTIImpl->isLegalAddImmediate(Imm);
|
return TTIImpl->isLegalAddImmediate(Imm);
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,11 +13,12 @@
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
#include "llvm/CodeGen/Passes.h"
|
#include "llvm/CodeGen/Passes.h"
|
||||||
#include "llvm/Analysis/TargetTransformInfo.h"
|
|
||||||
#include "llvm/CodeGen/Analysis.h"
|
|
||||||
#include "llvm/CodeGen/MachineFunction.h"
|
#include "llvm/CodeGen/MachineFunction.h"
|
||||||
#include "llvm/CodeGen/MachineFunctionPass.h"
|
#include "llvm/CodeGen/MachineFunctionPass.h"
|
||||||
|
#include "llvm/CodeGen/MachineInstrBuilder.h"
|
||||||
#include "llvm/Target/TargetFrameLowering.h"
|
#include "llvm/Target/TargetFrameLowering.h"
|
||||||
|
#include "llvm/Target/TargetInstrInfo.h"
|
||||||
|
#include "llvm/Target/TargetSubtargetInfo.h"
|
||||||
|
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
|
|
||||||
|
@ -28,7 +29,6 @@ struct PatchableFunction : public MachineFunctionPass {
|
||||||
initializePatchableFunctionPass(*PassRegistry::getPassRegistry());
|
initializePatchableFunctionPass(*PassRegistry::getPassRegistry());
|
||||||
}
|
}
|
||||||
|
|
||||||
void getAnalysisUsage(AnalysisUsage &AU) const override;
|
|
||||||
bool runOnMachineFunction(MachineFunction &F) override;
|
bool runOnMachineFunction(MachineFunction &F) override;
|
||||||
MachineFunctionProperties getRequiredProperties() const override {
|
MachineFunctionProperties getRequiredProperties() const override {
|
||||||
return MachineFunctionProperties().set(
|
return MachineFunctionProperties().set(
|
||||||
|
@ -53,29 +53,31 @@ static bool doesNotGeneratecode(const MachineInstr &MI) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PatchableFunction::getAnalysisUsage(AnalysisUsage &AU) const {
|
|
||||||
MachineFunctionPass::getAnalysisUsage(AU);
|
|
||||||
AU.addRequired<TargetTransformInfoWrapperPass>();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool PatchableFunction::runOnMachineFunction(MachineFunction &MF) {
|
bool PatchableFunction::runOnMachineFunction(MachineFunction &MF) {
|
||||||
if (!MF.getFunction()->hasFnAttribute("patchable-function"))
|
if (!MF.getFunction()->hasFnAttribute("patchable-function"))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
#ifndef NDEBUG
|
||||||
Attribute PatchAttr = MF.getFunction()->getFnAttribute("patchable-function");
|
Attribute PatchAttr = MF.getFunction()->getFnAttribute("patchable-function");
|
||||||
StringRef PatchType = PatchAttr.getValueAsString();
|
StringRef PatchType = PatchAttr.getValueAsString();
|
||||||
assert((PatchType == "prologue-short-redirect" ||
|
assert(PatchType == "prologue-short-redirect" && "Only possibility today!");
|
||||||
PatchType == "ms-hotpatch") && "Only possibilities today!");
|
#endif
|
||||||
|
|
||||||
auto &FirstMBB = *MF.begin();
|
auto &FirstMBB = *MF.begin();
|
||||||
MachineBasicBlock::iterator FirstActualI = FirstMBB.begin();
|
MachineBasicBlock::iterator FirstActualI = FirstMBB.begin();
|
||||||
for (; doesNotGeneratecode(*FirstActualI); ++FirstActualI)
|
for (; doesNotGeneratecode(*FirstActualI); ++FirstActualI)
|
||||||
assert(FirstActualI != FirstMBB.end());
|
assert(FirstActualI != FirstMBB.end());
|
||||||
|
|
||||||
const TargetTransformInfo &TTI =
|
auto *TII = MF.getSubtarget().getInstrInfo();
|
||||||
getAnalysis<TargetTransformInfoWrapperPass>().getTTI(*MF.getFunction());
|
auto MIB = BuildMI(FirstMBB, FirstActualI, FirstActualI->getDebugLoc(),
|
||||||
TTI.emitPatchableOp(PatchType, FirstMBB, FirstActualI);
|
TII->get(TargetOpcode::PATCHABLE_OP))
|
||||||
|
.addImm(2)
|
||||||
|
.addImm(FirstActualI->getOpcode());
|
||||||
|
|
||||||
|
for (auto &MO : FirstActualI->operands())
|
||||||
|
MIB.addOperand(MO);
|
||||||
|
|
||||||
|
FirstActualI->eraseFromParent();
|
||||||
MF.ensureAlignment(4);
|
MF.ensureAlignment(4);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -76,31 +76,6 @@ bool X86AsmPrinter::runOnMachineFunction(MachineFunction &MF) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void X86AsmPrinter::EmitConstantPool() {
|
|
||||||
if (MF) {
|
|
||||||
// If an MS hotpatch function, we need to ensure 64 (32-bit) or 128 (64-bit)
|
|
||||||
// bytes of padding precede the label. This is the scratch space used
|
|
||||||
// by the hotpatching mechanism to insert the patch code. The movl %edi,
|
|
||||||
// %edi instruction emitted as the very first instruction of a hotpatch
|
|
||||||
// function is usually overwritten with a short jump instruction when the
|
|
||||||
// patch is installed, so it will jump directly into this space. (But
|
|
||||||
// don't add the space when targeting MSVC. There, the /FUNCTIONPADMIN
|
|
||||||
// option to link.exe is expected to be used.)
|
|
||||||
const Function *Fn = MF->getFunction();
|
|
||||||
if (!Subtarget->isTargetKnownWindowsMSVC() &&
|
|
||||||
Fn->hasFnAttribute("patchable-function") &&
|
|
||||||
Fn->getFnAttribute("patchable-function").getValueAsString() ==
|
|
||||||
"ms-hotpatch") {
|
|
||||||
// Emit INT3 instructions instead of NOPs. If a patch runs off the end,
|
|
||||||
// best to let the patcher know with a crash/debug break than to silently
|
|
||||||
// continue, only to run into the jump back into the patch.
|
|
||||||
OutStreamer->emitFill(Subtarget->is64Bit() ? 128 : 64, 0xcc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
AsmPrinter::EmitConstantPool();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// printSymbolOperand - Print a raw symbol reference operand. This handles
|
/// printSymbolOperand - Print a raw symbol reference operand. This handles
|
||||||
/// jump tables, constant pools, global address and external symbols, all of
|
/// jump tables, constant pools, global address and external symbols, all of
|
||||||
/// which print to a label with various suffixes for relocation types etc.
|
/// which print to a label with various suffixes for relocation types etc.
|
||||||
|
|
|
@ -140,8 +140,6 @@ public:
|
||||||
SMShadowTracker.emitShadowPadding(*OutStreamer, getSubtargetInfo());
|
SMShadowTracker.emitShadowPadding(*OutStreamer, getSubtargetInfo());
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmitConstantPool() override;
|
|
||||||
|
|
||||||
bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
|
bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
|
||||||
unsigned AsmVariant, const char *ExtraCode,
|
unsigned AsmVariant, const char *ExtraCode,
|
||||||
raw_ostream &OS) override;
|
raw_ostream &OS) override;
|
||||||
|
|
|
@ -928,10 +928,6 @@ void X86FrameLowering::emitPrologue(MachineFunction &MF,
|
||||||
bool NeedsWinCFI = IsWin64Prologue && Fn->needsUnwindTableEntry();
|
bool NeedsWinCFI = IsWin64Prologue && Fn->needsUnwindTableEntry();
|
||||||
bool NeedsDwarfCFI =
|
bool NeedsDwarfCFI =
|
||||||
!IsWin64Prologue && (MMI.hasDebugInfo() || Fn->needsUnwindTableEntry());
|
!IsWin64Prologue && (MMI.hasDebugInfo() || Fn->needsUnwindTableEntry());
|
||||||
bool IsMSHotpatch =
|
|
||||||
Fn->hasFnAttribute("patchable-function") &&
|
|
||||||
Fn->getFnAttribute("patchable-function").getValueAsString() ==
|
|
||||||
"ms-hotpatch";
|
|
||||||
unsigned FramePtr = TRI->getFrameRegister(MF);
|
unsigned FramePtr = TRI->getFrameRegister(MF);
|
||||||
const unsigned MachineFramePtr =
|
const unsigned MachineFramePtr =
|
||||||
STI.isTarget64BitILP32()
|
STI.isTarget64BitILP32()
|
||||||
|
@ -1073,9 +1069,7 @@ void X86FrameLowering::emitPrologue(MachineFunction &MF,
|
||||||
if (!IsWin64Prologue && !IsFunclet) {
|
if (!IsWin64Prologue && !IsFunclet) {
|
||||||
// Update EBP with the new base value.
|
// Update EBP with the new base value.
|
||||||
BuildMI(MBB, MBBI, DL,
|
BuildMI(MBB, MBBI, DL,
|
||||||
TII.get(IsMSHotpatch ?
|
TII.get(Uses64BitFramePtr ? X86::MOV64rr : X86::MOV32rr),
|
||||||
(Uses64BitFramePtr ? X86::MOV64rr_REV : X86::MOV32rr_REV):
|
|
||||||
(Uses64BitFramePtr ? X86::MOV64rr : X86::MOV32rr)),
|
|
||||||
FramePtr)
|
FramePtr)
|
||||||
.addReg(StackPtr)
|
.addReg(StackPtr)
|
||||||
.setMIFlag(MachineInstr::FrameSetup);
|
.setMIFlag(MachineInstr::FrameSetup);
|
||||||
|
|
|
@ -2577,12 +2577,9 @@ SDValue X86TargetLowering::LowerFormalArguments(
|
||||||
const TargetFrameLowering &TFI = *Subtarget.getFrameLowering();
|
const TargetFrameLowering &TFI = *Subtarget.getFrameLowering();
|
||||||
|
|
||||||
const Function *Fn = MF.getFunction();
|
const Function *Fn = MF.getFunction();
|
||||||
if ((Fn->hasExternalLinkage() &&
|
if (Fn->hasExternalLinkage() &&
|
||||||
Subtarget.isTargetCygMing() &&
|
Subtarget.isTargetCygMing() &&
|
||||||
Fn->getName() == "main") ||
|
Fn->getName() == "main")
|
||||||
(!Subtarget.is64Bit() && Fn->hasFnAttribute("patchable-function") &&
|
|
||||||
Fn->getFnAttribute("patchable-function").getValueAsString() ==
|
|
||||||
"ms-hotpatch"))
|
|
||||||
FuncInfo->setForceFramePointer(true);
|
FuncInfo->setForceFramePointer(true);
|
||||||
|
|
||||||
MachineFrameInfo &MFI = MF.getFrameInfo();
|
MachineFrameInfo &MFI = MF.getFrameInfo();
|
||||||
|
|
|
@ -1681,18 +1681,3 @@ bool X86TTIImpl::areInlineCompatible(const Function *Caller,
|
||||||
// correct.
|
// correct.
|
||||||
return (CallerBits & CalleeBits) == CalleeBits;
|
return (CallerBits & CalleeBits) == CalleeBits;
|
||||||
}
|
}
|
||||||
|
|
||||||
void X86TTIImpl::emitPatchableOp(StringRef PatchType,
|
|
||||||
MachineBasicBlock &MBB,
|
|
||||||
MachineBasicBlock::iterator &MBBI) const {
|
|
||||||
if (PatchType != "ms-hotpatch" || !ST->is32Bit()) {
|
|
||||||
BaseT::emitPatchableOp(PatchType, MBB, MBBI);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto &TII = *MBB.getParent()->getSubtarget().getInstrInfo();
|
|
||||||
BuildMI(MBB, MBBI, MBBI->getDebugLoc(),
|
|
||||||
TII.get(X86::MOV32rr_REV), X86::EDI)
|
|
||||||
.addReg(X86::EDI)
|
|
||||||
.setMIFlag(MachineInstr::FrameSetup);
|
|
||||||
}
|
|
||||||
|
|
|
@ -50,13 +50,6 @@ public:
|
||||||
: BaseT(std::move(static_cast<BaseT &>(Arg))), ST(std::move(Arg.ST)),
|
: BaseT(std::move(static_cast<BaseT &>(Arg))), ST(std::move(Arg.ST)),
|
||||||
TLI(std::move(Arg.TLI)) {}
|
TLI(std::move(Arg.TLI)) {}
|
||||||
|
|
||||||
/// \name Generic TTI Implementations
|
|
||||||
/// @{
|
|
||||||
void emitPatchableOp(StringRef PatchType, MachineBasicBlock &MBB,
|
|
||||||
MachineBasicBlock::iterator &MBBI) const;
|
|
||||||
|
|
||||||
/// @}
|
|
||||||
|
|
||||||
/// \name Scalar TTI Implementations
|
/// \name Scalar TTI Implementations
|
||||||
/// @{
|
/// @{
|
||||||
TTI::PopcntSupportKind getPopcntSupport(unsigned TyWidth);
|
TTI::PopcntSupportKind getPopcntSupport(unsigned TyWidth);
|
||||||
|
|
|
@ -1,27 +0,0 @@
|
||||||
; RUN: llc < %s -march=x86 -filetype=asm | FileCheck -check-prefix=CHECK-32 %s
|
|
||||||
; RUN: llc < %s -march=x86-64 -filetype=asm | FileCheck -check-prefix=CHECK-64 %s
|
|
||||||
; RUN: llc < %s -mtriple=i386-windows-msvc -filetype=asm | FileCheck -check-prefix=MSVC-32 %s
|
|
||||||
; RUN: llc < %s -mtriple=x86_64-windows-msvc -filetype=asm | FileCheck -check-prefix=MSVC-64 %s
|
|
||||||
|
|
||||||
; CHECK-32: .space 64,204
|
|
||||||
; CHECK-32: .p2align 4, 0x90
|
|
||||||
; CHECK-32-LABEL: foo:
|
|
||||||
; CHECK-32: movl %edi, %edi
|
|
||||||
; CHECK-32-NEXT: pushl %ebp
|
|
||||||
; CHECK-32-NEXT: movl %esp, %ebp
|
|
||||||
; CHECK-64: .space 128,204
|
|
||||||
; CHECK-64: .p2align 4, 0x90
|
|
||||||
; CHECK-64-LABEL: foo:
|
|
||||||
; CHECK-64: xchgw %ax, %ax
|
|
||||||
; MSVC-32-NOT: .space 64,204
|
|
||||||
; MSVC-32-LABEL: _foo:
|
|
||||||
; MSVC-32: movl %edi, %edi
|
|
||||||
; MSVC-32-NEXT: pushl %ebp
|
|
||||||
; MSVC-32-NEXT: movl %esp, %ebp
|
|
||||||
; MSVC-64-NOT: .space 128,204
|
|
||||||
; MSVC-64-LABEL: foo:
|
|
||||||
; MSVC-64: xchgw %ax, %ax
|
|
||||||
define void @foo() nounwind "patchable-function"="ms-hotpatch" {
|
|
||||||
entry:
|
|
||||||
ret void
|
|
||||||
}
|
|
Loading…
Reference in New Issue