Home | History | Annotate | Download | only in X86
      1 ; RUN: llc -mtriple=i386-linux-gnu %s -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK32
      2 ; RUN: llc -mtriple=x86_64-linux-gnu -mattr=+sahf %s -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK64
      3 
      4 ; TODO: Reenable verify-machineinstrs once the if (!AXDead) // FIXME in
      5 ; X86InstrInfo::copyPhysReg() is resolved.
      6 
      7 ; The peephole optimizer can elide some physical register copies such as
      8 ; EFLAGS. Make sure the flags are used directly, instead of needlessly using
      9 ; lahf, when possible.
     10 
     11 @L = external global i32
     12 @M = external global i8
     13 declare i32 @bar(i64)
     14 
     15 ; CHECK-LABEL: plus_one
     16 ; CHECK-NOT: seto
     17 ; CHECK-NOT: lahf
     18 ; CHECK-NOT: sahf
     19 ; CHECK-NOT: pushf
     20 ; CHECK-NOT: popf
     21 ; CHECK: incl L
     22 define i1 @plus_one() {
     23 entry:
     24   %loaded_L = load i32, i32* @L
     25   %val = add nsw i32 %loaded_L, 1 ; N.B. will emit inc.
     26   store i32 %val, i32* @L
     27   %loaded_M = load i8, i8* @M
     28   %masked = and i8 %loaded_M, 8
     29   %M_is_true = icmp ne i8 %masked, 0
     30   %L_is_false = icmp eq i32 %val, 0
     31   %cond = and i1 %L_is_false, %M_is_true
     32   br i1 %cond, label %exit2, label %exit
     33 
     34 exit:
     35   ret i1 true
     36 
     37 exit2:
     38   ret i1 false
     39 }
     40 
     41 ; CHECK-LABEL: plus_forty_two
     42 ; CHECK-NOT: seto
     43 ; CHECK-NOT: lahf
     44 ; CHECK-NOT: sahf
     45 ; CHECK-NOT: pushf
     46 ; CHECK-NOT: popf
     47 ; CHECK: addl $42,
     48 define i1 @plus_forty_two() {
     49 entry:
     50   %loaded_L = load i32, i32* @L
     51   %val = add nsw i32 %loaded_L, 42 ; N.B. won't emit inc.
     52   store i32 %val, i32* @L
     53   %loaded_M = load i8, i8* @M
     54   %masked = and i8 %loaded_M, 8
     55   %M_is_true = icmp ne i8 %masked, 0
     56   %L_is_false = icmp eq i32 %val, 0
     57   %cond = and i1 %L_is_false, %M_is_true
     58   br i1 %cond, label %exit2, label %exit
     59 
     60 exit:
     61   ret i1 true
     62 
     63 exit2:
     64   ret i1 false
     65 }
     66 
     67 ; CHECK-LABEL: minus_one
     68 ; CHECK-NOT: seto
     69 ; CHECK-NOT: lahf
     70 ; CHECK-NOT: sahf
     71 ; CHECK-NOT: pushf
     72 ; CHECK-NOT: popf
     73 ; CHECK: decl L
     74 define i1 @minus_one() {
     75 entry:
     76   %loaded_L = load i32, i32* @L
     77   %val = add nsw i32 %loaded_L, -1 ; N.B. will emit dec.
     78   store i32 %val, i32* @L
     79   %loaded_M = load i8, i8* @M
     80   %masked = and i8 %loaded_M, 8
     81   %M_is_true = icmp ne i8 %masked, 0
     82   %L_is_false = icmp eq i32 %val, 0
     83   %cond = and i1 %L_is_false, %M_is_true
     84   br i1 %cond, label %exit2, label %exit
     85 
     86 exit:
     87   ret i1 true
     88 
     89 exit2:
     90   ret i1 false
     91 }
     92 
     93 ; CHECK-LABEL: minus_forty_two
     94 ; CHECK-NOT: seto
     95 ; CHECK-NOT: lahf
     96 ; CHECK-NOT: sahf
     97 ; CHECK-NOT: pushf
     98 ; CHECK-NOT: popf
     99 ; CHECK: addl $-42,
    100 define i1 @minus_forty_two() {
    101 entry:
    102   %loaded_L = load i32, i32* @L
    103   %val = add nsw i32 %loaded_L, -42 ; N.B. won't emit dec.
    104   store i32 %val, i32* @L
    105   %loaded_M = load i8, i8* @M
    106   %masked = and i8 %loaded_M, 8
    107   %M_is_true = icmp ne i8 %masked, 0
    108   %L_is_false = icmp eq i32 %val, 0
    109   %cond = and i1 %L_is_false, %M_is_true
    110   br i1 %cond, label %exit2, label %exit
    111 
    112 exit:
    113   ret i1 true
    114 
    115 exit2:
    116   ret i1 false
    117 }
    118 
    119 ; CHECK-LABEL: test_intervening_call:
    120 ; CHECK:       cmpxchg
    121 ; CHECK:       seto %al
    122 ; CHECK-NEXT:  lahf
    123 ; CHECK:       call{{[lq]}} bar
    124 ; CHECK:       addb $127, %al
    125 ; CHECK-NEXT:  sahf
    126 define i64 @test_intervening_call(i64* %foo, i64 %bar, i64 %baz) {
    127   ; cmpxchg sets EFLAGS, call clobbers it, then br uses EFLAGS.
    128   %cx = cmpxchg i64* %foo, i64 %bar, i64 %baz seq_cst seq_cst
    129   %v = extractvalue { i64, i1 } %cx, 0
    130   %p = extractvalue { i64, i1 } %cx, 1
    131   call i32 @bar(i64 %v)
    132   br i1 %p, label %t, label %f
    133 
    134 t:
    135   ret i64 42
    136 
    137 f:
    138   ret i64 0
    139 }
    140 
    141 ; CHECK-LABEL: test_two_live_flags:
    142 ; CHECK:       cmpxchg
    143 ; CHECK:       seto %al
    144 ; CHECK-NEXT:  lahf
    145 ; Save result of the first cmpxchg into a temporary.
    146 ; For 32-bit ISA, EDX, EAX are used by the results.
    147 ; EAX, EBX, ECX, and EDX are used to set the arguments.
    148 ; That leaves us EDI and ESI.
    149 ; CHECK32-NEXT:  movl %[[AX:eax]], %[[TMP:e[ds]i]]
    150 ; For 64-bit ISA, RAX is used for both the result and argument.
    151 ; This leaves us plenty of choices for the temporary. For now,
    152 ; this is rdx, but any register could do.
    153 ; CHECK64-NEXT:  mov{{[lq]}} %[[AX:[er]ax]], %[[TMP:rdx]]
    154 ; CHECK:       cmpxchg
    155 ; CHECK-NEXT:  sete %al
    156 ; Save result of the second cmpxchg onto the stack.
    157 ; CHECK-NEXT:  push{{[lq]}} %[[AX]]
    158 ; Restore result of the first cmpxchg from D, put it back in EFLAGS.
    159 ; CHECK-NEXT:  mov{{[lq]}} %[[TMP]], %[[AX]]
    160 ; CHECK-NEXT:  addb $127, %al
    161 ; CHECK-NEXT:  sahf
    162 ; Restore result of the second cmpxchg from the stack.
    163 ; CHECK-NEXT:  pop{{[lq]}} %[[AX]]
    164 ; Test from EFLAGS restored from first cmpxchg, jump if that fails.
    165 ; CHECK-NEXT:  jne
    166 ; Fallthrough to test the second cmpxchg's result.
    167 ; CHECK:       testb %al, %al
    168 ; CHECK-NEXT:  je
    169 define i64 @test_two_live_flags(
    170        i64* %foo0, i64 %bar0, i64 %baz0,
    171        i64* %foo1, i64 %bar1, i64 %baz1) {
    172   %cx0 = cmpxchg i64* %foo0, i64 %bar0, i64 %baz0 seq_cst seq_cst
    173   %p0 = extractvalue { i64, i1 } %cx0, 1
    174   %cx1 = cmpxchg i64* %foo1, i64 %bar1, i64 %baz1 seq_cst seq_cst
    175   %p1 = extractvalue { i64, i1 } %cx1, 1
    176   %flag = and i1 %p0, %p1
    177   br i1 %flag, label %t, label %f
    178 
    179 t:
    180   ret i64 42
    181 
    182 f:
    183   ret i64 0
    184 }
    185 
    186 ; CHECK-LABEL: asm_clobbering_flags:
    187 ; CHECK:       test
    188 ; CHECK-NEXT:  setg
    189 ; CHECK-NEXT:  #APP
    190 ; CHECK-NEXT:  bsfl
    191 ; CHECK-NEXT:  #NO_APP
    192 ; CHECK-NEXT:  movl
    193 ; CHECK-NEXT:  ret
    194 define i1 @asm_clobbering_flags(i32* %mem) {
    195   %val = load i32, i32* %mem, align 4
    196   %cmp = icmp sgt i32 %val, 0
    197   %res = tail call i32 asm "bsfl $1,$0", "=r,r,~{cc},~{dirflag},~{fpsr},~{flags}"(i32 %val)
    198   store i32 %res, i32* %mem, align 4
    199   ret i1 %cmp
    200 }
    201