<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Thu, Dec 17, 2015 at 3:18 PM, Hans Wennborg via llvm-commits <span dir="ltr"><<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">Author: hans<br>
Date: Thu Dec 17 17:18:39 2015<br>
New Revision: 255936<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=255936&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=255936&view=rev</a><br>
Log:<br>
[X86] Use push-pop for materializing small constants under 'minsize'<br>
<br>
Use the 3-byte (4 with REX prefix) push-pop sequence for materializing<br>
small constants. This is smaller than using a mov (5, 6 or 7 bytes<br>
depending on size and REX prefix), but it's likely to be slower, so<br>
only used for 'minsize'.<br>
<br>
This is a follow-up to r255656.<br>
<br>
Differential Revision: <a href="http://reviews.llvm.org/D15549" rel="noreferrer" target="_blank">http://reviews.llvm.org/D15549</a><br>
<br>
Added:<br>
    llvm/trunk/test/CodeGen/X86/materialize.ll<br>
Removed:<br>
    llvm/trunk/test/CodeGen/X86/materialize-one.ll<br>
Modified:<br>
    llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp<br>
    llvm/trunk/lib/Target/X86/X86InstrCompiler.td<br>
    llvm/trunk/lib/Target/X86/X86InstrInfo.cpp<br>
    llvm/trunk/lib/Target/X86/X86InstrInfo.h<br>
    llvm/trunk/lib/Target/X86/X86InstrInfo.td<br>
    llvm/trunk/test/CodeGen/X86/powi.ll<br>
<br>
Modified: llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp?rev=255936&r1=255935&r2=255936&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp?rev=255936&r1=255935&r2=255936&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp (original)<br>
+++ llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp Thu Dec 17 17:18:39 2015<br>
@@ -157,9 +157,13 @@ namespace {<br>
     /// performance.<br>
     bool OptForSize;<br>
<br>
+    /// If true, selector should try to optimize for minimum code size.<br>
+    bool OptForMinSize;<br>
+<br>
   public:<br>
     explicit X86DAGToDAGISel(X86TargetMachine &tm, CodeGenOpt::Level OptLevel)<br>
-        : SelectionDAGISel(tm, OptLevel), OptForSize(false) {}<br>
+        : SelectionDAGISel(tm, OptLevel), OptForSize(false),<br>
+          OptForMinSize(false) {}<br>
<br>
     const char *getPassName() const override {<br>
       return "X86 DAG->DAG Instruction Selection";<br>
@@ -531,8 +535,10 @@ static bool isCalleeLoad(SDValue Callee,<br>
 }<br>
<br>
 void X86DAGToDAGISel::PreprocessISelDAG() {<br>
-  // OptForSize is used in pattern predicates that isel is matching.<br>
+  // OptFor[Min]Size are used in pattern predicates that isel is matching.<br>
   OptForSize = MF->getFunction()->optForSize();<br>
+  OptForMinSize = MF->getFunction()->optForMinSize();<br>
+  assert((!OptForMinSize || OptForSize) && "OptForMinSize implies OptForSize");<br>
<br>
   for (SelectionDAG::allnodes_iterator I = CurDAG->allnodes_begin(),<br>
        E = CurDAG->allnodes_end(); I != E; ) {<br>
<br>
Modified: llvm/trunk/lib/Target/X86/X86InstrCompiler.td<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrCompiler.td?rev=255936&r1=255935&r2=255936&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrCompiler.td?rev=255936&r1=255935&r2=255936&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Target/X86/X86InstrCompiler.td (original)<br>
+++ llvm/trunk/lib/Target/X86/X86InstrCompiler.td Thu Dec 17 17:18:39 2015<br>
@@ -250,7 +250,7 @@ def MORESTACK_RET_RESTORE_R10 : I<0, Pse<br>
 // Alias instruction mapping movr0 to xor.<br>
 // FIXME: remove when we can teach regalloc that xor reg, reg is ok.<br>
 let Defs = [EFLAGS], isReMaterializable = 1, isAsCheapAsAMove = 1,<br>
-    isPseudo = 1 in<br>
+    isPseudo = 1, AddedComplexity = 20 in<br>
 def MOV32r0  : I<0, Pseudo, (outs GR32:$dst), (ins), "",<br>
                  [(set GR32:$dst, 0)], IIC_ALU_NONMEM>, Sched<[WriteZero]>;<br>
<br>
@@ -263,7 +263,7 @@ def : Pat<(i64 0), (SUBREG_TO_REG (i64 0<br>
 }<br>
<br>
 let Predicates = [OptForSize, NotSlowIncDec, Not64BitMode],<br>
-    AddedComplexity = 1 in {<br>
+    AddedComplexity = 15 in {<br>
   // Pseudo instructions for materializing 1 and -1 using XOR+INC/DEC,<br>
   // which only require 3 bytes compared to MOV32ri which requires 5.<br>
   let Defs = [EFLAGS], isReMaterializable = 1, isPseudo = 1 in {<br>
@@ -278,6 +278,17 @@ let Predicates = [OptForSize, NotSlowInc<br>
   def : Pat<(i16 -1), (EXTRACT_SUBREG (MOV32r_1), sub_16bit)>;<br>
 }<br>
<br>
+let isReMaterializable = 1, isPseudo = 1, AddedComplexity = 10 in {<br>
+// AddedComplexity higher than MOV64ri but lower than MOV32r0 and MOV32r1.<br>
+// FIXME: Add itinerary class and Schedule.<br>
+def MOV32ImmSExti8 : I<0, Pseudo, (outs GR32:$dst), (ins i32i8imm:$src), "",<br>
+                       [(set GR32:$dst, i32immSExt8:$src)]>,<br>
+                     Requires<[OptForMinSize]>;<br>
+def MOV64ImmSExti8 : I<0, Pseudo, (outs GR64:$dst), (ins i64i8imm:$src), "",<br>
+                       [(set GR64:$dst, i64immSExt8:$src)]>,<br>
+                     Requires<[OptForMinSize, NotWin64WithoutFP]>;<br>
+}<br>
+<br>
 // Materialize i64 constant where top 32-bits are zero. This could theoretically<br>
 // use MOV32ri with a SUBREG_TO_REG to represent the zero-extension, however<br>
 // that would make it more difficult to rematerialize.<br>
<br>
Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.cpp?rev=255936&r1=255935&r2=255936&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.cpp?rev=255936&r1=255935&r2=255936&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Target/X86/X86InstrInfo.cpp (original)<br>
+++ llvm/trunk/lib/Target/X86/X86InstrInfo.cpp Thu Dec 17 17:18:39 2015<br>
@@ -23,6 +23,7 @@<br>
 #include "llvm/CodeGen/MachineDominators.h"<br>
 #include "llvm/CodeGen/MachineFrameInfo.h"<br>
 #include "llvm/CodeGen/MachineInstrBuilder.h"<br>
+#include "llvm/CodeGen/MachineModuleInfo.h"<br>
 #include "llvm/CodeGen/MachineRegisterInfo.h"<br>
 #include "llvm/CodeGen/StackMaps.h"<br>
 #include "llvm/IR/DerivedTypes.h"<br>
@@ -5297,6 +5298,50 @@ static bool expandMOV32r1(MachineInstrBu<br>
   return true;<br>
 }<br>
<br>
+bool X86InstrInfo::ExpandMOVImmSExti8(MachineInstrBuilder &MIB) const {<br>
+  MachineBasicBlock &MBB = *MIB->getParent();<br>
+  DebugLoc DL = MIB->getDebugLoc();<br>
+  int64_t Imm = MIB->getOperand(1).getImm();<br>
+  assert(Imm != 0 && "Using push/pop for 0 is not efficient.");<br>
+  MachineBasicBlock::iterator I = MIB.getInstr();<br>
+<br>
+  int StackAdjustment;<br>
+<br>
+  if (Subtarget.is64Bit()) {<br>
+    assert(MIB->getOpcode() == X86::MOV64ImmSExti8 ||<br>
+           MIB->getOpcode() == X86::MOV32ImmSExti8);<br>
+    // 64-bit mode doesn't have 32-bit push/pop, so use 64-bit operations and<br>
+    // widen the register if necessary.<br>
+    StackAdjustment = 8;<br>
+    BuildMI(MBB, I, DL, get(X86::PUSH64i8)).addImm(Imm);<br>
+    MIB->setDesc(get(X86::POP64r));<br>
+    MIB->getOperand(0)<br>
+        .setReg(getX86SubSuperRegister(MIB->getOperand(0).getReg(), MVT::i64));<br>
+  } else {<br>
+    assert(MIB->getOpcode() == X86::MOV32ImmSExti8);<br>
+    StackAdjustment = 4;<br>
+    BuildMI(MBB, I, DL, get(X86::PUSH32i8)).addImm(Imm);<br>
+    MIB->setDesc(get(X86::POP32r));<br>
+  }<br>
+<br>
+  // Build CFI if necessary.<br>
+  MachineFunction &MF = *MBB.getParent();<br>
+  const X86FrameLowering *TFL = Subtarget.getFrameLowering();<br>
+  bool IsWin64Prologue = MF.getTarget().getMCAsmInfo()->usesWindowsCFI();<br>
+  bool NeedsDwarfCFI =<br>
+      !IsWin64Prologue &&<br>
+      (MF.getMMI().hasDebugInfo() || MF.getFunction()->needsUnwindTableEntry());<br>
+  bool EmitCFI = !TFL->hasFP(MF) && NeedsDwarfCFI;<br>
+  if (EmitCFI) {<br>
+    TFL->BuildCFI(MBB, I, DL,<br>
+        MCCFIInstruction::createAdjustCfaOffset(nullptr, StackAdjustment));<br>
+    TFL->BuildCFI(MBB, std::next(I), DL,<br>
+        MCCFIInstruction::createAdjustCfaOffset(nullptr, -StackAdjustment));<br>
+  }<br>
+<br>
+  return true;<br>
+}<br>
+<br>
 // LoadStackGuard has so far only been implemented for 64-bit MachO. Different<br>
 // code sequence is needed for other targets.<br>
 static void expandLoadStackGuard(MachineInstrBuilder &MIB,<br>
@@ -5329,6 +5374,9 @@ bool X86InstrInfo::expandPostRAPseudo(Ma<br>
     return expandMOV32r1(MIB, *this, /*MinusOne=*/ false);<br>
   case X86::MOV32r_1:<br>
     return expandMOV32r1(MIB, *this, /*MinusOne=*/ true);<br>
+  case X86::MOV32ImmSExti8:<br>
+  case X86::MOV64ImmSExti8:<br>
+    return ExpandMOVImmSExti8(MIB);<br>
   case X86::SETB_C8r:<br>
     return Expand2AddrUndef(MIB, get(X86::SBB8rr));<br>
   case X86::SETB_C16r:<br>
<br>
Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.h?rev=255936&r1=255935&r2=255936&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.h?rev=255936&r1=255935&r2=255936&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Target/X86/X86InstrInfo.h (original)<br>
+++ llvm/trunk/lib/Target/X86/X86InstrInfo.h Thu Dec 17 17:18:39 2015<br>
@@ -23,6 +23,7 @@<br>
 #include "X86GenInstrInfo.inc"<br>
<br>
 namespace llvm {<br>
+  class MachineInstrBuilder;<br>
   class X86RegisterInfo;<br>
   class X86Subtarget;<br>
<br>
@@ -564,6 +565,9 @@ private:<br>
   /// operand and follow operands form a reference to the stack frame.<br>
   bool isFrameOperand(const MachineInstr *MI, unsigned int Op,<br>
                       int &FrameIndex) const;<br>
+<br>
+  /// Expand the MOVImmSExti8 pseudo-instructions.<br>
+  bool ExpandMOVImmSExti8(MachineInstrBuilder &MIB) const;<br>
 };<br>
<br>
 } // End llvm namespace<br>
<br>
Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.td<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.td?rev=255936&r1=255935&r2=255936&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.td?rev=255936&r1=255935&r2=255936&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Target/X86/X86InstrInfo.td (original)<br>
+++ llvm/trunk/lib/Target/X86/X86InstrInfo.td Thu Dec 17 17:18:39 2015<br>
@@ -820,6 +820,8 @@ def In32BitMode  : Predicate<"Subtarget-<br>
                              AssemblerPredicate<"Mode32Bit", "32-bit mode">;<br>
 def IsWin64      : Predicate<"Subtarget->isTargetWin64()">;<br>
 def NotWin64     : Predicate<"!Subtarget->isTargetWin64()">;<br>
+def NotWin64WithoutFP : Predicate<"!Subtarget->isTargetWin64() ||"<br>
+                                  "Subtarget->getFrameLowering()->hasFP(*MF)">;<br>
 def IsPS4        : Predicate<"Subtarget->isTargetPS4()">;<br>
 def NotPS4       : Predicate<"!Subtarget->isTargetPS4()">;<br>
 def IsNaCl       : Predicate<"Subtarget->isTargetNaCl()">;<br>
@@ -833,6 +835,7 @@ def NearData     : Predicate<"TM.getCode<br>
 def IsStatic     : Predicate<"TM.getRelocationModel() == Reloc::Static">;<br>
 def IsNotPIC     : Predicate<"TM.getRelocationModel() != Reloc::PIC_">;<br>
 def OptForSize   : Predicate<"OptForSize">;<br>
+def OptForMinSize : Predicate<"OptForMinSize">;<br>
 def OptForSpeed  : Predicate<"!OptForSize">;<br>
 def FastBTMem    : Predicate<"!Subtarget->isBTMemSlow()">;<br>
 def CallImmAddr  : Predicate<"Subtarget->IsLegalToCallImmediateAddr(TM)">;<br>
<br>
Removed: llvm/trunk/test/CodeGen/X86/materialize-one.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/materialize-one.ll?rev=255935&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/materialize-one.ll?rev=255935&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/test/CodeGen/X86/materialize-one.ll (original)<br>
+++ llvm/trunk/test/CodeGen/X86/materialize-one.ll (removed)<br>
@@ -1,100 +0,0 @@<br>
-; RUN: llc -mtriple=i686-unknown-linux-gnu -mattr=+cmov %s -o - | FileCheck %s --check-prefix=CHECK32<br>
-; RUN: llc -mtriple=x86_64-unknown-linux-gnu -mattr=+cmov %s -o - | FileCheck %s --check-prefix=CHECK64<br>
-<br>
-define i32 @one32() optsize {<br>
-entry:<br>
-  ret i32 1<br>
-<br>
-; CHECK32-LABEL: one32<br>
-; CHECK32:       xorl %eax, %eax<br>
-; CHECK32-NEXT:  incl %eax<br>
-; CHECK32-NEXT:  ret<br>
-<br>
-; FIXME: Figure out the best approach in 64-bit mode.<br>
-; CHECK64-LABEL: one32<br>
-; CHECK64:       movl $1, %eax<br>
-; CHECK64-NEXT:  retq<br>
-}<br>
-<br>
-define i32 @minus_one32() optsize {<br>
-entry:<br>
-  ret i32 -1<br>
-<br>
-; CHECK32-LABEL: minus_one32<br>
-; CHECK32:       xorl %eax, %eax<br>
-; CHECK32-NEXT:  decl %eax<br>
-; CHECK32-NEXT:  ret<br>
-}<br>
-<br>
-define i16 @one16() optsize {<br>
-entry:<br>
-  ret i16 1<br>
-<br>
-; CHECK32-LABEL: one16<br>
-; CHECK32:       xorl %eax, %eax<br>
-; CHECK32-NEXT:  incl %eax<br>
-; CHECK32-NEXT:  retl<br>
-}<br>
-<br>
-define i16 @minus_one16() optsize {<br>
-entry:<br>
-  ret i16 -1<br>
-<br>
-; CHECK32-LABEL: minus_one16<br>
-; CHECK32:       xorl %eax, %eax<br>
-; CHECK32-NEXT:  decl %eax<br>
-; CHECK32-NEXT:  retl<br>
-}<br>
-<br>
-define i32 @test_rematerialization() optsize {<br>
-entry:<br>
-  ; Materialize -1 (thiscall forces it into %ecx).<br>
-  tail call x86_thiscallcc void @f(i32 -1)<br>
-<br>
-  ; Clobber all registers except %esp, leaving nowhere to store the -1 besides<br>
-  ; spilling it to the stack.<br>
-  tail call void asm sideeffect "", "~{eax},~{ebx},~{ecx},~{edx},~{edi},~{esi},~{ebp},~{dirflag},~{fpsr},~{flags}"()<br>
-<br>
-  ; -1 should be re-materialized here instead of getting spilled above.<br>
-  ret i32 -1<br>
-<br>
-; CHECK32-LABEL: test_rematerialization<br>
-; CHECK32:       xorl %ecx, %ecx<br>
-; CHECK32-NEXT:  decl %ecx<br>
-; CHECK32:       calll<br>
-; CHECK32:       xorl %eax, %eax<br>
-; CHECK32-NEXT:  decl %eax<br>
-; CHECK32-NOT:   %eax<br>
-; CHECK32:       retl<br>
-}<br>
-<br>
-define i32 @test_rematerialization2(i32 %x) optsize {<br>
-entry:<br>
-  ; Materialize -1 (thiscall forces it into %ecx).<br>
-  tail call x86_thiscallcc void @f(i32 -1)<br>
-<br>
-  ; Clobber all registers except %esp, leaving nowhere to store the -1 besides<br>
-  ; spilling it to the stack.<br>
-  tail call void asm sideeffect "", "~{eax},~{ebx},~{ecx},~{edx},~{edi},~{esi},~{ebp},~{dirflag},~{fpsr},~{flags}"()<br>
-<br>
-  ; Define eflags.<br>
-  %a = icmp ne i32 %x, 123<br>
-  %b = zext i1 %a to i32<br>
-  ; Cause -1 to be rematerialized right in front of the cmov, which needs eflags.<br>
-  ; It must therefore not use the xor-dec lowering.<br>
-  %c = select i1 %a, i32 %b, i32 -1<br>
-  ret i32 %c<br>
-<br>
-; CHECK32-LABEL: test_rematerialization2<br>
-; CHECK32:       xorl %ecx, %ecx<br>
-; CHECK32-NEXT:  decl %ecx<br>
-; CHECK32:       calll<br>
-; CHECK32:       cmpl<br>
-; CHECK32:       setne<br>
-; CHECK32-NOT:   xorl<br>
-; CHECK32:       movl $-1<br>
-; CHECK32:       cmov<br>
-; CHECK32:       retl<br>
-}<br>
-<br>
-declare x86_thiscallcc void @f(i32)<br>
<br>
Added: llvm/trunk/test/CodeGen/X86/materialize.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/materialize.ll?rev=255936&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/materialize.ll?rev=255936&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/test/CodeGen/X86/materialize.ll (added)<br>
+++ llvm/trunk/test/CodeGen/X86/materialize.ll Thu Dec 17 17:18:39 2015<br>
@@ -0,0 +1,184 @@<br>
+; RUN: llc -mtriple=i686-unknown-linux-gnu -mattr=+cmov %s -o - | FileCheck %s --check-prefix=CHECK32<br>
+; RUN: llc -mtriple=x86_64-unknown-linux-gnu -mattr=+cmov %s -o - | FileCheck %s --check-prefix=CHECK64<br>
+; RUN: llc -mtriple=x86_64-pc-win32 -mattr=+cmov %s -o - | FileCheck %s --check-prefix=CHECKWIN64<br>
+<br>
+define i32 @one32_nooptsize() {<br>
+entry:<br>
+  ret i32 1<br>
+<br>
+; When not optimizing for size, use mov.<br>
+; CHECK32-LABEL: one32_nooptsize:<br>
+; CHECK32:       movl $1, %eax<br>
+; CHECK32-NEXT:  retl<br>
+; CHECK64-LABEL: one32_nooptsize:<br>
+; CHECK64:       movl $1, %eax<br>
+; CHECK64-NEXT:  retq<br>
+}<br>
+<br>
+define i32 @one32() optsize {<br>
+entry:<br>
+  ret i32 1<br>
+<br>
+; CHECK32-LABEL: one32:<br>
+; CHECK32:       xorl %eax, %eax<br>
+; CHECK32-NEXT:  incl %eax<br>
+; CHECK32-NEXT:  retl<br>
+<br>
+; FIXME: Figure out the best approach in 64-bit mode.<br>
+; CHECK64-LABEL: one32:<br>
+; CHECK64:       movl $1, %eax<br>
+; CHECK64-NEXT:  retq<br>
+}<br>
+<br>
+define i32 @one32_minsize() minsize {<br>
+entry:<br>
+  ret i32 1<br>
+<br>
+; On 32-bit, xor-inc is preferred over push-pop.<br>
+; CHECK32-LABEL: one32_minsize:<br>
+; CHECK32:       xorl %eax, %eax<br>
+; CHECK32-NEXT:  incl %eax<br>
+; CHECK32-NEXT:  retl<br>
+<br>
+; On 64-bit we don't do xor-inc yet, so push-pop it is. Note that we have to<br>
+; pop into a 64-bit register even when we just need 32 bits.<br>
+; CHECK64-LABEL: one32_minsize:<br>
+; CHECK64:       pushq $1<br>
+; CHECK64:       .cfi_adjust_cfa_offset 8<br>
+; CHECK64:       popq %rax<br>
+; CHECK64:       .cfi_adjust_cfa_offset -8<br>
+; CHECK64-NEXT:  retq<br>
+}<br>
+<br>
+define i64 @one64_minsize() minsize {<br>
+entry:<br>
+  ret i64 1<br>
+; On 64-bit we don't do xor-inc yet, so push-pop it is.<br>
+; CHECK64-LABEL: one64_minsize:<br>
+; CHECK64:       pushq $1<br>
+; CHECK64:       .cfi_adjust_cfa_offset 8<br>
+; CHECK64:       popq %rax<br>
+; CHECK64:       .cfi_adjust_cfa_offset -8<br>
+; CHECK64-NEXT:  retq<br>
+<br>
+; On Win64 we can't adjust the stack unless there's a frame pointer.<br>
+; CHECKWIN64-LABEL: one64_minsize:<br>
+; CHECKWIN64:       movl $1, %eax<br>
+; CHECKWIN64-NEXT:  retq<br>
+}<br>
+<br>
+define i32 @minus_one32() optsize {<br>
+entry:<br>
+  ret i32 -1<br>
+<br>
+; CHECK32-LABEL: minus_one32:<br>
+; CHECK32:       xorl %eax, %eax<br>
+; CHECK32-NEXT:  decl %eax<br>
+; CHECK32-NEXT:  retl<br>
+}<br>
+<br>
+define i32 @minus_one32_minsize() minsize {<br>
+entry:<br>
+  ret i32 -1<br>
+<br>
+; xor-dec is preferred over push-pop.<br>
+; CHECK32-LABEL: minus_one32_minsize:<br>
+; CHECK32:       xorl %eax, %eax<br>
+; CHECK32-NEXT:  decl %eax<br>
+; CHECK32-NEXT:  retl<br>
+}<br>
+<br>
+define i16 @one16() optsize {<br>
+entry:<br>
+  ret i16 1<br>
+<br>
+; CHECK32-LABEL: one16:<br>
+; CHECK32:       xorl %eax, %eax<br>
+; CHECK32-NEXT:  incl %eax<br>
+; CHECK32-NEXT:  retl<br>
+}<br>
+<br>
+define i16 @minus_one16() optsize {<br>
+entry:<br>
+  ret i16 -1<br>
+<br>
+; CHECK32-LABEL: minus_one16:<br>
+; CHECK32:       xorl %eax, %eax<br>
+; CHECK32-NEXT:  decl %eax<br>
+; CHECK32-NEXT:  retl<br>
+}<br>
+<br>
+define i32 @minus_five32() minsize {<br>
+entry:<br>
+  ret i32 -5<br>
+<br>
+; CHECK32-LABEL: minus_five32:<br>
+; CHECK32: pushl $-5<br>
+; CHECK32: popl %eax<br>
+; CHECK32: retl<br>
+}<br>
+<br>
+define i64 @minus_five64() minsize {<br>
+entry:<br>
+  ret i64 -5<br>
+<br>
+; CHECK64-LABEL: minus_five64:<br>
+; CHECK64: pushq $-5<br>
+; CHECK64:       .cfi_adjust_cfa_offset 8<br>
+; CHECK64: popq %rax<br>
+; CHECK64:       .cfi_adjust_cfa_offset -8<br>
+; CHECK64: retq<br>
+}<br>
+<br>
+define i32 @rematerialize_minus_one() optsize {<br>
+entry:<br>
+  ; Materialize -1 (thiscall forces it into %ecx).<br>
+  tail call x86_thiscallcc void @f(i32 -1)<br>
+<br>
+  ; Clobber all registers except %esp, leaving nowhere to store the -1 besides<br>
+  ; spilling it to the stack.<br>
+  tail call void asm sideeffect "", "~{eax},~{ebx},~{ecx},~{edx},~{edi},~{esi},~{ebp},~{dirflag},~{fpsr},~{flags}"()<br>
+<br>
+  ; -1 should be re-materialized here instead of getting spilled above.<br>
+  ret i32 -1<br>
+<br>
+; CHECK32-LABEL: rematerialize_minus_one<br>
+; CHECK32:       xorl %ecx, %ecx<br>
+; CHECK32-NEXT:  decl %ecx<br>
+; CHECK32:       calll<br>
+; CHECK32:       xorl %eax, %eax<br>
+; CHECK32-NEXT:  decl %eax<br>
+; CHECK32-NOT:   %eax<br>
+; CHECK32:       retl<br>
+}<br>
+<br>
+define i32 @rematerialize_minus_one_eflags(i32 %x) optsize {<br>
+entry:<br>
+  ; Materialize -1 (thiscall forces it into %ecx).<br>
+  tail call x86_thiscallcc void @f(i32 -1)<br>
+<br>
+  ; Clobber all registers except %esp, leaving nowhere to store the -1 besides<br>
+  ; spilling it to the stack.<br>
+  tail call void asm sideeffect "", "~{eax},~{ebx},~{ecx},~{edx},~{edi},~{esi},~{ebp},~{dirflag},~{fpsr},~{flags}"()<br>
+<br>
+  ; Define eflags.<br>
+  %a = icmp ne i32 %x, 123<br>
+  %b = zext i1 %a to i32<br>
+  ; Cause -1 to be rematerialized right in front of the cmov, which needs eflags.<br>
+  ; It must therefore not use the xor-dec lowering.<br>
+  %c = select i1 %a, i32 %b, i32 -1<br>
+  ret i32 %c<br>
+<br>
+; CHECK32-LABEL: rematerialize_minus_one_eflags<br>
+; CHECK32:       xorl %ecx, %ecx<br>
+; CHECK32-NEXT:  decl %ecx<br>
+; CHECK32:       calll<br>
+; CHECK32:       cmpl<br>
+; CHECK32:       setne<br>
+; CHECK32-NOT:   xorl<br>
+; CHECK32:       movl $-1<br>
+; CHECK32:       cmov<br>
+; CHECK32:       retl<br>
+}<br>
+<br>
+declare x86_thiscallcc void @f(i32)<br>
<br>
Modified: llvm/trunk/test/CodeGen/X86/powi.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/powi.ll?rev=255936&r1=255935&r2=255936&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/powi.ll?rev=255936&r1=255935&r2=255936&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/test/CodeGen/X86/powi.ll (original)<br>
+++ llvm/trunk/test/CodeGen/X86/powi.ll Thu Dec 17 17:18:39 2015<br>
@@ -29,9 +29,9 @@ define double @pow_wrapper_optsize(doubl<br>
 define double @pow_wrapper_minsize(double %a) minsize {<br>
 ; CHECK-LABEL: pow_wrapper_minsize:<br>
 ; CHECK:       # BB#0:<br>
-; CHECK-NEXT:    movl  $15, %edi<br>
+; CHECK-NEXT:    movl  $128, %edi<br>
 ; CHECK-NEXT:    jmp<br>
-  %ret = tail call double @llvm.powi.f64(double %a, i32 15) nounwind ; <double> [#uses=1]<br>
+  %ret = tail call double @llvm.powi.f64(double %a, i32 128) nounwind ; <double> [#uses=1]<br>
   ret double %ret<br>
 }<br>
<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@lists.llvm.org">llvm-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits</a><br>
</blockquote></div><br></div><div class="gmail_extra">This was reverted in r255656 because it caused a regression, PR26023.  Please see r255656 and PR26023 for more details.</div></div>