Home | History | Annotate | Download | only in AMDGPU
      1 ; RUN: llc -march=amdgcn < %s | FileCheck -check-prefix=SI -check-prefix=FUNC %s
      2 ; RUN: llc -march=r600 -mcpu=cypress < %s | FileCheck -check-prefix=EG -check-prefix=FUNC %s
      3 
      4 declare i32 @llvm.amdgcn.workitem.id.x() nounwind readnone
      5 
      6 ; FUNC-LABEL: {{^}}v_test_imin_sle_i32:
      7 ; SI: v_min_i32_e32
      8 
      9 ; EG: MIN_INT
     10 define void @v_test_imin_sle_i32(i32 addrspace(1)* %out, i32 addrspace(1)* %aptr, i32 addrspace(1)* %bptr) nounwind {
     11   %a = load i32, i32 addrspace(1)* %aptr, align 4
     12   %b = load i32, i32 addrspace(1)* %bptr, align 4
     13   %cmp = icmp sle i32 %a, %b
     14   %val = select i1 %cmp, i32 %a, i32 %b
     15   store i32 %val, i32 addrspace(1)* %out, align 4
     16   ret void
     17 }
     18 
     19 ; FUNC-LABEL: {{^}}s_test_imin_sle_i32:
     20 ; SI: s_min_i32
     21 
     22 ; EG: MIN_INT
     23 define void @s_test_imin_sle_i32(i32 addrspace(1)* %out, i32 %a, i32 %b) nounwind {
     24   %cmp = icmp sle i32 %a, %b
     25   %val = select i1 %cmp, i32 %a, i32 %b
     26   store i32 %val, i32 addrspace(1)* %out, align 4
     27   ret void
     28 }
     29 
     30 ; FUNC-LABEL: {{^}}s_test_imin_sle_v1i32:
     31 ; SI: s_min_i32
     32 
     33 ; EG: MIN_INT
     34 define void @s_test_imin_sle_v1i32(<1 x i32> addrspace(1)* %out, <1 x i32> %a, <1 x i32> %b) nounwind {
     35   %cmp = icmp sle <1 x i32> %a, %b
     36   %val = select <1 x i1> %cmp, <1 x i32> %a, <1 x i32> %b
     37   store <1 x i32> %val, <1 x i32> addrspace(1)* %out
     38   ret void
     39 }
     40 
     41 ; FUNC-LABEL: {{^}}s_test_imin_sle_v4i32:
     42 ; SI: s_min_i32
     43 ; SI: s_min_i32
     44 ; SI: s_min_i32
     45 ; SI: s_min_i32
     46 
     47 ; EG: MIN_INT
     48 ; EG: MIN_INT
     49 ; EG: MIN_INT
     50 ; EG: MIN_INT
     51 define void @s_test_imin_sle_v4i32(<4 x i32> addrspace(1)* %out, <4 x i32> %a, <4 x i32> %b) nounwind {
     52   %cmp = icmp sle <4 x i32> %a, %b
     53   %val = select <4 x i1> %cmp, <4 x i32> %a, <4 x i32> %b
     54   store <4 x i32> %val, <4 x i32> addrspace(1)* %out
     55   ret void
     56 }
     57 
     58 ; FUNC-LABEL: {{^}}s_test_imin_sle_i8:
     59 ; SI: s_load_dword
     60 ; SI: s_load_dword
     61 ; SI: s_sext_i32_i8
     62 ; SI: s_sext_i32_i8
     63 ; SI: s_min_i32
     64 define void @s_test_imin_sle_i8(i8 addrspace(1)* %out, i8 %a, i8 %b) nounwind {
     65   %cmp = icmp sle i8 %a, %b
     66   %val = select i1 %cmp, i8 %a, i8 %b
     67   store i8 %val, i8 addrspace(1)* %out
     68   ret void
     69 }
     70 
     71 ; XXX - should be able to use s_min if we stop unnecessarily doing
     72 ; extloads with mubuf instructions.
     73 
     74 ; FUNC-LABEL: {{^}}s_test_imin_sle_v4i8:
     75 ; SI: buffer_load_sbyte
     76 ; SI: buffer_load_sbyte
     77 ; SI: buffer_load_sbyte
     78 ; SI: buffer_load_sbyte
     79 ; SI: buffer_load_sbyte
     80 ; SI: buffer_load_sbyte
     81 ; SI: buffer_load_sbyte
     82 ; SI: buffer_load_sbyte
     83 
     84 ; SI: v_min_i32
     85 ; SI: v_min_i32
     86 ; SI: v_min_i32
     87 ; SI: v_min_i32
     88 
     89 ; SI: s_endpgm
     90 
     91 ; EG: MIN_INT
     92 ; EG: MIN_INT
     93 ; EG: MIN_INT
     94 ; EG: MIN_INT
     95 define void @s_test_imin_sle_v4i8(<4 x i8> addrspace(1)* %out, <4 x i8> %a, <4 x i8> %b) nounwind {
     96   %cmp = icmp sle <4 x i8> %a, %b
     97   %val = select <4 x i1> %cmp, <4 x i8> %a, <4 x i8> %b
     98   store <4 x i8> %val, <4 x i8> addrspace(1)* %out
     99   ret void
    100 }
    101 
    102 ; FUNC-LABEL: {{^}}s_test_imin_sle_v4i16:
    103 ; SI: v_min_i32
    104 ; SI: v_min_i32
    105 ; SI: v_min_i32
    106 ; SI: v_min_i32
    107 
    108 ; EG: MIN_INT
    109 ; EG: MIN_INT
    110 ; EG: MIN_INT
    111 ; EG: MIN_INT
    112 define void @s_test_imin_sle_v4i16(<4 x i16> addrspace(1)* %out, <4 x i16> %a, <4 x i16> %b) nounwind {
    113   %cmp = icmp sle <4 x i16> %a, %b
    114   %val = select <4 x i1> %cmp, <4 x i16> %a, <4 x i16> %b
    115   store <4 x i16> %val, <4 x i16> addrspace(1)* %out
    116   ret void
    117 }
    118 
    119 ; FUNC-LABEL: @v_test_imin_slt_i32
    120 ; SI: v_min_i32_e32
    121 
    122 ; EG: MIN_INT
    123 define void @v_test_imin_slt_i32(i32 addrspace(1)* %out, i32 addrspace(1)* %aptr, i32 addrspace(1)* %bptr) nounwind {
    124   %a = load i32, i32 addrspace(1)* %aptr, align 4
    125   %b = load i32, i32 addrspace(1)* %bptr, align 4
    126   %cmp = icmp slt i32 %a, %b
    127   %val = select i1 %cmp, i32 %a, i32 %b
    128   store i32 %val, i32 addrspace(1)* %out, align 4
    129   ret void
    130 }
    131 
    132 ; FUNC-LABEL: @s_test_imin_slt_i32
    133 ; SI: s_min_i32
    134 
    135 ; EG: MIN_INT
    136 define void @s_test_imin_slt_i32(i32 addrspace(1)* %out, i32 %a, i32 %b) nounwind {
    137   %cmp = icmp slt i32 %a, %b
    138   %val = select i1 %cmp, i32 %a, i32 %b
    139   store i32 %val, i32 addrspace(1)* %out, align 4
    140   ret void
    141 }
    142 
    143 ; FUNC-LABEL: {{^}}s_test_imin_slt_v2i32:
    144 ; SI: s_min_i32
    145 ; SI: s_min_i32
    146 
    147 ; EG: MIN_INT
    148 ; EG: MIN_INT
    149 define void @s_test_imin_slt_v2i32(<2 x i32> addrspace(1)* %out, <2 x i32> %a, <2 x i32> %b) nounwind {
    150   %cmp = icmp slt <2 x i32> %a, %b
    151   %val = select <2 x i1> %cmp, <2 x i32> %a, <2 x i32> %b
    152   store <2 x i32> %val, <2 x i32> addrspace(1)* %out
    153   ret void
    154 }
    155 
    156 ; FUNC-LABEL: {{^}}s_test_imin_slt_imm_i32:
    157 ; SI: s_min_i32 {{s[0-9]+}}, {{s[0-9]+}}, 8
    158 
    159 ; EG: MIN_INT {{.*}}literal.{{[xyzw]}}
    160 define void @s_test_imin_slt_imm_i32(i32 addrspace(1)* %out, i32 %a) nounwind {
    161   %cmp = icmp slt i32 %a, 8
    162   %val = select i1 %cmp, i32 %a, i32 8
    163   store i32 %val, i32 addrspace(1)* %out, align 4
    164   ret void
    165 }
    166 
    167 ; FUNC-LABEL: {{^}}s_test_imin_sle_imm_i32:
    168 ; SI: s_min_i32 {{s[0-9]+}}, {{s[0-9]+}}, 8
    169 
    170 ; EG: MIN_INT {{.*}}literal.{{[xyzw]}}
    171 define void @s_test_imin_sle_imm_i32(i32 addrspace(1)* %out, i32 %a) nounwind {
    172   %cmp = icmp sle i32 %a, 8
    173   %val = select i1 %cmp, i32 %a, i32 8
    174   store i32 %val, i32 addrspace(1)* %out, align 4
    175   ret void
    176 }
    177 
    178 ; FUNC-LABEL: @v_test_umin_ule_i32
    179 ; SI: v_min_u32_e32
    180 
    181 ; EG: MIN_UINT
    182 define void @v_test_umin_ule_i32(i32 addrspace(1)* %out, i32 addrspace(1)* %aptr, i32 addrspace(1)* %bptr) nounwind {
    183   %a = load i32, i32 addrspace(1)* %aptr, align 4
    184   %b = load i32, i32 addrspace(1)* %bptr, align 4
    185   %cmp = icmp ule i32 %a, %b
    186   %val = select i1 %cmp, i32 %a, i32 %b
    187   store i32 %val, i32 addrspace(1)* %out, align 4
    188   ret void
    189 }
    190 
    191 ; FUNC-LABEL: @v_test_umin_ule_v3i32
    192 ; SI: v_min_u32_e32
    193 ; SI: v_min_u32_e32
    194 ; SI: v_min_u32_e32
    195 ; SI-NOT: v_min_u32_e32
    196 ; SI: s_endpgm
    197 
    198 ; EG: MIN_UINT
    199 ; EG: MIN_UINT
    200 ; EG: MIN_UINT
    201 define void @v_test_umin_ule_v3i32(<3 x i32> addrspace(1)* %out, <3 x i32> addrspace(1)* %aptr, <3 x i32> addrspace(1)* %bptr) nounwind {
    202   %a = load <3 x i32>, <3 x i32> addrspace(1)* %aptr
    203   %b = load <3 x i32>, <3 x i32> addrspace(1)* %bptr
    204   %cmp = icmp ule <3 x i32> %a, %b
    205   %val = select <3 x i1> %cmp, <3 x i32> %a, <3 x i32> %b
    206   store <3 x i32> %val, <3 x i32> addrspace(1)* %out
    207   ret void
    208 }
    209 ; FUNC-LABEL: @s_test_umin_ule_i32
    210 ; SI: s_min_u32
    211 
    212 ; EG: MIN_UINT
    213 define void @s_test_umin_ule_i32(i32 addrspace(1)* %out, i32 %a, i32 %b) nounwind {
    214   %cmp = icmp ule i32 %a, %b
    215   %val = select i1 %cmp, i32 %a, i32 %b
    216   store i32 %val, i32 addrspace(1)* %out, align 4
    217   ret void
    218 }
    219 
    220 ; FUNC-LABEL: @v_test_umin_ult_i32
    221 ; SI: v_min_u32_e32
    222 
    223 ; EG: MIN_UINT
    224 define void @v_test_umin_ult_i32(i32 addrspace(1)* %out, i32 addrspace(1)* %aptr, i32 addrspace(1)* %bptr) nounwind {
    225   %a = load i32, i32 addrspace(1)* %aptr, align 4
    226   %b = load i32, i32 addrspace(1)* %bptr, align 4
    227   %cmp = icmp ult i32 %a, %b
    228   %val = select i1 %cmp, i32 %a, i32 %b
    229   store i32 %val, i32 addrspace(1)* %out, align 4
    230   ret void
    231 }
    232 
    233 ; FUNC-LABEL: {{^}}v_test_umin_ult_i8:
    234 ; SI: buffer_load_ubyte
    235 ; SI: buffer_load_ubyte
    236 ; SI: v_min_u32_e32
    237 
    238 ; EG: MIN_UINT
    239 define void @v_test_umin_ult_i8(i8 addrspace(1)* %out, i8 addrspace(1)* %aptr, i8 addrspace(1)* %bptr) nounwind {
    240   %a = load i8, i8 addrspace(1)* %aptr, align 1
    241   %b = load i8, i8 addrspace(1)* %bptr, align 1
    242   %cmp = icmp ult i8 %a, %b
    243   %val = select i1 %cmp, i8 %a, i8 %b
    244   store i8 %val, i8 addrspace(1)* %out, align 1
    245   ret void
    246 }
    247 
    248 ; FUNC-LABEL: @s_test_umin_ult_i32
    249 ; SI: s_min_u32
    250 
    251 ; EG: MIN_UINT
    252 define void @s_test_umin_ult_i32(i32 addrspace(1)* %out, i32 %a, i32 %b) nounwind {
    253   %cmp = icmp ult i32 %a, %b
    254   %val = select i1 %cmp, i32 %a, i32 %b
    255   store i32 %val, i32 addrspace(1)* %out, align 4
    256   ret void
    257 }
    258 
    259 ; FUNC-LABEL: @v_test_umin_ult_i32_multi_use
    260 ; SI-NOT: v_min
    261 ; SI: v_cmp_lt_u32
    262 ; SI-NEXT: v_cndmask_b32
    263 ; SI-NOT: v_min
    264 ; SI: s_endpgm
    265 
    266 ; EG-NOT: MIN_UINT
    267 define void @v_test_umin_ult_i32_multi_use(i32 addrspace(1)* %out0, i1 addrspace(1)* %out1, i32 addrspace(1)* %aptr, i32 addrspace(1)* %bptr) nounwind {
    268   %a = load i32, i32 addrspace(1)* %aptr, align 4
    269   %b = load i32, i32 addrspace(1)* %bptr, align 4
    270   %cmp = icmp ult i32 %a, %b
    271   %val = select i1 %cmp, i32 %a, i32 %b
    272   store i32 %val, i32 addrspace(1)* %out0, align 4
    273   store i1 %cmp, i1 addrspace(1)* %out1
    274   ret void
    275 }
    276 
    277 
    278 ; FUNC-LABEL: @s_test_umin_ult_v1i32
    279 ; SI: s_min_u32
    280 
    281 ; EG: MIN_UINT
    282 define void @s_test_umin_ult_v1i32(<1 x i32> addrspace(1)* %out, <1 x i32> %a, <1 x i32> %b) nounwind {
    283   %cmp = icmp ult <1 x i32> %a, %b
    284   %val = select <1 x i1> %cmp, <1 x i32> %a, <1 x i32> %b
    285   store <1 x i32> %val, <1 x i32> addrspace(1)* %out
    286   ret void
    287 }
    288 
    289 ; FUNC-LABEL: {{^}}s_test_umin_ult_v8i32:
    290 ; SI: s_min_u32
    291 ; SI: s_min_u32
    292 ; SI: s_min_u32
    293 ; SI: s_min_u32
    294 ; SI: s_min_u32
    295 ; SI: s_min_u32
    296 ; SI: s_min_u32
    297 ; SI: s_min_u32
    298 
    299 ; EG: MIN_UINT
    300 ; EG: MIN_UINT
    301 ; EG: MIN_UINT
    302 ; EG: MIN_UINT
    303 ; EG: MIN_UINT
    304 ; EG: MIN_UINT
    305 ; EG: MIN_UINT
    306 ; EG: MIN_UINT
    307 define void @s_test_umin_ult_v8i32(<8 x i32> addrspace(1)* %out, <8 x i32> %a, <8 x i32> %b) nounwind {
    308   %cmp = icmp ult <8 x i32> %a, %b
    309   %val = select <8 x i1> %cmp, <8 x i32> %a, <8 x i32> %b
    310   store <8 x i32> %val, <8 x i32> addrspace(1)* %out
    311   ret void
    312 }
    313 
    314 ; FUNC-LABEL: {{^}}s_test_umin_ult_v8i16:
    315 ; SI: v_min_u32
    316 ; SI: v_min_u32
    317 ; SI: v_min_u32
    318 ; SI: v_min_u32
    319 ; SI: v_min_u32
    320 ; SI: v_min_u32
    321 ; SI: v_min_u32
    322 ; SI: v_min_u32
    323 
    324 ; EG: MIN_UINT
    325 ; EG: MIN_UINT
    326 ; EG: MIN_UINT
    327 ; EG: MIN_UINT
    328 ; EG: MIN_UINT
    329 ; EG: MIN_UINT
    330 ; EG: MIN_UINT
    331 ; EG: MIN_UINT
    332 define void @s_test_umin_ult_v8i16(<8 x i16> addrspace(1)* %out, <8 x i16> %a, <8 x i16> %b) nounwind {
    333   %cmp = icmp ult <8 x i16> %a, %b
    334   %val = select <8 x i1> %cmp, <8 x i16> %a, <8 x i16> %b
    335   store <8 x i16> %val, <8 x i16> addrspace(1)* %out
    336   ret void
    337 }
    338 
    339 ; Make sure redundant and removed
    340 ; FUNC-LABEL: {{^}}simplify_demanded_bits_test_umin_ult_i16:
    341 ; SI-DAG: s_load_dword [[A:s[0-9]+]], {{s\[[0-9]+:[0-9]+\]}}, 0xb
    342 ; SI-DAG: s_load_dword [[B:s[0-9]+]], {{s\[[0-9]+:[0-9]+\]}}, 0xc
    343 ; SI: s_min_u32 [[MIN:s[0-9]+]], [[A]], [[B]]
    344 ; SI: v_mov_b32_e32 [[VMIN:v[0-9]+]], [[MIN]]
    345 ; SI: buffer_store_dword [[VMIN]]
    346 
    347 ; EG: MIN_UINT
    348 define void @simplify_demanded_bits_test_umin_ult_i16(i32 addrspace(1)* %out, i16 zeroext %a, i16 zeroext %b) nounwind {
    349   %a.ext = zext i16 %a to i32
    350   %b.ext = zext i16 %b to i32
    351   %cmp = icmp ult i32 %a.ext, %b.ext
    352   %val = select i1 %cmp, i32 %a.ext, i32 %b.ext
    353   %mask = and i32 %val, 65535
    354   store i32 %mask, i32 addrspace(1)* %out
    355   ret void
    356 }
    357 
    358 ; Make sure redundant sign_extend_inreg removed.
    359 
    360 ; FUNC-LABEL: {{^}}simplify_demanded_bits_test_min_slt_i16:
    361 ; SI-DAG: s_load_dword [[A:s[0-9]+]], {{s\[[0-9]+:[0-9]+\]}}, 0xb
    362 ; SI-DAG: s_load_dword [[B:s[0-9]+]], {{s\[[0-9]+:[0-9]+\]}}, 0xc
    363 ; SI: s_min_i32 [[MIN:s[0-9]+]], [[A]], [[B]]
    364 ; SI: v_mov_b32_e32 [[VMIN:v[0-9]+]], [[MIN]]
    365 ; SI: buffer_store_dword [[VMIN]]
    366 
    367 ; EG: MIN_INT
    368 define void @simplify_demanded_bits_test_min_slt_i16(i32 addrspace(1)* %out, i16 signext %a, i16 signext %b) nounwind {
    369   %a.ext = sext i16 %a to i32
    370   %b.ext = sext i16 %b to i32
    371   %cmp = icmp slt i32 %a.ext, %b.ext
    372   %val = select i1 %cmp, i32 %a.ext, i32 %b.ext
    373   %shl = shl i32 %val, 16
    374   %sextinreg = ashr i32 %shl, 16
    375   store i32 %sextinreg, i32 addrspace(1)* %out
    376   ret void
    377 }
    378 
    379 ; FUNC-LABEL: {{^}}s_test_imin_sle_i16:
    380 ; SI: s_min_i32
    381 
    382 ; EG: MIN_INT
    383 define void @s_test_imin_sle_i16(i16 addrspace(1)* %out, i16 %a, i16 %b) nounwind {
    384   %cmp = icmp sle i16 %a, %b
    385   %val = select i1 %cmp, i16 %a, i16 %b
    386   store i16 %val, i16 addrspace(1)* %out
    387   ret void
    388 }
    389 
    390 ; 64 bit
    391 ; FUNC-LABEL: {{^}}test_umin_ult_i64
    392 ; SI: s_endpgm
    393 
    394 ; EG: MIN_UINT
    395 ; EG: MIN_UINT
    396 define void @test_umin_ult_i64(i64 addrspace(1)* %out, i64 %a, i64 %b) nounwind {
    397   %tmp = icmp ult i64 %a, %b
    398   %val = select i1 %tmp, i64 %a, i64 %b
    399   store i64 %val, i64 addrspace(1)* %out, align 8
    400   ret void
    401 }
    402 
    403 ; FUNC-LABEL: {{^}}test_umin_ule_i64
    404 ; SI: s_endpgm
    405 
    406 ; EG: MIN_UINT
    407 ; EG: MIN_UINT
    408 define void @test_umin_ule_i64(i64 addrspace(1)* %out, i64 %a, i64 %b) nounwind {
    409   %tmp = icmp ule i64 %a, %b
    410   %val = select i1 %tmp, i64 %a, i64 %b
    411   store i64 %val, i64 addrspace(1)* %out, align 8
    412   ret void
    413 }
    414 
    415 ; FUNC-LABEL: {{^}}test_imin_slt_i64
    416 ; SI: s_endpgm
    417 
    418 ; EG-DAG: MIN_UINT
    419 ; EG-DAG: MIN_INT
    420 define void @test_imin_slt_i64(i64 addrspace(1)* %out, i64 %a, i64 %b) nounwind {
    421   %tmp = icmp slt i64 %a, %b
    422   %val = select i1 %tmp, i64 %a, i64 %b
    423   store i64 %val, i64 addrspace(1)* %out, align 8
    424   ret void
    425 }
    426 
    427 ; FUNC-LABEL: {{^}}test_imin_sle_i64
    428 ; SI: s_endpgm
    429 
    430 ; EG-DAG: MIN_UINT
    431 ; EG-DAG: MIN_INT
    432 define void @test_imin_sle_i64(i64 addrspace(1)* %out, i64 %a, i64 %b) nounwind {
    433   %tmp = icmp sle i64 %a, %b
    434   %val = select i1 %tmp, i64 %a, i64 %b
    435   store i64 %val, i64 addrspace(1)* %out, align 8
    436   ret void
    437 }
    438