llvm-project/llvm/test/CodeGen/AMDGPU/dagcombine-select.ll
Frederik Harwath 47793f9a73
[AMDGPU] Implement IR expansion for frem instruction (#130988)
This patch implements a correctly rounded expansion of the frem
instruction in LLVM IR. This is useful for target architectures for
which such an expansion is too involved to be implement in ISel
Lowering. The expansion is based on the code from the AMD device libs
and has been tested successfully against the OpenCL conformance tests on
amdgpu. The expansion is implemented in the preexisting "expand-fp"
pass. It replaces the expansion of "frem" in ISel for the amdgpu target;
it is enabled for targets which do not directly support "frem" and for
which no matching "fmod" LibCall is available.

---------

Co-authored-by: Matt Arsenault <Matthew.Arsenault@amd.com>
2025-09-03 16:27:15 +02:00

740 lines
28 KiB
LLVM

; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
; RUN: llc -mtriple=amdgcn -mcpu=gfx900 < %s | FileCheck -enable-var-scope -check-prefixes=GCN,GFX9 %s
; RUN: llc -mtriple=amdgcn -mcpu=gfx942 < %s | FileCheck -enable-var-scope -check-prefixes=GCN,GFX942 %s
define amdgpu_kernel void @select_and1(ptr addrspace(1) %p, i32 %x, i32 %y) {
; GCN-LABEL: select_and1:
; GCN: ; %bb.0:
; GCN-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x24
; GCN-NEXT: v_mov_b32_e32 v0, 0
; GCN-NEXT: s_waitcnt lgkmcnt(0)
; GCN-NEXT: s_cmp_gt_i32 s2, 10
; GCN-NEXT: s_cselect_b32 s2, s3, 0
; GCN-NEXT: v_mov_b32_e32 v1, s2
; GCN-NEXT: global_store_dword v0, v1, s[0:1]
; GCN-NEXT: s_endpgm
%c = icmp slt i32 %x, 11
%s = select i1 %c, i32 0, i32 -1
%a = and i32 %y, %s
store i32 %a, ptr addrspace(1) %p, align 4
ret void
}
define amdgpu_kernel void @select_and2(ptr addrspace(1) %p, i32 %x, i32 %y) {
; GCN-LABEL: select_and2:
; GCN: ; %bb.0:
; GCN-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x24
; GCN-NEXT: v_mov_b32_e32 v0, 0
; GCN-NEXT: s_waitcnt lgkmcnt(0)
; GCN-NEXT: s_cmp_gt_i32 s2, 10
; GCN-NEXT: s_cselect_b32 s2, s3, 0
; GCN-NEXT: v_mov_b32_e32 v1, s2
; GCN-NEXT: global_store_dword v0, v1, s[0:1]
; GCN-NEXT: s_endpgm
%c = icmp slt i32 %x, 11
%s = select i1 %c, i32 0, i32 -1
%a = and i32 %s, %y
store i32 %a, ptr addrspace(1) %p, align 4
ret void
}
define amdgpu_kernel void @select_and3(ptr addrspace(1) %p, i32 %x, i32 %y) {
; GCN-LABEL: select_and3:
; GCN: ; %bb.0:
; GCN-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x24
; GCN-NEXT: v_mov_b32_e32 v0, 0
; GCN-NEXT: s_waitcnt lgkmcnt(0)
; GCN-NEXT: s_cmp_lt_i32 s2, 11
; GCN-NEXT: s_cselect_b32 s2, s3, 0
; GCN-NEXT: v_mov_b32_e32 v1, s2
; GCN-NEXT: global_store_dword v0, v1, s[0:1]
; GCN-NEXT: s_endpgm
%c = icmp slt i32 %x, 11
%s = select i1 %c, i32 -1, i32 0
%a = and i32 %y, %s
store i32 %a, ptr addrspace(1) %p, align 4
ret void
}
define amdgpu_kernel void @select_and_v4(ptr addrspace(1) %p, i32 %x, <4 x i32> %y) {
; GFX9-LABEL: select_and_v4:
; GFX9: ; %bb.0:
; GFX9-NEXT: s_load_dword s8, s[4:5], 0x2c
; GFX9-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x34
; GFX9-NEXT: s_load_dwordx2 s[6:7], s[4:5], 0x24
; GFX9-NEXT: v_mov_b32_e32 v4, 0
; GFX9-NEXT: s_waitcnt lgkmcnt(0)
; GFX9-NEXT: s_cmp_gt_i32 s8, 10
; GFX9-NEXT: s_cselect_b32 s3, s3, 0
; GFX9-NEXT: s_cselect_b32 s2, s2, 0
; GFX9-NEXT: s_cselect_b32 s1, s1, 0
; GFX9-NEXT: s_cselect_b32 s0, s0, 0
; GFX9-NEXT: v_mov_b32_e32 v0, s0
; GFX9-NEXT: v_mov_b32_e32 v1, s1
; GFX9-NEXT: v_mov_b32_e32 v2, s2
; GFX9-NEXT: v_mov_b32_e32 v3, s3
; GFX9-NEXT: global_store_dwordx4 v4, v[0:3], s[6:7]
; GFX9-NEXT: s_endpgm
;
; GFX942-LABEL: select_and_v4:
; GFX942: ; %bb.0:
; GFX942-NEXT: s_load_dword s8, s[4:5], 0x2c
; GFX942-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x34
; GFX942-NEXT: s_load_dwordx2 s[6:7], s[4:5], 0x24
; GFX942-NEXT: v_mov_b32_e32 v0, 0
; GFX942-NEXT: s_waitcnt lgkmcnt(0)
; GFX942-NEXT: s_cmp_gt_i32 s8, 10
; GFX942-NEXT: s_cselect_b32 s3, s3, 0
; GFX942-NEXT: s_cselect_b32 s2, s2, 0
; GFX942-NEXT: s_cselect_b32 s1, s1, 0
; GFX942-NEXT: s_cselect_b32 s0, s0, 0
; GFX942-NEXT: v_mov_b32_e32 v2, s0
; GFX942-NEXT: v_mov_b32_e32 v3, s1
; GFX942-NEXT: v_mov_b32_e32 v4, s2
; GFX942-NEXT: v_mov_b32_e32 v5, s3
; GFX942-NEXT: global_store_dwordx4 v0, v[2:5], s[6:7]
; GFX942-NEXT: s_endpgm
%c = icmp slt i32 %x, 11
%s = select i1 %c, <4 x i32> zeroinitializer, <4 x i32> <i32 -1, i32 -1, i32 -1, i32 -1>
%a = and <4 x i32> %s, %y
store <4 x i32> %a, ptr addrspace(1) %p, align 32
ret void
}
define amdgpu_kernel void @select_or1(ptr addrspace(1) %p, i32 %x, i32 %y) {
; GCN-LABEL: select_or1:
; GCN: ; %bb.0:
; GCN-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x24
; GCN-NEXT: v_mov_b32_e32 v0, 0
; GCN-NEXT: s_waitcnt lgkmcnt(0)
; GCN-NEXT: s_cmp_lt_i32 s2, 11
; GCN-NEXT: s_cselect_b32 s2, s3, -1
; GCN-NEXT: v_mov_b32_e32 v1, s2
; GCN-NEXT: global_store_dword v0, v1, s[0:1]
; GCN-NEXT: s_endpgm
%c = icmp slt i32 %x, 11
%s = select i1 %c, i32 0, i32 -1
%a = or i32 %y, %s
store i32 %a, ptr addrspace(1) %p, align 4
ret void
}
define amdgpu_kernel void @select_or2(ptr addrspace(1) %p, i32 %x, i32 %y) {
; GCN-LABEL: select_or2:
; GCN: ; %bb.0:
; GCN-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x24
; GCN-NEXT: v_mov_b32_e32 v0, 0
; GCN-NEXT: s_waitcnt lgkmcnt(0)
; GCN-NEXT: s_cmp_lt_i32 s2, 11
; GCN-NEXT: s_cselect_b32 s2, s3, -1
; GCN-NEXT: v_mov_b32_e32 v1, s2
; GCN-NEXT: global_store_dword v0, v1, s[0:1]
; GCN-NEXT: s_endpgm
%c = icmp slt i32 %x, 11
%s = select i1 %c, i32 0, i32 -1
%a = or i32 %s, %y
store i32 %a, ptr addrspace(1) %p, align 4
ret void
}
define amdgpu_kernel void @select_or3(ptr addrspace(1) %p, i32 %x, i32 %y) {
; GCN-LABEL: select_or3:
; GCN: ; %bb.0:
; GCN-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x24
; GCN-NEXT: v_mov_b32_e32 v0, 0
; GCN-NEXT: s_waitcnt lgkmcnt(0)
; GCN-NEXT: s_cmp_gt_i32 s2, 10
; GCN-NEXT: s_cselect_b32 s2, s3, -1
; GCN-NEXT: v_mov_b32_e32 v1, s2
; GCN-NEXT: global_store_dword v0, v1, s[0:1]
; GCN-NEXT: s_endpgm
%c = icmp slt i32 %x, 11
%s = select i1 %c, i32 -1, i32 0
%a = or i32 %y, %s
store i32 %a, ptr addrspace(1) %p, align 4
ret void
}
define amdgpu_kernel void @select_or_v4(ptr addrspace(1) %p, i32 %x, <4 x i32> %y) {
; GFX9-LABEL: select_or_v4:
; GFX9: ; %bb.0:
; GFX9-NEXT: s_load_dword s8, s[4:5], 0x2c
; GFX9-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x34
; GFX9-NEXT: s_load_dwordx2 s[6:7], s[4:5], 0x24
; GFX9-NEXT: v_mov_b32_e32 v4, 0
; GFX9-NEXT: s_waitcnt lgkmcnt(0)
; GFX9-NEXT: s_cmp_lt_i32 s8, 11
; GFX9-NEXT: s_cselect_b32 s3, s3, -1
; GFX9-NEXT: s_cselect_b32 s2, s2, -1
; GFX9-NEXT: s_cselect_b32 s1, s1, -1
; GFX9-NEXT: s_cselect_b32 s0, s0, -1
; GFX9-NEXT: v_mov_b32_e32 v0, s0
; GFX9-NEXT: v_mov_b32_e32 v1, s1
; GFX9-NEXT: v_mov_b32_e32 v2, s2
; GFX9-NEXT: v_mov_b32_e32 v3, s3
; GFX9-NEXT: global_store_dwordx4 v4, v[0:3], s[6:7]
; GFX9-NEXT: s_endpgm
;
; GFX942-LABEL: select_or_v4:
; GFX942: ; %bb.0:
; GFX942-NEXT: s_load_dword s8, s[4:5], 0x2c
; GFX942-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x34
; GFX942-NEXT: s_load_dwordx2 s[6:7], s[4:5], 0x24
; GFX942-NEXT: v_mov_b32_e32 v0, 0
; GFX942-NEXT: s_waitcnt lgkmcnt(0)
; GFX942-NEXT: s_cmp_lt_i32 s8, 11
; GFX942-NEXT: s_cselect_b32 s3, s3, -1
; GFX942-NEXT: s_cselect_b32 s2, s2, -1
; GFX942-NEXT: s_cselect_b32 s1, s1, -1
; GFX942-NEXT: s_cselect_b32 s0, s0, -1
; GFX942-NEXT: v_mov_b32_e32 v2, s0
; GFX942-NEXT: v_mov_b32_e32 v3, s1
; GFX942-NEXT: v_mov_b32_e32 v4, s2
; GFX942-NEXT: v_mov_b32_e32 v5, s3
; GFX942-NEXT: global_store_dwordx4 v0, v[2:5], s[6:7]
; GFX942-NEXT: s_endpgm
%c = icmp slt i32 %x, 11
%s = select i1 %c, <4 x i32> zeroinitializer, <4 x i32> <i32 -1, i32 -1, i32 -1, i32 -1>
%a = or <4 x i32> %s, %y
store <4 x i32> %a, ptr addrspace(1) %p, align 32
ret void
}
define amdgpu_kernel void @sel_constants_sub_constant_sel_constants(ptr addrspace(1) %p, i1 %cond) {
; GCN-LABEL: sel_constants_sub_constant_sel_constants:
; GCN: ; %bb.0:
; GCN-NEXT: s_load_dword s2, s[4:5], 0x2c
; GCN-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x24
; GCN-NEXT: v_mov_b32_e32 v0, 0
; GCN-NEXT: s_waitcnt lgkmcnt(0)
; GCN-NEXT: s_bitcmp1_b32 s2, 0
; GCN-NEXT: s_cselect_b32 s2, 9, 2
; GCN-NEXT: v_mov_b32_e32 v1, s2
; GCN-NEXT: global_store_dword v0, v1, s[0:1]
; GCN-NEXT: s_endpgm
%sel = select i1 %cond, i32 -4, i32 3
%bo = sub i32 5, %sel
store i32 %bo, ptr addrspace(1) %p, align 4
ret void
}
define amdgpu_kernel void @sel_constants_sub_constant_sel_constants_i16(ptr addrspace(1) %p, i1 %cond) {
; GCN-LABEL: sel_constants_sub_constant_sel_constants_i16:
; GCN: ; %bb.0:
; GCN-NEXT: s_load_dword s2, s[4:5], 0x2c
; GCN-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x24
; GCN-NEXT: v_mov_b32_e32 v0, 0
; GCN-NEXT: s_waitcnt lgkmcnt(0)
; GCN-NEXT: s_bitcmp1_b32 s2, 0
; GCN-NEXT: s_cselect_b32 s2, 9, 2
; GCN-NEXT: v_mov_b32_e32 v1, s2
; GCN-NEXT: global_store_short v0, v1, s[0:1]
; GCN-NEXT: s_endpgm
%sel = select i1 %cond, i16 -4, i16 3
%bo = sub i16 5, %sel
store i16 %bo, ptr addrspace(1) %p, align 2
ret void
}
define amdgpu_kernel void @sel_constants_sub_constant_sel_constants_i16_neg(ptr addrspace(1) %p, i1 %cond) {
; GCN-LABEL: sel_constants_sub_constant_sel_constants_i16_neg:
; GCN: ; %bb.0:
; GCN-NEXT: s_load_dword s2, s[4:5], 0x2c
; GCN-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x24
; GCN-NEXT: v_mov_b32_e32 v0, 0
; GCN-NEXT: s_waitcnt lgkmcnt(0)
; GCN-NEXT: s_bitcmp1_b32 s2, 0
; GCN-NEXT: s_mov_b32 s2, 0xfffd
; GCN-NEXT: s_cselect_b32 s2, s2, 0xf449
; GCN-NEXT: v_mov_b32_e32 v1, s2
; GCN-NEXT: global_store_short v0, v1, s[0:1]
; GCN-NEXT: s_endpgm
%sel = select i1 %cond, i16 4, i16 3000
%bo = sub i16 1, %sel
store i16 %bo, ptr addrspace(1) %p, align 2
ret void
}
define amdgpu_kernel void @sel_constants_sub_constant_sel_constants_v2i16(ptr addrspace(1) %p, i1 %cond) {
; GCN-LABEL: sel_constants_sub_constant_sel_constants_v2i16:
; GCN: ; %bb.0:
; GCN-NEXT: s_load_dword s2, s[4:5], 0x2c
; GCN-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x24
; GCN-NEXT: v_mov_b32_e32 v0, 0
; GCN-NEXT: s_waitcnt lgkmcnt(0)
; GCN-NEXT: s_bitcmp1_b32 s2, 0
; GCN-NEXT: s_mov_b32 s2, 0x50009
; GCN-NEXT: s_cselect_b32 s2, s2, 0x60002
; GCN-NEXT: v_mov_b32_e32 v1, s2
; GCN-NEXT: global_store_dword v0, v1, s[0:1]
; GCN-NEXT: s_endpgm
%sel = select i1 %cond, <2 x i16> <i16 -4, i16 2>, <2 x i16> <i16 3, i16 1>
%bo = sub <2 x i16> <i16 5, i16 7>, %sel
store <2 x i16> %bo, ptr addrspace(1) %p, align 4
ret void
}
define amdgpu_kernel void @sel_constants_sub_constant_sel_constants_v4i32(ptr addrspace(1) %p, i1 %cond) {
; GFX9-LABEL: sel_constants_sub_constant_sel_constants_v4i32:
; GFX9: ; %bb.0:
; GFX9-NEXT: s_load_dword s2, s[4:5], 0x2c
; GFX9-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x24
; GFX9-NEXT: v_mov_b32_e32 v4, 0
; GFX9-NEXT: s_waitcnt lgkmcnt(0)
; GFX9-NEXT: s_bitcmp1_b32 s2, 0
; GFX9-NEXT: s_cselect_b32 s2, 7, 14
; GFX9-NEXT: s_cselect_b32 s3, 6, 10
; GFX9-NEXT: s_cselect_b32 s4, 5, 6
; GFX9-NEXT: s_cselect_b32 s5, 9, 2
; GFX9-NEXT: v_mov_b32_e32 v0, s5
; GFX9-NEXT: v_mov_b32_e32 v1, s4
; GFX9-NEXT: v_mov_b32_e32 v2, s3
; GFX9-NEXT: v_mov_b32_e32 v3, s2
; GFX9-NEXT: global_store_dwordx4 v4, v[0:3], s[0:1]
; GFX9-NEXT: s_endpgm
;
; GFX942-LABEL: sel_constants_sub_constant_sel_constants_v4i32:
; GFX942: ; %bb.0:
; GFX942-NEXT: s_load_dword s2, s[4:5], 0x2c
; GFX942-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x24
; GFX942-NEXT: v_mov_b32_e32 v0, 0
; GFX942-NEXT: s_waitcnt lgkmcnt(0)
; GFX942-NEXT: s_bitcmp1_b32 s2, 0
; GFX942-NEXT: s_cselect_b32 s2, 7, 14
; GFX942-NEXT: s_cselect_b32 s3, 6, 10
; GFX942-NEXT: s_cselect_b32 s4, 5, 6
; GFX942-NEXT: s_cselect_b32 s5, 9, 2
; GFX942-NEXT: v_mov_b32_e32 v2, s5
; GFX942-NEXT: v_mov_b32_e32 v3, s4
; GFX942-NEXT: v_mov_b32_e32 v4, s3
; GFX942-NEXT: v_mov_b32_e32 v5, s2
; GFX942-NEXT: global_store_dwordx4 v0, v[2:5], s[0:1]
; GFX942-NEXT: s_endpgm
%sel = select i1 %cond, <4 x i32> <i32 -4, i32 2, i32 3, i32 4>, <4 x i32> <i32 3, i32 1, i32 -1, i32 -3>
%bo = sub <4 x i32> <i32 5, i32 7, i32 9, i32 11>, %sel
store <4 x i32> %bo, ptr addrspace(1) %p, align 32
ret void
}
define amdgpu_kernel void @sdiv_constant_sel_constants_i64(ptr addrspace(1) %p, i1 %cond) {
; GCN-LABEL: sdiv_constant_sel_constants_i64:
; GCN: ; %bb.0:
; GCN-NEXT: s_load_dword s2, s[4:5], 0x2c
; GCN-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x24
; GCN-NEXT: v_mov_b32_e32 v1, 0
; GCN-NEXT: s_waitcnt lgkmcnt(0)
; GCN-NEXT: s_bitcmp1_b32 s2, 0
; GCN-NEXT: s_cselect_b32 s2, 0, 5
; GCN-NEXT: v_mov_b32_e32 v0, s2
; GCN-NEXT: global_store_dwordx2 v1, v[0:1], s[0:1]
; GCN-NEXT: s_endpgm
%sel = select i1 %cond, i64 121, i64 23
%bo = sdiv i64 120, %sel
store i64 %bo, ptr addrspace(1) %p, align 8
ret void
}
define amdgpu_kernel void @sdiv_constant_sel_constants_i32(ptr addrspace(1) %p, i1 %cond) {
; GCN-LABEL: sdiv_constant_sel_constants_i32:
; GCN: ; %bb.0:
; GCN-NEXT: s_load_dword s2, s[4:5], 0x2c
; GCN-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x24
; GCN-NEXT: v_mov_b32_e32 v0, 0
; GCN-NEXT: s_waitcnt lgkmcnt(0)
; GCN-NEXT: s_bitcmp1_b32 s2, 0
; GCN-NEXT: s_cselect_b32 s2, 26, 8
; GCN-NEXT: v_mov_b32_e32 v1, s2
; GCN-NEXT: global_store_dword v0, v1, s[0:1]
; GCN-NEXT: s_endpgm
%sel = select i1 %cond, i32 7, i32 23
%bo = sdiv i32 184, %sel
store i32 %bo, ptr addrspace(1) %p, align 8
ret void
}
define amdgpu_kernel void @udiv_constant_sel_constants_i64(ptr addrspace(1) %p, i1 %cond) {
; GCN-LABEL: udiv_constant_sel_constants_i64:
; GCN: ; %bb.0:
; GCN-NEXT: s_load_dword s2, s[4:5], 0x2c
; GCN-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x24
; GCN-NEXT: v_mov_b32_e32 v1, 0
; GCN-NEXT: s_waitcnt lgkmcnt(0)
; GCN-NEXT: s_bitcmp1_b32 s2, 0
; GCN-NEXT: s_cselect_b32 s2, 0, 5
; GCN-NEXT: v_mov_b32_e32 v0, s2
; GCN-NEXT: global_store_dwordx2 v1, v[0:1], s[0:1]
; GCN-NEXT: s_endpgm
%sel = select i1 %cond, i64 -4, i64 23
%bo = udiv i64 120, %sel
store i64 %bo, ptr addrspace(1) %p, align 8
ret void
}
define amdgpu_kernel void @srem_constant_sel_constants(ptr addrspace(1) %p, i1 %cond) {
; GCN-LABEL: srem_constant_sel_constants:
; GCN: ; %bb.0:
; GCN-NEXT: s_load_dword s2, s[4:5], 0x2c
; GCN-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x24
; GCN-NEXT: v_mov_b32_e32 v1, 0
; GCN-NEXT: s_waitcnt lgkmcnt(0)
; GCN-NEXT: s_bitcmp1_b32 s2, 0
; GCN-NEXT: s_cselect_b32 s2, 33, 3
; GCN-NEXT: v_mov_b32_e32 v0, s2
; GCN-NEXT: global_store_dwordx2 v1, v[0:1], s[0:1]
; GCN-NEXT: s_endpgm
%sel = select i1 %cond, i64 34, i64 15
%bo = srem i64 33, %sel
store i64 %bo, ptr addrspace(1) %p, align 8
ret void
}
define amdgpu_kernel void @urem_constant_sel_constants(ptr addrspace(1) %p, i1 %cond) {
; GCN-LABEL: urem_constant_sel_constants:
; GCN: ; %bb.0:
; GCN-NEXT: s_load_dword s2, s[4:5], 0x2c
; GCN-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x24
; GCN-NEXT: v_mov_b32_e32 v1, 0
; GCN-NEXT: s_waitcnt lgkmcnt(0)
; GCN-NEXT: s_bitcmp1_b32 s2, 0
; GCN-NEXT: s_cselect_b32 s2, 33, 3
; GCN-NEXT: v_mov_b32_e32 v0, s2
; GCN-NEXT: global_store_dwordx2 v1, v[0:1], s[0:1]
; GCN-NEXT: s_endpgm
%sel = select i1 %cond, i64 34, i64 15
%bo = urem i64 33, %sel
store i64 %bo, ptr addrspace(1) %p, align 8
ret void
}
define amdgpu_kernel void @shl_constant_sel_constants(ptr addrspace(1) %p, i1 %cond) {
; GCN-LABEL: shl_constant_sel_constants:
; GCN: ; %bb.0:
; GCN-NEXT: s_load_dword s2, s[4:5], 0x2c
; GCN-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x24
; GCN-NEXT: v_mov_b32_e32 v0, 0
; GCN-NEXT: s_waitcnt lgkmcnt(0)
; GCN-NEXT: s_bitcmp1_b32 s2, 0
; GCN-NEXT: s_cselect_b32 s2, 4, 8
; GCN-NEXT: v_mov_b32_e32 v1, s2
; GCN-NEXT: global_store_dword v0, v1, s[0:1]
; GCN-NEXT: s_endpgm
%sel = select i1 %cond, i32 2, i32 3
%bo = shl i32 1, %sel
store i32 %bo, ptr addrspace(1) %p, align 4
ret void
}
define amdgpu_kernel void @lshr_constant_sel_constants(ptr addrspace(1) %p, i1 %cond) {
; GCN-LABEL: lshr_constant_sel_constants:
; GCN: ; %bb.0:
; GCN-NEXT: s_load_dword s2, s[4:5], 0x2c
; GCN-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x24
; GCN-NEXT: v_mov_b32_e32 v0, 0
; GCN-NEXT: s_waitcnt lgkmcnt(0)
; GCN-NEXT: s_bitcmp1_b32 s2, 0
; GCN-NEXT: s_cselect_b32 s2, 16, 8
; GCN-NEXT: v_mov_b32_e32 v1, s2
; GCN-NEXT: global_store_dword v0, v1, s[0:1]
; GCN-NEXT: s_endpgm
%sel = select i1 %cond, i32 2, i32 3
%bo = lshr i32 64, %sel
store i32 %bo, ptr addrspace(1) %p, align 4
ret void
}
define amdgpu_kernel void @ashr_constant_sel_constants(ptr addrspace(1) %p, i1 %cond) {
; GCN-LABEL: ashr_constant_sel_constants:
; GCN: ; %bb.0:
; GCN-NEXT: s_load_dword s2, s[4:5], 0x2c
; GCN-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x24
; GCN-NEXT: v_mov_b32_e32 v0, 0
; GCN-NEXT: s_waitcnt lgkmcnt(0)
; GCN-NEXT: s_bitcmp1_b32 s2, 0
; GCN-NEXT: s_cselect_b32 s2, 32, 16
; GCN-NEXT: v_mov_b32_e32 v1, s2
; GCN-NEXT: global_store_dword v0, v1, s[0:1]
; GCN-NEXT: s_endpgm
%sel = select i1 %cond, i32 2, i32 3
%bo = ashr i32 128, %sel
store i32 %bo, ptr addrspace(1) %p, align 4
ret void
}
define amdgpu_kernel void @fsub_constant_sel_constants(ptr addrspace(1) %p, i1 %cond) {
; GCN-LABEL: fsub_constant_sel_constants:
; GCN: ; %bb.0:
; GCN-NEXT: s_load_dword s2, s[4:5], 0x2c
; GCN-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x24
; GCN-NEXT: v_mov_b32_e32 v0, 0
; GCN-NEXT: s_waitcnt lgkmcnt(0)
; GCN-NEXT: s_bitcmp1_b32 s2, 0
; GCN-NEXT: s_cselect_b64 s[2:3], -1, 0
; GCN-NEXT: v_cndmask_b32_e64 v1, -4.0, 1.0, s[2:3]
; GCN-NEXT: global_store_dword v0, v1, s[0:1]
; GCN-NEXT: s_endpgm
%sel = select i1 %cond, float -2.0, float 3.0
%bo = fsub float -1.0, %sel
store float %bo, ptr addrspace(1) %p, align 4
ret void
}
; TODO: it shall be possible to fold constants with OpSel
define amdgpu_kernel void @fsub_constant_sel_constants_f16(ptr addrspace(1) %p, i1 %cond) {
; GCN-LABEL: fsub_constant_sel_constants_f16:
; GCN: ; %bb.0:
; GCN-NEXT: s_load_dword s2, s[4:5], 0x2c
; GCN-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x24
; GCN-NEXT: v_mov_b32_e32 v1, 0xc400
; GCN-NEXT: v_mov_b32_e32 v2, 0x3c00
; GCN-NEXT: v_mov_b32_e32 v0, 0
; GCN-NEXT: s_waitcnt lgkmcnt(0)
; GCN-NEXT: s_bitcmp1_b32 s2, 0
; GCN-NEXT: s_cselect_b64 vcc, -1, 0
; GCN-NEXT: v_cndmask_b32_e32 v1, v1, v2, vcc
; GCN-NEXT: global_store_short v0, v1, s[0:1]
; GCN-NEXT: s_endpgm
%sel = select i1 %cond, half -2.0, half 3.0
%bo = fsub half -1.0, %sel
store half %bo, ptr addrspace(1) %p, align 2
ret void
}
define amdgpu_kernel void @fsub_constant_sel_constants_v2f16(ptr addrspace(1) %p, i1 %cond) {
; GCN-LABEL: fsub_constant_sel_constants_v2f16:
; GCN: ; %bb.0:
; GCN-NEXT: s_load_dword s2, s[4:5], 0x2c
; GCN-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x24
; GCN-NEXT: v_mov_b32_e32 v0, 0
; GCN-NEXT: s_waitcnt lgkmcnt(0)
; GCN-NEXT: s_bitcmp1_b32 s2, 0
; GCN-NEXT: s_cselect_b32 s2, 0x45003c00, -2.0
; GCN-NEXT: v_mov_b32_e32 v1, s2
; GCN-NEXT: global_store_dword v0, v1, s[0:1]
; GCN-NEXT: s_endpgm
%sel = select i1 %cond, <2 x half> <half -2.0, half -3.0>, <2 x half> <half -1.0, half 4.0>
%bo = fsub <2 x half> <half -1.0, half 2.0>, %sel
store <2 x half> %bo, ptr addrspace(1) %p, align 4
ret void
}
define amdgpu_kernel void @fsub_constant_sel_constants_v4f32(ptr addrspace(1) %p, i1 %cond) {
; GFX9-LABEL: fsub_constant_sel_constants_v4f32:
; GFX9: ; %bb.0:
; GFX9-NEXT: s_load_dword s2, s[4:5], 0x2c
; GFX9-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x24
; GFX9-NEXT: s_mov_b32 s3, 0x41500000
; GFX9-NEXT: v_mov_b32_e32 v4, 0
; GFX9-NEXT: s_waitcnt lgkmcnt(0)
; GFX9-NEXT: s_bitcmp1_b32 s2, 0
; GFX9-NEXT: s_cselect_b32 s2, s3, 0x40c00000
; GFX9-NEXT: s_cselect_b32 s3, 0x41100000, 4.0
; GFX9-NEXT: s_cselect_b32 s4, 0x40a00000, 2.0
; GFX9-NEXT: s_cselect_b32 s5, 1.0, 0
; GFX9-NEXT: v_mov_b32_e32 v0, s5
; GFX9-NEXT: v_mov_b32_e32 v1, s4
; GFX9-NEXT: v_mov_b32_e32 v2, s3
; GFX9-NEXT: v_mov_b32_e32 v3, s2
; GFX9-NEXT: global_store_dwordx4 v4, v[0:3], s[0:1]
; GFX9-NEXT: s_endpgm
;
; GFX942-LABEL: fsub_constant_sel_constants_v4f32:
; GFX942: ; %bb.0:
; GFX942-NEXT: s_load_dword s2, s[4:5], 0x2c
; GFX942-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x24
; GFX942-NEXT: s_mov_b32 s3, 0x41500000
; GFX942-NEXT: v_mov_b32_e32 v0, 0
; GFX942-NEXT: s_waitcnt lgkmcnt(0)
; GFX942-NEXT: s_bitcmp1_b32 s2, 0
; GFX942-NEXT: s_cselect_b32 s2, s3, 0x40c00000
; GFX942-NEXT: s_cselect_b32 s3, 0x41100000, 4.0
; GFX942-NEXT: s_cselect_b32 s4, 0x40a00000, 2.0
; GFX942-NEXT: s_cselect_b32 s5, 1.0, 0
; GFX942-NEXT: v_mov_b32_e32 v2, s5
; GFX942-NEXT: v_mov_b32_e32 v3, s4
; GFX942-NEXT: v_mov_b32_e32 v4, s3
; GFX942-NEXT: v_mov_b32_e32 v5, s2
; GFX942-NEXT: global_store_dwordx4 v0, v[2:5], s[0:1]
; GFX942-NEXT: s_endpgm
%sel = select i1 %cond, <4 x float> <float -2.0, float -3.0, float -4.0, float -5.0>, <4 x float> <float -1.0, float 0.0, float 1.0, float 2.0>
%bo = fsub <4 x float> <float -1.0, float 2.0, float 5.0, float 8.0>, %sel
store <4 x float> %bo, ptr addrspace(1) %p, align 32
ret void
}
define amdgpu_kernel void @fdiv_constant_sel_constants(ptr addrspace(1) %p, i1 %cond) {
; GCN-LABEL: fdiv_constant_sel_constants:
; GCN: ; %bb.0:
; GCN-NEXT: s_load_dword s2, s[4:5], 0x2c
; GCN-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x24
; GCN-NEXT: v_mov_b32_e32 v0, 0
; GCN-NEXT: s_waitcnt lgkmcnt(0)
; GCN-NEXT: s_bitcmp1_b32 s2, 0
; GCN-NEXT: s_cselect_b64 s[2:3], -1, 0
; GCN-NEXT: v_cndmask_b32_e64 v1, 4.0, -2.0, s[2:3]
; GCN-NEXT: global_store_dword v0, v1, s[0:1]
; GCN-NEXT: s_endpgm
%sel = select i1 %cond, float -4.0, float 2.0
%bo = fdiv float 8.0, %sel
store float %bo, ptr addrspace(1) %p, align 4
ret void
}
; ExpandFp now expands frem before it reaches dagcombine.
; TODO Implement this optimization in/before ExpandFP
define amdgpu_kernel void @frem_constant_sel_constants(ptr addrspace(1) %p, i1 %cond) {
; GFX9-LABEL: frem_constant_sel_constants:
; GFX9: ; %bb.0:
; GFX9-NEXT: s_load_dword s0, s[4:5], 0x2c
; GFX9-NEXT: v_mov_b32_e32 v0, 0x40400000
; GFX9-NEXT: s_waitcnt lgkmcnt(0)
; GFX9-NEXT: s_bitcmp1_b32 s0, 0
; GFX9-NEXT: s_cselect_b64 s[0:1], -1, 0
; GFX9-NEXT: v_cndmask_b32_e64 v1, v0, -4.0, s[0:1]
; GFX9-NEXT: s_mov_b32 s0, 0x40a00000
; GFX9-NEXT: v_cmp_nlt_f32_e64 s[2:3], |v1|, s0
; GFX9-NEXT: s_and_b64 vcc, exec, s[2:3]
; GFX9-NEXT: s_cbranch_vccz .LBB26_2
; GFX9-NEXT: ; %bb.1: ; %frem.else
; GFX9-NEXT: v_mov_b32_e32 v0, 0x40a00000
; GFX9-NEXT: v_cmp_eq_f32_e64 s[0:1], |v1|, s0
; GFX9-NEXT: v_cndmask_b32_e64 v0, v0, 0, s[0:1]
; GFX9-NEXT: s_cbranch_execz .LBB26_3
; GFX9-NEXT: s_branch .LBB26_7
; GFX9-NEXT: .LBB26_2:
; GFX9-NEXT: ; implicit-def: $vgpr0
; GFX9-NEXT: .LBB26_3: ; %frem.compute
; GFX9-NEXT: v_frexp_mant_f32_e64 v0, |v1|
; GFX9-NEXT: v_ldexp_f32 v0, v0, 1
; GFX9-NEXT: v_div_scale_f32 v2, s[0:1], v0, v0, 1.0
; GFX9-NEXT: v_div_scale_f32 v3, vcc, 1.0, v0, 1.0
; GFX9-NEXT: v_rcp_f32_e32 v4, v2
; GFX9-NEXT: v_fma_f32 v5, -v2, v4, 1.0
; GFX9-NEXT: v_fma_f32 v4, v5, v4, v4
; GFX9-NEXT: v_mul_f32_e32 v5, v3, v4
; GFX9-NEXT: v_fma_f32 v6, -v2, v5, v3
; GFX9-NEXT: v_fma_f32 v5, v6, v4, v5
; GFX9-NEXT: v_fma_f32 v2, -v2, v5, v3
; GFX9-NEXT: v_div_fmas_f32 v3, v2, v4, v5
; GFX9-NEXT: v_frexp_exp_i32_f32_e32 v2, v1
; GFX9-NEXT: v_sub_u32_e32 v1, 3, v2
; GFX9-NEXT: v_cmp_gt_i32_e32 vcc, 13, v1
; GFX9-NEXT: v_mov_b32_e32 v4, 0x45200000
; GFX9-NEXT: v_div_fixup_f32 v3, v3, v0, 1.0
; GFX9-NEXT: s_cbranch_vccnz .LBB26_6
; GFX9-NEXT: ; %bb.4: ; %frem.loop_body.preheader
; GFX9-NEXT: v_sub_u32_e32 v1, 15, v2
; GFX9-NEXT: v_mov_b32_e32 v5, 0x45200000
; GFX9-NEXT: .LBB26_5: ; %frem.loop_body
; GFX9-NEXT: ; =>This Inner Loop Header: Depth=1
; GFX9-NEXT: v_mov_b32_e32 v4, v5
; GFX9-NEXT: v_mul_f32_e32 v5, v4, v3
; GFX9-NEXT: v_rndne_f32_e32 v5, v5
; GFX9-NEXT: v_fma_f32 v5, -v5, v0, v4
; GFX9-NEXT: v_add_f32_e32 v6, v5, v0
; GFX9-NEXT: v_cmp_gt_f32_e32 vcc, 0, v5
; GFX9-NEXT: v_add_u32_e32 v1, -12, v1
; GFX9-NEXT: v_cndmask_b32_e32 v5, v5, v6, vcc
; GFX9-NEXT: v_cmp_lt_i32_e32 vcc, 12, v1
; GFX9-NEXT: v_ldexp_f32 v5, v5, 12
; GFX9-NEXT: s_cbranch_vccnz .LBB26_5
; GFX9-NEXT: .LBB26_6: ; %Flow12
; GFX9-NEXT: v_add_u32_e32 v1, -11, v1
; GFX9-NEXT: v_ldexp_f32 v1, v4, v1
; GFX9-NEXT: v_mul_f32_e32 v3, v1, v3
; GFX9-NEXT: v_rndne_f32_e32 v3, v3
; GFX9-NEXT: v_fma_f32 v1, -v3, v0, v1
; GFX9-NEXT: v_add_f32_e32 v0, v1, v0
; GFX9-NEXT: v_cmp_gt_f32_e32 vcc, 0, v1
; GFX9-NEXT: v_add_u32_e32 v2, -1, v2
; GFX9-NEXT: v_cndmask_b32_e32 v0, v1, v0, vcc
; GFX9-NEXT: v_ldexp_f32 v0, v0, v2
; GFX9-NEXT: v_and_b32_e32 v0, 0x7fffffff, v0
; GFX9-NEXT: .LBB26_7: ; %Flow14
; GFX9-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x24
; GFX9-NEXT: v_mov_b32_e32 v1, 0
; GFX9-NEXT: s_waitcnt lgkmcnt(0)
; GFX9-NEXT: global_store_dword v1, v0, s[0:1]
; GFX9-NEXT: s_endpgm
;
; GFX942-LABEL: frem_constant_sel_constants:
; GFX942: ; %bb.0:
; GFX942-NEXT: s_load_dword s0, s[4:5], 0x2c
; GFX942-NEXT: v_mov_b32_e32 v0, 0x40400000
; GFX942-NEXT: s_waitcnt lgkmcnt(0)
; GFX942-NEXT: s_bitcmp1_b32 s0, 0
; GFX942-NEXT: s_cselect_b64 s[0:1], -1, 0
; GFX942-NEXT: v_cndmask_b32_e64 v1, v0, -4.0, s[0:1]
; GFX942-NEXT: s_mov_b32 s0, 0x40a00000
; GFX942-NEXT: v_cmp_nlt_f32_e64 s[2:3], |v1|, s0
; GFX942-NEXT: s_and_b64 vcc, exec, s[2:3]
; GFX942-NEXT: s_cbranch_vccz .LBB26_2
; GFX942-NEXT: ; %bb.1: ; %frem.else
; GFX942-NEXT: v_mov_b32_e32 v0, 0x40a00000
; GFX942-NEXT: v_cmp_eq_f32_e64 s[0:1], |v1|, s0
; GFX942-NEXT: s_nop 1
; GFX942-NEXT: v_cndmask_b32_e64 v0, v0, 0, s[0:1]
; GFX942-NEXT: s_cbranch_execz .LBB26_3
; GFX942-NEXT: s_branch .LBB26_7
; GFX942-NEXT: .LBB26_2:
; GFX942-NEXT: ; implicit-def: $vgpr0
; GFX942-NEXT: .LBB26_3: ; %frem.compute
; GFX942-NEXT: v_frexp_mant_f32_e64 v0, |v1|
; GFX942-NEXT: v_ldexp_f32 v0, v0, 1
; GFX942-NEXT: v_div_scale_f32 v3, s[0:1], v0, v0, 1.0
; GFX942-NEXT: v_rcp_f32_e32 v4, v3
; GFX942-NEXT: v_frexp_exp_i32_f32_e32 v2, v1
; GFX942-NEXT: v_sub_u32_e32 v1, 3, v2
; GFX942-NEXT: v_fma_f32 v5, -v3, v4, 1.0
; GFX942-NEXT: v_fmac_f32_e32 v4, v5, v4
; GFX942-NEXT: v_div_scale_f32 v5, vcc, 1.0, v0, 1.0
; GFX942-NEXT: v_mul_f32_e32 v6, v5, v4
; GFX942-NEXT: v_fma_f32 v7, -v3, v6, v5
; GFX942-NEXT: v_fmac_f32_e32 v6, v7, v4
; GFX942-NEXT: v_fma_f32 v3, -v3, v6, v5
; GFX942-NEXT: v_div_fmas_f32 v3, v3, v4, v6
; GFX942-NEXT: v_cmp_gt_i32_e32 vcc, 13, v1
; GFX942-NEXT: v_div_fixup_f32 v3, v3, v0, 1.0
; GFX942-NEXT: v_mov_b32_e32 v4, 0x45200000
; GFX942-NEXT: s_cbranch_vccnz .LBB26_6
; GFX942-NEXT: ; %bb.4: ; %frem.loop_body.preheader
; GFX942-NEXT: v_sub_u32_e32 v1, 15, v2
; GFX942-NEXT: v_mov_b32_e32 v5, 0x45200000
; GFX942-NEXT: .LBB26_5: ; %frem.loop_body
; GFX942-NEXT: ; =>This Inner Loop Header: Depth=1
; GFX942-NEXT: v_mov_b32_e32 v4, v5
; GFX942-NEXT: v_mul_f32_e32 v5, v4, v3
; GFX942-NEXT: v_rndne_f32_e32 v5, v5
; GFX942-NEXT: v_fma_f32 v5, -v5, v0, v4
; GFX942-NEXT: v_add_f32_e32 v6, v5, v0
; GFX942-NEXT: v_cmp_gt_f32_e32 vcc, 0, v5
; GFX942-NEXT: v_add_u32_e32 v1, -12, v1
; GFX942-NEXT: s_nop 0
; GFX942-NEXT: v_cndmask_b32_e32 v5, v5, v6, vcc
; GFX942-NEXT: v_cmp_lt_i32_e32 vcc, 12, v1
; GFX942-NEXT: v_ldexp_f32 v5, v5, 12
; GFX942-NEXT: s_cbranch_vccnz .LBB26_5
; GFX942-NEXT: .LBB26_6: ; %Flow12
; GFX942-NEXT: v_add_u32_e32 v1, -11, v1
; GFX942-NEXT: v_ldexp_f32 v1, v4, v1
; GFX942-NEXT: v_mul_f32_e32 v3, v1, v3
; GFX942-NEXT: v_rndne_f32_e32 v3, v3
; GFX942-NEXT: v_fma_f32 v1, -v3, v0, v1
; GFX942-NEXT: v_add_f32_e32 v0, v1, v0
; GFX942-NEXT: v_cmp_gt_f32_e32 vcc, 0, v1
; GFX942-NEXT: v_add_u32_e32 v2, -1, v2
; GFX942-NEXT: s_nop 0
; GFX942-NEXT: v_cndmask_b32_e32 v0, v1, v0, vcc
; GFX942-NEXT: v_ldexp_f32 v0, v0, v2
; GFX942-NEXT: v_and_b32_e32 v0, 0x7fffffff, v0
; GFX942-NEXT: .LBB26_7: ; %Flow14
; GFX942-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x24
; GFX942-NEXT: v_mov_b32_e32 v1, 0
; GFX942-NEXT: s_waitcnt lgkmcnt(0)
; GFX942-NEXT: global_store_dword v1, v0, s[0:1]
; GFX942-NEXT: s_endpgm
%sel = select i1 %cond, float -4.0, float 3.0
%bo = frem float 5.0, %sel
store float %bo, ptr addrspace(1) %p, align 4
ret void
}