Home | History | Annotate | Download | only in AMDGPU
      1 ; RUN: llc -march=amdgcn -mcpu=SI -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 ; This really folds away to false
     40 ; FUNC-LABEL: {{^}}sext_bool_icmp_eq_1:
     41 ; GCN: v_cmp_eq_i32_e32 vcc,
     42 ; GCN-NEXT: v_cndmask_b32_e64 [[TMP:v[0-9]+]], 0, -1, vcc
     43 ; GCN-NEXT: v_cmp_eq_i32_e32 vcc, 1, [[TMP]]{{$}}
     44 ; GCN-NEXT: v_cndmask_b32_e64 [[TMP:v[0-9]+]], 0, 1,
     45 ; GCN-NEXT: buffer_store_byte [[TMP]]
     46 ; GCN-NEXT: s_endpgm
     47 define void @sext_bool_icmp_eq_1(i1 addrspace(1)* %out, i32 %a, i32 %b) nounwind {
     48   %icmp0 = icmp eq i32 %a, %b
     49   %ext = sext i1 %icmp0 to i32
     50   %icmp1 = icmp eq i32 %ext, 1
     51   store i1 %icmp1, i1 addrspace(1)* %out
     52   ret void
     53 }
     54 
     55 ; This really folds away to true
     56 ; FUNC-LABEL: {{^}}sext_bool_icmp_ne_1:
     57 ; GCN: v_cmp_ne_i32_e32 vcc,
     58 ; GCN-NEXT: v_cndmask_b32_e64 [[TMP:v[0-9]+]], 0, -1, vcc
     59 ; GCN-NEXT: v_cmp_ne_i32_e32 vcc, 1, [[TMP]]{{$}}
     60 ; GCN-NEXT: v_cndmask_b32_e64 [[TMP:v[0-9]+]], 0, 1,
     61 ; GCN-NEXT: buffer_store_byte [[TMP]]
     62 ; GCN-NEXT: s_endpgm
     63 define void @sext_bool_icmp_ne_1(i1 addrspace(1)* %out, i32 %a, i32 %b) nounwind {
     64   %icmp0 = icmp ne i32 %a, %b
     65   %ext = sext i1 %icmp0 to i32
     66   %icmp1 = icmp ne i32 %ext, 1
     67   store i1 %icmp1, i1 addrspace(1)* %out
     68   ret void
     69 }
     70 
     71 ; FUNC-LABEL: {{^}}zext_bool_icmp_eq_0:
     72 ; GCN-NOT: v_cmp
     73 ; GCN: v_cmp_ne_i32_e32 vcc,
     74 ; GCN-NEXT: v_cndmask_b32_e64 [[RESULT:v[0-9]+]], 0, 1, vcc
     75 ; GCN-NEXT: buffer_store_byte [[RESULT]]
     76 ; GCN-NEXT: s_endpgm
     77 define void @zext_bool_icmp_eq_0(i1 addrspace(1)* %out, i32 %a, i32 %b) nounwind {
     78   %icmp0 = icmp eq i32 %a, %b
     79   %ext = zext i1 %icmp0 to i32
     80   %icmp1 = icmp eq i32 %ext, 0
     81   store i1 %icmp1, i1 addrspace(1)* %out
     82   ret void
     83 }
     84 
     85 ; FUNC-LABEL: {{^}}zext_bool_icmp_ne_0:
     86 ; GCN-NOT: v_cmp
     87 ; GCN: v_cmp_ne_i32_e32 vcc,
     88 ; GCN-NEXT: v_cndmask_b32_e64 [[RESULT:v[0-9]+]], 0, 1, vcc
     89 ; GCN-NEXT: buffer_store_byte [[RESULT]]
     90 ; GCN-NEXT: s_endpgm
     91 define void @zext_bool_icmp_ne_0(i1 addrspace(1)* %out, i32 %a, i32 %b) nounwind {
     92   %icmp0 = icmp ne i32 %a, %b
     93   %ext = zext i1 %icmp0 to i32
     94   %icmp1 = icmp ne i32 %ext, 0
     95   store i1 %icmp1, i1 addrspace(1)* %out
     96   ret void
     97 }
     98 
     99 ; FUNC-LABEL: {{^}}zext_bool_icmp_eq_1:
    100 ; GCN-NOT: v_cmp
    101 ; GCN: v_cmp_eq_i32_e32 vcc,
    102 ; GCN-NEXT: v_cndmask_b32_e64 [[RESULT:v[0-9]+]], 0, 1, vcc
    103 ; GCN-NEXT: buffer_store_byte [[RESULT]]
    104 ; GCN-NEXT: s_endpgm
    105 define void @zext_bool_icmp_eq_1(i1 addrspace(1)* %out, i32 %a, i32 %b) nounwind {
    106   %icmp0 = icmp eq i32 %a, %b
    107   %ext = zext i1 %icmp0 to i32
    108   %icmp1 = icmp eq i32 %ext, 1
    109   store i1 %icmp1, i1 addrspace(1)* %out
    110   ret void
    111 }
    112 
    113 ; FUNC-LABEL: {{^}}zext_bool_icmp_ne_1:
    114 ; GCN-NOT: v_cmp
    115 ; GCN: v_cmp_eq_i32_e32 vcc,
    116 ; GCN-NEXT: v_cndmask_b32_e64 [[RESULT:v[0-9]+]], 0, 1, vcc
    117 ; GCN-NEXT: buffer_store_byte [[RESULT]]
    118 define void @zext_bool_icmp_ne_1(i1 addrspace(1)* %out, i32 %a, i32 %b) nounwind {
    119   %icmp0 = icmp ne i32 %a, %b
    120   %ext = zext i1 %icmp0 to i32
    121   %icmp1 = icmp ne i32 %ext, 1
    122   store i1 %icmp1, i1 addrspace(1)* %out
    123   ret void
    124 }
    125 
    126 ; FUNC-LABEL: {{^}}sext_bool_icmp_ne_k:
    127 ; SI-DAG: s_load_dword [[A:s[0-9]+]], s{{\[[0-9]+:[0-9]+\]}}, 0xb
    128 ; SI-DAG: s_load_dword [[B:s[0-9]+]], s{{\[[0-9]+:[0-9]+\]}}, 0xc
    129 ; VI-DAG: s_load_dword [[A:s[0-9]+]], s{{\[[0-9]+:[0-9]+\]}}, 0x2c
    130 ; VI-DAG: s_load_dword [[B:s[0-9]+]], s{{\[[0-9]+:[0-9]+\]}}, 0x30
    131 ; GCN: v_mov_b32_e32 [[VB:v[0-9]+]], [[B]]
    132 ; GCN: v_cmp_ne_i32_e32 vcc, 2, [[VB]]{{$}}
    133 ; GCN: v_cndmask_b32_e64 [[RESULT:v[0-9]+]], 0, 1, vcc
    134 ; GCN: buffer_store_byte
    135 ; GCN: s_endpgm
    136 define void @sext_bool_icmp_ne_k(i1 addrspace(1)* %out, i32 %a, i32 %b) nounwind {
    137   %icmp0 = icmp ne i32 %a, %b
    138   %ext = sext i1 %icmp0 to i32
    139   %icmp1 = icmp ne i32 %ext, 2
    140   store i1 %icmp1, i1 addrspace(1)* %out
    141   ret void
    142 }
    143 
    144 ; FUNC-LABEL: {{^}}cmp_zext_k_i8max:
    145 ; SI: s_load_dword [[VALUE:s[0-9]+]], s{{\[[0-9]+:[0-9]+\]}}, 0xb
    146 ; VI: s_load_dword [[VALUE:s[0-9]+]], s{{\[[0-9]+:[0-9]+\]}}, 0x2c
    147 ; GCN: s_movk_i32 [[K255:s[0-9]+]], 0xff
    148 ; GCN: s_and_b32 [[B:s[0-9]+]], [[VALUE]], [[K255]]
    149 ; GCN: v_mov_b32_e32 [[VK255:v[0-9]+]], [[K255]]
    150 ; GCN: v_cmp_ne_i32_e32 vcc, [[B]], [[VK255]]
    151 ; GCN-NEXT: v_cndmask_b32_e64 [[RESULT:v[0-9]+]], 0, 1, vcc
    152 ; GCN: buffer_store_byte [[RESULT]]
    153 ; GCN: s_endpgm
    154 define void @cmp_zext_k_i8max(i1 addrspace(1)* %out, i8 %b) nounwind {
    155   %b.ext = zext i8 %b to i32
    156   %icmp0 = icmp ne i32 %b.ext, 255
    157   store i1 %icmp0, i1 addrspace(1)* %out
    158   ret void
    159 }
    160 
    161 ; FUNC-LABEL: {{^}}cmp_sext_k_neg1:
    162 ; GCN: buffer_load_sbyte [[B:v[0-9]+]]
    163 ; GCN: v_cmp_ne_i32_e32 vcc, -1, [[B]]{{$}}
    164 ; GCN-NEXT: v_cndmask_b32_e64 [[RESULT:v[0-9]+]], 0, 1, vcc
    165 ; GCN-NEXT: buffer_store_byte [[RESULT]]
    166 ; GCN: s_endpgm
    167 define void @cmp_sext_k_neg1(i1 addrspace(1)* %out, i8 addrspace(1)* %b.ptr) nounwind {
    168   %b = load i8, i8 addrspace(1)* %b.ptr
    169   %b.ext = sext i8 %b to i32
    170   %icmp0 = icmp ne i32 %b.ext, -1
    171   store i1 %icmp0, i1 addrspace(1)* %out
    172   ret void
    173 }
    174 
    175 ; FUNC-LABEL: {{^}}cmp_sext_k_neg1_i8_sext_arg:
    176 ; GCN: s_load_dword [[B:s[0-9]+]]
    177 ; GCN: v_cmp_ne_i32_e64 [[CMP:s\[[0-9]+:[0-9]+\]]], -1, [[B]]
    178 ; GCN-NEXT: v_cndmask_b32_e64 [[RESULT:v[0-9]+]], 0, 1, [[CMP]]
    179 ; GCN-NEXT: buffer_store_byte [[RESULT]]
    180 ; GCN: s_endpgm
    181 define void @cmp_sext_k_neg1_i8_sext_arg(i1 addrspace(1)* %out, i8 signext %b) nounwind {
    182   %b.ext = sext i8 %b to i32
    183   %icmp0 = icmp ne i32 %b.ext, -1
    184   store i1 %icmp0, i1 addrspace(1)* %out
    185   ret void
    186 }
    187 
    188 ; FIXME: This ends up doing a buffer_load_ubyte, and and compare to
    189 ; 255. Seems to be because of ordering problems when not allowing load widths to be reduced.
    190 ; Should do a buffer_load_sbyte and compare with -1
    191 
    192 ; FUNC-LABEL: {{^}}cmp_sext_k_neg1_i8_arg:
    193 ; SI: s_load_dword [[VAL:s[0-9]+]], s[{{[0-9]+:[0-9]+}}], 0xb
    194 ; VI: s_load_dword [[VAL:s[0-9]+]], s{{\[[0-9]+:[0-9]+\]}}, 0x2c
    195 ; GCN: s_movk_i32 [[K:s[0-9]+]], 0xff
    196 ; GCN: s_and_b32 [[B:s[0-9]+]], [[VAL]], [[K]]
    197 ; GCN: v_mov_b32_e32 [[VK:v[0-9]+]], [[K]]
    198 ; GCN: v_cmp_ne_i32_e32 vcc, [[B]], [[VK]]{{$}}
    199 ; GCN-NEXT: v_cndmask_b32_e64 [[RESULT:v[0-9]+]], 0, 1, vcc
    200 ; GCN: buffer_store_byte [[RESULT]]
    201 ; GCN: s_endpgm
    202 define void @cmp_sext_k_neg1_i8_arg(i1 addrspace(1)* %out, i8 %b) nounwind {
    203   %b.ext = sext i8 %b to i32
    204   %icmp0 = icmp ne i32 %b.ext, -1
    205   store i1 %icmp0, i1 addrspace(1)* %out
    206   ret void
    207 }
    208 
    209 ; FUNC-LABEL: {{^}}cmp_zext_k_neg1:
    210 ; GCN: v_mov_b32_e32 [[RESULT:v[0-9]+]], 1{{$}}
    211 ; GCN: buffer_store_byte [[RESULT]]
    212 ; GCN: s_endpgm
    213 define void @cmp_zext_k_neg1(i1 addrspace(1)* %out, i8 %b) nounwind {
    214   %b.ext = zext i8 %b to i32
    215   %icmp0 = icmp ne i32 %b.ext, -1
    216   store i1 %icmp0, i1 addrspace(1)* %out
    217   ret void
    218 }
    219 
    220 ; FUNC-LABEL: {{^}}zext_bool_icmp_ne_k:
    221 ; GCN: v_mov_b32_e32 [[RESULT:v[0-9]+]], 1{{$}}
    222 ; GCN: buffer_store_byte [[RESULT]]
    223 ; GCN-NEXT: s_endpgm
    224 define void @zext_bool_icmp_ne_k(i1 addrspace(1)* %out, i32 %a, i32 %b) nounwind {
    225   %icmp0 = icmp ne i32 %a, %b
    226   %ext = zext i1 %icmp0 to i32
    227   %icmp1 = icmp ne i32 %ext, 2
    228   store i1 %icmp1, i1 addrspace(1)* %out
    229   ret void
    230 }
    231 
    232 ; FUNC-LABEL: {{^}}zext_bool_icmp_eq_k:
    233 ; GCN: v_mov_b32_e32 [[RESULT:v[0-9]+]], 0{{$}}
    234 ; GCN: buffer_store_byte [[RESULT]]
    235 ; GCN-NEXT: s_endpgm
    236 define void @zext_bool_icmp_eq_k(i1 addrspace(1)* %out, i32 %a, i32 %b) nounwind {
    237   %icmp0 = icmp ne i32 %a, %b
    238   %ext = zext i1 %icmp0 to i32
    239   %icmp1 = icmp eq i32 %ext, 2
    240   store i1 %icmp1, i1 addrspace(1)* %out
    241   ret void
    242 }
    243