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