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