Home | History | Annotate | Download | only in X86
      1 ; RUN: llc -mtriple=i686-unknown-linux-gnu -mattr=+cmov %s -o - | FileCheck %s --check-prefix=CHECK32
      2 ; RUN: llc -mtriple=x86_64-unknown-linux-gnu -mattr=+cmov %s -o - | FileCheck %s --check-prefix=CHECK64
      3 ; RUN: llc -mtriple=x86_64-pc-win32 -mattr=+cmov %s -o - | FileCheck %s --check-prefix=CHECKWIN64
      4 
      5 define i32 @one32_nooptsize() {
      6 entry:
      7   ret i32 1
      8 
      9 ; When not optimizing for size, use mov.
     10 ; CHECK32-LABEL: one32_nooptsize:
     11 ; CHECK32:       movl $1, %eax
     12 ; CHECK32-NEXT:  retl
     13 ; CHECK64-LABEL: one32_nooptsize:
     14 ; CHECK64:       movl $1, %eax
     15 ; CHECK64-NEXT:  retq
     16 }
     17 
     18 define i32 @one32() optsize {
     19 entry:
     20   ret i32 1
     21 
     22 ; CHECK32-LABEL: one32:
     23 ; CHECK32:       xorl %eax, %eax
     24 ; CHECK32-NEXT:  incl %eax
     25 ; CHECK32-NEXT:  retl
     26 
     27 ; FIXME: Figure out the best approach in 64-bit mode.
     28 ; CHECK64-LABEL: one32:
     29 ; CHECK64:       movl $1, %eax
     30 ; CHECK64-NEXT:  retq
     31 }
     32 
     33 define i32 @one32_minsize() minsize {
     34 entry:
     35   ret i32 1
     36 
     37 ; On 32-bit, xor-inc is preferred over push-pop.
     38 ; CHECK32-LABEL: one32_minsize:
     39 ; CHECK32:       xorl %eax, %eax
     40 ; CHECK32-NEXT:  incl %eax
     41 ; CHECK32-NEXT:  retl
     42 
     43 ; On 64-bit we don't do xor-inc yet, so push-pop it is. Note that we have to
     44 ; pop into a 64-bit register even when we just need 32 bits.
     45 ; CHECK64-LABEL: one32_minsize:
     46 ; CHECK64:       pushq $1
     47 ; CHECK64:       .cfi_adjust_cfa_offset 8
     48 ; CHECK64:       popq %rax
     49 ; CHECK64:       .cfi_adjust_cfa_offset -8
     50 ; CHECK64-NEXT:  retq
     51 }
     52 
     53 define i64 @one64_minsize() minsize {
     54 entry:
     55   ret i64 1
     56 ; On 64-bit we don't do xor-inc yet, so push-pop it is.
     57 ; CHECK64-LABEL: one64_minsize:
     58 ; CHECK64:       pushq $1
     59 ; CHECK64:       .cfi_adjust_cfa_offset 8
     60 ; CHECK64:       popq %rax
     61 ; CHECK64:       .cfi_adjust_cfa_offset -8
     62 ; CHECK64-NEXT:  retq
     63 
     64 ; On Win64 we can't adjust the stack unless there's a frame pointer.
     65 ; CHECKWIN64-LABEL: one64_minsize:
     66 ; CHECKWIN64:       movl $1, %eax
     67 ; CHECKWIN64-NEXT:  retq
     68 }
     69 
     70 define i32 @minus_one32() optsize {
     71 entry:
     72   ret i32 -1
     73 
     74 ; CHECK32-LABEL: minus_one32:
     75 ; CHECK32:       xorl %eax, %eax
     76 ; CHECK32-NEXT:  decl %eax
     77 ; CHECK32-NEXT:  retl
     78 }
     79 
     80 define i32 @minus_one32_minsize() minsize {
     81 entry:
     82   ret i32 -1
     83 
     84 ; xor-dec is preferred over push-pop.
     85 ; CHECK32-LABEL: minus_one32_minsize:
     86 ; CHECK32:       xorl %eax, %eax
     87 ; CHECK32-NEXT:  decl %eax
     88 ; CHECK32-NEXT:  retl
     89 }
     90 
     91 define i16 @one16() optsize {
     92 entry:
     93   ret i16 1
     94 
     95 ; CHECK32-LABEL: one16:
     96 ; CHECK32:       xorl %eax, %eax
     97 ; CHECK32-NEXT:  incl %eax
     98 ; CHECK32-NEXT:  retl
     99 }
    100 
    101 define i16 @minus_one16() optsize {
    102 entry:
    103   ret i16 -1
    104 
    105 ; CHECK32-LABEL: minus_one16:
    106 ; CHECK32:       xorl %eax, %eax
    107 ; CHECK32-NEXT:  decl %eax
    108 ; CHECK32-NEXT:  retl
    109 }
    110 
    111 define i32 @minus_five32() minsize {
    112 entry:
    113   ret i32 -5
    114 
    115 ; CHECK32-LABEL: minus_five32:
    116 ; CHECK32: pushl $-5
    117 ; CHECK32: popl %eax
    118 ; CHECK32: retl
    119 }
    120 
    121 define i64 @minus_five64() minsize {
    122 entry:
    123   ret i64 -5
    124 
    125 ; CHECK64-LABEL: minus_five64:
    126 ; CHECK64: pushq $-5
    127 ; CHECK64:       .cfi_adjust_cfa_offset 8
    128 ; CHECK64: popq %rax
    129 ; CHECK64:       .cfi_adjust_cfa_offset -8
    130 ; CHECK64: retq
    131 }
    132 
    133 define i32 @rematerialize_minus_one() optsize {
    134 entry:
    135   ; Materialize -1 (thiscall forces it into %ecx).
    136   tail call x86_thiscallcc void @f(i32 -1)
    137 
    138   ; Clobber all registers except %esp, leaving nowhere to store the -1 besides
    139   ; spilling it to the stack.
    140   tail call void asm sideeffect "", "~{eax},~{ebx},~{ecx},~{edx},~{edi},~{esi},~{ebp},~{dirflag},~{fpsr},~{flags}"()
    141 
    142   ; -1 should be re-materialized here instead of getting spilled above.
    143   ret i32 -1
    144 
    145 ; CHECK32-LABEL: rematerialize_minus_one
    146 ; CHECK32:       xorl %ecx, %ecx
    147 ; CHECK32-NEXT:  decl %ecx
    148 ; CHECK32:       calll
    149 ; CHECK32:       xorl %eax, %eax
    150 ; CHECK32-NEXT:  decl %eax
    151 ; CHECK32-NOT:   %eax
    152 ; CHECK32:       retl
    153 }
    154 
    155 define i32 @rematerialize_minus_one_eflags(i32 %x) optsize {
    156 entry:
    157   ; Materialize -1 (thiscall forces it into %ecx).
    158   tail call x86_thiscallcc void @f(i32 -1)
    159 
    160   ; Clobber all registers except %esp, leaving nowhere to store the -1 besides
    161   ; spilling it to the stack.
    162   tail call void asm sideeffect "", "~{eax},~{ebx},~{ecx},~{edx},~{edi},~{esi},~{ebp},~{dirflag},~{fpsr},~{flags}"()
    163 
    164   ; Define eflags.
    165   %a = icmp ne i32 %x, 123
    166   %b = zext i1 %a to i32
    167   ; Cause -1 to be rematerialized right in front of the cmov, which needs eflags.
    168   ; It must therefore not use the xor-dec lowering.
    169   %c = select i1 %a, i32 %b, i32 -1
    170   ret i32 %c
    171 
    172 ; CHECK32-LABEL: rematerialize_minus_one_eflags
    173 ; CHECK32:       xorl %ecx, %ecx
    174 ; CHECK32-NEXT:  decl %ecx
    175 ; CHECK32:       calll
    176 ; CHECK32:       cmpl
    177 ; CHECK32:       setne
    178 ; CHECK32-NOT:   xorl
    179 ; CHECK32:       movl $-1
    180 ; CHECK32:       cmov
    181 ; CHECK32:       retl
    182 }
    183 
    184 declare x86_thiscallcc void @f(i32)
    185