Home | History | Annotate | Download | only in AMDGPU
      1 ; RUN: llc -march=amdgcn -verify-machineinstrs < %s | FileCheck -check-prefix=SI -check-prefix=GCN -check-prefix=FUNC %s
      2 ; RUN: llc -march=amdgcn -mcpu=tonga -verify-machineinstrs < %s | FileCheck -check-prefix=VI -check-prefix=GCN -check-prefix=FUNC %s
      3 ; RUN: llc -march=r600 -mcpu=cypress -verify-machineinstrs < %s | FileCheck -check-prefix=EG -check-prefix=FUNC %s
      4 
      5 ; FUNC-LABEL: {{^}}sext_bool_icmp_eq_0:
      6 ; GCN-NOT: v_cmp
      7 ; GCN: v_cmp_ne_i32_e32 vcc,
      8 ; GCN-NEXT: v_cndmask_b32_e64 [[RESULT:v[0-9]+]], 0, 1, vcc
      9 ; GCN-NEXT:buffer_store_byte [[RESULT]]
     10 ; GCN-NEXT: s_endpgm
     11 
     12 ; EG: SETNE_INT * [[CMP:T[0-9]+]].[[CMPCHAN:[XYZW]]], KC0[2].Z, KC0[2].W
     13 ; EG: AND_INT T{{[0-9]+.[XYZW]}}, PS, 1
     14 define void @sext_bool_icmp_eq_0(i1 addrspace(1)* %out, i32 %a, i32 %b) nounwind {
     15   %icmp0 = icmp eq i32 %a, %b
     16   %ext = sext i1 %icmp0 to i32
     17   %icmp1 = icmp eq i32 %ext, 0
     18   store i1 %icmp1, i1 addrspace(1)* %out
     19   ret void
     20 }
     21 
     22 ; FUNC-LABEL: {{^}}sext_bool_icmp_ne_0:
     23 ; GCN-NOT: v_cmp
     24 ; GCN: v_cmp_ne_i32_e32 vcc,
     25 ; GCN-NEXT: v_cndmask_b32_e64 [[RESULT:v[0-9]+]], 0, 1, vcc
     26 ; GCN-NEXT: buffer_store_byte [[RESULT]]
     27 ; GCN-NEXT: s_endpgm
     28 
     29 ; EG: SETNE_INT * [[CMP:T[0-9]+]].[[CMPCHAN:[XYZW]]], KC0[2].Z, KC0[2].W
     30 ; EG: AND_INT T{{[0-9]+.[XYZW]}}, PS, 1
     31 define void @sext_bool_icmp_ne_0(i1 addrspace(1)* %out, i32 %a, i32 %b) nounwind {
     32   %icmp0 = icmp ne i32 %a, %b
     33   %ext = sext i1 %icmp0 to i32
     34   %icmp1 = icmp ne i32 %ext, 0
     35   store i1 %icmp1, i1 addrspace(1)* %out
     36   ret void
     37 }
     38 
     39 ; FUNC-LABEL: {{^}}sext_bool_icmp_eq_neg1:
     40 ; GCN-NOT: v_cmp
     41 ; GCN: v_cmp_eq_i32_e32 vcc,
     42 ; GCN-NEXT: v_cndmask_b32_e64 [[RESULT:v[0-9]+]], 0, 1, vcc
     43 ; GCN-NEXT: buffer_store_byte [[RESULT]]
     44 ; GCN-NEXT: s_endpgm
     45 define void @sext_bool_icmp_eq_neg1(i1 addrspace(1)* %out, i32 %a, i32 %b) nounwind {
     46   %icmp0 = icmp eq i32 %a, %b
     47   %ext = sext i1 %icmp0 to i32
     48   %icmp1 = icmp eq i32 %ext, -1
     49   store i1 %icmp1, i1 addrspace(1)* %out
     50   ret void
     51 }
     52 
     53 ; FUNC-LABEL: {{^}}sext_bool_icmp_ne_neg1:
     54 ; GCN-NOT: v_cmp
     55 ; GCN: v_cmp_eq_i32_e32 vcc,
     56 ; GCN-NEXT: v_cndmask_b32_e64 [[RESULT:v[0-9]+]], 0, 1, vcc
     57 ; GCN-NEXT: buffer_store_byte [[RESULT]]
     58 ; GCN-NEXT: s_endpgm
     59 define void @sext_bool_icmp_ne_neg1(i1 addrspace(1)* %out, i32 %a, i32 %b) nounwind {
     60   %icmp0 = icmp ne i32 %a, %b
     61   %ext = sext i1 %icmp0 to i32
     62   %icmp1 = icmp ne i32 %ext, -1
     63   store i1 %icmp1, i1 addrspace(1)* %out
     64   ret void
     65 }
     66 
     67 ; FUNC-LABEL: {{^}}zext_bool_icmp_eq_0:
     68 ; GCN-NOT: v_cmp
     69 ; GCN: v_cmp_ne_i32_e32 vcc,
     70 ; GCN-NEXT: v_cndmask_b32_e64 [[RESULT:v[0-9]+]], 0, 1, vcc
     71 ; GCN-NEXT: buffer_store_byte [[RESULT]]
     72 ; GCN-NEXT: s_endpgm
     73 define void @zext_bool_icmp_eq_0(i1 addrspace(1)* %out, i32 %a, i32 %b) nounwind {
     74   %icmp0 = icmp eq i32 %a, %b
     75   %ext = zext i1 %icmp0 to i32
     76   %icmp1 = icmp eq i32 %ext, 0
     77   store i1 %icmp1, i1 addrspace(1)* %out
     78   ret void
     79 }
     80 
     81 ; FUNC-LABEL: {{^}}zext_bool_icmp_ne_0:
     82 ; GCN-NOT: v_cmp
     83 ; GCN: v_cmp_ne_i32_e32 vcc,
     84 ; GCN-NEXT: v_cndmask_b32_e64 [[RESULT:v[0-9]+]], 0, 1, vcc
     85 ; GCN-NEXT: buffer_store_byte [[RESULT]]
     86 ; GCN-NEXT: s_endpgm
     87 define void @zext_bool_icmp_ne_0(i1 addrspace(1)* %out, i32 %a, i32 %b) nounwind {
     88   %icmp0 = icmp ne i32 %a, %b
     89   %ext = zext i1 %icmp0 to i32
     90   %icmp1 = icmp ne i32 %ext, 0
     91   store i1 %icmp1, i1 addrspace(1)* %out
     92   ret void
     93 }
     94 
     95 ; FUNC-LABEL: {{^}}zext_bool_icmp_eq_1:
     96 ; GCN-NOT: v_cmp
     97 ; GCN: v_cmp_eq_i32_e32 vcc,
     98 ; GCN-NEXT: v_cndmask_b32_e64 [[RESULT:v[0-9]+]], 0, 1, vcc
     99 ; GCN-NEXT: buffer_store_byte [[RESULT]]
    100 ; GCN-NEXT: s_endpgm
    101 define void @zext_bool_icmp_eq_1(i1 addrspace(1)* %out, i32 %a, i32 %b) nounwind {
    102   %icmp0 = icmp eq i32 %a, %b
    103   %ext = zext i1 %icmp0 to i32
    104   %icmp1 = icmp eq i32 %ext, 1
    105   store i1 %icmp1, i1 addrspace(1)* %out
    106   ret void
    107 }
    108 
    109 ; FUNC-LABEL: {{^}}zext_bool_icmp_ne_1:
    110 ; GCN-NOT: v_cmp
    111 ; GCN: v_cmp_eq_i32_e32 vcc,
    112 ; GCN-NEXT: v_cndmask_b32_e64 [[RESULT:v[0-9]+]], 0, 1, vcc
    113 ; GCN-NEXT: buffer_store_byte [[RESULT]]
    114 define void @zext_bool_icmp_ne_1(i1 addrspace(1)* %out, i32 %a, i32 %b) nounwind {
    115   %icmp0 = icmp ne i32 %a, %b
    116   %ext = zext i1 %icmp0 to i32
    117   %icmp1 = icmp ne i32 %ext, 1
    118   store i1 %icmp1, i1 addrspace(1)* %out
    119   ret void
    120 }
    121 
    122 ; Reduces to false:
    123 ; FUNC-LABEL: {{^}}zext_bool_icmp_eq_neg1:
    124 ; GCN: v_mov_b32_e32 [[TMP:v[0-9]+]], 0{{$}}
    125 ; GCN: buffer_store_byte [[TMP]]
    126 ; GCN-NEXT: s_endpgm
    127 define void @zext_bool_icmp_eq_neg1(i1 addrspace(1)* %out, i32 %a, i32 %b) nounwind {
    128   %icmp0 = icmp eq i32 %a, %b
    129   %ext = zext i1 %icmp0 to i32
    130   %icmp1 = icmp eq i32 %ext, -1
    131   store i1 %icmp1, i1 addrspace(1)* %out
    132   ret void
    133 }
    134 
    135 ; Reduces to true:
    136 ; FUNC-LABEL: {{^}}zext_bool_icmp_ne_neg1:
    137 ; GCN: v_mov_b32_e32 [[TMP:v[0-9]+]], 1{{$}}
    138 ; GCN: buffer_store_byte [[TMP]]
    139 ; GCN-NEXT: s_endpgm
    140 define void @zext_bool_icmp_ne_neg1(i1 addrspace(1)* %out, i32 %a, i32 %b) nounwind {
    141   %icmp0 = icmp ne i32 %a, %b
    142   %ext = zext i1 %icmp0 to i32
    143   %icmp1 = icmp ne i32 %ext, -1
    144   store i1 %icmp1, i1 addrspace(1)* %out
    145   ret void
    146 }
    147 
    148 ; FUNC-LABEL: {{^}}cmp_zext_k_i8max:
    149 ; SI: s_load_dword [[VALUE:s[0-9]+]], s{{\[[0-9]+:[0-9]+\]}}, 0xb
    150 ; VI: s_load_dword [[VALUE:s[0-9]+]], s{{\[[0-9]+:[0-9]+\]}}, 0x2c
    151 ; GCN: s_movk_i32 [[K255:s[0-9]+]], 0xff
    152 ; GCN-DAG: s_and_b32 [[B:s[0-9]+]], [[VALUE]], [[K255]]
    153 ; GCN-DAG: v_mov_b32_e32 [[VK255:v[0-9]+]], [[K255]]
    154 ; GCN: v_cmp_ne_i32_e32 vcc, [[B]], [[VK255]]
    155 ; GCN: v_cndmask_b32_e64 [[RESULT:v[0-9]+]], 0, 1, vcc
    156 ; GCN: buffer_store_byte [[RESULT]]
    157 ; GCN: s_endpgm
    158 define void @cmp_zext_k_i8max(i1 addrspace(1)* %out, i8 %b) nounwind {
    159   %b.ext = zext i8 %b to i32
    160   %icmp0 = icmp ne i32 %b.ext, 255
    161   store i1 %icmp0, i1 addrspace(1)* %out
    162   ret void
    163 }
    164 
    165 ; FUNC-LABEL: {{^}}cmp_sext_k_neg1:
    166 ; GCN: buffer_load_sbyte [[B:v[0-9]+]]
    167 ; GCN: v_cmp_ne_i32_e32 vcc, -1, [[B]]{{$}}
    168 ; GCN-NEXT: v_cndmask_b32_e64 [[RESULT:v[0-9]+]], 0, 1, vcc
    169 ; GCN: buffer_store_byte [[RESULT]]
    170 ; GCN: s_endpgm
    171 define void @cmp_sext_k_neg1(i1 addrspace(1)* %out, i8 addrspace(1)* %b.ptr) nounwind {
    172   %b = load i8, i8 addrspace(1)* %b.ptr
    173   %b.ext = sext i8 %b to i32
    174   %icmp0 = icmp ne i32 %b.ext, -1
    175   store i1 %icmp0, i1 addrspace(1)* %out
    176   ret void
    177 }
    178 
    179 ; FUNC-LABEL: {{^}}cmp_sext_k_neg1_i8_sext_arg:
    180 ; GCN: s_load_dword [[B:s[0-9]+]]
    181 ; GCN: v_cmp_ne_i32_e64 [[CMP:s\[[0-9]+:[0-9]+\]]], -1, [[B]]
    182 ; GCN-NEXT: v_cndmask_b32_e64 [[RESULT:v[0-9]+]], 0, 1, [[CMP]]
    183 ; GCN-NEXT: buffer_store_byte [[RESULT]]
    184 ; GCN: s_endpgm
    185 define void @cmp_sext_k_neg1_i8_sext_arg(i1 addrspace(1)* %out, i8 signext %b) nounwind {
    186   %b.ext = sext i8 %b to i32
    187   %icmp0 = icmp ne i32 %b.ext, -1
    188   store i1 %icmp0, i1 addrspace(1)* %out
    189   ret void
    190 }
    191 
    192 ; FIXME: This ends up doing a buffer_load_ubyte, and and compare to
    193 ; 255. Seems to be because of ordering problems when not allowing load widths to be reduced.
    194 ; Should do a buffer_load_sbyte and compare with -1
    195 
    196 ; FUNC-LABEL: {{^}}cmp_sext_k_neg1_i8_arg:
    197 ; SI: s_load_dword [[VAL:s[0-9]+]], s[{{[0-9]+:[0-9]+}}], 0xb
    198 ; VI: s_load_dword [[VAL:s[0-9]+]], s{{\[[0-9]+:[0-9]+\]}}, 0x2c
    199 ; GCN: s_movk_i32 [[K:s[0-9]+]], 0xff
    200 ; GCN-DAG: s_and_b32 [[B:s[0-9]+]], [[VAL]], [[K]]
    201 ; GCN-DAG: v_mov_b32_e32 [[VK:v[0-9]+]], [[K]]
    202 ; GCN: v_cmp_ne_i32_e32 vcc, [[B]], [[VK]]{{$}}
    203 ; GCN: v_cndmask_b32_e64 [[RESULT:v[0-9]+]], 0, 1, vcc
    204 ; GCN: buffer_store_byte [[RESULT]]
    205 ; GCN: s_endpgm
    206 define void @cmp_sext_k_neg1_i8_arg(i1 addrspace(1)* %out, i8 %b) nounwind {
    207   %b.ext = sext i8 %b to i32
    208   %icmp0 = icmp ne i32 %b.ext, -1
    209   store i1 %icmp0, i1 addrspace(1)* %out
    210   ret void
    211 }
    212 
    213 ; FUNC-LABEL: {{^}}cmp_zext_k_neg1:
    214 ; GCN: v_mov_b32_e32 [[RESULT:v[0-9]+]], 1{{$}}
    215 ; GCN: buffer_store_byte [[RESULT]]
    216 ; GCN: s_endpgm
    217 define void @cmp_zext_k_neg1(i1 addrspace(1)* %out, i8 %b) nounwind {
    218   %b.ext = zext i8 %b to i32
    219   %icmp0 = icmp ne i32 %b.ext, -1
    220   store i1 %icmp0, i1 addrspace(1)* %out
    221   ret void
    222 }
    223 
    224 ; FUNC-LABEL: {{^}}zext_bool_icmp_ne_k:
    225 ; GCN: v_mov_b32_e32 [[RESULT:v[0-9]+]], 1{{$}}
    226 ; GCN: buffer_store_byte [[RESULT]]
    227 ; GCN-NEXT: s_endpgm
    228 define void @zext_bool_icmp_ne_k(i1 addrspace(1)* %out, i32 %a, i32 %b) nounwind {
    229   %icmp0 = icmp ne i32 %a, %b
    230   %ext = zext i1 %icmp0 to i32
    231   %icmp1 = icmp ne i32 %ext, 2
    232   store i1 %icmp1, i1 addrspace(1)* %out
    233   ret void
    234 }
    235 
    236 ; FUNC-LABEL: {{^}}zext_bool_icmp_eq_k:
    237 ; GCN: v_mov_b32_e32 [[RESULT:v[0-9]+]], 0{{$}}
    238 ; GCN: buffer_store_byte [[RESULT]]
    239 ; GCN-NEXT: s_endpgm
    240 define void @zext_bool_icmp_eq_k(i1 addrspace(1)* %out, i32 %a, i32 %b) nounwind {
    241   %icmp0 = icmp ne i32 %a, %b
    242   %ext = zext i1 %icmp0 to i32
    243   %icmp1 = icmp eq i32 %ext, 2
    244   store i1 %icmp1, i1 addrspace(1)* %out
    245   ret void
    246 }
    247 
    248 ; FIXME: These cases should really be able fold to true/false in
    249 ; DAGCombiner
    250 
    251 ; This really folds away to false
    252 ; FUNC-LABEL: {{^}}sext_bool_icmp_eq_1:
    253 ; GCN: v_mov_b32_e32 [[K:v[0-9]+]], 0{{$}}
    254 ; GCN: buffer_store_byte [[K]]
    255 define void @sext_bool_icmp_eq_1(i1 addrspace(1)* %out, i32 %a, i32 %b) nounwind {
    256   %icmp0 = icmp eq i32 %a, %b
    257   %ext = sext i1 %icmp0 to i32
    258   %icmp1 = icmp eq i32 %ext, 1
    259   store i1 %icmp1, i1 addrspace(1)* %out
    260   ret void
    261 }
    262 
    263 ; FUNC-LABEL: {{^}}sext_bool_icmp_ne_1:
    264 ; GCN: v_mov_b32_e32 [[K:v[0-9]+]], 1{{$}}
    265 ; GCN: buffer_store_byte [[K]]
    266 define void @sext_bool_icmp_ne_1(i1 addrspace(1)* %out, i32 %a, i32 %b) nounwind {
    267   %icmp0 = icmp ne i32 %a, %b
    268   %ext = sext i1 %icmp0 to i32
    269   %icmp1 = icmp ne i32 %ext, 1
    270   store i1 %icmp1, i1 addrspace(1)* %out
    271   ret void
    272 }
    273 
    274 ; FUNC-LABEL: {{^}}sext_bool_icmp_ne_k:
    275 ; GCN: v_mov_b32_e32 [[K:v[0-9]+]], 1{{$}}
    276 ; GCN: buffer_store_byte [[K]]
    277 define void @sext_bool_icmp_ne_k(i1 addrspace(1)* %out, i32 %a, i32 %b) nounwind {
    278   %icmp0 = icmp ne i32 %a, %b
    279   %ext = sext i1 %icmp0 to i32
    280   %icmp1 = icmp ne i32 %ext, 2
    281   store i1 %icmp1, i1 addrspace(1)* %out
    282   ret void
    283 }
    284