Home | History | Annotate | Download | only in X86
      1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
      2 ; RUN: llc -mtriple=i686-unknown -verify-machineinstrs < %s | FileCheck %s
      3 ; RUN: opt < %s -codegenprepare -S -mtriple=x86_64-unknown-unknown | FileCheck --check-prefix=CHECK-CGP %s
      4 
      5 @A = global i32 zeroinitializer
      6 @B = global i32 zeroinitializer
      7 @C = global i32 zeroinitializer
      8 
      9 ; Test that 'and' is sunk into bb0.
     10 define i32 @and_sink1(i32 %a, i1 %c) {
     11 ; CHECK-LABEL: and_sink1:
     12 ; CHECK:       # %bb.0:
     13 ; CHECK-NEXT:    testb $1, {{[0-9]+}}(%esp)
     14 ; CHECK-NEXT:    je .LBB0_3
     15 ; CHECK-NEXT:  # %bb.1: # %bb0
     16 ; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %eax
     17 ; CHECK-NEXT:    testb $4, %al
     18 ; CHECK-NEXT:    movl $0, A
     19 ; CHECK-NEXT:    jne .LBB0_3
     20 ; CHECK-NEXT:  # %bb.2: # %bb1
     21 ; CHECK-NEXT:    movl $1, %eax
     22 ; CHECK-NEXT:    retl
     23 ; CHECK-NEXT:  .LBB0_3: # %bb2
     24 ; CHECK-NEXT:    xorl %eax, %eax
     25 ; CHECK-NEXT:    retl
     26 
     27 ; CHECK-CGP-LABEL: @and_sink1(
     28 ; CHECK-CGP-NOT: and i32
     29   %and = and i32 %a, 4
     30   br i1 %c, label %bb0, label %bb2
     31 bb0:
     32 ; CHECK-CGP-LABEL: bb0:
     33 ; CHECK-CGP: and i32
     34 ; CHECK-CGP-NEXT: icmp eq i32
     35 ; CHECK-CGP-NEXT: store
     36 ; CHECK-CGP-NEXT: br
     37   %cmp = icmp eq i32 %and, 0
     38   store i32 0, i32* @A
     39   br i1 %cmp, label %bb1, label %bb2
     40 bb1:
     41   ret i32 1
     42 bb2:
     43   ret i32 0
     44 }
     45 
     46 ; Test that both 'and' and cmp get sunk to bb1.
     47 define i32 @and_sink2(i32 %a, i1 %c, i1 %c2) {
     48 ; CHECK-LABEL: and_sink2:
     49 ; CHECK:       # %bb.0:
     50 ; CHECK-NEXT:    movl $0, A
     51 ; CHECK-NEXT:    testb $1, {{[0-9]+}}(%esp)
     52 ; CHECK-NEXT:    je .LBB1_5
     53 ; CHECK-NEXT:  # %bb.1: # %bb0.preheader
     54 ; CHECK-NEXT:    movb {{[0-9]+}}(%esp), %al
     55 ; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %ecx
     56 ; CHECK-NEXT:    .p2align 4, 0x90
     57 ; CHECK-NEXT:  .LBB1_2: # %bb0
     58 ; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
     59 ; CHECK-NEXT:    movl $0, B
     60 ; CHECK-NEXT:    testb $1, %al
     61 ; CHECK-NEXT:    je .LBB1_5
     62 ; CHECK-NEXT:  # %bb.3: # %bb1
     63 ; CHECK-NEXT:    # in Loop: Header=BB1_2 Depth=1
     64 ; CHECK-NEXT:    testb $4, %cl
     65 ; CHECK-NEXT:    movl $0, C
     66 ; CHECK-NEXT:    jne .LBB1_2
     67 ; CHECK-NEXT:  # %bb.4: # %bb2
     68 ; CHECK-NEXT:    movl $1, %eax
     69 ; CHECK-NEXT:    retl
     70 ; CHECK-NEXT:  .LBB1_5: # %bb3
     71 ; CHECK-NEXT:    xorl %eax, %eax
     72 ; CHECK-NEXT:    retl
     73 
     74 ; CHECK-CGP-LABEL: @and_sink2(
     75 ; CHECK-CGP-NOT: and i32
     76   %and = and i32 %a, 4
     77   store i32 0, i32* @A
     78   br i1 %c, label %bb0, label %bb3
     79 bb0:
     80 ; CHECK-CGP-LABEL: bb0:
     81 ; CHECK-CGP-NOT: and i32
     82 ; CHECK-CGP-NOT: icmp
     83   %cmp = icmp eq i32 %and, 0
     84   store i32 0, i32* @B
     85   br i1 %c2, label %bb1, label %bb3
     86 bb1:
     87 ; CHECK-CGP-LABEL: bb1:
     88 ; CHECK-CGP: and i32
     89 ; CHECK-CGP-NEXT: icmp eq i32
     90 ; CHECK-CGP-NEXT: store
     91 ; CHECK-CGP-NEXT: br
     92   store i32 0, i32* @C
     93   br i1 %cmp, label %bb2, label %bb0
     94 bb2:
     95   ret i32 1
     96 bb3:
     97   ret i32 0
     98 }
     99 
    100 ; Test that CodeGenPrepare doesn't get stuck in a loop sinking and hoisting a masked load.
    101 define i32 @and_sink3(i1 %c, i32* %p) {
    102 ; CHECK-LABEL: and_sink3:
    103 ; CHECK:       # %bb.0:
    104 ; CHECK-NEXT:    testb $1, {{[0-9]+}}(%esp)
    105 ; CHECK-NEXT:    je .LBB2_3
    106 ; CHECK-NEXT:  # %bb.1: # %bb0
    107 ; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %eax
    108 ; CHECK-NEXT:    movzbl (%eax), %eax
    109 ; CHECK-NEXT:    testl %eax, %eax
    110 ; CHECK-NEXT:    movl $0, A
    111 ; CHECK-NEXT:    je .LBB2_2
    112 ; CHECK-NEXT:  .LBB2_3: # %bb2
    113 ; CHECK-NEXT:    xorl %eax, %eax
    114 ; CHECK-NEXT:    retl
    115 ; CHECK-NEXT:  .LBB2_2: # %bb1
    116 ; CHECK-NEXT:    movl $1, %eax
    117 ; CHECK-NEXT:    retl
    118 
    119 ; CHECK-CGP-LABEL: @and_sink3(
    120 ; CHECK-CGP: load i32
    121 ; CHECK-CGP-NEXT: and i32
    122   %load = load i32, i32* %p
    123   %and = and i32 %load, 255
    124   br i1 %c, label %bb0, label %bb2
    125 bb0:
    126 ; CHECK-CGP-LABEL: bb0:
    127 ; CHECK-CGP-NOT: and i32
    128 ; CHECK-CGP: icmp eq i32
    129   %cmp = icmp eq i32 %and, 0
    130   store i32 0, i32* @A
    131   br i1 %cmp, label %bb1, label %bb2
    132 bb1:
    133   ret i32 1
    134 bb2:
    135   ret i32 0
    136 }
    137 
    138 ; Test that CodeGenPrepare sinks/duplicates non-immediate 'and'.
    139 define i32 @and_sink4(i32 %a, i32 %b, i1 %c) {
    140 ; CHECK-LABEL: and_sink4:
    141 ; CHECK:       # %bb.0:
    142 ; CHECK-NEXT:    testb $1, {{[0-9]+}}(%esp)
    143 ; CHECK-NEXT:    je .LBB3_4
    144 ; CHECK-NEXT:  # %bb.1: # %bb0
    145 ; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %eax
    146 ; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %ecx
    147 ; CHECK-NEXT:    testl %eax, %ecx
    148 ; CHECK-NEXT:    movl $0, A
    149 ; CHECK-NEXT:    jne .LBB3_4
    150 ; CHECK-NEXT:  # %bb.2: # %bb1
    151 ; CHECK-NEXT:    leal (%ecx,%eax), %edx
    152 ; CHECK-NEXT:    testl %eax, %ecx
    153 ; CHECK-NEXT:    movl %edx, B
    154 ; CHECK-NEXT:    je .LBB3_3
    155 ; CHECK-NEXT:  .LBB3_4: # %bb3
    156 ; CHECK-NEXT:    xorl %eax, %eax
    157 ; CHECK-NEXT:    retl
    158 ; CHECK-NEXT:  .LBB3_3: # %bb2
    159 ; CHECK-NEXT:    movl $1, %eax
    160 ; CHECK-NEXT:    retl
    161 
    162 ; CHECK-CGP-LABEL: @and_sink4(
    163 ; CHECK-CGP-NOT: and i32
    164 ; CHECK-CGP-NOT: icmp
    165   %and = and i32 %a, %b
    166   %cmp = icmp eq i32 %and, 0
    167   br i1 %c, label %bb0, label %bb3
    168 bb0:
    169 ; CHECK-CGP-LABEL: bb0:
    170 ; CHECK-CGP: and i32
    171 ; CHECK-CGP-NEXT: icmp eq i32
    172   store i32 0, i32* @A
    173   br i1 %cmp, label %bb1, label %bb3
    174 bb1:
    175 ; CHECK-CGP-LABEL: bb1:
    176 ; CHECK-CGP: and i32
    177 ; CHECK-CGP-NEXT: icmp eq i32
    178   %add = add i32 %a, %b
    179   store i32 %add, i32* @B
    180   br i1 %cmp, label %bb2, label %bb3
    181 bb2:
    182   ret i32 1
    183 bb3:
    184   ret i32 0
    185 }
    186 
    187 
    188 ; Test that CodeGenPrepare doesn't sink/duplicate non-immediate 'and'
    189 ; when it would increase register pressure.
    190 define i32 @and_sink5(i32 %a, i32 %b, i32 %a2, i32 %b2, i1 %c) {
    191 ; CHECK-LABEL: and_sink5:
    192 ; CHECK:       # %bb.0:
    193 ; CHECK-NEXT:    testb $1, {{[0-9]+}}(%esp)
    194 ; CHECK-NEXT:    je .LBB4_4
    195 ; CHECK-NEXT:  # %bb.1: # %bb0
    196 ; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %eax
    197 ; CHECK-NEXT:    andl {{[0-9]+}}(%esp), %eax
    198 ; CHECK-NEXT:    movl $0, A
    199 ; CHECK-NEXT:    jne .LBB4_4
    200 ; CHECK-NEXT:  # %bb.2: # %bb1
    201 ; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %ecx
    202 ; CHECK-NEXT:    addl {{[0-9]+}}(%esp), %ecx
    203 ; CHECK-NEXT:    testl %eax, %eax
    204 ; CHECK-NEXT:    movl %ecx, B
    205 ; CHECK-NEXT:    je .LBB4_3
    206 ; CHECK-NEXT:  .LBB4_4: # %bb3
    207 ; CHECK-NEXT:    xorl %eax, %eax
    208 ; CHECK-NEXT:    retl
    209 ; CHECK-NEXT:  .LBB4_3: # %bb2
    210 ; CHECK-NEXT:    movl $1, %eax
    211 ; CHECK-NEXT:    retl
    212 
    213 ; CHECK-CGP-LABEL: @and_sink5(
    214 ; CHECK-CGP: and i32
    215 ; CHECK-CGP-NOT: icmp
    216   %and = and i32 %a, %b
    217   %cmp = icmp eq i32 %and, 0
    218   br i1 %c, label %bb0, label %bb3
    219 bb0:
    220 ; CHECK-CGP-LABEL: bb0:
    221 ; CHECK-CGP-NOT: and i32
    222 ; CHECK-CGP: icmp eq i32
    223   store i32 0, i32* @A
    224   br i1 %cmp, label %bb1, label %bb3
    225 bb1:
    226 ; CHECK-CGP-LABEL: bb1:
    227 ; CHECK-CGP-NOT: and i32
    228 ; CHECK-CGP: icmp eq i32
    229   %add = add i32 %a2, %b2
    230   store i32 %add, i32* @B
    231   br i1 %cmp, label %bb2, label %bb3
    232 bb2:
    233   ret i32 1
    234 bb3:
    235   ret i32 0
    236 }
    237