[llvm] r244503 - x86: Emit LAHF/SAHF instead of PUSHF/POPF

JF Bastien via llvm-commits llvm-commits at lists.llvm.org
Wed Aug 12 10:42:02 PDT 2015


I added the lahf/sahf feature to LLVM in the attached patch, without giving
the property to any CPU for now: with my patch no CPUs are known to support
lahf/sahf, whereas they all were believed to support lahf/sahf before the
patch.

Doing so causes 20 tests to fail (listed below).

The problem dates back to 2012-04-27 with r155704 when Benjamin checked
in X86TargetLowering::ConvertCmpIfNecessary for Christoph Erhardt to fix
PR6679 <https://llvm.org/bugs/show_bug.cgi?id=6679>. This happens
semi-frequently when materializing the results of floating-point
comparisons. I could fix the issue with ConvertCmpIfNecessary as well as
the one I added with X86InstrInfo::copyPhysReg, but at this point in time I
question whether the problem is worth fixing at all: the copyPhysReg corner
case I modified happens *way* less often than ConvertCmpIfNecessary!

WDYT?


Failing tests:
    LLVM :: CodeGen/X86/2004-02-22-Casts.ll
    LLVM :: CodeGen/X86/2004-06-10-StackifierCrash.ll
    LLVM :: CodeGen/X86/2006-05-22-FPSetEQ.ll
    LLVM :: CodeGen/X86/2008-05-01-InvalidOrdCompare.ll
    LLVM :: CodeGen/X86/2009-02-12-SpillerBug.ll
    LLVM :: CodeGen/X86/2009-03-09-SpillerBug.ll
    LLVM :: CodeGen/X86/2012-08-28-UnsafeMathCrash.ll
    LLVM :: CodeGen/X86/2012-10-02-DAGCycle.ll
    LLVM :: CodeGen/X86/bitcast-int-to-vector.ll
    LLVM :: CodeGen/X86/block-placement.ll
    LLVM :: CodeGen/X86/cmovcmov.ll
    LLVM :: CodeGen/X86/constpool.ll
    LLVM :: CodeGen/X86/crash.ll
    LLVM :: CodeGen/X86/fabs.ll
    LLVM :: CodeGen/X86/fp-stack-O0-crash.ll
    LLVM :: CodeGen/X86/fp-stack-compare.ll
    LLVM :: CodeGen/X86/fp-stack.ll
    LLVM :: CodeGen/X86/isnan.ll
    LLVM :: CodeGen/X86/setuge.ll
    LLVM :: CodeGen/X86/stack-protector.ll

On Mon, Aug 10, 2015 at 6:02 PM, JF Bastien <jfb at google.com> wrote:

> Ha, you're right. Thanks for pointing it out.
>
> How about I add a FeatureLAHFSAHF, and continue using PUSHF/POPF if
> unsupported?
>
> On Mon, Aug 10, 2015 at 5:41 PM, Eli Friedman <eli.friedman at gmail.com>
> wrote:
>
>> On Mon, Aug 10, 2015 at 1:59 PM, JF Bastien via llvm-commits <
>> llvm-commits at lists.llvm.org> wrote:
>>
>>> Author: jfb
>>> Date: Mon Aug 10 15:59:36 2015
>>> New Revision: 244503
>>>
>>> URL: http://llvm.org/viewvc/llvm-project?rev=244503&view=rev
>>> Log:
>>> x86: Emit LAHF/SAHF instead of PUSHF/POPF
>>>
>>> NaCl's sandbox doesn't allow PUSHF/POPF out of security concerns
>>> (priviledged emulators have forgotten to mask system bits in the past, and
>>> EFLAGS's DF bit is a constant source of hilarity). Commit r220529 fixed
>>> PR20376 by saving cmpxchg's flags result using EFLAGS, this commit now
>>> generated LAHF/SAHF instead, for all of x86 (not just NaCl) because it
>>> leads to an overall performance gain over PUSHF/POPF.
>>>
>>
>> There's a problem with this: not all x86 CPUs support lahf/sahf in 64-bit
>> mode.
>>
>> -Eli
>>
>>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20150812/43fb9bd2/attachment.html>
-------------- next part --------------
diff --git a/lib/Target/X86/X86.td b/lib/Target/X86/X86.td
index 7c2a0c0..b929ec2 100644
--- a/lib/Target/X86/X86.td
+++ b/lib/Target/X86/X86.td
@@ -166,6 +166,8 @@ def FeatureSHA     : SubtargetFeature<"sha", "HasSHA", "true",
                                       [FeatureSSE2]>;
 def FeaturePRFCHW  : SubtargetFeature<"prfchw", "HasPRFCHW", "true",
                                       "Support PRFCHW instructions">;
+def FeatureLAHFSAHF : SubtargetFeature<"lahfsahf", "HasLAHFSAHF", "true",
+                                       "Support LAHF and SAHF instructions">;
 def FeatureRDSEED  : SubtargetFeature<"rdseed", "HasRDSEED", "true",
                                       "Support RDSEED instruction">;
 def FeatureMPX     : SubtargetFeature<"mpx", "HasMPX", "true",
diff --git a/lib/Target/X86/X86InstrInfo.td b/lib/Target/X86/X86InstrInfo.td
index 17b13e3..58e038c 100644
--- a/lib/Target/X86/X86InstrInfo.td
+++ b/lib/Target/X86/X86InstrInfo.td
@@ -796,6 +796,7 @@ def HasSHA       : Predicate<"Subtarget->hasSHA()">;
 def HasPRFCHW    : Predicate<"Subtarget->hasPRFCHW()">;
 def HasRDSEED    : Predicate<"Subtarget->hasRDSEED()">;
 def HasPrefetchW : Predicate<"Subtarget->hasPRFCHW()">;
+def HasLAHFSAHF  : Predicate<"Subtarget->hasLAHFSAHF()">;
 def FPStackf32   : Predicate<"!Subtarget->hasSSE1()">;
 def FPStackf64   : Predicate<"!Subtarget->hasSSE2()">;
 def HasMPX       : Predicate<"Subtarget->hasMPX()">;
@@ -1499,10 +1500,12 @@ def MOV8rm_NOREX : I<0x8A, MRMSrcMem,
 let SchedRW = [WriteALU] in {
 let Defs = [EFLAGS], Uses = [AH] in
 def SAHF     : I<0x9E, RawFrm, (outs),  (ins), "sahf",
-                 [(set EFLAGS, (X86sahf AH))], IIC_AHF>;
+                 [(set EFLAGS, (X86sahf AH))], IIC_AHF>,
+		Requires<[HasLAHFSAHF]>;
 let Defs = [AH], Uses = [EFLAGS], hasSideEffects = 0 in
 def LAHF     : I<0x9F, RawFrm, (outs),  (ins), "lahf", [],
-                IIC_AHF>;  // AH = flags
+                 IIC_AHF>, // AH = flags
+		Requires<[HasLAHFSAHF]>;
 } // SchedRW
 
 //===----------------------------------------------------------------------===//
diff --git a/lib/Target/X86/X86Subtarget.cpp b/lib/Target/X86/X86Subtarget.cpp
index dff3624..d64422e 100644
--- a/lib/Target/X86/X86Subtarget.cpp
+++ b/lib/Target/X86/X86Subtarget.cpp
@@ -255,6 +255,7 @@ void X86Subtarget::initializeEnvironment() {
   HasSHA = false;
   HasPRFCHW = false;
   HasRDSEED = false;
+  HasLAHFSAHF = false;
   HasMPX = false;
   IsBTMemSlow = false;
   IsSHLDSlow = false;
@@ -320,4 +321,3 @@ X86Subtarget::X86Subtarget(const Triple &TT, const std::string &CPU,
 bool X86Subtarget::enableEarlyIfConversion() const {
   return hasCMov() && X86EarlyIfConv;
 }
-
diff --git a/lib/Target/X86/X86Subtarget.h b/lib/Target/X86/X86Subtarget.h
index f026d42..a018019 100644
--- a/lib/Target/X86/X86Subtarget.h
+++ b/lib/Target/X86/X86Subtarget.h
@@ -140,6 +140,9 @@ protected:
   /// Processor has RDSEED instructions.
   bool HasRDSEED;
 
+  /// Processor has LAHF/SAHF instructions.
+  bool HasLAHFSAHF;
+
   /// True if BT (bit test) of memory instructions are slow.
   bool IsBTMemSlow;
 
@@ -355,6 +358,7 @@ public:
   bool hasSHA() const { return HasSHA; }
   bool hasPRFCHW() const { return HasPRFCHW; }
   bool hasRDSEED() const { return HasRDSEED; }
+  bool hasLAHFSAHF() const { return HasLAHFSAHF; }
   bool isBTMemSlow() const { return IsBTMemSlow; }
   bool isSHLDSlow() const { return IsSHLDSlow; }
   bool isUnalignedMemAccessFast() const { return IsUAMemFast; }


More information about the llvm-commits mailing list