From 578efa920abd218ba75a0fb3c9b8398f4c0a774b Mon Sep 17 00:00:00 2001 From: Devang Patel Date: Fri, 5 Jun 2009 21:57:13 +0000 Subject: [PATCH] Add new function attribute - noimplicitfloat Update code generator to use this attribute and remove NoImplicitFloat target option. Update llc to set this attribute when -no-implicit-float command line option is used. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@72959 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Attributes.h | 4 ++- include/llvm/Target/TargetLowering.h | 3 +- include/llvm/Target/TargetOptions.h | 6 ---- lib/AsmParser/LLLexer.cpp | 1 + lib/AsmParser/LLParser.cpp | 37 +++++++++++----------- lib/AsmParser/LLToken.h | 1 + lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 2 +- lib/Target/TargetMachine.cpp | 5 --- lib/Target/X86/X86ISelLowering.cpp | 17 +++++++--- lib/Target/X86/X86ISelLowering.h | 3 +- lib/VMCore/Attributes.cpp | 2 ++ test/Other/2009-06-05-no-implicit-float.ll | 4 +++ tools/llc/llc.cpp | 7 ++++ 13 files changed, 54 insertions(+), 38 deletions(-) create mode 100644 test/Other/2009-06-05-no-implicit-float.ll diff --git a/include/llvm/Attributes.h b/include/llvm/Attributes.h index 492b023663b..a594e3223d4 100644 --- a/include/llvm/Attributes.h +++ b/include/llvm/Attributes.h @@ -55,6 +55,8 @@ const Attributes Alignment = 31<<16; ///< Alignment of parameter (5 bits) // 0 means unaligned different from align 1 const Attributes NoCapture = 1<<21; ///< Function creates no aliases of pointer const Attributes NoRedZone = 1<<22; /// disable redzone +const Attributes NoImplicitFloat = 1<<23; /// disable implicit floating point + /// instructions. /// @brief Attributes that only apply to function parameters. const Attributes ParameterOnly = ByVal | Nest | StructRet | NoCapture; @@ -62,7 +64,7 @@ const Attributes ParameterOnly = ByVal | Nest | StructRet | NoCapture; /// @brief Attributes that only apply to function. const Attributes FunctionOnly = NoReturn | NoUnwind | ReadNone | ReadOnly | NoInline | AlwaysInline | OptimizeForSize | StackProtect | StackProtectReq | - NoRedZone; + NoRedZone | NoImplicitFloat; /// @brief Parameter attributes that do not apply to vararg call arguments. const Attributes VarArgsIncompatible = StructRet; diff --git a/include/llvm/Target/TargetLowering.h b/include/llvm/Target/TargetLowering.h index ef166a26c55..327af275114 100644 --- a/include/llvm/Target/TargetLowering.h +++ b/include/llvm/Target/TargetLowering.h @@ -632,7 +632,8 @@ public: /// It returns MVT::iAny if SelectionDAG should be responsible for /// determining it. virtual MVT getOptimalMemOpType(uint64_t Size, unsigned Align, - bool isSrcConst, bool isSrcStr) const { + bool isSrcConst, bool isSrcStr, + SelectionDAG &DAG) const { return MVT::iAny; } diff --git a/include/llvm/Target/TargetOptions.h b/include/llvm/Target/TargetOptions.h index 4869157d746..0c74fa1f2c1 100644 --- a/include/llvm/Target/TargetOptions.h +++ b/include/llvm/Target/TargetOptions.h @@ -73,12 +73,6 @@ namespace llvm { /// target FP instructions. extern bool UseSoftFloat; - /// NoImplicitFloat - This flag is enabled when the -no-implicit-float flag is - /// specified on the command line. When this flag is on, the code generator - /// won't generate any implicit floating point instructions. I.e., no XMM or - /// x87 or vectorized memcpy/memmove instructions. This is for X86 only. - extern bool NoImplicitFloat; - /// NoZerosInBSS - By default some codegens place zero-initialized data to /// .bss section. This flag disables such behaviour (necessary, e.g. for /// crt*.o compiling). diff --git a/lib/AsmParser/LLLexer.cpp b/lib/AsmParser/LLLexer.cpp index 2cfb36656a2..c5190efc4da 100644 --- a/lib/AsmParser/LLLexer.cpp +++ b/lib/AsmParser/LLLexer.cpp @@ -548,6 +548,7 @@ lltok::Kind LLLexer::LexIdentifier() { KEYWORD(ssp); KEYWORD(sspreq); KEYWORD(noredzone); + KEYWORD(noimplicitfloat); KEYWORD(type); KEYWORD(opaque); diff --git a/lib/AsmParser/LLParser.cpp b/lib/AsmParser/LLParser.cpp index b4577ad726d..5c4450244c1 100644 --- a/lib/AsmParser/LLParser.cpp +++ b/lib/AsmParser/LLParser.cpp @@ -712,25 +712,26 @@ bool LLParser::ParseOptionalAttrs(unsigned &Attrs, unsigned AttrKind) { return Error(AttrLoc, "invalid use of parameter-only attribute"); return false; - case lltok::kw_zeroext: Attrs |= Attribute::ZExt; break; - case lltok::kw_signext: Attrs |= Attribute::SExt; break; - case lltok::kw_inreg: Attrs |= Attribute::InReg; break; - case lltok::kw_sret: Attrs |= Attribute::StructRet; break; - case lltok::kw_noalias: Attrs |= Attribute::NoAlias; break; - case lltok::kw_nocapture: Attrs |= Attribute::NoCapture; break; - case lltok::kw_byval: Attrs |= Attribute::ByVal; break; - case lltok::kw_nest: Attrs |= Attribute::Nest; break; + case lltok::kw_zeroext: Attrs |= Attribute::ZExt; break; + case lltok::kw_signext: Attrs |= Attribute::SExt; break; + case lltok::kw_inreg: Attrs |= Attribute::InReg; break; + case lltok::kw_sret: Attrs |= Attribute::StructRet; break; + case lltok::kw_noalias: Attrs |= Attribute::NoAlias; break; + case lltok::kw_nocapture: Attrs |= Attribute::NoCapture; break; + case lltok::kw_byval: Attrs |= Attribute::ByVal; break; + case lltok::kw_nest: Attrs |= Attribute::Nest; break; - case lltok::kw_noreturn: Attrs |= Attribute::NoReturn; break; - case lltok::kw_nounwind: Attrs |= Attribute::NoUnwind; break; - case lltok::kw_noinline: Attrs |= Attribute::NoInline; break; - case lltok::kw_readnone: Attrs |= Attribute::ReadNone; break; - case lltok::kw_readonly: Attrs |= Attribute::ReadOnly; break; - case lltok::kw_alwaysinline: Attrs |= Attribute::AlwaysInline; break; - case lltok::kw_optsize: Attrs |= Attribute::OptimizeForSize; break; - case lltok::kw_ssp: Attrs |= Attribute::StackProtect; break; - case lltok::kw_sspreq: Attrs |= Attribute::StackProtectReq; break; - case lltok::kw_noredzone: Attrs |= Attribute::NoRedZone; break; + case lltok::kw_noreturn: Attrs |= Attribute::NoReturn; break; + case lltok::kw_nounwind: Attrs |= Attribute::NoUnwind; break; + case lltok::kw_noinline: Attrs |= Attribute::NoInline; break; + case lltok::kw_readnone: Attrs |= Attribute::ReadNone; break; + case lltok::kw_readonly: Attrs |= Attribute::ReadOnly; break; + case lltok::kw_alwaysinline: Attrs |= Attribute::AlwaysInline; break; + case lltok::kw_optsize: Attrs |= Attribute::OptimizeForSize; break; + case lltok::kw_ssp: Attrs |= Attribute::StackProtect; break; + case lltok::kw_sspreq: Attrs |= Attribute::StackProtectReq; break; + case lltok::kw_noredzone: Attrs |= Attribute::NoRedZone; break; + case lltok::kw_noimplicitfloat: Attrs |= Attribute::NoImplicitFloat; break; case lltok::kw_align: { unsigned Alignment; diff --git a/lib/AsmParser/LLToken.h b/lib/AsmParser/LLToken.h index c2ce5601d41..9335d19612a 100644 --- a/lib/AsmParser/LLToken.h +++ b/lib/AsmParser/LLToken.h @@ -81,6 +81,7 @@ namespace lltok { kw_ssp, kw_sspreq, kw_noredzone, + kw_noimplicitfloat, kw_type, kw_opaque, diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index c2c884e8d17..a9adce8fdc5 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -3062,7 +3062,7 @@ bool MeetsMaxMemopRequirement(std::vector &MemOps, isSrcStr = isMemSrcFromString(Src, Str); bool isSrcConst = isa(Src); bool AllowUnalign = TLI.allowsUnalignedMemoryAccesses(); - MVT VT = TLI.getOptimalMemOpType(Size, Align, isSrcConst, isSrcStr); + MVT VT = TLI.getOptimalMemOpType(Size, Align, isSrcConst, isSrcStr, DAG); if (VT != MVT::iAny) { unsigned NewAlign = (unsigned) TLI.getTargetData()->getABITypeAlignment(VT.getTypeForMVT()); diff --git a/lib/Target/TargetMachine.cpp b/lib/Target/TargetMachine.cpp index 1259dbee6d0..dea293b502c 100644 --- a/lib/Target/TargetMachine.cpp +++ b/lib/Target/TargetMachine.cpp @@ -85,11 +85,6 @@ GenerateSoftFloatCalls("soft-float", cl::location(UseSoftFloat), cl::init(false)); static cl::opt -GenerateNoImplicitFloats("no-implicit-float", - cl::desc("Don't generate implicit floating point instructions (x86-only)"), - cl::location(NoImplicitFloat), - cl::init(false)); -static cl::opt DontPlaceZerosInBSS("nozero-initialized-in-bss", cl::desc("Don't place zero-initialized symbols into bss section"), cl::location(NoZerosInBSS), diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp index 77c9f3d02a6..b449c7303ea 100644 --- a/lib/Target/X86/X86ISelLowering.cpp +++ b/lib/Target/X86/X86ISelLowering.cpp @@ -868,11 +868,14 @@ unsigned X86TargetLowering::getByValTypeAlignment(const Type *Ty) const { /// determining it. MVT X86TargetLowering::getOptimalMemOpType(uint64_t Size, unsigned Align, - bool isSrcConst, bool isSrcStr) const { + bool isSrcConst, bool isSrcStr, + SelectionDAG &DAG) const { // FIXME: This turns off use of xmm stores for memset/memcpy on targets like // linux. This is because the stack realignment code can't handle certain // cases like PR2962. This should be removed when PR2962 is fixed. - if (!NoImplicitFloat && Subtarget->getStackAlignment() >= 16) { + const Function *F = DAG.getMachineFunction().getFunction(); + bool NoImplicitFloatOps = F->hasFnAttr(Attribute::NoImplicitFloat); + if (!NoImplicitFloatOps && Subtarget->getStackAlignment() >= 16) { if ((isSrcConst || isSrcStr) && Subtarget->hasSSE2() && Size >= 16) return MVT::v4i32; if ((isSrcConst || isSrcStr) && Subtarget->hasSSE1() && Size >= 16) @@ -1404,11 +1407,12 @@ X86TargetLowering::LowerFORMAL_ARGUMENTS(SDValue Op, SelectionDAG &DAG) { unsigned NumXMMRegs = CCInfo.getFirstUnallocated(XMMArgRegs, TotalNumXMMRegs); + bool NoImplicitFloatOps = Fn->hasFnAttr(Attribute::NoImplicitFloat); assert(!(NumXMMRegs && !Subtarget->hasSSE1()) && "SSE register cannot be used when SSE is disabled!"); - assert(!(NumXMMRegs && UseSoftFloat && NoImplicitFloat) && + assert(!(NumXMMRegs && UseSoftFloat && NoImplicitFloatOps) && "SSE register cannot be used when SSE is disabled!"); - if (UseSoftFloat || NoImplicitFloat || !Subtarget->hasSSE1()) + if (UseSoftFloat || NoImplicitFloatOps || !Subtarget->hasSSE1()) // Kernel mode asks for SSE to be disabled, so don't push them // on the stack. TotalNumXMMRegs = 0; @@ -8281,7 +8285,10 @@ static SDValue PerformSTORECombine(SDNode *N, SelectionDAG &DAG, if (VT.getSizeInBits() != 64) return SDValue(); - bool F64IsLegal = !UseSoftFloat && !NoImplicitFloat && Subtarget->hasSSE2(); + const Function *F = DAG.getMachineFunction().getFunction(); + bool NoImplicitFloatOps = F->hasFnAttr(Attribute::NoImplicitFloat); + bool F64IsLegal = !UseSoftFloat && !NoImplicitFloatOps + && Subtarget->hasSSE2(); if ((VT.isVector() || (VT == MVT::i64 && F64IsLegal && !Subtarget->is64Bit())) && isa(St->getValue()) && diff --git a/lib/Target/X86/X86ISelLowering.h b/lib/Target/X86/X86ISelLowering.h index 550f8bdf9b6..fb4eb6815b2 100644 --- a/lib/Target/X86/X86ISelLowering.h +++ b/lib/Target/X86/X86ISelLowering.h @@ -378,7 +378,8 @@ namespace llvm { /// determining it. virtual MVT getOptimalMemOpType(uint64_t Size, unsigned Align, - bool isSrcConst, bool isSrcStr) const; + bool isSrcConst, bool isSrcStr, + SelectionDAG &DAG) const; /// LowerOperation - Provide custom lowering hooks for some operations. /// diff --git a/lib/VMCore/Attributes.cpp b/lib/VMCore/Attributes.cpp index 3ebcadb2330..8dfbd1d5021 100644 --- a/lib/VMCore/Attributes.cpp +++ b/lib/VMCore/Attributes.cpp @@ -61,6 +61,8 @@ std::string Attribute::getAsString(Attributes Attrs) { Result += "sspreq "; if (Attrs & Attribute::NoRedZone) Result += "noredzone "; + if (Attrs & Attribute::NoImplicitFloat) + Result += "noimplicitfloat "; if (Attrs & Attribute::Alignment) { Result += "align "; Result += utostr(Attribute::getAlignmentFromAttrs(Attrs)); diff --git a/test/Other/2009-06-05-no-implicit-float.ll b/test/Other/2009-06-05-no-implicit-float.ll new file mode 100644 index 00000000000..5addfe2d99a --- /dev/null +++ b/test/Other/2009-06-05-no-implicit-float.ll @@ -0,0 +1,4 @@ + +; RUN: llvm-as < %s | opt -verify | llvm-dis | grep noimplicitfloat +define void @f() noimplicitfloat { +} diff --git a/tools/llc/llc.cpp b/tools/llc/llc.cpp index a2474729dd2..c630331d684 100644 --- a/tools/llc/llc.cpp +++ b/tools/llc/llc.cpp @@ -105,6 +105,11 @@ DisableRedZone("disable-red-zone", cl::desc("Do not emit code that uses the red zone."), cl::init(false)); +static cl::opt +NoImplicitFloats("no-implicit-float", + cl::desc("Don't generate implicit floating point instructions (x86-only)"), + cl::init(false)); + // GetFileNameRoot - Helper function to get the basename of a filename. static inline std::string GetFileNameRoot(const std::string &InputFilename) { @@ -344,6 +349,8 @@ int main(int argc, char **argv) { if (!I->isDeclaration()) { if (DisableRedZone) I->addFnAttr(Attribute::NoRedZone); + if (NoImplicitFloats) + I->addFnAttr(Attribute::NoImplicitFloat); Passes.run(*I); }