]> granicus.if.org Git - llvm/commitdiff
[PowerPC] Refactor soft-float support, and enable PPC64 soft float
authorHal Finkel <hfinkel@anl.gov>
Sun, 2 Oct 2016 02:10:20 +0000 (02:10 +0000)
committerHal Finkel <hfinkel@anl.gov>
Sun, 2 Oct 2016 02:10:20 +0000 (02:10 +0000)
This change enables soft-float for PowerPC64, and also makes soft-float disable
all vector instruction sets for both 32-bit and 64-bit modes. This latter part
is necessary because the PPC backend canonicalizes many Altivec vector types to
floating-point types, and so soft-float breaks scalarization support for many
operations. Both for embedded targets and for operating-system kernels desiring
soft-float support, it seems reasonable that disabling hardware floating-point
also disables vector instructions (embedded targets without hardware floating
point support are unlikely to have Altivec, etc. and operating system kernels
desiring not to use floating-point registers to lower syscall cost are unlikely
to want to use vector registers either). If someone needs this to work, we'll
need to change the fact that we promote many Altivec operations to act on
v4f32. To make it possible to disable Altivec when soft-float is enabled,
hardware floating-point support needs to be expressed as a positive feature,
like the others, and not a negative feature, because target features cannot
have dependencies on the disabling of some other feature. So +soft-float has
now become -hard-float.

Fixes PR26970.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@283060 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/PowerPC/PPC.td
lib/Target/PowerPC/PPCISelLowering.cpp
lib/Target/PowerPC/PPCSubtarget.cpp
lib/Target/PowerPC/PPCSubtarget.h
lib/Target/PowerPC/PPCTargetMachine.cpp
test/CodeGen/PowerPC/ppcsoftops.ll

index 279c430e1ce9a7356ea0425787abbe7328cdc9da..ee3d6501fae66c868a00fa1c8f65a27f7c8ee118 100644 (file)
@@ -53,40 +53,52 @@ def DirectivePwr9: SubtargetFeature<"", "DarwinDirective", "PPC::DIR_PWR9", "">;
 
 def Feature64Bit     : SubtargetFeature<"64bit","Has64BitSupport", "true",
                                         "Enable 64-bit instructions">;
-def FeatureSoftFloat : SubtargetFeature<"soft-float", "UseSoftFloat", "true",
-                              "Use software emulation for floating point">;                                        
+def FeatureHardFloat : SubtargetFeature<"hard-float", "HasHardFloat", "true",
+                              "Enable floating-point instructions">;
 def Feature64BitRegs : SubtargetFeature<"64bitregs","Use64BitRegs", "true",
                               "Enable 64-bit registers usage for ppc32 [beta]">;
 def FeatureCRBits    : SubtargetFeature<"crbits", "UseCRBits", "true",
                               "Use condition-register bits individually">;
 def FeatureAltivec   : SubtargetFeature<"altivec","HasAltivec", "true",
-                                        "Enable Altivec instructions">;
+                                        "Enable Altivec instructions",
+                                        [FeatureHardFloat]>;
 def FeatureSPE       : SubtargetFeature<"spe","HasSPE", "true",
-                                        "Enable SPE instructions">;
+                                        "Enable SPE instructions",
+                                        [FeatureHardFloat]>;
 def FeatureMFOCRF    : SubtargetFeature<"mfocrf","HasMFOCRF", "true",
                                         "Enable the MFOCRF instruction">;
 def FeatureFSqrt     : SubtargetFeature<"fsqrt","HasFSQRT", "true",
-                                        "Enable the fsqrt instruction">;
+                                        "Enable the fsqrt instruction",
+                                        [FeatureHardFloat]>;
 def FeatureFCPSGN    : SubtargetFeature<"fcpsgn", "HasFCPSGN", "true",
-                                        "Enable the fcpsgn instruction">;
+                                        "Enable the fcpsgn instruction",
+                                        [FeatureHardFloat]>;
 def FeatureFRE       : SubtargetFeature<"fre", "HasFRE", "true",
-                                        "Enable the fre instruction">;
+                                        "Enable the fre instruction",
+                                        [FeatureHardFloat]>;
 def FeatureFRES      : SubtargetFeature<"fres", "HasFRES", "true",
-                                        "Enable the fres instruction">;
+                                        "Enable the fres instruction",
+                                        [FeatureHardFloat]>;
 def FeatureFRSQRTE   : SubtargetFeature<"frsqrte", "HasFRSQRTE", "true",
-                                        "Enable the frsqrte instruction">;
+                                        "Enable the frsqrte instruction",
+                                        [FeatureHardFloat]>;
 def FeatureFRSQRTES  : SubtargetFeature<"frsqrtes", "HasFRSQRTES", "true",
-                                        "Enable the frsqrtes instruction">;
+                                        "Enable the frsqrtes instruction",
+                                        [FeatureHardFloat]>;
 def FeatureRecipPrec : SubtargetFeature<"recipprec", "HasRecipPrec", "true",
                               "Assume higher precision reciprocal estimates">;
 def FeatureSTFIWX    : SubtargetFeature<"stfiwx","HasSTFIWX", "true",
-                                        "Enable the stfiwx instruction">;
+                                        "Enable the stfiwx instruction",
+                                        [FeatureHardFloat]>;
 def FeatureLFIWAX    : SubtargetFeature<"lfiwax","HasLFIWAX", "true",
-                                        "Enable the lfiwax instruction">;
+                                        "Enable the lfiwax instruction",
+                                        [FeatureHardFloat]>;
 def FeatureFPRND     : SubtargetFeature<"fprnd", "HasFPRND", "true",
-                                        "Enable the fri[mnpz] instructions">;
+                                        "Enable the fri[mnpz] instructions",
+                                        [FeatureHardFloat]>;
 def FeatureFPCVT     : SubtargetFeature<"fpcvt", "HasFPCVT", "true",
-  "Enable fc[ft]* (unsigned and single-precision) and lfiwzx instructions">;
+  "Enable fc[ft]* (unsigned and single-precision) and lfiwzx instructions",
+                                        [FeatureHardFloat]>;
 def FeatureISEL      : SubtargetFeature<"isel","HasISEL", "true",
                                         "Enable the isel instruction">;
 def FeatureBPERMD    : SubtargetFeature<"bpermd", "HasBPERMD", "true",
@@ -112,7 +124,8 @@ def FeaturePPC4xx    : SubtargetFeature<"ppc4xx", "IsPPC4xx", "true",
 def FeaturePPC6xx    : SubtargetFeature<"ppc6xx", "IsPPC6xx", "true",
                                         "Enable PPC 6xx instructions">;
 def FeatureQPX       : SubtargetFeature<"qpx","HasQPX", "true",
-                                        "Enable QPX instructions">;
+                                        "Enable QPX instructions",
+                                        [FeatureHardFloat]>;
 def FeatureVSX       : SubtargetFeature<"vsx","HasVSX", "true",
                                         "Enable VSX instructions",
                                         [FeatureAltivec]>;
@@ -282,7 +295,8 @@ include "PPCInstrInfo.td"
 // PowerPC processors supported.
 //
 
-def : Processor<"generic", G3Itineraries, [Directive32, FeatureMFTB]>;
+def : Processor<"generic", G3Itineraries, [Directive32, FeatureHardFloat,
+                                           FeatureMFTB]>;
 def : ProcessorModel<"440", PPC440Model, [Directive440, FeatureISEL,
                                           FeatureFRES, FeatureFRSQRTE,
                                           FeatureICBT, FeatureBookE, 
@@ -291,8 +305,8 @@ def : ProcessorModel<"450", PPC440Model, [Directive440, FeatureISEL,
                                           FeatureFRES, FeatureFRSQRTE,
                                           FeatureICBT, FeatureBookE, 
                                           FeatureMSYNC, FeatureMFTB]>;
-def : Processor<"601", G3Itineraries, [Directive601]>;
-def : Processor<"602", G3Itineraries, [Directive602,
+def : Processor<"601", G3Itineraries, [Directive601, FeatureHardFloat]>;
+def : Processor<"602", G3Itineraries, [Directive602, FeatureHardFloat,
                                        FeatureMFTB]>;
 def : Processor<"603", G3Itineraries, [Directive603,
                                        FeatureFRES, FeatureFRSQRTE,
@@ -406,7 +420,10 @@ def : ProcessorModel<"pwr7", P7Model, ProcessorFeatures.Power7FeatureList>;
 def : ProcessorModel<"pwr8", P8Model, ProcessorFeatures.Power8FeatureList>;
 // FIXME: Same as P8 until the POWER9 scheduling info is available
 def : ProcessorModel<"pwr9", P8Model, ProcessorFeatures.Power9FeatureList>;
-def : Processor<"ppc", G3Itineraries, [Directive32, FeatureMFTB]>;
+def : Processor<"ppc", G3Itineraries, [Directive32, FeatureHardFloat,
+                                       FeatureMFTB]>;
+def : Processor<"ppc32", G3Itineraries, [Directive32, FeatureHardFloat,
+                                         FeatureMFTB]>;
 def : ProcessorModel<"ppc64", G5Model,
                   [Directive64, FeatureAltivec,
                    FeatureMFOCRF, FeatureFSqrt, FeatureFRES,
index d203404659e93069c0a571de7a3905c341b724b3..614f368f557463abfce5495a101b00326f0ea491 100644 (file)
@@ -3175,7 +3175,7 @@ SDValue PPCTargetLowering::LowerFormalArguments_64SVR4(
   };
 
   const unsigned Num_GPR_Regs = array_lengthof(GPR);
-  const unsigned Num_FPR_Regs = 13;
+  const unsigned Num_FPR_Regs = useSoftFloat() ? 0 : 13;
   const unsigned Num_VR_Regs  = array_lengthof(VR);
   const unsigned Num_QFPR_Regs = Num_FPR_Regs;
 
@@ -3588,7 +3588,7 @@ SDValue PPCTargetLowering::LowerFormalArguments_Darwin(
   };
 
   const unsigned Num_GPR_Regs = array_lengthof(GPR_32);
-  const unsigned Num_FPR_Regs = 13;
+  const unsigned Num_FPR_Regs = useSoftFloat() ? 0 : 13;
   const unsigned Num_VR_Regs  = array_lengthof( VR);
 
   unsigned GPR_idx = 0, FPR_idx = 0, VR_idx = 0;
@@ -10564,7 +10564,7 @@ SDValue PPCTargetLowering::combineFPToIntToFP(SDNode *N,
           N->getOpcode() == ISD::UINT_TO_FP) &&
          "Need an int -> FP conversion node here");
 
-  if (!Subtarget.has64BitSupport())
+  if (useSoftFloat() || !Subtarget.has64BitSupport())
     return SDValue();
 
   SelectionDAG &DAG = DCI.DAG;
index 195707352953086e92bb648ca60c99195cbd2021..e8a87e7f4437feb3f31fe08214bad161434c8a97 100644 (file)
@@ -62,7 +62,7 @@ void PPCSubtarget::initializeEnvironment() {
   Has64BitSupport = false;
   Use64BitRegs = false;
   UseCRBits = false;
-  UseSoftFloat = false;
+  HasHardFloat = false;
   HasAltivec = false;
   HasSPE = false;
   HasQPX = false;
index d80a9ad8d34bbd93f55866cba54dea713c0ca278..7fd907990cebe0d459fd323a4f3b5d9070abb666 100644 (file)
@@ -91,7 +91,7 @@ protected:
   bool Has64BitSupport;
   bool Use64BitRegs;
   bool UseCRBits;
-  bool UseSoftFloat;
+  bool HasHardFloat;
   bool IsPPC64;
   bool HasAltivec;
   bool HasSPE;
@@ -205,7 +205,7 @@ public:
   /// instructions, regardless of whether we are in 32-bit or 64-bit mode.
   bool has64BitSupport() const { return Has64BitSupport; }
   // useSoftFloat - Return true if soft-float option is turned on.
-  bool useSoftFloat() const { return UseSoftFloat; }
+  bool useSoftFloat() const { return !HasHardFloat; }
 
   /// use64BitRegs - Return true if in 64-bit mode or if we should use 64-bit
   /// registers in 32-bit mode when possible.  This can only true if
index a4ff86cb1e217139621f7f20fc21372ed14e4095..1bb6b674081b4891974b01c856d85cdf3f905bf3 100644 (file)
@@ -268,7 +268,7 @@ PPCTargetMachine::getSubtargetImpl(const Function &F) const {
   // If the soft float attribute is set on the function turn on the soft float
   // subtarget feature.
   if (SoftFloat)
-    FS += FS.empty() ? "+soft-float" : ",+soft-float";
+    FS += FS.empty() ? "-hard-float" : ",-hard-float";
 
   auto &I = SubtargetMap[CPU + FS];
   if (!I) {
index 19c241d667f7a817919366eacaa34d454b3a0265..5ecfbb4414e9b505f6eb89b3aab5748a1f159c6e 100644 (file)
@@ -1,4 +1,6 @@
 ; RUN: llc -verify-machineinstrs  -mtriple=powerpc-unknown-linux-gnu -O0 < %s | FileCheck %s
+; RUN: llc -verify-machineinstrs  -mtriple=powerpc64-unknown-linux-gnu -O0 < %s | FileCheck %s
+; RUN: llc -verify-machineinstrs  -mtriple=powerpc64le-unknown-linux-gnu -O0 < %s | FileCheck %s
 
 ; Testing operations in soft-float mode
 define double @foo() #0 {