diff options
| -rw-r--r-- | llvm/lib/Target/X86/X86InstrInfo.td | 7 | ||||
| -rw-r--r-- | llvm/lib/Target/X86/X86Subtarget.cpp | 12 | ||||
| -rw-r--r-- | llvm/lib/Target/X86/X86Subtarget.h | 4 | ||||
| -rw-r--r-- | llvm/test/CodeGen/X86/call-imm.ll | 3 | 
4 files changed, 20 insertions, 6 deletions
diff --git a/llvm/lib/Target/X86/X86InstrInfo.td b/llvm/lib/Target/X86/X86InstrInfo.td index 10eddf0f110..84c357308a5 100644 --- a/llvm/lib/Target/X86/X86InstrInfo.td +++ b/llvm/lib/Target/X86/X86InstrInfo.td @@ -234,9 +234,9 @@ def In64BitMode  : Predicate<"Subtarget->is64Bit()">;  def SmallCode    : Predicate<"TM.getCodeModel() == CodeModel::Small">;  def NotSmallCode : Predicate<"TM.getCodeModel() != CodeModel::Small">;  def IsStatic     : Predicate<"TM.getRelocationModel() == Reloc::Static">; -def IsNotPIC     : Predicate<"TM.getRelocationModel() != Reloc::PIC_">;  def OptForSpeed  : Predicate<"!OptForSize">;  def FastBTMem    : Predicate<"!Subtarget->isBTMemSlow()">; +def CallImmAddr  : Predicate<"Subtarget->IsLegalToCallImmediateAddr(TM)">;  //===----------------------------------------------------------------------===//  // X86 Instruction Format Definitions. @@ -562,8 +562,7 @@ let isCall = 1 in                XMM8, XMM9, XMM10, XMM11, XMM12, XMM13, XMM14, XMM15, EFLAGS],        Uses = [ESP] in {      def CALLpcrel32 : Ii32<0xE8, RawFrm, (outs), (ins i32imm:$dst,variable_ops), -                           "call\t${dst:call}", [(X86call imm:$dst)]>, -                      Requires<[In32BitMode, IsNotPIC]>; +                           "call\t${dst:call}", []>;      def CALL32r     : I<0xFF, MRM2r, (outs), (ins GR32:$dst, variable_ops),                          "call\t{*}$dst", [(X86call GR32:$dst)]>;      def CALL32m     : I<0xFF, MRM2m, (outs), (ins i32mem:$dst, variable_ops), @@ -3342,6 +3341,8 @@ def : Pat<(X86call (i32 tglobaladdr:$dst)),            (CALLpcrel32 tglobaladdr:$dst)>;  def : Pat<(X86call (i32 texternalsym:$dst)),            (CALLpcrel32 texternalsym:$dst)>; +def : Pat<(X86call (i32 imm:$dst)), +          (CALLpcrel32 imm:$dst)>, Requires<[CallImmAddr]>;  // X86 specific add which produces a flag.  def : Pat<(addc GR32:$src1, GR32:$src2), diff --git a/llvm/lib/Target/X86/X86Subtarget.cpp b/llvm/lib/Target/X86/X86Subtarget.cpp index df1f7db85fc..d54ccb37e3b 100644 --- a/llvm/lib/Target/X86/X86Subtarget.cpp +++ b/llvm/lib/Target/X86/X86Subtarget.cpp @@ -74,8 +74,8 @@ bool X86Subtarget::GVRequiresExtraLoad(const GlobalValue* GV,  /// cases where GVRequiresExtraLoad is true.  Some variations of PIC require  /// a register, but not an extra load.  bool X86Subtarget::GVRequiresRegister(const GlobalValue *GV, -                                       const TargetMachine& TM, -                                       bool isDirectCall) const +                                      const TargetMachine& TM, +                                      bool isDirectCall) const  {    if (GVRequiresExtraLoad(GV, TM, isDirectCall))      return true; @@ -99,6 +99,14 @@ const char *X86Subtarget::getBZeroEntry() const {    return 0;  } +/// IsLegalToCallImmediateAddr - Return true if the subtarget allows calls +/// to immediate address. +bool X86Subtarget::IsLegalToCallImmediateAddr(const TargetMachine &TM) const { +  if (Is64Bit) +    return false; +  return isTargetELF() || TM.getRelocationModel() == Reloc::Static; +} +  /// getSpecialAddressLatency - For targets where it is beneficial to  /// backschedule instructions that compute addresses, return a value  /// indicating the number of scheduling cycles of backscheduling that diff --git a/llvm/lib/Target/X86/X86Subtarget.h b/llvm/lib/Target/X86/X86Subtarget.h index ded26e891e1..abf1e814175 100644 --- a/llvm/lib/Target/X86/X86Subtarget.h +++ b/llvm/lib/Target/X86/X86Subtarget.h @@ -189,6 +189,10 @@ public:    bool GVRequiresRegister(const GlobalValue* GV, const TargetMachine& TM,                             bool isDirectCall) const; +  /// IsLegalToCallImmediateAddr - Return true if the subtarget allows calls +  /// to immediate address. +  bool IsLegalToCallImmediateAddr(const TargetMachine &TM) const; +    /// This function returns the name of a function which has an interface    /// like the non-standard bzero function, if such a function exists on    /// the current subtarget and it is considered prefereable over diff --git a/llvm/test/CodeGen/X86/call-imm.ll b/llvm/test/CodeGen/X86/call-imm.ll index b22b65eaea2..c39c6c09292 100644 --- a/llvm/test/CodeGen/X86/call-imm.ll +++ b/llvm/test/CodeGen/X86/call-imm.ll @@ -1,4 +1,5 @@ -; RUN: llvm-as < %s | llc -march=x86    | grep {call.*12345678} +; RUN: llvm-as < %s | llc -mtriple=i386-darwin-apple -relocation-model=static | grep {call.*12345678} +; RUN: llvm-as < %s | llc -mtriple=i386-pc-linux -relocation-model=dynamic-no-pic | grep {call.*12345678}  ; RUN: llvm-as < %s | llc -march=x86 -relocation-model=pic | not grep {call.*12345678}  ; Call to immediate is not safe on x86-64 unless we *know* that the  | 

