[llvm] d3a96fc - AMDGPU: Add baseline tests for CGP div expansion

Matt Arsenault via llvm-commits llvm-commits at lists.llvm.org
Tue Feb 11 15:11:51 PST 2020


Author: Matt Arsenault
Date: 2020-02-11T18:11:39-05:00
New Revision: d3a96fc082bef6a15f1ce8aed1849ff4122636dc

URL: https://github.com/llvm/llvm-project/commit/d3a96fc082bef6a15f1ce8aed1849ff4122636dc
DIFF: https://github.com/llvm/llvm-project/commit/d3a96fc082bef6a15f1ce8aed1849ff4122636dc.diff

LOG: AMDGPU: Add baseline tests for CGP div expansion

These cases are harmed by expanding division early in the IR, before
DAGCombiner.

Added: 
    

Modified: 
    llvm/test/CodeGen/AMDGPU/amdgpu-codegenprepare-idiv.ll

Removed: 
    


################################################################################
diff  --git a/llvm/test/CodeGen/AMDGPU/amdgpu-codegenprepare-idiv.ll b/llvm/test/CodeGen/AMDGPU/amdgpu-codegenprepare-idiv.ll
index f1a5722467b1..6ed9d23f64be 100644
--- a/llvm/test/CodeGen/AMDGPU/amdgpu-codegenprepare-idiv.ll
+++ b/llvm/test/CodeGen/AMDGPU/amdgpu-codegenprepare-idiv.ll
@@ -1,5 +1,7 @@
 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
-; RUN: opt -S -mtriple=amdgcn-- -amdgpu-codegenprepare %s | FileCheck %s
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: opt -S -mtriple=amdgcn-- -mcpu=tahiti -amdgpu-codegenprepare %s | FileCheck %s
+; RUN: llc -mtriple=amdgcn-- -mcpu=tahiti < %s | FileCheck -check-prefix=GCN %s
 
 define amdgpu_kernel void @udiv_i32(i32 addrspace(1)* %out, i32 %x, i32 %y) {
 ; CHECK-LABEL: @udiv_i32(
@@ -46,6 +48,38 @@ define amdgpu_kernel void @udiv_i32(i32 addrspace(1)* %out, i32 %x, i32 %y) {
 ; CHECK-NEXT:    store i32 [[TMP40]], i32 addrspace(1)* [[OUT:%.*]]
 ; CHECK-NEXT:    ret void
 ;
+; GCN-LABEL: udiv_i32:
+; GCN:       ; %bb.0:
+; GCN-NEXT:    s_load_dwordx2 s[8:9], s[0:1], 0xb
+; GCN-NEXT:    s_load_dwordx2 s[4:5], s[0:1], 0x9
+; GCN-NEXT:    s_mov_b32 s7, 0xf000
+; GCN-NEXT:    s_mov_b32 s6, -1
+; GCN-NEXT:    s_waitcnt lgkmcnt(0)
+; GCN-NEXT:    v_cvt_f32_u32_e32 v0, s9
+; GCN-NEXT:    v_rcp_iflag_f32_e32 v0, v0
+; GCN-NEXT:    v_mul_f32_e32 v0, 0x4f800000, v0
+; GCN-NEXT:    v_cvt_u32_f32_e32 v0, v0
+; GCN-NEXT:    v_mul_lo_u32 v1, v0, s9
+; GCN-NEXT:    v_mul_hi_u32 v2, v0, s9
+; GCN-NEXT:    v_sub_i32_e32 v3, vcc, 0, v1
+; GCN-NEXT:    v_cmp_eq_u32_e64 s[2:3], 0, v2
+; GCN-NEXT:    v_cndmask_b32_e64 v1, v1, v3, s[2:3]
+; GCN-NEXT:    v_mul_hi_u32 v1, v1, v0
+; GCN-NEXT:    v_add_i32_e32 v2, vcc, v1, v0
+; GCN-NEXT:    v_subrev_i32_e32 v0, vcc, v1, v0
+; GCN-NEXT:    v_cndmask_b32_e64 v0, v0, v2, s[2:3]
+; GCN-NEXT:    v_mul_hi_u32 v0, v0, s8
+; GCN-NEXT:    v_mul_lo_u32 v1, v0, s9
+; GCN-NEXT:    v_add_i32_e32 v2, vcc, 1, v0
+; GCN-NEXT:    v_add_i32_e32 v3, vcc, -1, v0
+; GCN-NEXT:    v_sub_i32_e32 v4, vcc, s8, v1
+; GCN-NEXT:    v_cmp_ge_u32_e32 vcc, s8, v1
+; GCN-NEXT:    v_cmp_le_u32_e64 s[0:1], s9, v4
+; GCN-NEXT:    s_and_b64 s[0:1], s[0:1], vcc
+; GCN-NEXT:    v_cndmask_b32_e64 v0, v0, v2, s[0:1]
+; GCN-NEXT:    v_cndmask_b32_e32 v0, v3, v0, vcc
+; GCN-NEXT:    buffer_store_dword v0, off, s[4:7], 0
+; GCN-NEXT:    s_endpgm
   %r = udiv i32 %x, %y
   store i32 %r, i32 addrspace(1)* %out
   ret void
@@ -96,6 +130,38 @@ define amdgpu_kernel void @urem_i32(i32 addrspace(1)* %out, i32 %x, i32 %y) {
 ; CHECK-NEXT:    store i32 [[TMP40]], i32 addrspace(1)* [[OUT:%.*]]
 ; CHECK-NEXT:    ret void
 ;
+; GCN-LABEL: urem_i32:
+; GCN:       ; %bb.0:
+; GCN-NEXT:    s_load_dwordx2 s[8:9], s[0:1], 0xb
+; GCN-NEXT:    s_load_dwordx2 s[4:5], s[0:1], 0x9
+; GCN-NEXT:    s_mov_b32 s7, 0xf000
+; GCN-NEXT:    s_mov_b32 s6, -1
+; GCN-NEXT:    s_waitcnt lgkmcnt(0)
+; GCN-NEXT:    v_cvt_f32_u32_e32 v0, s9
+; GCN-NEXT:    v_rcp_iflag_f32_e32 v0, v0
+; GCN-NEXT:    v_mul_f32_e32 v0, 0x4f800000, v0
+; GCN-NEXT:    v_cvt_u32_f32_e32 v0, v0
+; GCN-NEXT:    v_mul_lo_u32 v1, v0, s9
+; GCN-NEXT:    v_mul_hi_u32 v2, v0, s9
+; GCN-NEXT:    v_sub_i32_e32 v3, vcc, 0, v1
+; GCN-NEXT:    v_cmp_eq_u32_e64 s[2:3], 0, v2
+; GCN-NEXT:    v_cndmask_b32_e64 v1, v1, v3, s[2:3]
+; GCN-NEXT:    v_mul_hi_u32 v1, v1, v0
+; GCN-NEXT:    v_add_i32_e32 v2, vcc, v1, v0
+; GCN-NEXT:    v_subrev_i32_e32 v0, vcc, v1, v0
+; GCN-NEXT:    v_cndmask_b32_e64 v0, v0, v2, s[2:3]
+; GCN-NEXT:    v_mul_hi_u32 v0, v0, s8
+; GCN-NEXT:    v_mul_lo_u32 v0, v0, s9
+; GCN-NEXT:    v_sub_i32_e32 v1, vcc, s8, v0
+; GCN-NEXT:    v_cmp_ge_u32_e64 s[2:3], s8, v0
+; GCN-NEXT:    v_cmp_le_u32_e64 s[0:1], s9, v1
+; GCN-NEXT:    v_add_i32_e32 v2, vcc, s9, v1
+; GCN-NEXT:    v_subrev_i32_e32 v0, vcc, s9, v1
+; GCN-NEXT:    s_and_b64 vcc, s[0:1], s[2:3]
+; GCN-NEXT:    v_cndmask_b32_e32 v0, v1, v0, vcc
+; GCN-NEXT:    v_cndmask_b32_e64 v0, v2, v0, s[2:3]
+; GCN-NEXT:    buffer_store_dword v0, off, s[4:7], 0
+; GCN-NEXT:    s_endpgm
   %r = urem i32 %x, %y
   store i32 %r, i32 addrspace(1)* %out
   ret void
@@ -155,6 +221,47 @@ define amdgpu_kernel void @sdiv_i32(i32 addrspace(1)* %out, i32 %x, i32 %y) {
 ; CHECK-NEXT:    store i32 [[TMP49]], i32 addrspace(1)* [[OUT:%.*]]
 ; CHECK-NEXT:    ret void
 ;
+; GCN-LABEL: sdiv_i32:
+; GCN:       ; %bb.0:
+; GCN-NEXT:    s_load_dwordx2 s[2:3], s[0:1], 0xb
+; GCN-NEXT:    s_load_dwordx2 s[4:5], s[0:1], 0x9
+; GCN-NEXT:    s_mov_b32 s7, 0xf000
+; GCN-NEXT:    s_mov_b32 s6, -1
+; GCN-NEXT:    s_waitcnt lgkmcnt(0)
+; GCN-NEXT:    s_ashr_i32 s8, s3, 31
+; GCN-NEXT:    s_add_i32 s3, s3, s8
+; GCN-NEXT:    s_xor_b32 s9, s3, s8
+; GCN-NEXT:    v_cvt_f32_u32_e32 v0, s9
+; GCN-NEXT:    s_ashr_i32 s3, s2, 31
+; GCN-NEXT:    s_add_i32 s2, s2, s3
+; GCN-NEXT:    s_xor_b32 s2, s2, s3
+; GCN-NEXT:    v_rcp_iflag_f32_e32 v0, v0
+; GCN-NEXT:    s_xor_b32 s3, s3, s8
+; GCN-NEXT:    v_mul_f32_e32 v0, 0x4f800000, v0
+; GCN-NEXT:    v_cvt_u32_f32_e32 v0, v0
+; GCN-NEXT:    v_mul_lo_u32 v1, v0, s9
+; GCN-NEXT:    v_mul_hi_u32 v2, v0, s9
+; GCN-NEXT:    v_sub_i32_e32 v3, vcc, 0, v1
+; GCN-NEXT:    v_cmp_eq_u32_e64 s[0:1], 0, v2
+; GCN-NEXT:    v_cndmask_b32_e64 v1, v1, v3, s[0:1]
+; GCN-NEXT:    v_mul_hi_u32 v1, v1, v0
+; GCN-NEXT:    v_add_i32_e32 v2, vcc, v1, v0
+; GCN-NEXT:    v_subrev_i32_e32 v0, vcc, v1, v0
+; GCN-NEXT:    v_cndmask_b32_e64 v0, v0, v2, s[0:1]
+; GCN-NEXT:    v_mul_hi_u32 v0, v0, s2
+; GCN-NEXT:    v_mul_lo_u32 v1, v0, s9
+; GCN-NEXT:    v_add_i32_e32 v2, vcc, 1, v0
+; GCN-NEXT:    v_add_i32_e32 v3, vcc, -1, v0
+; GCN-NEXT:    v_sub_i32_e32 v4, vcc, s2, v1
+; GCN-NEXT:    v_cmp_ge_u32_e32 vcc, s2, v1
+; GCN-NEXT:    v_cmp_le_u32_e64 s[0:1], s9, v4
+; GCN-NEXT:    s_and_b64 s[0:1], s[0:1], vcc
+; GCN-NEXT:    v_cndmask_b32_e64 v0, v0, v2, s[0:1]
+; GCN-NEXT:    v_cndmask_b32_e32 v0, v3, v0, vcc
+; GCN-NEXT:    v_xor_b32_e32 v0, s3, v0
+; GCN-NEXT:    v_subrev_i32_e32 v0, vcc, s3, v0
+; GCN-NEXT:    buffer_store_dword v0, off, s[4:7], 0
+; GCN-NEXT:    s_endpgm
   %r = sdiv i32 %x, %y
   store i32 %r, i32 addrspace(1)* %out
   ret void
@@ -213,6 +320,47 @@ define amdgpu_kernel void @srem_i32(i32 addrspace(1)* %out, i32 %x, i32 %y) {
 ; CHECK-NEXT:    store i32 [[TMP48]], i32 addrspace(1)* [[OUT:%.*]]
 ; CHECK-NEXT:    ret void
 ;
+; GCN-LABEL: srem_i32:
+; GCN:       ; %bb.0:
+; GCN-NEXT:    s_load_dwordx2 s[4:5], s[0:1], 0xb
+; GCN-NEXT:    s_mov_b32 s7, 0xf000
+; GCN-NEXT:    s_mov_b32 s6, -1
+; GCN-NEXT:    s_waitcnt lgkmcnt(0)
+; GCN-NEXT:    s_ashr_i32 s2, s5, 31
+; GCN-NEXT:    s_add_i32 s3, s5, s2
+; GCN-NEXT:    s_xor_b32 s10, s3, s2
+; GCN-NEXT:    v_cvt_f32_u32_e32 v0, s10
+; GCN-NEXT:    s_ashr_i32 s8, s4, 31
+; GCN-NEXT:    s_add_i32 s4, s4, s8
+; GCN-NEXT:    s_xor_b32 s9, s4, s8
+; GCN-NEXT:    v_rcp_iflag_f32_e32 v0, v0
+; GCN-NEXT:    s_load_dwordx2 s[4:5], s[0:1], 0x9
+; GCN-NEXT:    v_mul_f32_e32 v0, 0x4f800000, v0
+; GCN-NEXT:    v_cvt_u32_f32_e32 v0, v0
+; GCN-NEXT:    v_mul_lo_u32 v1, v0, s10
+; GCN-NEXT:    v_mul_hi_u32 v2, v0, s10
+; GCN-NEXT:    v_sub_i32_e32 v3, vcc, 0, v1
+; GCN-NEXT:    v_cmp_eq_u32_e64 s[2:3], 0, v2
+; GCN-NEXT:    v_cndmask_b32_e64 v1, v1, v3, s[2:3]
+; GCN-NEXT:    v_mul_hi_u32 v1, v1, v0
+; GCN-NEXT:    v_add_i32_e32 v2, vcc, v1, v0
+; GCN-NEXT:    v_subrev_i32_e32 v0, vcc, v1, v0
+; GCN-NEXT:    v_cndmask_b32_e64 v0, v0, v2, s[2:3]
+; GCN-NEXT:    v_mul_hi_u32 v0, v0, s9
+; GCN-NEXT:    v_mul_lo_u32 v0, v0, s10
+; GCN-NEXT:    v_sub_i32_e32 v1, vcc, s9, v0
+; GCN-NEXT:    v_cmp_ge_u32_e64 s[2:3], s9, v0
+; GCN-NEXT:    v_cmp_le_u32_e64 s[0:1], s10, v1
+; GCN-NEXT:    v_add_i32_e32 v2, vcc, s10, v1
+; GCN-NEXT:    v_subrev_i32_e32 v0, vcc, s10, v1
+; GCN-NEXT:    s_and_b64 vcc, s[0:1], s[2:3]
+; GCN-NEXT:    v_cndmask_b32_e32 v0, v1, v0, vcc
+; GCN-NEXT:    v_cndmask_b32_e64 v0, v2, v0, s[2:3]
+; GCN-NEXT:    v_xor_b32_e32 v0, s8, v0
+; GCN-NEXT:    v_subrev_i32_e32 v0, vcc, s8, v0
+; GCN-NEXT:    s_waitcnt lgkmcnt(0)
+; GCN-NEXT:    buffer_store_dword v0, off, s[4:7], 0
+; GCN-NEXT:    s_endpgm
   %r = srem i32 %x, %y
   store i32 %r, i32 addrspace(1)* %out
   ret void
@@ -240,6 +388,26 @@ define amdgpu_kernel void @udiv_i16(i16 addrspace(1)* %out, i16 %x, i16 %y) {
 ; CHECK-NEXT:    store i16 [[TMP17]], i16 addrspace(1)* [[OUT:%.*]]
 ; CHECK-NEXT:    ret void
 ;
+; GCN-LABEL: udiv_i16:
+; GCN:       ; %bb.0:
+; GCN-NEXT:    s_load_dword s2, s[0:1], 0xb
+; GCN-NEXT:    s_load_dwordx2 s[0:1], s[0:1], 0x9
+; GCN-NEXT:    s_waitcnt lgkmcnt(0)
+; GCN-NEXT:    s_lshr_b32 s3, s2, 16
+; GCN-NEXT:    v_cvt_f32_u32_e32 v0, s3
+; GCN-NEXT:    s_and_b32 s2, s2, 0xffff
+; GCN-NEXT:    v_cvt_f32_u32_e32 v1, s2
+; GCN-NEXT:    s_mov_b32 s3, 0xf000
+; GCN-NEXT:    v_rcp_iflag_f32_e32 v2, v0
+; GCN-NEXT:    s_mov_b32 s2, -1
+; GCN-NEXT:    v_mul_f32_e32 v2, v1, v2
+; GCN-NEXT:    v_trunc_f32_e32 v2, v2
+; GCN-NEXT:    v_cvt_u32_f32_e32 v3, v2
+; GCN-NEXT:    v_mad_f32 v1, -v2, v0, v1
+; GCN-NEXT:    v_cmp_ge_f32_e64 vcc, |v1|, v0
+; GCN-NEXT:    v_addc_u32_e32 v0, vcc, 0, v3, vcc
+; GCN-NEXT:    buffer_store_short v0, off, s[0:3], 0
+; GCN-NEXT:    s_endpgm
   %r = udiv i16 %x, %y
   store i16 %r, i16 addrspace(1)* %out
   ret void
@@ -269,6 +437,28 @@ define amdgpu_kernel void @urem_i16(i16 addrspace(1)* %out, i16 %x, i16 %y) {
 ; CHECK-NEXT:    store i16 [[TMP19]], i16 addrspace(1)* [[OUT:%.*]]
 ; CHECK-NEXT:    ret void
 ;
+; GCN-LABEL: urem_i16:
+; GCN:       ; %bb.0:
+; GCN-NEXT:    s_load_dword s4, s[0:1], 0xb
+; GCN-NEXT:    s_load_dwordx2 s[0:1], s[0:1], 0x9
+; GCN-NEXT:    s_waitcnt lgkmcnt(0)
+; GCN-NEXT:    s_lshr_b32 s2, s4, 16
+; GCN-NEXT:    v_cvt_f32_u32_e32 v0, s2
+; GCN-NEXT:    s_and_b32 s3, s4, 0xffff
+; GCN-NEXT:    v_cvt_f32_u32_e32 v1, s3
+; GCN-NEXT:    s_mov_b32 s3, 0xf000
+; GCN-NEXT:    v_rcp_iflag_f32_e32 v2, v0
+; GCN-NEXT:    v_mul_f32_e32 v2, v1, v2
+; GCN-NEXT:    v_trunc_f32_e32 v2, v2
+; GCN-NEXT:    v_cvt_u32_f32_e32 v3, v2
+; GCN-NEXT:    v_mad_f32 v1, -v2, v0, v1
+; GCN-NEXT:    v_cmp_ge_f32_e64 vcc, |v1|, v0
+; GCN-NEXT:    v_addc_u32_e32 v0, vcc, 0, v3, vcc
+; GCN-NEXT:    v_mul_lo_u32 v0, v0, s2
+; GCN-NEXT:    s_mov_b32 s2, -1
+; GCN-NEXT:    v_sub_i32_e32 v0, vcc, s4, v0
+; GCN-NEXT:    buffer_store_short v0, off, s[0:3], 0
+; GCN-NEXT:    s_endpgm
   %r = urem i16 %x, %y
   store i16 %r, i16 addrspace(1)* %out
   ret void
@@ -300,6 +490,31 @@ define amdgpu_kernel void @sdiv_i16(i16 addrspace(1)* %out, i16 %x, i16 %y) {
 ; CHECK-NEXT:    store i16 [[TMP21]], i16 addrspace(1)* [[OUT:%.*]]
 ; CHECK-NEXT:    ret void
 ;
+; GCN-LABEL: sdiv_i16:
+; GCN:       ; %bb.0:
+; GCN-NEXT:    s_load_dwordx2 s[4:5], s[0:1], 0x9
+; GCN-NEXT:    s_load_dword s0, s[0:1], 0xb
+; GCN-NEXT:    s_mov_b32 s7, 0xf000
+; GCN-NEXT:    s_mov_b32 s6, -1
+; GCN-NEXT:    s_waitcnt lgkmcnt(0)
+; GCN-NEXT:    s_ashr_i32 s1, s0, 16
+; GCN-NEXT:    v_cvt_f32_i32_e32 v0, s1
+; GCN-NEXT:    s_sext_i32_i16 s0, s0
+; GCN-NEXT:    v_cvt_f32_i32_e32 v1, s0
+; GCN-NEXT:    s_xor_b32 s0, s0, s1
+; GCN-NEXT:    v_rcp_iflag_f32_e32 v2, v0
+; GCN-NEXT:    s_ashr_i32 s0, s0, 30
+; GCN-NEXT:    s_or_b32 s0, s0, 1
+; GCN-NEXT:    v_mov_b32_e32 v3, s0
+; GCN-NEXT:    v_mul_f32_e32 v2, v1, v2
+; GCN-NEXT:    v_trunc_f32_e32 v2, v2
+; GCN-NEXT:    v_mad_f32 v1, -v2, v0, v1
+; GCN-NEXT:    v_cvt_i32_f32_e32 v2, v2
+; GCN-NEXT:    v_cmp_ge_f32_e64 vcc, |v1|, |v0|
+; GCN-NEXT:    v_cndmask_b32_e32 v0, 0, v3, vcc
+; GCN-NEXT:    v_add_i32_e32 v0, vcc, v0, v2
+; GCN-NEXT:    buffer_store_short v0, off, s[4:7], 0
+; GCN-NEXT:    s_endpgm
   %r = sdiv i16 %x, %y
   store i16 %r, i16 addrspace(1)* %out
   ret void
@@ -333,6 +548,33 @@ define amdgpu_kernel void @srem_i16(i16 addrspace(1)* %out, i16 %x, i16 %y) {
 ; CHECK-NEXT:    store i16 [[TMP23]], i16 addrspace(1)* [[OUT:%.*]]
 ; CHECK-NEXT:    ret void
 ;
+; GCN-LABEL: srem_i16:
+; GCN:       ; %bb.0:
+; GCN-NEXT:    s_load_dword s4, s[0:1], 0xb
+; GCN-NEXT:    s_load_dwordx2 s[0:1], s[0:1], 0x9
+; GCN-NEXT:    s_waitcnt lgkmcnt(0)
+; GCN-NEXT:    s_ashr_i32 s2, s4, 16
+; GCN-NEXT:    v_cvt_f32_i32_e32 v0, s2
+; GCN-NEXT:    s_sext_i32_i16 s3, s4
+; GCN-NEXT:    v_cvt_f32_i32_e32 v1, s3
+; GCN-NEXT:    s_xor_b32 s3, s3, s2
+; GCN-NEXT:    v_rcp_iflag_f32_e32 v2, v0
+; GCN-NEXT:    s_ashr_i32 s3, s3, 30
+; GCN-NEXT:    s_or_b32 s3, s3, 1
+; GCN-NEXT:    v_mov_b32_e32 v3, s3
+; GCN-NEXT:    v_mul_f32_e32 v2, v1, v2
+; GCN-NEXT:    v_trunc_f32_e32 v2, v2
+; GCN-NEXT:    v_mad_f32 v1, -v2, v0, v1
+; GCN-NEXT:    v_cvt_i32_f32_e32 v2, v2
+; GCN-NEXT:    v_cmp_ge_f32_e64 vcc, |v1|, |v0|
+; GCN-NEXT:    v_cndmask_b32_e32 v0, 0, v3, vcc
+; GCN-NEXT:    s_mov_b32 s3, 0xf000
+; GCN-NEXT:    v_add_i32_e32 v0, vcc, v0, v2
+; GCN-NEXT:    v_mul_lo_u32 v0, v0, s2
+; GCN-NEXT:    s_mov_b32 s2, -1
+; GCN-NEXT:    v_sub_i32_e32 v0, vcc, s4, v0
+; GCN-NEXT:    buffer_store_short v0, off, s[0:3], 0
+; GCN-NEXT:    s_endpgm
   %r = srem i16 %x, %y
   store i16 %r, i16 addrspace(1)* %out
   ret void
@@ -360,6 +602,24 @@ define amdgpu_kernel void @udiv_i8(i8 addrspace(1)* %out, i8 %x, i8 %y) {
 ; CHECK-NEXT:    store i8 [[TMP17]], i8 addrspace(1)* [[OUT:%.*]]
 ; CHECK-NEXT:    ret void
 ;
+; GCN-LABEL: udiv_i8:
+; GCN:       ; %bb.0:
+; GCN-NEXT:    s_load_dwordx2 s[4:5], s[0:1], 0x9
+; GCN-NEXT:    s_load_dword s0, s[0:1], 0xb
+; GCN-NEXT:    s_mov_b32 s7, 0xf000
+; GCN-NEXT:    s_mov_b32 s6, -1
+; GCN-NEXT:    s_waitcnt lgkmcnt(0)
+; GCN-NEXT:    v_cvt_f32_ubyte1_e32 v0, s0
+; GCN-NEXT:    v_rcp_iflag_f32_e32 v1, v0
+; GCN-NEXT:    v_cvt_f32_ubyte0_e32 v2, s0
+; GCN-NEXT:    v_mul_f32_e32 v1, v2, v1
+; GCN-NEXT:    v_trunc_f32_e32 v1, v1
+; GCN-NEXT:    v_cvt_u32_f32_e32 v3, v1
+; GCN-NEXT:    v_mad_f32 v1, -v1, v0, v2
+; GCN-NEXT:    v_cmp_ge_f32_e64 vcc, |v1|, v0
+; GCN-NEXT:    v_addc_u32_e32 v0, vcc, 0, v3, vcc
+; GCN-NEXT:    buffer_store_byte v0, off, s[4:7], 0
+; GCN-NEXT:    s_endpgm
   %r = udiv i8 %x, %y
   store i8 %r, i8 addrspace(1)* %out
   ret void
@@ -389,6 +649,27 @@ define amdgpu_kernel void @urem_i8(i8 addrspace(1)* %out, i8 %x, i8 %y) {
 ; CHECK-NEXT:    store i8 [[TMP19]], i8 addrspace(1)* [[OUT:%.*]]
 ; CHECK-NEXT:    ret void
 ;
+; GCN-LABEL: urem_i8:
+; GCN:       ; %bb.0:
+; GCN-NEXT:    s_load_dword s4, s[0:1], 0xb
+; GCN-NEXT:    s_load_dwordx2 s[0:1], s[0:1], 0x9
+; GCN-NEXT:    s_mov_b32 s3, 0xf000
+; GCN-NEXT:    s_waitcnt lgkmcnt(0)
+; GCN-NEXT:    v_cvt_f32_ubyte1_e32 v0, s4
+; GCN-NEXT:    v_rcp_iflag_f32_e32 v1, v0
+; GCN-NEXT:    v_cvt_f32_ubyte0_e32 v2, s4
+; GCN-NEXT:    s_lshr_b32 s2, s4, 8
+; GCN-NEXT:    v_mul_f32_e32 v1, v2, v1
+; GCN-NEXT:    v_trunc_f32_e32 v1, v1
+; GCN-NEXT:    v_cvt_u32_f32_e32 v3, v1
+; GCN-NEXT:    v_mad_f32 v1, -v1, v0, v2
+; GCN-NEXT:    v_cmp_ge_f32_e64 vcc, |v1|, v0
+; GCN-NEXT:    v_addc_u32_e32 v0, vcc, 0, v3, vcc
+; GCN-NEXT:    v_mul_lo_u32 v0, v0, s2
+; GCN-NEXT:    s_mov_b32 s2, -1
+; GCN-NEXT:    v_sub_i32_e32 v0, vcc, s4, v0
+; GCN-NEXT:    buffer_store_byte v0, off, s[0:3], 0
+; GCN-NEXT:    s_endpgm
   %r = urem i8 %x, %y
   store i8 %r, i8 addrspace(1)* %out
   ret void
@@ -420,6 +701,31 @@ define amdgpu_kernel void @sdiv_i8(i8 addrspace(1)* %out, i8 %x, i8 %y) {
 ; CHECK-NEXT:    store i8 [[TMP21]], i8 addrspace(1)* [[OUT:%.*]]
 ; CHECK-NEXT:    ret void
 ;
+; GCN-LABEL: sdiv_i8:
+; GCN:       ; %bb.0:
+; GCN-NEXT:    s_load_dwordx2 s[4:5], s[0:1], 0x9
+; GCN-NEXT:    s_load_dword s0, s[0:1], 0xb
+; GCN-NEXT:    s_mov_b32 s7, 0xf000
+; GCN-NEXT:    s_mov_b32 s6, -1
+; GCN-NEXT:    s_waitcnt lgkmcnt(0)
+; GCN-NEXT:    s_bfe_i32 s1, s0, 0x80008
+; GCN-NEXT:    v_cvt_f32_i32_e32 v0, s1
+; GCN-NEXT:    s_sext_i32_i8 s0, s0
+; GCN-NEXT:    v_cvt_f32_i32_e32 v1, s0
+; GCN-NEXT:    s_xor_b32 s0, s0, s1
+; GCN-NEXT:    v_rcp_iflag_f32_e32 v2, v0
+; GCN-NEXT:    s_ashr_i32 s0, s0, 30
+; GCN-NEXT:    s_or_b32 s0, s0, 1
+; GCN-NEXT:    v_mov_b32_e32 v3, s0
+; GCN-NEXT:    v_mul_f32_e32 v2, v1, v2
+; GCN-NEXT:    v_trunc_f32_e32 v2, v2
+; GCN-NEXT:    v_mad_f32 v1, -v2, v0, v1
+; GCN-NEXT:    v_cvt_i32_f32_e32 v2, v2
+; GCN-NEXT:    v_cmp_ge_f32_e64 vcc, |v1|, |v0|
+; GCN-NEXT:    v_cndmask_b32_e32 v0, 0, v3, vcc
+; GCN-NEXT:    v_add_i32_e32 v0, vcc, v0, v2
+; GCN-NEXT:    buffer_store_byte v0, off, s[4:7], 0
+; GCN-NEXT:    s_endpgm
   %r = sdiv i8 %x, %y
   store i8 %r, i8 addrspace(1)* %out
   ret void
@@ -453,6 +759,34 @@ define amdgpu_kernel void @srem_i8(i8 addrspace(1)* %out, i8 %x, i8 %y) {
 ; CHECK-NEXT:    store i8 [[TMP23]], i8 addrspace(1)* [[OUT:%.*]]
 ; CHECK-NEXT:    ret void
 ;
+; GCN-LABEL: srem_i8:
+; GCN:       ; %bb.0:
+; GCN-NEXT:    s_load_dwordx2 s[4:5], s[0:1], 0x9
+; GCN-NEXT:    s_load_dword s0, s[0:1], 0xb
+; GCN-NEXT:    s_mov_b32 s7, 0xf000
+; GCN-NEXT:    s_mov_b32 s6, -1
+; GCN-NEXT:    s_waitcnt lgkmcnt(0)
+; GCN-NEXT:    s_bfe_i32 s1, s0, 0x80008
+; GCN-NEXT:    v_cvt_f32_i32_e32 v0, s1
+; GCN-NEXT:    s_sext_i32_i8 s3, s0
+; GCN-NEXT:    v_cvt_f32_i32_e32 v1, s3
+; GCN-NEXT:    s_xor_b32 s1, s3, s1
+; GCN-NEXT:    v_rcp_iflag_f32_e32 v2, v0
+; GCN-NEXT:    s_ashr_i32 s1, s1, 30
+; GCN-NEXT:    s_or_b32 s1, s1, 1
+; GCN-NEXT:    v_mov_b32_e32 v3, s1
+; GCN-NEXT:    v_mul_f32_e32 v2, v1, v2
+; GCN-NEXT:    v_trunc_f32_e32 v2, v2
+; GCN-NEXT:    v_mad_f32 v1, -v2, v0, v1
+; GCN-NEXT:    v_cvt_i32_f32_e32 v2, v2
+; GCN-NEXT:    v_cmp_ge_f32_e64 vcc, |v1|, |v0|
+; GCN-NEXT:    v_cndmask_b32_e32 v0, 0, v3, vcc
+; GCN-NEXT:    s_lshr_b32 s2, s0, 8
+; GCN-NEXT:    v_add_i32_e32 v0, vcc, v0, v2
+; GCN-NEXT:    v_mul_lo_u32 v0, v0, s2
+; GCN-NEXT:    v_sub_i32_e32 v0, vcc, s0, v0
+; GCN-NEXT:    buffer_store_byte v0, off, s[4:7], 0
+; GCN-NEXT:    s_endpgm
   %r = srem i8 %x, %y
   store i8 %r, i8 addrspace(1)* %out
   ret void
@@ -635,6 +969,108 @@ define amdgpu_kernel void @udiv_v4i32(<4 x i32> addrspace(1)* %out, <4 x i32> %x
 ; CHECK-NEXT:    store <4 x i32> [[TMP172]], <4 x i32> addrspace(1)* [[OUT:%.*]]
 ; CHECK-NEXT:    ret void
 ;
+; GCN-LABEL: udiv_v4i32:
+; GCN:       ; %bb.0:
+; GCN-NEXT:    s_load_dwordx8 s[8:15], s[0:1], 0xd
+; GCN-NEXT:    s_mov_b32 s6, 0x4f800000
+; GCN-NEXT:    s_load_dwordx2 s[16:17], s[0:1], 0x9
+; GCN-NEXT:    s_mov_b32 s19, 0xf000
+; GCN-NEXT:    s_mov_b32 s18, -1
+; GCN-NEXT:    s_waitcnt lgkmcnt(0)
+; GCN-NEXT:    v_cvt_f32_u32_e32 v0, s12
+; GCN-NEXT:    v_cvt_f32_u32_e32 v1, s13
+; GCN-NEXT:    v_cvt_f32_u32_e32 v7, s15
+; GCN-NEXT:    v_rcp_iflag_f32_e32 v0, v0
+; GCN-NEXT:    v_rcp_iflag_f32_e32 v1, v1
+; GCN-NEXT:    v_mul_f32_e32 v0, s6, v0
+; GCN-NEXT:    v_cvt_u32_f32_e32 v0, v0
+; GCN-NEXT:    v_mul_f32_e32 v1, s6, v1
+; GCN-NEXT:    v_cvt_u32_f32_e32 v1, v1
+; GCN-NEXT:    v_mul_hi_u32 v2, v0, s12
+; GCN-NEXT:    v_mul_lo_u32 v3, v0, s12
+; GCN-NEXT:    v_mul_hi_u32 v4, v1, s13
+; GCN-NEXT:    v_mul_lo_u32 v5, v1, s13
+; GCN-NEXT:    v_cmp_eq_u32_e64 s[0:1], 0, v2
+; GCN-NEXT:    v_sub_i32_e32 v6, vcc, 0, v3
+; GCN-NEXT:    v_cndmask_b32_e64 v2, v3, v6, s[0:1]
+; GCN-NEXT:    v_mul_hi_u32 v2, v2, v0
+; GCN-NEXT:    v_sub_i32_e32 v3, vcc, 0, v5
+; GCN-NEXT:    v_add_i32_e32 v6, vcc, v2, v0
+; GCN-NEXT:    v_subrev_i32_e32 v0, vcc, v2, v0
+; GCN-NEXT:    v_cndmask_b32_e64 v0, v0, v6, s[0:1]
+; GCN-NEXT:    v_mul_hi_u32 v0, v0, s8
+; GCN-NEXT:    v_cmp_eq_u32_e64 s[0:1], 0, v4
+; GCN-NEXT:    v_cndmask_b32_e64 v2, v5, v3, s[0:1]
+; GCN-NEXT:    v_mul_hi_u32 v2, v2, v1
+; GCN-NEXT:    v_mul_lo_u32 v3, v0, s12
+; GCN-NEXT:    v_add_i32_e32 v4, vcc, -1, v0
+; GCN-NEXT:    v_sub_i32_e32 v5, vcc, s8, v3
+; GCN-NEXT:    v_cmp_le_u32_e64 s[4:5], s12, v5
+; GCN-NEXT:    v_add_i32_e32 v5, vcc, v2, v1
+; GCN-NEXT:    v_subrev_i32_e32 v1, vcc, v2, v1
+; GCN-NEXT:    v_cvt_f32_u32_e32 v2, s14
+; GCN-NEXT:    v_cndmask_b32_e64 v1, v1, v5, s[0:1]
+; GCN-NEXT:    v_mul_hi_u32 v1, v1, s9
+; GCN-NEXT:    v_cmp_ge_u32_e64 s[2:3], s8, v3
+; GCN-NEXT:    v_rcp_iflag_f32_e32 v2, v2
+; GCN-NEXT:    v_add_i32_e32 v3, vcc, 1, v0
+; GCN-NEXT:    s_and_b64 vcc, s[4:5], s[2:3]
+; GCN-NEXT:    v_cndmask_b32_e32 v0, v0, v3, vcc
+; GCN-NEXT:    v_mul_f32_e32 v2, s6, v2
+; GCN-NEXT:    v_cvt_u32_f32_e32 v2, v2
+; GCN-NEXT:    v_mul_lo_u32 v3, v1, s13
+; GCN-NEXT:    v_cndmask_b32_e64 v0, v4, v0, s[2:3]
+; GCN-NEXT:    v_mul_hi_u32 v6, v2, s14
+; GCN-NEXT:    v_mul_lo_u32 v5, v2, s14
+; GCN-NEXT:    v_sub_i32_e32 v4, vcc, s9, v3
+; GCN-NEXT:    v_cmp_ge_u32_e64 s[2:3], s9, v3
+; GCN-NEXT:    v_cmp_eq_u32_e64 s[4:5], 0, v6
+; GCN-NEXT:    v_sub_i32_e32 v3, vcc, 0, v5
+; GCN-NEXT:    v_cndmask_b32_e64 v3, v5, v3, s[4:5]
+; GCN-NEXT:    v_mul_hi_u32 v3, v3, v2
+; GCN-NEXT:    v_cmp_le_u32_e64 s[0:1], s13, v4
+; GCN-NEXT:    v_add_i32_e32 v4, vcc, -1, v1
+; GCN-NEXT:    v_add_i32_e32 v5, vcc, 1, v1
+; GCN-NEXT:    v_add_i32_e32 v6, vcc, v3, v2
+; GCN-NEXT:    v_subrev_i32_e32 v2, vcc, v3, v2
+; GCN-NEXT:    v_rcp_iflag_f32_e32 v3, v7
+; GCN-NEXT:    v_cndmask_b32_e64 v2, v2, v6, s[4:5]
+; GCN-NEXT:    v_mul_hi_u32 v2, v2, s10
+; GCN-NEXT:    s_and_b64 vcc, s[0:1], s[2:3]
+; GCN-NEXT:    v_mul_f32_e32 v3, s6, v3
+; GCN-NEXT:    v_cvt_u32_f32_e32 v3, v3
+; GCN-NEXT:    v_cndmask_b32_e32 v1, v1, v5, vcc
+; GCN-NEXT:    v_mul_lo_u32 v5, v2, s14
+; GCN-NEXT:    v_cndmask_b32_e64 v1, v4, v1, s[2:3]
+; GCN-NEXT:    v_mul_hi_u32 v7, v3, s15
+; GCN-NEXT:    v_mul_lo_u32 v6, v3, s15
+; GCN-NEXT:    v_sub_i32_e32 v4, vcc, s10, v5
+; GCN-NEXT:    v_cmp_le_u32_e64 s[0:1], s14, v4
+; GCN-NEXT:    v_cmp_eq_u32_e64 s[2:3], 0, v7
+; GCN-NEXT:    v_sub_i32_e32 v4, vcc, 0, v6
+; GCN-NEXT:    v_cndmask_b32_e64 v4, v6, v4, s[2:3]
+; GCN-NEXT:    v_mul_hi_u32 v4, v4, v3
+; GCN-NEXT:    v_add_i32_e32 v6, vcc, -1, v2
+; GCN-NEXT:    v_add_i32_e32 v7, vcc, v4, v3
+; GCN-NEXT:    v_subrev_i32_e32 v3, vcc, v4, v3
+; GCN-NEXT:    v_cndmask_b32_e64 v3, v3, v7, s[2:3]
+; GCN-NEXT:    v_mul_hi_u32 v3, v3, s11
+; GCN-NEXT:    v_cmp_ge_u32_e64 s[2:3], s10, v5
+; GCN-NEXT:    v_add_i32_e32 v4, vcc, 1, v2
+; GCN-NEXT:    s_and_b64 vcc, s[0:1], s[2:3]
+; GCN-NEXT:    v_mul_lo_u32 v5, v3, s15
+; GCN-NEXT:    v_cndmask_b32_e32 v2, v2, v4, vcc
+; GCN-NEXT:    v_cndmask_b32_e64 v2, v6, v2, s[2:3]
+; GCN-NEXT:    v_sub_i32_e32 v4, vcc, s11, v5
+; GCN-NEXT:    v_cmp_le_u32_e64 s[0:1], s15, v4
+; GCN-NEXT:    v_cmp_ge_u32_e64 s[2:3], s11, v5
+; GCN-NEXT:    v_add_i32_e32 v4, vcc, -1, v3
+; GCN-NEXT:    v_add_i32_e32 v5, vcc, 1, v3
+; GCN-NEXT:    s_and_b64 vcc, s[0:1], s[2:3]
+; GCN-NEXT:    v_cndmask_b32_e32 v3, v3, v5, vcc
+; GCN-NEXT:    v_cndmask_b32_e64 v3, v4, v3, s[2:3]
+; GCN-NEXT:    buffer_store_dwordx4 v[0:3], off, s[16:19], 0
+; GCN-NEXT:    s_endpgm
   %r = udiv <4 x i32> %x, %y
   store <4 x i32> %r, <4 x i32> addrspace(1)* %out
   ret void
@@ -817,6 +1253,108 @@ define amdgpu_kernel void @urem_v4i32(<4 x i32> addrspace(1)* %out, <4 x i32> %x
 ; CHECK-NEXT:    store <4 x i32> [[TMP172]], <4 x i32> addrspace(1)* [[OUT:%.*]]
 ; CHECK-NEXT:    ret void
 ;
+; GCN-LABEL: urem_v4i32:
+; GCN:       ; %bb.0:
+; GCN-NEXT:    s_load_dwordx8 s[8:15], s[0:1], 0xd
+; GCN-NEXT:    s_mov_b32 s6, 0x4f800000
+; GCN-NEXT:    s_load_dwordx2 s[16:17], s[0:1], 0x9
+; GCN-NEXT:    s_mov_b32 s19, 0xf000
+; GCN-NEXT:    s_mov_b32 s18, -1
+; GCN-NEXT:    s_waitcnt lgkmcnt(0)
+; GCN-NEXT:    v_cvt_f32_u32_e32 v0, s12
+; GCN-NEXT:    v_cvt_f32_u32_e32 v1, s13
+; GCN-NEXT:    v_cvt_f32_u32_e32 v7, s15
+; GCN-NEXT:    v_rcp_iflag_f32_e32 v0, v0
+; GCN-NEXT:    v_rcp_iflag_f32_e32 v1, v1
+; GCN-NEXT:    v_mul_f32_e32 v0, s6, v0
+; GCN-NEXT:    v_cvt_u32_f32_e32 v0, v0
+; GCN-NEXT:    v_mul_f32_e32 v1, s6, v1
+; GCN-NEXT:    v_cvt_u32_f32_e32 v1, v1
+; GCN-NEXT:    v_mul_lo_u32 v2, v0, s12
+; GCN-NEXT:    v_mul_hi_u32 v3, v0, s12
+; GCN-NEXT:    v_sub_i32_e32 v4, vcc, 0, v2
+; GCN-NEXT:    v_cmp_eq_u32_e64 s[0:1], 0, v3
+; GCN-NEXT:    v_cndmask_b32_e64 v2, v2, v4, s[0:1]
+; GCN-NEXT:    v_mul_hi_u32 v2, v2, v0
+; GCN-NEXT:    v_mul_lo_u32 v3, v1, s13
+; GCN-NEXT:    v_add_i32_e32 v4, vcc, v2, v0
+; GCN-NEXT:    v_subrev_i32_e32 v0, vcc, v2, v0
+; GCN-NEXT:    v_mul_hi_u32 v2, v1, s13
+; GCN-NEXT:    v_cndmask_b32_e64 v0, v0, v4, s[0:1]
+; GCN-NEXT:    v_sub_i32_e32 v4, vcc, 0, v3
+; GCN-NEXT:    v_mul_hi_u32 v0, v0, s8
+; GCN-NEXT:    v_cmp_eq_u32_e64 s[0:1], 0, v2
+; GCN-NEXT:    v_cndmask_b32_e64 v2, v3, v4, s[0:1]
+; GCN-NEXT:    v_mul_hi_u32 v2, v2, v1
+; GCN-NEXT:    v_mul_lo_u32 v0, v0, s12
+; GCN-NEXT:    v_add_i32_e32 v5, vcc, v2, v1
+; GCN-NEXT:    v_subrev_i32_e32 v1, vcc, v2, v1
+; GCN-NEXT:    v_cvt_f32_u32_e32 v2, s14
+; GCN-NEXT:    v_cndmask_b32_e64 v1, v1, v5, s[0:1]
+; GCN-NEXT:    v_mul_hi_u32 v1, v1, s9
+; GCN-NEXT:    v_sub_i32_e32 v3, vcc, s8, v0
+; GCN-NEXT:    v_rcp_iflag_f32_e32 v2, v2
+; GCN-NEXT:    v_cmp_ge_u32_e64 s[4:5], s8, v0
+; GCN-NEXT:    v_mul_lo_u32 v1, v1, s13
+; GCN-NEXT:    v_cmp_le_u32_e64 s[2:3], s12, v3
+; GCN-NEXT:    v_mul_f32_e32 v2, s6, v2
+; GCN-NEXT:    v_cvt_u32_f32_e32 v2, v2
+; GCN-NEXT:    v_add_i32_e32 v4, vcc, s12, v3
+; GCN-NEXT:    v_subrev_i32_e32 v0, vcc, s12, v3
+; GCN-NEXT:    s_and_b64 vcc, s[2:3], s[4:5]
+; GCN-NEXT:    v_mul_lo_u32 v5, v2, s14
+; GCN-NEXT:    v_mul_hi_u32 v6, v2, s14
+; GCN-NEXT:    v_cndmask_b32_e32 v0, v3, v0, vcc
+; GCN-NEXT:    v_cndmask_b32_e64 v0, v4, v0, s[4:5]
+; GCN-NEXT:    v_sub_i32_e32 v3, vcc, s9, v1
+; GCN-NEXT:    v_cmp_ge_u32_e64 s[2:3], s9, v1
+; GCN-NEXT:    v_sub_i32_e32 v1, vcc, 0, v5
+; GCN-NEXT:    v_cmp_eq_u32_e64 s[4:5], 0, v6
+; GCN-NEXT:    v_cndmask_b32_e64 v1, v5, v1, s[4:5]
+; GCN-NEXT:    v_mul_hi_u32 v1, v1, v2
+; GCN-NEXT:    v_cmp_le_u32_e64 s[0:1], s13, v3
+; GCN-NEXT:    v_add_i32_e32 v4, vcc, s13, v3
+; GCN-NEXT:    v_subrev_i32_e32 v5, vcc, s13, v3
+; GCN-NEXT:    v_add_i32_e32 v6, vcc, v1, v2
+; GCN-NEXT:    v_subrev_i32_e32 v1, vcc, v1, v2
+; GCN-NEXT:    v_cndmask_b32_e64 v1, v1, v6, s[4:5]
+; GCN-NEXT:    v_mul_hi_u32 v1, v1, s10
+; GCN-NEXT:    v_rcp_iflag_f32_e32 v2, v7
+; GCN-NEXT:    s_and_b64 vcc, s[0:1], s[2:3]
+; GCN-NEXT:    v_cndmask_b32_e32 v3, v3, v5, vcc
+; GCN-NEXT:    v_mul_lo_u32 v5, v1, s14
+; GCN-NEXT:    v_mul_f32_e32 v1, s6, v2
+; GCN-NEXT:    v_cvt_u32_f32_e32 v2, v1
+; GCN-NEXT:    v_cndmask_b32_e64 v1, v4, v3, s[2:3]
+; GCN-NEXT:    v_sub_i32_e32 v3, vcc, s10, v5
+; GCN-NEXT:    v_cmp_le_u32_e64 s[0:1], s14, v3
+; GCN-NEXT:    v_mul_lo_u32 v4, v2, s15
+; GCN-NEXT:    v_mul_hi_u32 v6, v2, s15
+; GCN-NEXT:    v_sub_i32_e32 v7, vcc, 0, v4
+; GCN-NEXT:    v_cmp_eq_u32_e64 s[2:3], 0, v6
+; GCN-NEXT:    v_cndmask_b32_e64 v4, v4, v7, s[2:3]
+; GCN-NEXT:    v_mul_hi_u32 v4, v4, v2
+; GCN-NEXT:    v_add_i32_e32 v6, vcc, s14, v3
+; GCN-NEXT:    v_add_i32_e32 v7, vcc, v4, v2
+; GCN-NEXT:    v_subrev_i32_e32 v2, vcc, v4, v2
+; GCN-NEXT:    v_cndmask_b32_e64 v2, v2, v7, s[2:3]
+; GCN-NEXT:    v_mul_hi_u32 v2, v2, s11
+; GCN-NEXT:    v_cmp_ge_u32_e64 s[2:3], s10, v5
+; GCN-NEXT:    v_subrev_i32_e32 v4, vcc, s14, v3
+; GCN-NEXT:    s_and_b64 vcc, s[0:1], s[2:3]
+; GCN-NEXT:    v_mul_lo_u32 v5, v2, s15
+; GCN-NEXT:    v_cndmask_b32_e32 v2, v3, v4, vcc
+; GCN-NEXT:    v_cndmask_b32_e64 v2, v6, v2, s[2:3]
+; GCN-NEXT:    v_sub_i32_e32 v3, vcc, s11, v5
+; GCN-NEXT:    v_cmp_ge_u32_e64 s[2:3], s11, v5
+; GCN-NEXT:    v_cmp_le_u32_e64 s[0:1], s15, v3
+; GCN-NEXT:    v_add_i32_e32 v4, vcc, s15, v3
+; GCN-NEXT:    v_subrev_i32_e32 v5, vcc, s15, v3
+; GCN-NEXT:    s_and_b64 vcc, s[0:1], s[2:3]
+; GCN-NEXT:    v_cndmask_b32_e32 v3, v3, v5, vcc
+; GCN-NEXT:    v_cndmask_b32_e64 v3, v4, v3, s[2:3]
+; GCN-NEXT:    buffer_store_dwordx4 v[0:3], off, s[16:19], 0
+; GCN-NEXT:    s_endpgm
   %r = urem <4 x i32> %x, %y
   store <4 x i32> %r, <4 x i32> addrspace(1)* %out
   ret void
@@ -1035,6 +1573,144 @@ define amdgpu_kernel void @sdiv_v4i32(<4 x i32> addrspace(1)* %out, <4 x i32> %x
 ; CHECK-NEXT:    store <4 x i32> [[TMP208]], <4 x i32> addrspace(1)* [[OUT:%.*]]
 ; CHECK-NEXT:    ret void
 ;
+; GCN-LABEL: sdiv_v4i32:
+; GCN:       ; %bb.0:
+; GCN-NEXT:    s_load_dwordx8 s[12:19], s[0:1], 0xd
+; GCN-NEXT:    s_load_dwordx2 s[8:9], s[0:1], 0x9
+; GCN-NEXT:    s_mov_b32 s11, 0xf000
+; GCN-NEXT:    s_mov_b32 s10, -1
+; GCN-NEXT:    s_waitcnt lgkmcnt(0)
+; GCN-NEXT:    s_ashr_i32 s2, s16, 31
+; GCN-NEXT:    s_add_i32 s3, s16, s2
+; GCN-NEXT:    s_xor_b32 s5, s3, s2
+; GCN-NEXT:    v_cvt_f32_u32_e32 v0, s5
+; GCN-NEXT:    s_mov_b32 s16, 0x4f800000
+; GCN-NEXT:    s_ashr_i32 s6, s17, 31
+; GCN-NEXT:    s_add_i32 s0, s17, s6
+; GCN-NEXT:    v_rcp_iflag_f32_e32 v0, v0
+; GCN-NEXT:    s_xor_b32 s17, s0, s6
+; GCN-NEXT:    v_cvt_f32_u32_e32 v3, s17
+; GCN-NEXT:    s_ashr_i32 s3, s12, 31
+; GCN-NEXT:    v_mul_f32_e32 v0, s16, v0
+; GCN-NEXT:    v_cvt_u32_f32_e32 v0, v0
+; GCN-NEXT:    s_add_i32 s4, s12, s3
+; GCN-NEXT:    s_xor_b32 s4, s4, s3
+; GCN-NEXT:    s_xor_b32 s7, s3, s2
+; GCN-NEXT:    v_mul_lo_u32 v1, v0, s5
+; GCN-NEXT:    v_mul_hi_u32 v2, v0, s5
+; GCN-NEXT:    s_ashr_i32 s12, s13, 31
+; GCN-NEXT:    s_add_i32 s13, s13, s12
+; GCN-NEXT:    v_sub_i32_e32 v4, vcc, 0, v1
+; GCN-NEXT:    v_cmp_eq_u32_e64 s[0:1], 0, v2
+; GCN-NEXT:    v_cndmask_b32_e64 v1, v1, v4, s[0:1]
+; GCN-NEXT:    v_mul_hi_u32 v1, v1, v0
+; GCN-NEXT:    v_rcp_iflag_f32_e32 v2, v3
+; GCN-NEXT:    s_xor_b32 s13, s13, s12
+; GCN-NEXT:    v_add_i32_e32 v3, vcc, v1, v0
+; GCN-NEXT:    v_subrev_i32_e32 v0, vcc, v1, v0
+; GCN-NEXT:    v_cndmask_b32_e64 v0, v0, v3, s[0:1]
+; GCN-NEXT:    v_mul_hi_u32 v0, v0, s4
+; GCN-NEXT:    v_mul_f32_e32 v1, s16, v2
+; GCN-NEXT:    v_cvt_u32_f32_e32 v1, v1
+; GCN-NEXT:    v_mul_lo_u32 v2, v0, s5
+; GCN-NEXT:    v_add_i32_e32 v3, vcc, -1, v0
+; GCN-NEXT:    v_mul_hi_u32 v5, v1, s17
+; GCN-NEXT:    v_sub_i32_e32 v4, vcc, s4, v2
+; GCN-NEXT:    v_cmp_le_u32_e64 s[2:3], s5, v4
+; GCN-NEXT:    v_mul_lo_u32 v4, v1, s17
+; GCN-NEXT:    v_cmp_ge_u32_e64 s[0:1], s4, v2
+; GCN-NEXT:    v_cmp_eq_u32_e64 s[4:5], 0, v5
+; GCN-NEXT:    v_add_i32_e32 v2, vcc, 1, v0
+; GCN-NEXT:    v_sub_i32_e32 v6, vcc, 0, v4
+; GCN-NEXT:    v_cndmask_b32_e64 v4, v4, v6, s[4:5]
+; GCN-NEXT:    v_mul_hi_u32 v4, v4, v1
+; GCN-NEXT:    v_add_i32_e32 v5, vcc, v4, v1
+; GCN-NEXT:    v_subrev_i32_e32 v1, vcc, v4, v1
+; GCN-NEXT:    s_and_b64 vcc, s[2:3], s[0:1]
+; GCN-NEXT:    v_cndmask_b32_e64 v1, v1, v5, s[4:5]
+; GCN-NEXT:    v_cndmask_b32_e32 v0, v0, v2, vcc
+; GCN-NEXT:    s_ashr_i32 s5, s18, 31
+; GCN-NEXT:    v_cndmask_b32_e64 v0, v3, v0, s[0:1]
+; GCN-NEXT:    s_add_i32 s0, s18, s5
+; GCN-NEXT:    s_xor_b32 s4, s12, s6
+; GCN-NEXT:    s_xor_b32 s12, s0, s5
+; GCN-NEXT:    v_cvt_f32_u32_e32 v4, s12
+; GCN-NEXT:    v_mul_hi_u32 v1, v1, s13
+; GCN-NEXT:    v_xor_b32_e32 v0, s7, v0
+; GCN-NEXT:    v_subrev_i32_e32 v0, vcc, s7, v0
+; GCN-NEXT:    v_rcp_iflag_f32_e32 v4, v4
+; GCN-NEXT:    v_mul_lo_u32 v2, v1, s17
+; GCN-NEXT:    s_ashr_i32 s6, s19, 31
+; GCN-NEXT:    v_mul_f32_e32 v4, s16, v4
+; GCN-NEXT:    v_sub_i32_e32 v3, vcc, s13, v2
+; GCN-NEXT:    v_cvt_u32_f32_e32 v4, v4
+; GCN-NEXT:    v_cmp_le_u32_e64 s[0:1], s17, v3
+; GCN-NEXT:    v_cmp_ge_u32_e64 s[2:3], s13, v2
+; GCN-NEXT:    v_add_i32_e32 v3, vcc, -1, v1
+; GCN-NEXT:    v_add_i32_e32 v2, vcc, 1, v1
+; GCN-NEXT:    s_and_b64 vcc, s[0:1], s[2:3]
+; GCN-NEXT:    v_cndmask_b32_e32 v1, v1, v2, vcc
+; GCN-NEXT:    v_cndmask_b32_e64 v1, v3, v1, s[2:3]
+; GCN-NEXT:    v_mul_lo_u32 v2, v4, s12
+; GCN-NEXT:    v_mul_hi_u32 v3, v4, s12
+; GCN-NEXT:    s_ashr_i32 s2, s14, 31
+; GCN-NEXT:    s_add_i32 s3, s14, s2
+; GCN-NEXT:    v_sub_i32_e32 v5, vcc, 0, v2
+; GCN-NEXT:    v_cmp_eq_u32_e64 s[0:1], 0, v3
+; GCN-NEXT:    v_cndmask_b32_e64 v2, v2, v5, s[0:1]
+; GCN-NEXT:    v_mul_hi_u32 v2, v2, v4
+; GCN-NEXT:    s_xor_b32 s3, s3, s2
+; GCN-NEXT:    v_xor_b32_e32 v1, s4, v1
+; GCN-NEXT:    v_subrev_i32_e32 v1, vcc, s4, v1
+; GCN-NEXT:    v_add_i32_e32 v3, vcc, v2, v4
+; GCN-NEXT:    v_subrev_i32_e32 v2, vcc, v2, v4
+; GCN-NEXT:    v_cndmask_b32_e64 v2, v2, v3, s[0:1]
+; GCN-NEXT:    s_add_i32 s0, s19, s6
+; GCN-NEXT:    s_xor_b32 s14, s0, s6
+; GCN-NEXT:    v_cvt_f32_u32_e32 v4, s14
+; GCN-NEXT:    v_mul_hi_u32 v2, v2, s3
+; GCN-NEXT:    s_xor_b32 s7, s2, s5
+; GCN-NEXT:    v_rcp_iflag_f32_e32 v4, v4
+; GCN-NEXT:    v_mul_lo_u32 v3, v2, s12
+; GCN-NEXT:    v_mul_f32_e32 v4, s16, v4
+; GCN-NEXT:    v_cvt_u32_f32_e32 v4, v4
+; GCN-NEXT:    v_sub_i32_e32 v5, vcc, s3, v3
+; GCN-NEXT:    v_cmp_le_u32_e64 s[0:1], s12, v5
+; GCN-NEXT:    s_ashr_i32 s12, s15, 31
+; GCN-NEXT:    v_mul_lo_u32 v6, v4, s14
+; GCN-NEXT:    v_mul_hi_u32 v7, v4, s14
+; GCN-NEXT:    s_add_i32 s13, s15, s12
+; GCN-NEXT:    s_xor_b32 s13, s13, s12
+; GCN-NEXT:    v_sub_i32_e32 v8, vcc, 0, v6
+; GCN-NEXT:    v_cmp_eq_u32_e64 s[4:5], 0, v7
+; GCN-NEXT:    v_cndmask_b32_e64 v6, v6, v8, s[4:5]
+; GCN-NEXT:    v_mul_hi_u32 v6, v6, v4
+; GCN-NEXT:    v_cmp_ge_u32_e64 s[2:3], s3, v3
+; GCN-NEXT:    v_add_i32_e32 v5, vcc, -1, v2
+; GCN-NEXT:    v_add_i32_e32 v3, vcc, 1, v2
+; GCN-NEXT:    v_add_i32_e32 v7, vcc, v6, v4
+; GCN-NEXT:    v_subrev_i32_e32 v4, vcc, v6, v4
+; GCN-NEXT:    v_cndmask_b32_e64 v4, v4, v7, s[4:5]
+; GCN-NEXT:    v_mul_hi_u32 v4, v4, s13
+; GCN-NEXT:    s_and_b64 vcc, s[0:1], s[2:3]
+; GCN-NEXT:    v_cndmask_b32_e32 v2, v2, v3, vcc
+; GCN-NEXT:    v_cndmask_b32_e64 v2, v5, v2, s[2:3]
+; GCN-NEXT:    v_mul_lo_u32 v3, v4, s14
+; GCN-NEXT:    v_xor_b32_e32 v2, s7, v2
+; GCN-NEXT:    v_subrev_i32_e32 v2, vcc, s7, v2
+; GCN-NEXT:    s_xor_b32 s4, s12, s6
+; GCN-NEXT:    v_sub_i32_e32 v5, vcc, s13, v3
+; GCN-NEXT:    v_cmp_le_u32_e64 s[0:1], s14, v5
+; GCN-NEXT:    v_cmp_ge_u32_e64 s[2:3], s13, v3
+; GCN-NEXT:    v_add_i32_e32 v5, vcc, -1, v4
+; GCN-NEXT:    v_add_i32_e32 v3, vcc, 1, v4
+; GCN-NEXT:    s_and_b64 vcc, s[0:1], s[2:3]
+; GCN-NEXT:    v_cndmask_b32_e32 v3, v4, v3, vcc
+; GCN-NEXT:    v_cndmask_b32_e64 v3, v5, v3, s[2:3]
+; GCN-NEXT:    v_xor_b32_e32 v3, s4, v3
+; GCN-NEXT:    v_subrev_i32_e32 v3, vcc, s4, v3
+; GCN-NEXT:    buffer_store_dwordx4 v[0:3], off, s[8:11], 0
+; GCN-NEXT:    s_endpgm
   %r = sdiv <4 x i32> %x, %y
   store <4 x i32> %r, <4 x i32> addrspace(1)* %out
   ret void
@@ -1249,6 +1925,140 @@ define amdgpu_kernel void @srem_v4i32(<4 x i32> addrspace(1)* %out, <4 x i32> %x
 ; CHECK-NEXT:    store <4 x i32> [[TMP204]], <4 x i32> addrspace(1)* [[OUT:%.*]]
 ; CHECK-NEXT:    ret void
 ;
+; GCN-LABEL: srem_v4i32:
+; GCN:       ; %bb.0:
+; GCN-NEXT:    s_load_dwordx8 s[12:19], s[0:1], 0xd
+; GCN-NEXT:    s_load_dwordx2 s[8:9], s[0:1], 0x9
+; GCN-NEXT:    s_mov_b32 s11, 0xf000
+; GCN-NEXT:    s_mov_b32 s10, -1
+; GCN-NEXT:    s_waitcnt lgkmcnt(0)
+; GCN-NEXT:    s_ashr_i32 s2, s16, 31
+; GCN-NEXT:    s_add_i32 s3, s16, s2
+; GCN-NEXT:    s_xor_b32 s5, s3, s2
+; GCN-NEXT:    v_cvt_f32_u32_e32 v0, s5
+; GCN-NEXT:    s_mov_b32 s16, 0x4f800000
+; GCN-NEXT:    s_ashr_i32 s6, s12, 31
+; GCN-NEXT:    s_ashr_i32 s2, s17, 31
+; GCN-NEXT:    v_rcp_iflag_f32_e32 v0, v0
+; GCN-NEXT:    s_add_i32 s0, s12, s6
+; GCN-NEXT:    s_add_i32 s3, s17, s2
+; GCN-NEXT:    s_xor_b32 s4, s0, s6
+; GCN-NEXT:    v_mul_f32_e32 v0, s16, v0
+; GCN-NEXT:    v_cvt_u32_f32_e32 v0, v0
+; GCN-NEXT:    s_xor_b32 s17, s3, s2
+; GCN-NEXT:    s_ashr_i32 s7, s13, 31
+; GCN-NEXT:    s_add_i32 s12, s13, s7
+; GCN-NEXT:    v_mul_lo_u32 v1, v0, s5
+; GCN-NEXT:    v_mul_hi_u32 v2, v0, s5
+; GCN-NEXT:    s_xor_b32 s12, s12, s7
+; GCN-NEXT:    v_sub_i32_e32 v3, vcc, 0, v1
+; GCN-NEXT:    v_cmp_eq_u32_e64 s[0:1], 0, v2
+; GCN-NEXT:    v_cndmask_b32_e64 v1, v1, v3, s[0:1]
+; GCN-NEXT:    v_mul_hi_u32 v1, v1, v0
+; GCN-NEXT:    v_cvt_f32_u32_e32 v2, s17
+; GCN-NEXT:    v_add_i32_e32 v3, vcc, v1, v0
+; GCN-NEXT:    v_subrev_i32_e32 v0, vcc, v1, v0
+; GCN-NEXT:    v_rcp_iflag_f32_e32 v1, v2
+; GCN-NEXT:    v_cndmask_b32_e64 v0, v0, v3, s[0:1]
+; GCN-NEXT:    v_mul_hi_u32 v0, v0, s4
+; GCN-NEXT:    v_mul_f32_e32 v1, s16, v1
+; GCN-NEXT:    v_cvt_u32_f32_e32 v1, v1
+; GCN-NEXT:    v_mul_lo_u32 v0, v0, s5
+; GCN-NEXT:    v_mul_lo_u32 v4, v1, s17
+; GCN-NEXT:    v_mul_hi_u32 v5, v1, s17
+; GCN-NEXT:    v_sub_i32_e32 v2, vcc, s4, v0
+; GCN-NEXT:    v_cmp_ge_u32_e64 s[2:3], s4, v0
+; GCN-NEXT:    v_cmp_le_u32_e64 s[0:1], s5, v2
+; GCN-NEXT:    v_add_i32_e32 v3, vcc, s5, v2
+; GCN-NEXT:    v_subrev_i32_e32 v0, vcc, s5, v2
+; GCN-NEXT:    v_sub_i32_e32 v6, vcc, 0, v4
+; GCN-NEXT:    v_cmp_eq_u32_e64 s[4:5], 0, v5
+; GCN-NEXT:    v_cndmask_b32_e64 v4, v4, v6, s[4:5]
+; GCN-NEXT:    v_mul_hi_u32 v4, v4, v1
+; GCN-NEXT:    v_add_i32_e32 v5, vcc, v4, v1
+; GCN-NEXT:    v_subrev_i32_e32 v1, vcc, v4, v1
+; GCN-NEXT:    s_and_b64 vcc, s[0:1], s[2:3]
+; GCN-NEXT:    s_ashr_i32 s0, s18, 31
+; GCN-NEXT:    s_add_i32 s1, s18, s0
+; GCN-NEXT:    s_xor_b32 s13, s1, s0
+; GCN-NEXT:    v_cndmask_b32_e32 v0, v2, v0, vcc
+; GCN-NEXT:    v_cvt_f32_u32_e32 v2, s13
+; GCN-NEXT:    v_cndmask_b32_e64 v1, v1, v5, s[4:5]
+; GCN-NEXT:    v_mul_hi_u32 v1, v1, s12
+; GCN-NEXT:    v_cndmask_b32_e64 v0, v3, v0, s[2:3]
+; GCN-NEXT:    v_rcp_iflag_f32_e32 v2, v2
+; GCN-NEXT:    v_xor_b32_e32 v0, s6, v0
+; GCN-NEXT:    v_mul_lo_u32 v1, v1, s17
+; GCN-NEXT:    v_subrev_i32_e32 v0, vcc, s6, v0
+; GCN-NEXT:    v_mul_f32_e32 v2, s16, v2
+; GCN-NEXT:    v_cvt_u32_f32_e32 v2, v2
+; GCN-NEXT:    v_sub_i32_e32 v3, vcc, s12, v1
+; GCN-NEXT:    v_cmp_ge_u32_e64 s[2:3], s12, v1
+; GCN-NEXT:    v_cmp_le_u32_e64 s[0:1], s17, v3
+; GCN-NEXT:    v_mul_lo_u32 v5, v2, s13
+; GCN-NEXT:    v_mul_hi_u32 v6, v2, s13
+; GCN-NEXT:    v_add_i32_e32 v4, vcc, s17, v3
+; GCN-NEXT:    v_subrev_i32_e32 v1, vcc, s17, v3
+; GCN-NEXT:    v_sub_i32_e32 v7, vcc, 0, v5
+; GCN-NEXT:    v_cmp_eq_u32_e64 s[4:5], 0, v6
+; GCN-NEXT:    v_cndmask_b32_e64 v5, v5, v7, s[4:5]
+; GCN-NEXT:    v_mul_hi_u32 v5, v5, v2
+; GCN-NEXT:    s_ashr_i32 s6, s14, 31
+; GCN-NEXT:    s_add_i32 s12, s14, s6
+; GCN-NEXT:    s_xor_b32 s12, s12, s6
+; GCN-NEXT:    v_add_i32_e32 v6, vcc, v5, v2
+; GCN-NEXT:    v_subrev_i32_e32 v2, vcc, v5, v2
+; GCN-NEXT:    s_and_b64 vcc, s[0:1], s[2:3]
+; GCN-NEXT:    s_ashr_i32 s0, s19, 31
+; GCN-NEXT:    s_add_i32 s1, s19, s0
+; GCN-NEXT:    s_xor_b32 s14, s1, s0
+; GCN-NEXT:    v_cndmask_b32_e32 v1, v3, v1, vcc
+; GCN-NEXT:    v_cvt_f32_u32_e32 v3, s14
+; GCN-NEXT:    v_cndmask_b32_e64 v2, v2, v6, s[4:5]
+; GCN-NEXT:    v_mul_hi_u32 v2, v2, s12
+; GCN-NEXT:    v_cndmask_b32_e64 v1, v4, v1, s[2:3]
+; GCN-NEXT:    v_rcp_iflag_f32_e32 v3, v3
+; GCN-NEXT:    v_xor_b32_e32 v1, s7, v1
+; GCN-NEXT:    v_mul_lo_u32 v2, v2, s13
+; GCN-NEXT:    v_subrev_i32_e32 v1, vcc, s7, v1
+; GCN-NEXT:    v_mul_f32_e32 v3, s16, v3
+; GCN-NEXT:    v_cvt_u32_f32_e32 v3, v3
+; GCN-NEXT:    s_ashr_i32 s7, s15, 31
+; GCN-NEXT:    v_sub_i32_e32 v4, vcc, s12, v2
+; GCN-NEXT:    v_cmp_ge_u32_e64 s[2:3], s12, v2
+; GCN-NEXT:    v_mul_lo_u32 v6, v3, s14
+; GCN-NEXT:    v_mul_hi_u32 v7, v3, s14
+; GCN-NEXT:    s_add_i32 s12, s15, s7
+; GCN-NEXT:    s_xor_b32 s12, s12, s7
+; GCN-NEXT:    v_sub_i32_e32 v8, vcc, 0, v6
+; GCN-NEXT:    v_cmp_eq_u32_e64 s[4:5], 0, v7
+; GCN-NEXT:    v_cndmask_b32_e64 v6, v6, v8, s[4:5]
+; GCN-NEXT:    v_mul_hi_u32 v6, v6, v3
+; GCN-NEXT:    v_cmp_le_u32_e64 s[0:1], s13, v4
+; GCN-NEXT:    v_add_i32_e32 v5, vcc, s13, v4
+; GCN-NEXT:    v_subrev_i32_e32 v2, vcc, s13, v4
+; GCN-NEXT:    v_add_i32_e32 v7, vcc, v6, v3
+; GCN-NEXT:    v_subrev_i32_e32 v3, vcc, v6, v3
+; GCN-NEXT:    v_cndmask_b32_e64 v3, v3, v7, s[4:5]
+; GCN-NEXT:    v_mul_hi_u32 v3, v3, s12
+; GCN-NEXT:    s_and_b64 vcc, s[0:1], s[2:3]
+; GCN-NEXT:    v_cndmask_b32_e32 v2, v4, v2, vcc
+; GCN-NEXT:    v_cndmask_b32_e64 v2, v5, v2, s[2:3]
+; GCN-NEXT:    v_mul_lo_u32 v3, v3, s14
+; GCN-NEXT:    v_xor_b32_e32 v2, s6, v2
+; GCN-NEXT:    v_subrev_i32_e32 v2, vcc, s6, v2
+; GCN-NEXT:    v_sub_i32_e32 v4, vcc, s12, v3
+; GCN-NEXT:    v_cmp_ge_u32_e64 s[2:3], s12, v3
+; GCN-NEXT:    v_cmp_le_u32_e64 s[0:1], s14, v4
+; GCN-NEXT:    v_add_i32_e32 v5, vcc, s14, v4
+; GCN-NEXT:    v_subrev_i32_e32 v3, vcc, s14, v4
+; GCN-NEXT:    s_and_b64 vcc, s[0:1], s[2:3]
+; GCN-NEXT:    v_cndmask_b32_e32 v3, v4, v3, vcc
+; GCN-NEXT:    v_cndmask_b32_e64 v3, v5, v3, s[2:3]
+; GCN-NEXT:    v_xor_b32_e32 v3, s7, v3
+; GCN-NEXT:    v_subrev_i32_e32 v3, vcc, s7, v3
+; GCN-NEXT:    buffer_store_dwordx4 v[0:3], off, s[8:11], 0
+; GCN-NEXT:    s_endpgm
   %r = srem <4 x i32> %x, %y
   store <4 x i32> %r, <4 x i32> addrspace(1)* %out
   ret void
@@ -1339,6 +2149,66 @@ define amdgpu_kernel void @udiv_v4i16(<4 x i16> addrspace(1)* %out, <4 x i16> %x
 ; CHECK-NEXT:    store <4 x i16> [[TMP80]], <4 x i16> addrspace(1)* [[OUT:%.*]]
 ; CHECK-NEXT:    ret void
 ;
+; GCN-LABEL: udiv_v4i16:
+; GCN:       ; %bb.0:
+; GCN-NEXT:    s_load_dwordx2 s[4:5], s[0:1], 0x9
+; GCN-NEXT:    s_load_dwordx4 s[0:3], s[0:1], 0xb
+; GCN-NEXT:    s_mov_b32 s8, 0xffff
+; GCN-NEXT:    s_mov_b32 s7, 0xf000
+; GCN-NEXT:    s_mov_b32 s6, -1
+; GCN-NEXT:    s_waitcnt lgkmcnt(0)
+; GCN-NEXT:    s_and_b32 s9, s2, s8
+; GCN-NEXT:    v_cvt_f32_u32_e32 v0, s9
+; GCN-NEXT:    s_lshr_b32 s9, s0, 16
+; GCN-NEXT:    s_and_b32 s0, s0, s8
+; GCN-NEXT:    s_lshr_b32 s2, s2, 16
+; GCN-NEXT:    v_cvt_f32_u32_e32 v3, s2
+; GCN-NEXT:    v_cvt_f32_u32_e32 v1, s0
+; GCN-NEXT:    v_rcp_iflag_f32_e32 v2, v0
+; GCN-NEXT:    v_cvt_f32_u32_e32 v4, s9
+; GCN-NEXT:    v_rcp_iflag_f32_e32 v5, v3
+; GCN-NEXT:    s_and_b32 s2, s3, s8
+; GCN-NEXT:    v_mul_f32_e32 v2, v1, v2
+; GCN-NEXT:    v_trunc_f32_e32 v2, v2
+; GCN-NEXT:    v_mad_f32 v1, -v2, v0, v1
+; GCN-NEXT:    v_cvt_u32_f32_e32 v2, v2
+; GCN-NEXT:    v_cmp_ge_f32_e64 vcc, |v1|, v0
+; GCN-NEXT:    v_mul_f32_e32 v1, v4, v5
+; GCN-NEXT:    v_trunc_f32_e32 v1, v1
+; GCN-NEXT:    v_addc_u32_e32 v0, vcc, 0, v2, vcc
+; GCN-NEXT:    v_mad_f32 v2, -v1, v3, v4
+; GCN-NEXT:    v_cvt_f32_u32_e32 v4, s2
+; GCN-NEXT:    s_lshr_b32 s0, s1, 16
+; GCN-NEXT:    s_and_b32 s1, s1, s8
+; GCN-NEXT:    s_lshr_b32 s10, s3, 16
+; GCN-NEXT:    v_cmp_ge_f32_e64 vcc, |v2|, v3
+; GCN-NEXT:    v_cvt_u32_f32_e32 v1, v1
+; GCN-NEXT:    v_cvt_f32_u32_e32 v3, s10
+; GCN-NEXT:    v_cvt_f32_u32_e32 v5, s1
+; GCN-NEXT:    v_rcp_iflag_f32_e32 v6, v4
+; GCN-NEXT:    v_addc_u32_e32 v2, vcc, 0, v1, vcc
+; GCN-NEXT:    v_rcp_iflag_f32_e32 v7, v3
+; GCN-NEXT:    v_lshlrev_b32_e32 v2, 16, v2
+; GCN-NEXT:    v_mul_f32_e32 v1, v5, v6
+; GCN-NEXT:    v_cvt_f32_u32_e32 v6, s0
+; GCN-NEXT:    v_trunc_f32_e32 v1, v1
+; GCN-NEXT:    v_mad_f32 v5, -v1, v4, v5
+; GCN-NEXT:    v_cmp_ge_f32_e64 vcc, |v5|, v4
+; GCN-NEXT:    v_cvt_u32_f32_e32 v1, v1
+; GCN-NEXT:    v_mul_f32_e32 v4, v6, v7
+; GCN-NEXT:    v_trunc_f32_e32 v4, v4
+; GCN-NEXT:    v_cvt_u32_f32_e32 v5, v4
+; GCN-NEXT:    v_addc_u32_e32 v1, vcc, 0, v1, vcc
+; GCN-NEXT:    v_mad_f32 v4, -v4, v3, v6
+; GCN-NEXT:    v_cmp_ge_f32_e64 vcc, |v4|, v3
+; GCN-NEXT:    v_addc_u32_e32 v3, vcc, 0, v5, vcc
+; GCN-NEXT:    v_and_b32_e32 v0, s8, v0
+; GCN-NEXT:    v_lshlrev_b32_e32 v3, 16, v3
+; GCN-NEXT:    v_and_b32_e32 v1, s8, v1
+; GCN-NEXT:    v_or_b32_e32 v1, v1, v3
+; GCN-NEXT:    v_or_b32_e32 v0, v0, v2
+; GCN-NEXT:    buffer_store_dwordx2 v[0:1], off, s[4:7], 0
+; GCN-NEXT:    s_endpgm
   %r = udiv <4 x i16> %x, %y
   store <4 x i16> %r, <4 x i16> addrspace(1)* %out
   ret void
@@ -1437,6 +2307,74 @@ define amdgpu_kernel void @urem_v4i16(<4 x i16> addrspace(1)* %out, <4 x i16> %x
 ; CHECK-NEXT:    store <4 x i16> [[TMP88]], <4 x i16> addrspace(1)* [[OUT:%.*]]
 ; CHECK-NEXT:    ret void
 ;
+; GCN-LABEL: urem_v4i16:
+; GCN:       ; %bb.0:
+; GCN-NEXT:    s_load_dwordx2 s[4:5], s[0:1], 0x9
+; GCN-NEXT:    s_load_dwordx4 s[0:3], s[0:1], 0xb
+; GCN-NEXT:    s_mov_b32 s8, 0xffff
+; GCN-NEXT:    s_mov_b32 s7, 0xf000
+; GCN-NEXT:    s_mov_b32 s6, -1
+; GCN-NEXT:    s_waitcnt lgkmcnt(0)
+; GCN-NEXT:    s_and_b32 s9, s2, s8
+; GCN-NEXT:    v_cvt_f32_u32_e32 v0, s9
+; GCN-NEXT:    s_and_b32 s10, s0, s8
+; GCN-NEXT:    s_lshr_b32 s11, s2, 16
+; GCN-NEXT:    v_cvt_f32_u32_e32 v1, s10
+; GCN-NEXT:    v_rcp_iflag_f32_e32 v2, v0
+; GCN-NEXT:    v_cvt_f32_u32_e32 v3, s11
+; GCN-NEXT:    s_lshr_b32 s9, s0, 16
+; GCN-NEXT:    v_cvt_f32_u32_e32 v4, s9
+; GCN-NEXT:    v_mul_f32_e32 v2, v1, v2
+; GCN-NEXT:    v_rcp_iflag_f32_e32 v5, v3
+; GCN-NEXT:    v_trunc_f32_e32 v2, v2
+; GCN-NEXT:    v_mad_f32 v1, -v2, v0, v1
+; GCN-NEXT:    v_cvt_u32_f32_e32 v2, v2
+; GCN-NEXT:    v_cmp_ge_f32_e64 vcc, |v1|, v0
+; GCN-NEXT:    v_mul_f32_e32 v1, v4, v5
+; GCN-NEXT:    v_trunc_f32_e32 v1, v1
+; GCN-NEXT:    v_addc_u32_e32 v0, vcc, 0, v2, vcc
+; GCN-NEXT:    v_cvt_u32_f32_e32 v2, v1
+; GCN-NEXT:    v_mad_f32 v1, -v1, v3, v4
+; GCN-NEXT:    v_cmp_ge_f32_e64 vcc, |v1|, v3
+; GCN-NEXT:    v_mul_lo_u32 v0, v0, s2
+; GCN-NEXT:    s_and_b32 s2, s3, s8
+; GCN-NEXT:    v_addc_u32_e32 v1, vcc, 0, v2, vcc
+; GCN-NEXT:    v_cvt_f32_u32_e32 v2, s2
+; GCN-NEXT:    s_and_b32 s2, s1, s8
+; GCN-NEXT:    v_mul_lo_u32 v1, v1, s11
+; GCN-NEXT:    v_cvt_f32_u32_e32 v3, s2
+; GCN-NEXT:    v_rcp_iflag_f32_e32 v4, v2
+; GCN-NEXT:    s_lshr_b32 s12, s3, 16
+; GCN-NEXT:    v_sub_i32_e32 v5, vcc, s9, v1
+; GCN-NEXT:    s_lshr_b32 s10, s1, 16
+; GCN-NEXT:    v_mul_f32_e32 v1, v3, v4
+; GCN-NEXT:    v_cvt_f32_u32_e32 v4, s12
+; GCN-NEXT:    v_cvt_f32_u32_e32 v6, s10
+; GCN-NEXT:    v_trunc_f32_e32 v1, v1
+; GCN-NEXT:    v_sub_i32_e32 v0, vcc, s0, v0
+; GCN-NEXT:    v_rcp_iflag_f32_e32 v7, v4
+; GCN-NEXT:    v_mad_f32 v3, -v1, v2, v3
+; GCN-NEXT:    v_cmp_ge_f32_e64 vcc, |v3|, v2
+; GCN-NEXT:    v_cvt_u32_f32_e32 v1, v1
+; GCN-NEXT:    v_mul_f32_e32 v2, v6, v7
+; GCN-NEXT:    v_trunc_f32_e32 v2, v2
+; GCN-NEXT:    v_cvt_u32_f32_e32 v3, v2
+; GCN-NEXT:    v_addc_u32_e32 v1, vcc, 0, v1, vcc
+; GCN-NEXT:    v_mad_f32 v2, -v2, v4, v6
+; GCN-NEXT:    v_cmp_ge_f32_e64 vcc, |v2|, v4
+; GCN-NEXT:    v_addc_u32_e32 v2, vcc, 0, v3, vcc
+; GCN-NEXT:    v_mul_lo_u32 v1, v1, s3
+; GCN-NEXT:    v_mul_lo_u32 v2, v2, s12
+; GCN-NEXT:    v_and_b32_e32 v0, s8, v0
+; GCN-NEXT:    v_sub_i32_e32 v1, vcc, s1, v1
+; GCN-NEXT:    v_sub_i32_e32 v2, vcc, s10, v2
+; GCN-NEXT:    v_lshlrev_b32_e32 v2, 16, v2
+; GCN-NEXT:    v_and_b32_e32 v1, s8, v1
+; GCN-NEXT:    v_or_b32_e32 v1, v1, v2
+; GCN-NEXT:    v_lshlrev_b32_e32 v2, 16, v5
+; GCN-NEXT:    v_or_b32_e32 v0, v0, v2
+; GCN-NEXT:    buffer_store_dwordx2 v[0:1], off, s[4:7], 0
+; GCN-NEXT:    s_endpgm
   %r = urem <4 x i16> %x, %y
   store <4 x i16> %r, <4 x i16> addrspace(1)* %out
   ret void
@@ -1543,6 +2481,86 @@ define amdgpu_kernel void @sdiv_v4i16(<4 x i16> addrspace(1)* %out, <4 x i16> %x
 ; CHECK-NEXT:    store <4 x i16> [[TMP96]], <4 x i16> addrspace(1)* [[OUT:%.*]]
 ; CHECK-NEXT:    ret void
 ;
+; GCN-LABEL: sdiv_v4i16:
+; GCN:       ; %bb.0:
+; GCN-NEXT:    s_load_dwordx2 s[4:5], s[0:1], 0x9
+; GCN-NEXT:    s_load_dwordx4 s[0:3], s[0:1], 0xb
+; GCN-NEXT:    s_mov_b32 s7, 0xf000
+; GCN-NEXT:    s_mov_b32 s6, -1
+; GCN-NEXT:    s_waitcnt lgkmcnt(0)
+; GCN-NEXT:    s_sext_i32_i16 s8, s2
+; GCN-NEXT:    v_cvt_f32_i32_e32 v0, s8
+; GCN-NEXT:    s_sext_i32_i16 s9, s0
+; GCN-NEXT:    v_cvt_f32_i32_e32 v1, s9
+; GCN-NEXT:    s_xor_b32 s8, s9, s8
+; GCN-NEXT:    v_rcp_iflag_f32_e32 v2, v0
+; GCN-NEXT:    s_ashr_i32 s2, s2, 16
+; GCN-NEXT:    s_ashr_i32 s8, s8, 30
+; GCN-NEXT:    s_or_b32 s8, s8, 1
+; GCN-NEXT:    v_mul_f32_e32 v2, v1, v2
+; GCN-NEXT:    v_trunc_f32_e32 v2, v2
+; GCN-NEXT:    v_mad_f32 v1, -v2, v0, v1
+; GCN-NEXT:    v_cmp_ge_f32_e64 vcc, |v1|, |v0|
+; GCN-NEXT:    v_cvt_i32_f32_e32 v2, v2
+; GCN-NEXT:    v_cvt_f32_i32_e32 v1, s2
+; GCN-NEXT:    v_mov_b32_e32 v3, s8
+; GCN-NEXT:    v_cndmask_b32_e32 v0, 0, v3, vcc
+; GCN-NEXT:    s_ashr_i32 s0, s0, 16
+; GCN-NEXT:    v_add_i32_e32 v0, vcc, v0, v2
+; GCN-NEXT:    v_cvt_f32_i32_e32 v2, s0
+; GCN-NEXT:    v_rcp_iflag_f32_e32 v3, v1
+; GCN-NEXT:    s_xor_b32 s0, s0, s2
+; GCN-NEXT:    s_ashr_i32 s0, s0, 30
+; GCN-NEXT:    s_or_b32 s0, s0, 1
+; GCN-NEXT:    v_mul_f32_e32 v3, v2, v3
+; GCN-NEXT:    v_trunc_f32_e32 v3, v3
+; GCN-NEXT:    v_mad_f32 v2, -v3, v1, v2
+; GCN-NEXT:    v_mov_b32_e32 v4, s0
+; GCN-NEXT:    s_sext_i32_i16 s0, s3
+; GCN-NEXT:    v_cmp_ge_f32_e64 vcc, |v2|, |v1|
+; GCN-NEXT:    v_cvt_i32_f32_e32 v3, v3
+; GCN-NEXT:    v_cvt_f32_i32_e32 v2, s0
+; GCN-NEXT:    v_cndmask_b32_e32 v1, 0, v4, vcc
+; GCN-NEXT:    s_sext_i32_i16 s2, s1
+; GCN-NEXT:    v_add_i32_e32 v3, vcc, v1, v3
+; GCN-NEXT:    v_cvt_f32_i32_e32 v1, s2
+; GCN-NEXT:    v_rcp_iflag_f32_e32 v4, v2
+; GCN-NEXT:    s_xor_b32 s0, s2, s0
+; GCN-NEXT:    s_ashr_i32 s0, s0, 30
+; GCN-NEXT:    s_or_b32 s0, s0, 1
+; GCN-NEXT:    v_mul_f32_e32 v4, v1, v4
+; GCN-NEXT:    v_trunc_f32_e32 v4, v4
+; GCN-NEXT:    v_mad_f32 v1, -v4, v2, v1
+; GCN-NEXT:    v_mov_b32_e32 v5, s0
+; GCN-NEXT:    s_ashr_i32 s0, s3, 16
+; GCN-NEXT:    v_cmp_ge_f32_e64 vcc, |v1|, |v2|
+; GCN-NEXT:    v_cvt_i32_f32_e32 v4, v4
+; GCN-NEXT:    v_cvt_f32_i32_e32 v2, s0
+; GCN-NEXT:    v_cndmask_b32_e32 v1, 0, v5, vcc
+; GCN-NEXT:    s_ashr_i32 s1, s1, 16
+; GCN-NEXT:    v_add_i32_e32 v1, vcc, v1, v4
+; GCN-NEXT:    v_cvt_f32_i32_e32 v4, s1
+; GCN-NEXT:    v_rcp_iflag_f32_e32 v5, v2
+; GCN-NEXT:    s_xor_b32 s0, s1, s0
+; GCN-NEXT:    s_ashr_i32 s0, s0, 30
+; GCN-NEXT:    s_or_b32 s0, s0, 1
+; GCN-NEXT:    v_mul_f32_e32 v5, v4, v5
+; GCN-NEXT:    v_trunc_f32_e32 v5, v5
+; GCN-NEXT:    v_mad_f32 v4, -v5, v2, v4
+; GCN-NEXT:    v_cvt_i32_f32_e32 v5, v5
+; GCN-NEXT:    v_mov_b32_e32 v6, s0
+; GCN-NEXT:    v_cmp_ge_f32_e64 vcc, |v4|, |v2|
+; GCN-NEXT:    v_cndmask_b32_e32 v2, 0, v6, vcc
+; GCN-NEXT:    v_add_i32_e32 v2, vcc, v2, v5
+; GCN-NEXT:    s_mov_b32 s0, 0xffff
+; GCN-NEXT:    v_lshlrev_b32_e32 v2, 16, v2
+; GCN-NEXT:    v_and_b32_e32 v1, s0, v1
+; GCN-NEXT:    v_or_b32_e32 v1, v1, v2
+; GCN-NEXT:    v_lshlrev_b32_e32 v2, 16, v3
+; GCN-NEXT:    v_and_b32_e32 v0, s0, v0
+; GCN-NEXT:    v_or_b32_e32 v0, v0, v2
+; GCN-NEXT:    buffer_store_dwordx2 v[0:1], off, s[4:7], 0
+; GCN-NEXT:    s_endpgm
   %r = sdiv <4 x i16> %x, %y
   store <4 x i16> %r, <4 x i16> addrspace(1)* %out
   ret void
@@ -1657,6 +2675,94 @@ define amdgpu_kernel void @srem_v4i16(<4 x i16> addrspace(1)* %out, <4 x i16> %x
 ; CHECK-NEXT:    store <4 x i16> [[TMP104]], <4 x i16> addrspace(1)* [[OUT:%.*]]
 ; CHECK-NEXT:    ret void
 ;
+; GCN-LABEL: srem_v4i16:
+; GCN:       ; %bb.0:
+; GCN-NEXT:    s_load_dwordx2 s[4:5], s[0:1], 0x9
+; GCN-NEXT:    s_load_dwordx4 s[0:3], s[0:1], 0xb
+; GCN-NEXT:    s_mov_b32 s7, 0xf000
+; GCN-NEXT:    s_mov_b32 s6, -1
+; GCN-NEXT:    s_waitcnt lgkmcnt(0)
+; GCN-NEXT:    s_sext_i32_i16 s8, s2
+; GCN-NEXT:    v_cvt_f32_i32_e32 v0, s8
+; GCN-NEXT:    s_sext_i32_i16 s9, s0
+; GCN-NEXT:    v_cvt_f32_i32_e32 v1, s9
+; GCN-NEXT:    s_xor_b32 s8, s9, s8
+; GCN-NEXT:    v_rcp_iflag_f32_e32 v2, v0
+; GCN-NEXT:    s_ashr_i32 s8, s8, 30
+; GCN-NEXT:    s_or_b32 s8, s8, 1
+; GCN-NEXT:    v_mov_b32_e32 v3, s8
+; GCN-NEXT:    v_mul_f32_e32 v2, v1, v2
+; GCN-NEXT:    v_trunc_f32_e32 v2, v2
+; GCN-NEXT:    v_mad_f32 v1, -v2, v0, v1
+; GCN-NEXT:    v_cvt_i32_f32_e32 v2, v2
+; GCN-NEXT:    v_cmp_ge_f32_e64 vcc, |v1|, |v0|
+; GCN-NEXT:    v_cndmask_b32_e32 v0, 0, v3, vcc
+; GCN-NEXT:    v_add_i32_e32 v0, vcc, v0, v2
+; GCN-NEXT:    v_mul_lo_u32 v0, v0, s2
+; GCN-NEXT:    s_ashr_i32 s2, s2, 16
+; GCN-NEXT:    v_cvt_f32_i32_e32 v1, s2
+; GCN-NEXT:    v_sub_i32_e32 v0, vcc, s0, v0
+; GCN-NEXT:    s_ashr_i32 s0, s0, 16
+; GCN-NEXT:    v_cvt_f32_i32_e32 v2, s0
+; GCN-NEXT:    v_rcp_iflag_f32_e32 v3, v1
+; GCN-NEXT:    s_xor_b32 s8, s0, s2
+; GCN-NEXT:    s_ashr_i32 s8, s8, 30
+; GCN-NEXT:    s_or_b32 s8, s8, 1
+; GCN-NEXT:    v_mul_f32_e32 v3, v2, v3
+; GCN-NEXT:    v_trunc_f32_e32 v3, v3
+; GCN-NEXT:    v_mad_f32 v2, -v3, v1, v2
+; GCN-NEXT:    v_cvt_i32_f32_e32 v3, v3
+; GCN-NEXT:    v_mov_b32_e32 v4, s8
+; GCN-NEXT:    v_cmp_ge_f32_e64 vcc, |v2|, |v1|
+; GCN-NEXT:    v_cndmask_b32_e32 v1, 0, v4, vcc
+; GCN-NEXT:    v_add_i32_e32 v1, vcc, v1, v3
+; GCN-NEXT:    v_mul_lo_u32 v1, v1, s2
+; GCN-NEXT:    s_sext_i32_i16 s2, s3
+; GCN-NEXT:    v_cvt_f32_i32_e32 v2, s2
+; GCN-NEXT:    v_sub_i32_e32 v3, vcc, s0, v1
+; GCN-NEXT:    s_sext_i32_i16 s0, s1
+; GCN-NEXT:    v_cvt_f32_i32_e32 v1, s0
+; GCN-NEXT:    v_rcp_iflag_f32_e32 v4, v2
+; GCN-NEXT:    s_xor_b32 s0, s0, s2
+; GCN-NEXT:    s_ashr_i32 s0, s0, 30
+; GCN-NEXT:    s_or_b32 s0, s0, 1
+; GCN-NEXT:    v_mul_f32_e32 v4, v1, v4
+; GCN-NEXT:    v_trunc_f32_e32 v4, v4
+; GCN-NEXT:    v_mad_f32 v1, -v4, v2, v1
+; GCN-NEXT:    v_mov_b32_e32 v5, s0
+; GCN-NEXT:    s_ashr_i32 s0, s3, 16
+; GCN-NEXT:    v_cmp_ge_f32_e64 vcc, |v1|, |v2|
+; GCN-NEXT:    v_cvt_i32_f32_e32 v4, v4
+; GCN-NEXT:    v_cvt_f32_i32_e32 v2, s0
+; GCN-NEXT:    v_cndmask_b32_e32 v1, 0, v5, vcc
+; GCN-NEXT:    s_ashr_i32 s2, s1, 16
+; GCN-NEXT:    v_add_i32_e32 v1, vcc, v1, v4
+; GCN-NEXT:    v_cvt_f32_i32_e32 v4, s2
+; GCN-NEXT:    v_rcp_iflag_f32_e32 v5, v2
+; GCN-NEXT:    v_mul_lo_u32 v1, v1, s3
+; GCN-NEXT:    s_xor_b32 s3, s2, s0
+; GCN-NEXT:    s_ashr_i32 s3, s3, 30
+; GCN-NEXT:    v_mul_f32_e32 v5, v4, v5
+; GCN-NEXT:    v_trunc_f32_e32 v5, v5
+; GCN-NEXT:    v_mad_f32 v4, -v5, v2, v4
+; GCN-NEXT:    v_cvt_i32_f32_e32 v5, v5
+; GCN-NEXT:    s_or_b32 s3, s3, 1
+; GCN-NEXT:    v_mov_b32_e32 v6, s3
+; GCN-NEXT:    v_cmp_ge_f32_e64 vcc, |v4|, |v2|
+; GCN-NEXT:    v_cndmask_b32_e32 v2, 0, v6, vcc
+; GCN-NEXT:    v_add_i32_e32 v2, vcc, v2, v5
+; GCN-NEXT:    v_mul_lo_u32 v2, v2, s0
+; GCN-NEXT:    s_mov_b32 s0, 0xffff
+; GCN-NEXT:    v_sub_i32_e32 v1, vcc, s1, v1
+; GCN-NEXT:    v_and_b32_e32 v1, s0, v1
+; GCN-NEXT:    v_sub_i32_e32 v2, vcc, s2, v2
+; GCN-NEXT:    v_lshlrev_b32_e32 v2, 16, v2
+; GCN-NEXT:    v_or_b32_e32 v1, v1, v2
+; GCN-NEXT:    v_lshlrev_b32_e32 v2, 16, v3
+; GCN-NEXT:    v_and_b32_e32 v0, s0, v0
+; GCN-NEXT:    v_or_b32_e32 v0, v0, v2
+; GCN-NEXT:    buffer_store_dwordx2 v[0:1], off, s[4:7], 0
+; GCN-NEXT:    s_endpgm
   %r = srem <4 x i16> %x, %y
   store <4 x i16> %r, <4 x i16> addrspace(1)* %out
   ret void
@@ -1684,6 +2790,27 @@ define amdgpu_kernel void @udiv_i3(i3 addrspace(1)* %out, i3 %x, i3 %y) {
 ; CHECK-NEXT:    store i3 [[TMP17]], i3 addrspace(1)* [[OUT:%.*]]
 ; CHECK-NEXT:    ret void
 ;
+; GCN-LABEL: udiv_i3:
+; GCN:       ; %bb.0:
+; GCN-NEXT:    s_load_dwordx2 s[4:5], s[0:1], 0x9
+; GCN-NEXT:    s_load_dword s0, s[0:1], 0xb
+; GCN-NEXT:    s_mov_b32 s7, 0xf000
+; GCN-NEXT:    s_mov_b32 s6, -1
+; GCN-NEXT:    s_waitcnt lgkmcnt(0)
+; GCN-NEXT:    s_bfe_u32 s1, s0, 0x30008
+; GCN-NEXT:    v_cvt_f32_ubyte0_e32 v0, s1
+; GCN-NEXT:    v_rcp_iflag_f32_e32 v1, v0
+; GCN-NEXT:    s_and_b32 s0, s0, 7
+; GCN-NEXT:    v_cvt_f32_ubyte0_e32 v2, s0
+; GCN-NEXT:    v_mul_f32_e32 v1, v2, v1
+; GCN-NEXT:    v_trunc_f32_e32 v1, v1
+; GCN-NEXT:    v_cvt_u32_f32_e32 v3, v1
+; GCN-NEXT:    v_mad_f32 v1, -v1, v0, v2
+; GCN-NEXT:    v_cmp_ge_f32_e64 vcc, |v1|, v0
+; GCN-NEXT:    v_addc_u32_e32 v0, vcc, 0, v3, vcc
+; GCN-NEXT:    v_and_b32_e32 v0, 7, v0
+; GCN-NEXT:    buffer_store_byte v0, off, s[4:7], 0
+; GCN-NEXT:    s_endpgm
   %r = udiv i3 %x, %y
   store i3 %r, i3 addrspace(1)* %out
   ret void
@@ -1713,6 +2840,30 @@ define amdgpu_kernel void @urem_i3(i3 addrspace(1)* %out, i3 %x, i3 %y) {
 ; CHECK-NEXT:    store i3 [[TMP19]], i3 addrspace(1)* [[OUT:%.*]]
 ; CHECK-NEXT:    ret void
 ;
+; GCN-LABEL: urem_i3:
+; GCN:       ; %bb.0:
+; GCN-NEXT:    s_load_dwordx2 s[4:5], s[0:1], 0x9
+; GCN-NEXT:    s_load_dword s0, s[0:1], 0xb
+; GCN-NEXT:    s_mov_b32 s7, 0xf000
+; GCN-NEXT:    s_mov_b32 s6, -1
+; GCN-NEXT:    s_waitcnt lgkmcnt(0)
+; GCN-NEXT:    s_bfe_u32 s1, s0, 0x30008
+; GCN-NEXT:    v_cvt_f32_ubyte0_e32 v0, s1
+; GCN-NEXT:    v_rcp_iflag_f32_e32 v1, v0
+; GCN-NEXT:    s_and_b32 s2, s0, 7
+; GCN-NEXT:    v_cvt_f32_ubyte0_e32 v2, s2
+; GCN-NEXT:    s_lshr_b32 s1, s0, 8
+; GCN-NEXT:    v_mul_f32_e32 v1, v2, v1
+; GCN-NEXT:    v_trunc_f32_e32 v1, v1
+; GCN-NEXT:    v_cvt_u32_f32_e32 v3, v1
+; GCN-NEXT:    v_mad_f32 v1, -v1, v0, v2
+; GCN-NEXT:    v_cmp_ge_f32_e64 vcc, |v1|, v0
+; GCN-NEXT:    v_addc_u32_e32 v0, vcc, 0, v3, vcc
+; GCN-NEXT:    v_mul_lo_u32 v0, v0, s1
+; GCN-NEXT:    v_sub_i32_e32 v0, vcc, s0, v0
+; GCN-NEXT:    v_and_b32_e32 v0, 7, v0
+; GCN-NEXT:    buffer_store_byte v0, off, s[4:7], 0
+; GCN-NEXT:    s_endpgm
   %r = urem i3 %x, %y
   store i3 %r, i3 addrspace(1)* %out
   ret void
@@ -1744,6 +2895,32 @@ define amdgpu_kernel void @sdiv_i3(i3 addrspace(1)* %out, i3 %x, i3 %y) {
 ; CHECK-NEXT:    store i3 [[TMP21]], i3 addrspace(1)* [[OUT:%.*]]
 ; CHECK-NEXT:    ret void
 ;
+; GCN-LABEL: sdiv_i3:
+; GCN:       ; %bb.0:
+; GCN-NEXT:    s_load_dwordx2 s[4:5], s[0:1], 0x9
+; GCN-NEXT:    s_load_dword s0, s[0:1], 0xb
+; GCN-NEXT:    s_mov_b32 s7, 0xf000
+; GCN-NEXT:    s_mov_b32 s6, -1
+; GCN-NEXT:    s_waitcnt lgkmcnt(0)
+; GCN-NEXT:    s_bfe_i32 s1, s0, 0x30008
+; GCN-NEXT:    v_cvt_f32_i32_e32 v0, s1
+; GCN-NEXT:    s_bfe_i32 s0, s0, 0x30000
+; GCN-NEXT:    v_cvt_f32_i32_e32 v1, s0
+; GCN-NEXT:    s_xor_b32 s0, s0, s1
+; GCN-NEXT:    v_rcp_iflag_f32_e32 v2, v0
+; GCN-NEXT:    s_ashr_i32 s0, s0, 30
+; GCN-NEXT:    s_or_b32 s0, s0, 1
+; GCN-NEXT:    v_mov_b32_e32 v3, s0
+; GCN-NEXT:    v_mul_f32_e32 v2, v1, v2
+; GCN-NEXT:    v_trunc_f32_e32 v2, v2
+; GCN-NEXT:    v_mad_f32 v1, -v2, v0, v1
+; GCN-NEXT:    v_cvt_i32_f32_e32 v2, v2
+; GCN-NEXT:    v_cmp_ge_f32_e64 vcc, |v1|, |v0|
+; GCN-NEXT:    v_cndmask_b32_e32 v0, 0, v3, vcc
+; GCN-NEXT:    v_add_i32_e32 v0, vcc, v0, v2
+; GCN-NEXT:    v_and_b32_e32 v0, 7, v0
+; GCN-NEXT:    buffer_store_byte v0, off, s[4:7], 0
+; GCN-NEXT:    s_endpgm
   %r = sdiv i3 %x, %y
   store i3 %r, i3 addrspace(1)* %out
   ret void
@@ -1777,6 +2954,35 @@ define amdgpu_kernel void @srem_i3(i3 addrspace(1)* %out, i3 %x, i3 %y) {
 ; CHECK-NEXT:    store i3 [[TMP23]], i3 addrspace(1)* [[OUT:%.*]]
 ; CHECK-NEXT:    ret void
 ;
+; GCN-LABEL: srem_i3:
+; GCN:       ; %bb.0:
+; GCN-NEXT:    s_load_dwordx2 s[4:5], s[0:1], 0x9
+; GCN-NEXT:    s_load_dword s0, s[0:1], 0xb
+; GCN-NEXT:    s_mov_b32 s7, 0xf000
+; GCN-NEXT:    s_mov_b32 s6, -1
+; GCN-NEXT:    s_waitcnt lgkmcnt(0)
+; GCN-NEXT:    s_bfe_i32 s1, s0, 0x30008
+; GCN-NEXT:    v_cvt_f32_i32_e32 v0, s1
+; GCN-NEXT:    s_bfe_i32 s3, s0, 0x30000
+; GCN-NEXT:    v_cvt_f32_i32_e32 v1, s3
+; GCN-NEXT:    s_xor_b32 s1, s3, s1
+; GCN-NEXT:    v_rcp_iflag_f32_e32 v2, v0
+; GCN-NEXT:    s_ashr_i32 s1, s1, 30
+; GCN-NEXT:    s_or_b32 s1, s1, 1
+; GCN-NEXT:    v_mov_b32_e32 v3, s1
+; GCN-NEXT:    v_mul_f32_e32 v2, v1, v2
+; GCN-NEXT:    v_trunc_f32_e32 v2, v2
+; GCN-NEXT:    v_mad_f32 v1, -v2, v0, v1
+; GCN-NEXT:    v_cvt_i32_f32_e32 v2, v2
+; GCN-NEXT:    v_cmp_ge_f32_e64 vcc, |v1|, |v0|
+; GCN-NEXT:    v_cndmask_b32_e32 v0, 0, v3, vcc
+; GCN-NEXT:    s_lshr_b32 s2, s0, 8
+; GCN-NEXT:    v_add_i32_e32 v0, vcc, v0, v2
+; GCN-NEXT:    v_mul_lo_u32 v0, v0, s2
+; GCN-NEXT:    v_sub_i32_e32 v0, vcc, s0, v0
+; GCN-NEXT:    v_and_b32_e32 v0, 7, v0
+; GCN-NEXT:    buffer_store_byte v0, off, s[4:7], 0
+; GCN-NEXT:    s_endpgm
   %r = srem i3 %x, %y
   store i3 %r, i3 addrspace(1)* %out
   ret void
@@ -1847,6 +3053,54 @@ define amdgpu_kernel void @udiv_v3i16(<3 x i16> addrspace(1)* %out, <3 x i16> %x
 ; CHECK-NEXT:    store <3 x i16> [[TMP60]], <3 x i16> addrspace(1)* [[OUT:%.*]]
 ; CHECK-NEXT:    ret void
 ;
+; GCN-LABEL: udiv_v3i16:
+; GCN:       ; %bb.0:
+; GCN-NEXT:    s_load_dwordx2 s[4:5], s[0:1], 0x9
+; GCN-NEXT:    s_load_dwordx2 s[2:3], s[0:1], 0xb
+; GCN-NEXT:    s_load_dwordx2 s[0:1], s[0:1], 0xd
+; GCN-NEXT:    s_mov_b32 s8, 0xffff
+; GCN-NEXT:    s_mov_b32 s7, 0xf000
+; GCN-NEXT:    s_waitcnt lgkmcnt(0)
+; GCN-NEXT:    s_and_b32 s6, s0, s8
+; GCN-NEXT:    v_cvt_f32_u32_e32 v0, s6
+; GCN-NEXT:    s_and_b32 s6, s2, s8
+; GCN-NEXT:    s_lshr_b32 s0, s0, 16
+; GCN-NEXT:    v_cvt_f32_u32_e32 v3, s0
+; GCN-NEXT:    v_cvt_f32_u32_e32 v1, s6
+; GCN-NEXT:    v_rcp_iflag_f32_e32 v2, v0
+; GCN-NEXT:    s_lshr_b32 s0, s2, 16
+; GCN-NEXT:    v_cvt_f32_u32_e32 v4, s0
+; GCN-NEXT:    v_rcp_iflag_f32_e32 v5, v3
+; GCN-NEXT:    v_mul_f32_e32 v2, v1, v2
+; GCN-NEXT:    v_trunc_f32_e32 v2, v2
+; GCN-NEXT:    v_mad_f32 v1, -v2, v0, v1
+; GCN-NEXT:    v_cvt_u32_f32_e32 v2, v2
+; GCN-NEXT:    v_cmp_ge_f32_e64 vcc, |v1|, v0
+; GCN-NEXT:    v_mul_f32_e32 v1, v4, v5
+; GCN-NEXT:    v_trunc_f32_e32 v1, v1
+; GCN-NEXT:    s_and_b32 s0, s1, s8
+; GCN-NEXT:    v_addc_u32_e32 v0, vcc, 0, v2, vcc
+; GCN-NEXT:    v_mad_f32 v2, -v1, v3, v4
+; GCN-NEXT:    v_cvt_f32_u32_e32 v4, s0
+; GCN-NEXT:    s_and_b32 s0, s3, s8
+; GCN-NEXT:    v_cvt_f32_u32_e32 v5, s0
+; GCN-NEXT:    v_cvt_u32_f32_e32 v1, v1
+; GCN-NEXT:    v_rcp_iflag_f32_e32 v6, v4
+; GCN-NEXT:    v_cmp_ge_f32_e64 vcc, |v2|, v3
+; GCN-NEXT:    s_mov_b32 s6, -1
+; GCN-NEXT:    v_addc_u32_e32 v1, vcc, 0, v1, vcc
+; GCN-NEXT:    v_mul_f32_e32 v2, v5, v6
+; GCN-NEXT:    v_trunc_f32_e32 v2, v2
+; GCN-NEXT:    v_cvt_u32_f32_e32 v3, v2
+; GCN-NEXT:    v_mad_f32 v2, -v2, v4, v5
+; GCN-NEXT:    v_cmp_ge_f32_e64 vcc, |v2|, v4
+; GCN-NEXT:    v_lshlrev_b32_e32 v1, 16, v1
+; GCN-NEXT:    v_and_b32_e32 v0, s8, v0
+; GCN-NEXT:    v_addc_u32_e32 v2, vcc, 0, v3, vcc
+; GCN-NEXT:    v_or_b32_e32 v0, v0, v1
+; GCN-NEXT:    buffer_store_short v2, off, s[4:7], 0 offset:4
+; GCN-NEXT:    buffer_store_dword v0, off, s[4:7], 0
+; GCN-NEXT:    s_endpgm
   %r = udiv <3 x i16> %x, %y
   store <3 x i16> %r, <3 x i16> addrspace(1)* %out
   ret void
@@ -1923,6 +3177,64 @@ define amdgpu_kernel void @urem_v3i16(<3 x i16> addrspace(1)* %out, <3 x i16> %x
 ; CHECK-NEXT:    store <3 x i16> [[TMP66]], <3 x i16> addrspace(1)* [[OUT:%.*]]
 ; CHECK-NEXT:    ret void
 ;
+; GCN-LABEL: urem_v3i16:
+; GCN:       ; %bb.0:
+; GCN-NEXT:    s_load_dwordx2 s[4:5], s[0:1], 0x9
+; GCN-NEXT:    s_load_dwordx2 s[2:3], s[0:1], 0xb
+; GCN-NEXT:    s_load_dwordx2 s[0:1], s[0:1], 0xd
+; GCN-NEXT:    s_mov_b32 s8, 0xffff
+; GCN-NEXT:    s_mov_b32 s7, 0xf000
+; GCN-NEXT:    s_waitcnt lgkmcnt(0)
+; GCN-NEXT:    v_mov_b32_e32 v1, s2
+; GCN-NEXT:    s_and_b32 s6, s0, s8
+; GCN-NEXT:    v_cvt_f32_u32_e32 v0, s6
+; GCN-NEXT:    s_and_b32 s6, s2, s8
+; GCN-NEXT:    v_cvt_f32_u32_e32 v2, s6
+; GCN-NEXT:    v_mov_b32_e32 v4, s0
+; GCN-NEXT:    v_rcp_iflag_f32_e32 v3, v0
+; GCN-NEXT:    v_alignbit_b32 v4, s1, v4, 16
+; GCN-NEXT:    v_and_b32_e32 v5, s8, v4
+; GCN-NEXT:    v_alignbit_b32 v1, s3, v1, 16
+; GCN-NEXT:    v_mul_f32_e32 v3, v2, v3
+; GCN-NEXT:    v_trunc_f32_e32 v3, v3
+; GCN-NEXT:    v_mad_f32 v2, -v3, v0, v2
+; GCN-NEXT:    v_cvt_u32_f32_e32 v6, v3
+; GCN-NEXT:    v_cmp_ge_f32_e64 vcc, |v2|, v0
+; GCN-NEXT:    v_cvt_f32_u32_e32 v2, v5
+; GCN-NEXT:    v_and_b32_e32 v3, s8, v1
+; GCN-NEXT:    v_addc_u32_e32 v0, vcc, 0, v6, vcc
+; GCN-NEXT:    v_mul_lo_u32 v0, v0, s0
+; GCN-NEXT:    s_and_b32 s0, s1, s8
+; GCN-NEXT:    v_cvt_f32_u32_e32 v3, v3
+; GCN-NEXT:    v_rcp_iflag_f32_e32 v5, v2
+; GCN-NEXT:    v_cvt_f32_u32_e32 v6, s0
+; GCN-NEXT:    s_and_b32 s0, s3, s8
+; GCN-NEXT:    v_cvt_f32_u32_e32 v7, s0
+; GCN-NEXT:    v_mul_f32_e32 v5, v3, v5
+; GCN-NEXT:    v_trunc_f32_e32 v5, v5
+; GCN-NEXT:    v_rcp_iflag_f32_e32 v8, v6
+; GCN-NEXT:    v_mad_f32 v3, -v5, v2, v3
+; GCN-NEXT:    v_cvt_u32_f32_e32 v5, v5
+; GCN-NEXT:    v_sub_i32_e32 v0, vcc, s2, v0
+; GCN-NEXT:    v_cmp_ge_f32_e64 vcc, |v3|, v2
+; GCN-NEXT:    v_mul_f32_e32 v3, v7, v8
+; GCN-NEXT:    v_addc_u32_e32 v2, vcc, 0, v5, vcc
+; GCN-NEXT:    v_trunc_f32_e32 v3, v3
+; GCN-NEXT:    v_mul_lo_u32 v2, v2, v4
+; GCN-NEXT:    v_cvt_u32_f32_e32 v4, v3
+; GCN-NEXT:    v_mad_f32 v3, -v3, v6, v7
+; GCN-NEXT:    v_cmp_ge_f32_e64 vcc, |v3|, v6
+; GCN-NEXT:    s_mov_b32 s6, -1
+; GCN-NEXT:    v_addc_u32_e32 v3, vcc, 0, v4, vcc
+; GCN-NEXT:    v_mul_lo_u32 v3, v3, s1
+; GCN-NEXT:    v_sub_i32_e32 v1, vcc, v1, v2
+; GCN-NEXT:    v_lshlrev_b32_e32 v1, 16, v1
+; GCN-NEXT:    v_and_b32_e32 v0, s8, v0
+; GCN-NEXT:    v_sub_i32_e32 v2, vcc, s3, v3
+; GCN-NEXT:    v_or_b32_e32 v0, v0, v1
+; GCN-NEXT:    buffer_store_short v2, off, s[4:7], 0 offset:4
+; GCN-NEXT:    buffer_store_dword v0, off, s[4:7], 0
+; GCN-NEXT:    s_endpgm
   %r = urem <3 x i16> %x, %y
   store <3 x i16> %r, <3 x i16> addrspace(1)* %out
   ret void
@@ -2005,6 +3317,68 @@ define amdgpu_kernel void @sdiv_v3i16(<3 x i16> addrspace(1)* %out, <3 x i16> %x
 ; CHECK-NEXT:    store <3 x i16> [[TMP72]], <3 x i16> addrspace(1)* [[OUT:%.*]]
 ; CHECK-NEXT:    ret void
 ;
+; GCN-LABEL: sdiv_v3i16:
+; GCN:       ; %bb.0:
+; GCN-NEXT:    s_load_dwordx2 s[4:5], s[0:1], 0x9
+; GCN-NEXT:    s_load_dwordx2 s[2:3], s[0:1], 0xb
+; GCN-NEXT:    s_load_dwordx2 s[0:1], s[0:1], 0xd
+; GCN-NEXT:    s_mov_b32 s7, 0xf000
+; GCN-NEXT:    s_mov_b32 s6, -1
+; GCN-NEXT:    s_waitcnt lgkmcnt(0)
+; GCN-NEXT:    s_sext_i32_i16 s9, s2
+; GCN-NEXT:    s_sext_i32_i16 s8, s0
+; GCN-NEXT:    v_cvt_f32_i32_e32 v0, s8
+; GCN-NEXT:    v_cvt_f32_i32_e32 v1, s9
+; GCN-NEXT:    s_xor_b32 s8, s9, s8
+; GCN-NEXT:    s_ashr_i32 s0, s0, 16
+; GCN-NEXT:    v_rcp_iflag_f32_e32 v2, v0
+; GCN-NEXT:    s_ashr_i32 s8, s8, 30
+; GCN-NEXT:    s_or_b32 s8, s8, 1
+; GCN-NEXT:    v_mov_b32_e32 v3, s8
+; GCN-NEXT:    v_mul_f32_e32 v2, v1, v2
+; GCN-NEXT:    v_trunc_f32_e32 v2, v2
+; GCN-NEXT:    v_mad_f32 v1, -v2, v0, v1
+; GCN-NEXT:    v_cmp_ge_f32_e64 vcc, |v1|, |v0|
+; GCN-NEXT:    v_cvt_i32_f32_e32 v2, v2
+; GCN-NEXT:    v_cvt_f32_i32_e32 v1, s0
+; GCN-NEXT:    v_cndmask_b32_e32 v0, 0, v3, vcc
+; GCN-NEXT:    s_ashr_i32 s2, s2, 16
+; GCN-NEXT:    v_add_i32_e32 v0, vcc, v0, v2
+; GCN-NEXT:    v_cvt_f32_i32_e32 v2, s2
+; GCN-NEXT:    v_rcp_iflag_f32_e32 v3, v1
+; GCN-NEXT:    s_xor_b32 s0, s2, s0
+; GCN-NEXT:    s_ashr_i32 s0, s0, 30
+; GCN-NEXT:    s_or_b32 s0, s0, 1
+; GCN-NEXT:    v_mul_f32_e32 v3, v2, v3
+; GCN-NEXT:    v_trunc_f32_e32 v3, v3
+; GCN-NEXT:    v_mad_f32 v2, -v3, v1, v2
+; GCN-NEXT:    v_mov_b32_e32 v4, s0
+; GCN-NEXT:    s_sext_i32_i16 s0, s1
+; GCN-NEXT:    v_cmp_ge_f32_e64 vcc, |v2|, |v1|
+; GCN-NEXT:    v_cvt_i32_f32_e32 v3, v3
+; GCN-NEXT:    v_cvt_f32_i32_e32 v2, s0
+; GCN-NEXT:    v_cndmask_b32_e32 v1, 0, v4, vcc
+; GCN-NEXT:    s_sext_i32_i16 s1, s3
+; GCN-NEXT:    v_add_i32_e32 v1, vcc, v1, v3
+; GCN-NEXT:    v_cvt_f32_i32_e32 v3, s1
+; GCN-NEXT:    v_rcp_iflag_f32_e32 v4, v2
+; GCN-NEXT:    s_xor_b32 s0, s1, s0
+; GCN-NEXT:    s_ashr_i32 s0, s0, 30
+; GCN-NEXT:    s_or_b32 s0, s0, 1
+; GCN-NEXT:    v_mul_f32_e32 v4, v3, v4
+; GCN-NEXT:    v_trunc_f32_e32 v4, v4
+; GCN-NEXT:    v_mad_f32 v3, -v4, v2, v3
+; GCN-NEXT:    v_cvt_i32_f32_e32 v4, v4
+; GCN-NEXT:    v_mov_b32_e32 v5, s0
+; GCN-NEXT:    v_cmp_ge_f32_e64 vcc, |v3|, |v2|
+; GCN-NEXT:    v_cndmask_b32_e32 v2, 0, v5, vcc
+; GCN-NEXT:    v_add_i32_e32 v2, vcc, v2, v4
+; GCN-NEXT:    v_lshlrev_b32_e32 v1, 16, v1
+; GCN-NEXT:    v_and_b32_e32 v0, 0xffff, v0
+; GCN-NEXT:    v_or_b32_e32 v0, v0, v1
+; GCN-NEXT:    buffer_store_short v2, off, s[4:7], 0 offset:4
+; GCN-NEXT:    buffer_store_dword v0, off, s[4:7], 0
+; GCN-NEXT:    s_endpgm
   %r = sdiv <3 x i16> %x, %y
   store <3 x i16> %r, <3 x i16> addrspace(1)* %out
   ret void
@@ -2093,6 +3467,77 @@ define amdgpu_kernel void @srem_v3i16(<3 x i16> addrspace(1)* %out, <3 x i16> %x
 ; CHECK-NEXT:    store <3 x i16> [[TMP78]], <3 x i16> addrspace(1)* [[OUT:%.*]]
 ; CHECK-NEXT:    ret void
 ;
+; GCN-LABEL: srem_v3i16:
+; GCN:       ; %bb.0:
+; GCN-NEXT:    s_load_dwordx2 s[4:5], s[0:1], 0x9
+; GCN-NEXT:    s_load_dwordx2 s[2:3], s[0:1], 0xb
+; GCN-NEXT:    s_load_dwordx2 s[0:1], s[0:1], 0xd
+; GCN-NEXT:    s_mov_b32 s7, 0xf000
+; GCN-NEXT:    s_waitcnt lgkmcnt(0)
+; GCN-NEXT:    s_sext_i32_i16 s8, s2
+; GCN-NEXT:    s_sext_i32_i16 s6, s0
+; GCN-NEXT:    v_cvt_f32_i32_e32 v0, s6
+; GCN-NEXT:    v_cvt_f32_i32_e32 v1, s8
+; GCN-NEXT:    s_xor_b32 s6, s8, s6
+; GCN-NEXT:    s_ashr_i32 s6, s6, 30
+; GCN-NEXT:    v_rcp_iflag_f32_e32 v2, v0
+; GCN-NEXT:    s_or_b32 s6, s6, 1
+; GCN-NEXT:    v_mov_b32_e32 v3, s6
+; GCN-NEXT:    s_mov_b32 s6, -1
+; GCN-NEXT:    v_mul_f32_e32 v2, v1, v2
+; GCN-NEXT:    v_trunc_f32_e32 v2, v2
+; GCN-NEXT:    v_mad_f32 v1, -v2, v0, v1
+; GCN-NEXT:    v_cvt_i32_f32_e32 v2, v2
+; GCN-NEXT:    v_cmp_ge_f32_e64 vcc, |v1|, |v0|
+; GCN-NEXT:    v_cndmask_b32_e32 v0, 0, v3, vcc
+; GCN-NEXT:    v_mov_b32_e32 v1, s2
+; GCN-NEXT:    v_add_i32_e32 v0, vcc, v0, v2
+; GCN-NEXT:    v_mov_b32_e32 v2, s0
+; GCN-NEXT:    v_alignbit_b32 v2, s1, v2, 16
+; GCN-NEXT:    v_bfe_i32 v3, v2, 0, 16
+; GCN-NEXT:    v_cvt_f32_i32_e32 v4, v3
+; GCN-NEXT:    v_alignbit_b32 v1, s3, v1, 16
+; GCN-NEXT:    v_bfe_i32 v5, v1, 0, 16
+; GCN-NEXT:    v_cvt_f32_i32_e32 v6, v5
+; GCN-NEXT:    v_rcp_iflag_f32_e32 v7, v4
+; GCN-NEXT:    v_mul_lo_u32 v0, v0, s0
+; GCN-NEXT:    v_xor_b32_e32 v3, v5, v3
+; GCN-NEXT:    s_sext_i32_i16 s0, s1
+; GCN-NEXT:    v_mul_f32_e32 v5, v6, v7
+; GCN-NEXT:    v_trunc_f32_e32 v5, v5
+; GCN-NEXT:    v_sub_i32_e32 v0, vcc, s2, v0
+; GCN-NEXT:    v_mad_f32 v6, -v5, v4, v6
+; GCN-NEXT:    v_cvt_i32_f32_e32 v5, v5
+; GCN-NEXT:    v_ashrrev_i32_e32 v3, 30, v3
+; GCN-NEXT:    v_cmp_ge_f32_e64 vcc, |v6|, |v4|
+; GCN-NEXT:    v_cvt_f32_i32_e32 v4, s0
+; GCN-NEXT:    v_or_b32_e32 v3, 1, v3
+; GCN-NEXT:    v_cndmask_b32_e32 v3, 0, v3, vcc
+; GCN-NEXT:    v_add_i32_e32 v3, vcc, v3, v5
+; GCN-NEXT:    s_sext_i32_i16 s2, s3
+; GCN-NEXT:    v_mul_lo_u32 v2, v3, v2
+; GCN-NEXT:    v_cvt_f32_i32_e32 v3, s2
+; GCN-NEXT:    v_rcp_iflag_f32_e32 v5, v4
+; GCN-NEXT:    s_xor_b32 s0, s2, s0
+; GCN-NEXT:    s_ashr_i32 s0, s0, 30
+; GCN-NEXT:    s_or_b32 s0, s0, 1
+; GCN-NEXT:    v_mul_f32_e32 v5, v3, v5
+; GCN-NEXT:    v_trunc_f32_e32 v5, v5
+; GCN-NEXT:    v_mad_f32 v3, -v5, v4, v3
+; GCN-NEXT:    v_cvt_i32_f32_e32 v5, v5
+; GCN-NEXT:    v_mov_b32_e32 v6, s0
+; GCN-NEXT:    v_cmp_ge_f32_e64 vcc, |v3|, |v4|
+; GCN-NEXT:    v_cndmask_b32_e32 v3, 0, v6, vcc
+; GCN-NEXT:    v_add_i32_e32 v3, vcc, v3, v5
+; GCN-NEXT:    v_mul_lo_u32 v3, v3, s1
+; GCN-NEXT:    v_sub_i32_e32 v1, vcc, v1, v2
+; GCN-NEXT:    v_lshlrev_b32_e32 v1, 16, v1
+; GCN-NEXT:    v_and_b32_e32 v0, 0xffff, v0
+; GCN-NEXT:    v_sub_i32_e32 v2, vcc, s3, v3
+; GCN-NEXT:    v_or_b32_e32 v0, v0, v1
+; GCN-NEXT:    buffer_store_short v2, off, s[4:7], 0 offset:4
+; GCN-NEXT:    buffer_store_dword v0, off, s[4:7], 0
+; GCN-NEXT:    s_endpgm
   %r = srem <3 x i16> %x, %y
   store <3 x i16> %r, <3 x i16> addrspace(1)* %out
   ret void
@@ -2163,6 +3608,62 @@ define amdgpu_kernel void @udiv_v3i15(<3 x i15> addrspace(1)* %out, <3 x i15> %x
 ; CHECK-NEXT:    store <3 x i15> [[TMP60]], <3 x i15> addrspace(1)* [[OUT:%.*]]
 ; CHECK-NEXT:    ret void
 ;
+; GCN-LABEL: udiv_v3i15:
+; GCN:       ; %bb.0:
+; GCN-NEXT:    s_load_dwordx2 s[4:5], s[0:1], 0x9
+; GCN-NEXT:    s_load_dwordx2 s[2:3], s[0:1], 0xb
+; GCN-NEXT:    s_load_dwordx2 s[0:1], s[0:1], 0xd
+; GCN-NEXT:    s_mov_b32 s7, 0xf000
+; GCN-NEXT:    s_mov_b32 s6, -1
+; GCN-NEXT:    s_waitcnt lgkmcnt(0)
+; GCN-NEXT:    v_mov_b32_e32 v0, s2
+; GCN-NEXT:    v_alignbit_b32 v0, s3, v0, 30
+; GCN-NEXT:    s_movk_i32 s3, 0x7fff
+; GCN-NEXT:    s_and_b32 s9, s0, s3
+; GCN-NEXT:    v_cvt_f32_u32_e32 v1, s9
+; GCN-NEXT:    v_mov_b32_e32 v2, s0
+; GCN-NEXT:    s_and_b32 s8, s2, s3
+; GCN-NEXT:    s_bfe_u32 s0, s0, 0xf000f
+; GCN-NEXT:    v_cvt_f32_u32_e32 v5, s0
+; GCN-NEXT:    v_cvt_f32_u32_e32 v3, s8
+; GCN-NEXT:    v_rcp_iflag_f32_e32 v4, v1
+; GCN-NEXT:    s_bfe_u32 s2, s2, 0xf000f
+; GCN-NEXT:    v_alignbit_b32 v2, s1, v2, 30
+; GCN-NEXT:    v_cvt_f32_u32_e32 v6, s2
+; GCN-NEXT:    v_mul_f32_e32 v4, v3, v4
+; GCN-NEXT:    v_rcp_iflag_f32_e32 v7, v5
+; GCN-NEXT:    v_and_b32_e32 v2, s3, v2
+; GCN-NEXT:    v_trunc_f32_e32 v4, v4
+; GCN-NEXT:    v_mad_f32 v3, -v4, v1, v3
+; GCN-NEXT:    v_cvt_u32_f32_e32 v4, v4
+; GCN-NEXT:    v_cvt_f32_u32_e32 v2, v2
+; GCN-NEXT:    v_cmp_ge_f32_e64 vcc, |v3|, v1
+; GCN-NEXT:    v_mul_f32_e32 v1, v6, v7
+; GCN-NEXT:    v_and_b32_e32 v0, s3, v0
+; GCN-NEXT:    v_trunc_f32_e32 v1, v1
+; GCN-NEXT:    v_addc_u32_e32 v3, vcc, 0, v4, vcc
+; GCN-NEXT:    v_mad_f32 v4, -v1, v5, v6
+; GCN-NEXT:    v_cvt_u32_f32_e32 v1, v1
+; GCN-NEXT:    v_cvt_f32_u32_e32 v0, v0
+; GCN-NEXT:    v_rcp_iflag_f32_e32 v6, v2
+; GCN-NEXT:    v_cmp_ge_f32_e64 vcc, |v4|, v5
+; GCN-NEXT:    v_addc_u32_e32 v4, vcc, 0, v1, vcc
+; GCN-NEXT:    v_mul_f32_e32 v1, v0, v6
+; GCN-NEXT:    v_trunc_f32_e32 v1, v1
+; GCN-NEXT:    v_cvt_u32_f32_e32 v5, v1
+; GCN-NEXT:    v_mad_f32 v0, -v1, v2, v0
+; GCN-NEXT:    v_cmp_ge_f32_e64 vcc, |v0|, v2
+; GCN-NEXT:    v_and_b32_e32 v2, s3, v3
+; GCN-NEXT:    v_addc_u32_e32 v0, vcc, 0, v5, vcc
+; GCN-NEXT:    v_and_b32_e32 v3, s3, v4
+; GCN-NEXT:    v_lshl_b64 v[0:1], v[0:1], 30
+; GCN-NEXT:    v_lshlrev_b32_e32 v3, 15, v3
+; GCN-NEXT:    v_or_b32_e32 v2, v2, v3
+; GCN-NEXT:    v_or_b32_e32 v0, v2, v0
+; GCN-NEXT:    v_and_b32_e32 v1, 0x1fff, v1
+; GCN-NEXT:    buffer_store_dword v0, off, s[4:7], 0
+; GCN-NEXT:    buffer_store_short v1, off, s[4:7], 0 offset:4
+; GCN-NEXT:    s_endpgm
   %r = udiv <3 x i15> %x, %y
   store <3 x i15> %r, <3 x i15> addrspace(1)* %out
   ret void
@@ -2239,6 +3740,70 @@ define amdgpu_kernel void @urem_v3i15(<3 x i15> addrspace(1)* %out, <3 x i15> %x
 ; CHECK-NEXT:    store <3 x i15> [[TMP66]], <3 x i15> addrspace(1)* [[OUT:%.*]]
 ; CHECK-NEXT:    ret void
 ;
+; GCN-LABEL: urem_v3i15:
+; GCN:       ; %bb.0:
+; GCN-NEXT:    s_load_dwordx2 s[4:5], s[0:1], 0x9
+; GCN-NEXT:    s_load_dwordx2 s[2:3], s[0:1], 0xb
+; GCN-NEXT:    s_load_dwordx2 s[0:1], s[0:1], 0xd
+; GCN-NEXT:    s_mov_b32 s7, 0xf000
+; GCN-NEXT:    s_mov_b32 s6, -1
+; GCN-NEXT:    s_waitcnt lgkmcnt(0)
+; GCN-NEXT:    v_mov_b32_e32 v0, s2
+; GCN-NEXT:    v_alignbit_b32 v0, s3, v0, 30
+; GCN-NEXT:    s_movk_i32 s3, 0x7fff
+; GCN-NEXT:    s_and_b32 s10, s0, s3
+; GCN-NEXT:    v_cvt_f32_u32_e32 v1, s10
+; GCN-NEXT:    s_and_b32 s9, s2, s3
+; GCN-NEXT:    v_cvt_f32_u32_e32 v3, s9
+; GCN-NEXT:    v_mov_b32_e32 v2, s0
+; GCN-NEXT:    v_rcp_iflag_f32_e32 v4, v1
+; GCN-NEXT:    v_alignbit_b32 v2, s1, v2, 30
+; GCN-NEXT:    s_bfe_u32 s1, s0, 0xf000f
+; GCN-NEXT:    v_cvt_f32_u32_e32 v5, s1
+; GCN-NEXT:    v_mul_f32_e32 v4, v3, v4
+; GCN-NEXT:    v_trunc_f32_e32 v4, v4
+; GCN-NEXT:    v_mad_f32 v3, -v4, v1, v3
+; GCN-NEXT:    v_cvt_u32_f32_e32 v4, v4
+; GCN-NEXT:    v_cmp_ge_f32_e64 vcc, |v3|, v1
+; GCN-NEXT:    s_bfe_u32 s10, s2, 0xf000f
+; GCN-NEXT:    v_cvt_f32_u32_e32 v3, s10
+; GCN-NEXT:    v_addc_u32_e32 v1, vcc, 0, v4, vcc
+; GCN-NEXT:    v_mul_lo_u32 v1, v1, s0
+; GCN-NEXT:    v_rcp_iflag_f32_e32 v4, v5
+; GCN-NEXT:    v_and_b32_e32 v2, s3, v2
+; GCN-NEXT:    v_and_b32_e32 v0, s3, v0
+; GCN-NEXT:    v_sub_i32_e32 v6, vcc, s2, v1
+; GCN-NEXT:    v_mul_f32_e32 v1, v3, v4
+; GCN-NEXT:    v_cvt_f32_u32_e32 v4, v2
+; GCN-NEXT:    v_cvt_f32_u32_e32 v7, v0
+; GCN-NEXT:    v_trunc_f32_e32 v1, v1
+; GCN-NEXT:    v_mad_f32 v3, -v1, v5, v3
+; GCN-NEXT:    v_rcp_iflag_f32_e32 v8, v4
+; GCN-NEXT:    v_cmp_ge_f32_e64 vcc, |v3|, v5
+; GCN-NEXT:    v_cvt_u32_f32_e32 v1, v1
+; GCN-NEXT:    s_lshr_b32 s0, s0, 15
+; GCN-NEXT:    v_mul_f32_e32 v3, v7, v8
+; GCN-NEXT:    v_trunc_f32_e32 v3, v3
+; GCN-NEXT:    v_cvt_u32_f32_e32 v5, v3
+; GCN-NEXT:    v_addc_u32_e32 v1, vcc, 0, v1, vcc
+; GCN-NEXT:    v_mad_f32 v3, -v3, v4, v7
+; GCN-NEXT:    v_cmp_ge_f32_e64 vcc, |v3|, v4
+; GCN-NEXT:    v_addc_u32_e32 v3, vcc, 0, v5, vcc
+; GCN-NEXT:    v_mul_lo_u32 v1, v1, s0
+; GCN-NEXT:    v_mul_lo_u32 v2, v3, v2
+; GCN-NEXT:    s_lshr_b32 s8, s2, 15
+; GCN-NEXT:    v_sub_i32_e32 v3, vcc, s8, v1
+; GCN-NEXT:    v_subrev_i32_e32 v0, vcc, v2, v0
+; GCN-NEXT:    v_and_b32_e32 v3, s3, v3
+; GCN-NEXT:    v_lshl_b64 v[0:1], v[0:1], 30
+; GCN-NEXT:    v_and_b32_e32 v2, s3, v6
+; GCN-NEXT:    v_lshlrev_b32_e32 v3, 15, v3
+; GCN-NEXT:    v_or_b32_e32 v2, v2, v3
+; GCN-NEXT:    v_or_b32_e32 v0, v2, v0
+; GCN-NEXT:    v_and_b32_e32 v1, 0x1fff, v1
+; GCN-NEXT:    buffer_store_dword v0, off, s[4:7], 0
+; GCN-NEXT:    buffer_store_short v1, off, s[4:7], 0 offset:4
+; GCN-NEXT:    s_endpgm
   %r = urem <3 x i15> %x, %y
   store <3 x i15> %r, <3 x i15> addrspace(1)* %out
   ret void
@@ -2321,6 +3886,76 @@ define amdgpu_kernel void @sdiv_v3i15(<3 x i15> addrspace(1)* %out, <3 x i15> %x
 ; CHECK-NEXT:    store <3 x i15> [[TMP72]], <3 x i15> addrspace(1)* [[OUT:%.*]]
 ; CHECK-NEXT:    ret void
 ;
+; GCN-LABEL: sdiv_v3i15:
+; GCN:       ; %bb.0:
+; GCN-NEXT:    s_load_dwordx2 s[4:5], s[0:1], 0x9
+; GCN-NEXT:    s_load_dwordx2 s[2:3], s[0:1], 0xb
+; GCN-NEXT:    s_load_dwordx2 s[0:1], s[0:1], 0xd
+; GCN-NEXT:    s_mov_b32 s7, 0xf000
+; GCN-NEXT:    s_mov_b32 s6, -1
+; GCN-NEXT:    s_waitcnt lgkmcnt(0)
+; GCN-NEXT:    v_mov_b32_e32 v0, s2
+; GCN-NEXT:    v_alignbit_b32 v0, s3, v0, 30
+; GCN-NEXT:    s_bfe_i32 s3, s0, 0xf0000
+; GCN-NEXT:    v_cvt_f32_i32_e32 v2, s3
+; GCN-NEXT:    v_mov_b32_e32 v1, s0
+; GCN-NEXT:    v_alignbit_b32 v1, s1, v1, 30
+; GCN-NEXT:    s_bfe_i32 s1, s2, 0xf0000
+; GCN-NEXT:    v_cvt_f32_i32_e32 v3, s1
+; GCN-NEXT:    v_rcp_iflag_f32_e32 v4, v2
+; GCN-NEXT:    s_xor_b32 s1, s1, s3
+; GCN-NEXT:    s_bfe_i32 s0, s0, 0xf000f
+; GCN-NEXT:    s_ashr_i32 s1, s1, 30
+; GCN-NEXT:    v_mul_f32_e32 v4, v3, v4
+; GCN-NEXT:    v_trunc_f32_e32 v4, v4
+; GCN-NEXT:    v_mad_f32 v3, -v4, v2, v3
+; GCN-NEXT:    v_cmp_ge_f32_e64 vcc, |v3|, |v2|
+; GCN-NEXT:    v_cvt_i32_f32_e32 v4, v4
+; GCN-NEXT:    v_cvt_f32_i32_e32 v3, s0
+; GCN-NEXT:    s_or_b32 s1, s1, 1
+; GCN-NEXT:    v_mov_b32_e32 v5, s1
+; GCN-NEXT:    v_cndmask_b32_e32 v2, 0, v5, vcc
+; GCN-NEXT:    s_bfe_i32 s1, s2, 0xf000f
+; GCN-NEXT:    v_add_i32_e32 v2, vcc, v2, v4
+; GCN-NEXT:    v_cvt_f32_i32_e32 v4, s1
+; GCN-NEXT:    v_rcp_iflag_f32_e32 v5, v3
+; GCN-NEXT:    s_xor_b32 s0, s1, s0
+; GCN-NEXT:    v_bfe_i32 v1, v1, 0, 15
+; GCN-NEXT:    s_ashr_i32 s0, s0, 30
+; GCN-NEXT:    v_mul_f32_e32 v5, v4, v5
+; GCN-NEXT:    v_trunc_f32_e32 v5, v5
+; GCN-NEXT:    v_mad_f32 v4, -v5, v3, v4
+; GCN-NEXT:    v_cmp_ge_f32_e64 vcc, |v4|, |v3|
+; GCN-NEXT:    v_cvt_i32_f32_e32 v5, v5
+; GCN-NEXT:    v_cvt_f32_i32_e32 v4, v1
+; GCN-NEXT:    s_or_b32 s0, s0, 1
+; GCN-NEXT:    v_mov_b32_e32 v6, s0
+; GCN-NEXT:    v_cndmask_b32_e32 v3, 0, v6, vcc
+; GCN-NEXT:    v_bfe_i32 v0, v0, 0, 15
+; GCN-NEXT:    v_add_i32_e32 v3, vcc, v3, v5
+; GCN-NEXT:    v_cvt_f32_i32_e32 v5, v0
+; GCN-NEXT:    v_rcp_iflag_f32_e32 v6, v4
+; GCN-NEXT:    v_xor_b32_e32 v0, v0, v1
+; GCN-NEXT:    v_ashrrev_i32_e32 v0, 30, v0
+; GCN-NEXT:    v_or_b32_e32 v0, 1, v0
+; GCN-NEXT:    v_mul_f32_e32 v1, v5, v6
+; GCN-NEXT:    v_trunc_f32_e32 v1, v1
+; GCN-NEXT:    v_mad_f32 v5, -v1, v4, v5
+; GCN-NEXT:    v_cvt_i32_f32_e32 v1, v1
+; GCN-NEXT:    v_cmp_ge_f32_e64 vcc, |v5|, |v4|
+; GCN-NEXT:    v_cndmask_b32_e32 v0, 0, v0, vcc
+; GCN-NEXT:    s_movk_i32 s0, 0x7fff
+; GCN-NEXT:    v_add_i32_e32 v0, vcc, v0, v1
+; GCN-NEXT:    v_and_b32_e32 v3, s0, v3
+; GCN-NEXT:    v_lshl_b64 v[0:1], v[0:1], 30
+; GCN-NEXT:    v_and_b32_e32 v2, s0, v2
+; GCN-NEXT:    v_lshlrev_b32_e32 v3, 15, v3
+; GCN-NEXT:    v_or_b32_e32 v2, v2, v3
+; GCN-NEXT:    v_or_b32_e32 v0, v2, v0
+; GCN-NEXT:    v_and_b32_e32 v1, 0x1fff, v1
+; GCN-NEXT:    buffer_store_dword v0, off, s[4:7], 0
+; GCN-NEXT:    buffer_store_short v1, off, s[4:7], 0 offset:4
+; GCN-NEXT:    s_endpgm
   %r = sdiv <3 x i15> %x, %y
   store <3 x i15> %r, <3 x i15> addrspace(1)* %out
   ret void
@@ -2409,7 +4044,3581 @@ define amdgpu_kernel void @srem_v3i15(<3 x i15> addrspace(1)* %out, <3 x i15> %x
 ; CHECK-NEXT:    store <3 x i15> [[TMP78]], <3 x i15> addrspace(1)* [[OUT:%.*]]
 ; CHECK-NEXT:    ret void
 ;
+; GCN-LABEL: srem_v3i15:
+; GCN:       ; %bb.0:
+; GCN-NEXT:    s_load_dwordx2 s[4:5], s[0:1], 0x9
+; GCN-NEXT:    s_load_dwordx2 s[2:3], s[0:1], 0xb
+; GCN-NEXT:    s_load_dwordx2 s[0:1], s[0:1], 0xd
+; GCN-NEXT:    s_mov_b32 s7, 0xf000
+; GCN-NEXT:    s_mov_b32 s6, -1
+; GCN-NEXT:    s_waitcnt lgkmcnt(0)
+; GCN-NEXT:    v_mov_b32_e32 v0, s2
+; GCN-NEXT:    v_alignbit_b32 v0, s3, v0, 30
+; GCN-NEXT:    s_movk_i32 s3, 0x7fff
+; GCN-NEXT:    s_and_b32 s11, s0, s3
+; GCN-NEXT:    s_bfe_i32 s11, s11, 0xf0000
+; GCN-NEXT:    v_cvt_f32_i32_e32 v2, s11
+; GCN-NEXT:    s_and_b32 s9, s2, s3
+; GCN-NEXT:    s_bfe_i32 s9, s9, 0xf0000
+; GCN-NEXT:    v_cvt_f32_i32_e32 v3, s9
+; GCN-NEXT:    v_rcp_iflag_f32_e32 v4, v2
+; GCN-NEXT:    s_xor_b32 s9, s9, s11
+; GCN-NEXT:    s_ashr_i32 s9, s9, 30
+; GCN-NEXT:    s_or_b32 s9, s9, 1
+; GCN-NEXT:    v_mul_f32_e32 v4, v3, v4
+; GCN-NEXT:    v_trunc_f32_e32 v4, v4
+; GCN-NEXT:    v_mad_f32 v3, -v4, v2, v3
+; GCN-NEXT:    v_cvt_i32_f32_e32 v4, v4
+; GCN-NEXT:    v_mov_b32_e32 v5, s9
+; GCN-NEXT:    v_cmp_ge_f32_e64 vcc, |v3|, |v2|
+; GCN-NEXT:    v_cndmask_b32_e32 v2, 0, v5, vcc
+; GCN-NEXT:    v_mov_b32_e32 v1, s0
+; GCN-NEXT:    v_add_i32_e32 v2, vcc, v2, v4
+; GCN-NEXT:    s_bfe_u32 s12, s0, 0xf000f
+; GCN-NEXT:    v_alignbit_b32 v1, s1, v1, 30
+; GCN-NEXT:    v_mul_lo_u32 v2, v2, s0
+; GCN-NEXT:    s_lshr_b32 s1, s0, 15
+; GCN-NEXT:    s_bfe_i32 s0, s12, 0xf0000
+; GCN-NEXT:    v_cvt_f32_i32_e32 v3, s0
+; GCN-NEXT:    s_bfe_u32 s10, s2, 0xf000f
+; GCN-NEXT:    v_sub_i32_e32 v2, vcc, s2, v2
+; GCN-NEXT:    s_lshr_b32 s8, s2, 15
+; GCN-NEXT:    s_bfe_i32 s2, s10, 0xf0000
+; GCN-NEXT:    v_cvt_f32_i32_e32 v4, s2
+; GCN-NEXT:    v_rcp_iflag_f32_e32 v5, v3
+; GCN-NEXT:    s_xor_b32 s0, s2, s0
+; GCN-NEXT:    s_ashr_i32 s0, s0, 30
+; GCN-NEXT:    s_or_b32 s0, s0, 1
+; GCN-NEXT:    v_mul_f32_e32 v5, v4, v5
+; GCN-NEXT:    v_trunc_f32_e32 v5, v5
+; GCN-NEXT:    v_mad_f32 v4, -v5, v3, v4
+; GCN-NEXT:    v_cvt_i32_f32_e32 v5, v5
+; GCN-NEXT:    v_and_b32_e32 v1, s3, v1
+; GCN-NEXT:    v_cmp_ge_f32_e64 vcc, |v4|, |v3|
+; GCN-NEXT:    v_mov_b32_e32 v6, s0
+; GCN-NEXT:    v_cndmask_b32_e32 v3, 0, v6, vcc
+; GCN-NEXT:    v_bfe_i32 v4, v1, 0, 15
+; GCN-NEXT:    v_add_i32_e32 v3, vcc, v3, v5
+; GCN-NEXT:    v_cvt_f32_i32_e32 v5, v4
+; GCN-NEXT:    v_and_b32_e32 v0, s3, v0
+; GCN-NEXT:    v_bfe_i32 v6, v0, 0, 15
+; GCN-NEXT:    v_cvt_f32_i32_e32 v7, v6
+; GCN-NEXT:    v_rcp_iflag_f32_e32 v8, v5
+; GCN-NEXT:    v_xor_b32_e32 v4, v6, v4
+; GCN-NEXT:    v_ashrrev_i32_e32 v4, 30, v4
+; GCN-NEXT:    v_or_b32_e32 v4, 1, v4
+; GCN-NEXT:    v_mul_f32_e32 v6, v7, v8
+; GCN-NEXT:    v_trunc_f32_e32 v6, v6
+; GCN-NEXT:    v_mad_f32 v7, -v6, v5, v7
+; GCN-NEXT:    v_cvt_i32_f32_e32 v6, v6
+; GCN-NEXT:    v_cmp_ge_f32_e64 vcc, |v7|, |v5|
+; GCN-NEXT:    v_cndmask_b32_e32 v4, 0, v4, vcc
+; GCN-NEXT:    v_mul_lo_u32 v3, v3, s1
+; GCN-NEXT:    v_add_i32_e32 v4, vcc, v4, v6
+; GCN-NEXT:    v_mul_lo_u32 v1, v4, v1
+; GCN-NEXT:    v_and_b32_e32 v2, s3, v2
+; GCN-NEXT:    v_sub_i32_e32 v3, vcc, s8, v3
+; GCN-NEXT:    v_and_b32_e32 v3, s3, v3
+; GCN-NEXT:    v_subrev_i32_e32 v0, vcc, v1, v0
+; GCN-NEXT:    v_lshl_b64 v[0:1], v[0:1], 30
+; GCN-NEXT:    v_lshlrev_b32_e32 v3, 15, v3
+; GCN-NEXT:    v_or_b32_e32 v2, v2, v3
+; GCN-NEXT:    v_or_b32_e32 v0, v2, v0
+; GCN-NEXT:    v_and_b32_e32 v1, 0x1fff, v1
+; GCN-NEXT:    buffer_store_dword v0, off, s[4:7], 0
+; GCN-NEXT:    buffer_store_short v1, off, s[4:7], 0 offset:4
+; GCN-NEXT:    s_endpgm
   %r = srem <3 x i15> %x, %y
   store <3 x i15> %r, <3 x i15> addrspace(1)* %out
   ret void
 }
+
+define amdgpu_kernel void @udiv_i32_oddk_denom(i32 addrspace(1)* %out, i32 %x) {
+; CHECK-LABEL: @udiv_i32_oddk_denom(
+; CHECK-NEXT:    [[R:%.*]] = udiv i32 [[X:%.*]], 1235195
+; CHECK-NEXT:    store i32 [[R]], i32 addrspace(1)* [[OUT:%.*]]
+; CHECK-NEXT:    ret void
+;
+; GCN-LABEL: udiv_i32_oddk_denom:
+; GCN:       ; %bb.0:
+; GCN-NEXT:    s_load_dwordx2 s[4:5], s[0:1], 0x9
+; GCN-NEXT:    s_load_dword s0, s[0:1], 0xb
+; GCN-NEXT:    v_mov_b32_e32 v0, 0xb2a50881
+; GCN-NEXT:    s_mov_b32 s7, 0xf000
+; GCN-NEXT:    s_mov_b32 s6, -1
+; GCN-NEXT:    s_waitcnt lgkmcnt(0)
+; GCN-NEXT:    v_mul_hi_u32 v0, s0, v0
+; GCN-NEXT:    v_sub_i32_e32 v1, vcc, s0, v0
+; GCN-NEXT:    v_lshrrev_b32_e32 v1, 1, v1
+; GCN-NEXT:    v_add_i32_e32 v0, vcc, v0, v1
+; GCN-NEXT:    v_lshrrev_b32_e32 v0, 20, v0
+; GCN-NEXT:    buffer_store_dword v0, off, s[4:7], 0
+; GCN-NEXT:    s_endpgm
+  %r = udiv i32 %x, 1235195
+  store i32 %r, i32 addrspace(1)* %out
+  ret void
+}
+
+define amdgpu_kernel void @udiv_i32_pow2k_denom(i32 addrspace(1)* %out, i32 %x) {
+; CHECK-LABEL: @udiv_i32_pow2k_denom(
+; CHECK-NEXT:    [[R:%.*]] = udiv i32 [[X:%.*]], 4096
+; CHECK-NEXT:    store i32 [[R]], i32 addrspace(1)* [[OUT:%.*]]
+; CHECK-NEXT:    ret void
+;
+; GCN-LABEL: udiv_i32_pow2k_denom:
+; GCN:       ; %bb.0:
+; GCN-NEXT:    s_load_dwordx2 s[4:5], s[0:1], 0x9
+; GCN-NEXT:    s_load_dword s0, s[0:1], 0xb
+; GCN-NEXT:    s_mov_b32 s7, 0xf000
+; GCN-NEXT:    s_mov_b32 s6, -1
+; GCN-NEXT:    s_waitcnt lgkmcnt(0)
+; GCN-NEXT:    s_lshr_b32 s0, s0, 12
+; GCN-NEXT:    v_mov_b32_e32 v0, s0
+; GCN-NEXT:    buffer_store_dword v0, off, s[4:7], 0
+; GCN-NEXT:    s_endpgm
+  %r = udiv i32 %x, 4096
+  store i32 %r, i32 addrspace(1)* %out
+  ret void
+}
+
+define amdgpu_kernel void @udiv_i32_pow2_shl_denom(i32 addrspace(1)* %out, i32 %x, i32 %y) {
+; CHECK-LABEL: @udiv_i32_pow2_shl_denom(
+; CHECK-NEXT:    [[SHL_Y:%.*]] = shl i32 4096, [[Y:%.*]]
+; CHECK-NEXT:    [[TMP1:%.*]] = uitofp i32 [[SHL_Y]] to float
+; CHECK-NEXT:    [[TMP2:%.*]] = call fast float @llvm.amdgcn.rcp.f32(float [[TMP1]])
+; CHECK-NEXT:    [[TMP3:%.*]] = fmul fast float [[TMP2]], 0x41F0000000000000
+; CHECK-NEXT:    [[TMP4:%.*]] = fptoui float [[TMP3]] to i32
+; CHECK-NEXT:    [[TMP5:%.*]] = zext i32 [[TMP4]] to i64
+; CHECK-NEXT:    [[TMP6:%.*]] = zext i32 [[SHL_Y]] to i64
+; CHECK-NEXT:    [[TMP7:%.*]] = mul i64 [[TMP5]], [[TMP6]]
+; CHECK-NEXT:    [[TMP8:%.*]] = trunc i64 [[TMP7]] to i32
+; CHECK-NEXT:    [[TMP9:%.*]] = lshr i64 [[TMP7]], 32
+; CHECK-NEXT:    [[TMP10:%.*]] = trunc i64 [[TMP9]] to i32
+; CHECK-NEXT:    [[TMP11:%.*]] = sub i32 0, [[TMP8]]
+; CHECK-NEXT:    [[TMP12:%.*]] = icmp eq i32 [[TMP10]], 0
+; CHECK-NEXT:    [[TMP13:%.*]] = select i1 [[TMP12]], i32 [[TMP11]], i32 [[TMP8]]
+; CHECK-NEXT:    [[TMP14:%.*]] = zext i32 [[TMP13]] to i64
+; CHECK-NEXT:    [[TMP15:%.*]] = zext i32 [[TMP4]] to i64
+; CHECK-NEXT:    [[TMP16:%.*]] = mul i64 [[TMP14]], [[TMP15]]
+; CHECK-NEXT:    [[TMP17:%.*]] = trunc i64 [[TMP16]] to i32
+; CHECK-NEXT:    [[TMP18:%.*]] = lshr i64 [[TMP16]], 32
+; CHECK-NEXT:    [[TMP19:%.*]] = trunc i64 [[TMP18]] to i32
+; CHECK-NEXT:    [[TMP20:%.*]] = add i32 [[TMP4]], [[TMP19]]
+; CHECK-NEXT:    [[TMP21:%.*]] = sub i32 [[TMP4]], [[TMP19]]
+; CHECK-NEXT:    [[TMP22:%.*]] = select i1 [[TMP12]], i32 [[TMP20]], i32 [[TMP21]]
+; CHECK-NEXT:    [[TMP23:%.*]] = zext i32 [[TMP22]] to i64
+; CHECK-NEXT:    [[TMP24:%.*]] = zext i32 [[X:%.*]] to i64
+; CHECK-NEXT:    [[TMP25:%.*]] = mul i64 [[TMP23]], [[TMP24]]
+; CHECK-NEXT:    [[TMP26:%.*]] = trunc i64 [[TMP25]] to i32
+; CHECK-NEXT:    [[TMP27:%.*]] = lshr i64 [[TMP25]], 32
+; CHECK-NEXT:    [[TMP28:%.*]] = trunc i64 [[TMP27]] to i32
+; CHECK-NEXT:    [[TMP29:%.*]] = mul i32 [[TMP28]], [[SHL_Y]]
+; CHECK-NEXT:    [[TMP30:%.*]] = sub i32 [[X]], [[TMP29]]
+; CHECK-NEXT:    [[TMP31:%.*]] = icmp uge i32 [[TMP30]], [[SHL_Y]]
+; CHECK-NEXT:    [[TMP32:%.*]] = select i1 [[TMP31]], i32 -1, i32 0
+; CHECK-NEXT:    [[TMP33:%.*]] = icmp uge i32 [[X]], [[TMP29]]
+; CHECK-NEXT:    [[TMP34:%.*]] = select i1 [[TMP33]], i32 -1, i32 0
+; CHECK-NEXT:    [[TMP35:%.*]] = and i32 [[TMP32]], [[TMP34]]
+; CHECK-NEXT:    [[TMP36:%.*]] = icmp eq i32 [[TMP35]], 0
+; CHECK-NEXT:    [[TMP37:%.*]] = add i32 [[TMP28]], 1
+; CHECK-NEXT:    [[TMP38:%.*]] = sub i32 [[TMP28]], 1
+; CHECK-NEXT:    [[TMP39:%.*]] = select i1 [[TMP36]], i32 [[TMP28]], i32 [[TMP37]]
+; CHECK-NEXT:    [[TMP40:%.*]] = select i1 [[TMP33]], i32 [[TMP39]], i32 [[TMP38]]
+; CHECK-NEXT:    store i32 [[TMP40]], i32 addrspace(1)* [[OUT:%.*]]
+; CHECK-NEXT:    ret void
+;
+; GCN-LABEL: udiv_i32_pow2_shl_denom:
+; GCN:       ; %bb.0:
+; GCN-NEXT:    s_load_dwordx2 s[8:9], s[0:1], 0xb
+; GCN-NEXT:    s_load_dwordx2 s[4:5], s[0:1], 0x9
+; GCN-NEXT:    s_mov_b32 s7, 0xf000
+; GCN-NEXT:    s_mov_b32 s6, -1
+; GCN-NEXT:    s_waitcnt lgkmcnt(0)
+; GCN-NEXT:    s_lshl_b32 s9, 0x1000, s9
+; GCN-NEXT:    v_cvt_f32_u32_e32 v0, s9
+; GCN-NEXT:    v_rcp_iflag_f32_e32 v0, v0
+; GCN-NEXT:    v_mul_f32_e32 v0, 0x4f800000, v0
+; GCN-NEXT:    v_cvt_u32_f32_e32 v0, v0
+; GCN-NEXT:    v_mul_lo_u32 v1, v0, s9
+; GCN-NEXT:    v_mul_hi_u32 v2, v0, s9
+; GCN-NEXT:    v_sub_i32_e32 v3, vcc, 0, v1
+; GCN-NEXT:    v_cmp_eq_u32_e64 s[2:3], 0, v2
+; GCN-NEXT:    v_cndmask_b32_e64 v1, v1, v3, s[2:3]
+; GCN-NEXT:    v_mul_hi_u32 v1, v1, v0
+; GCN-NEXT:    v_add_i32_e32 v2, vcc, v1, v0
+; GCN-NEXT:    v_subrev_i32_e32 v0, vcc, v1, v0
+; GCN-NEXT:    v_cndmask_b32_e64 v0, v0, v2, s[2:3]
+; GCN-NEXT:    v_mul_hi_u32 v0, v0, s8
+; GCN-NEXT:    v_mul_lo_u32 v1, v0, s9
+; GCN-NEXT:    v_add_i32_e32 v2, vcc, 1, v0
+; GCN-NEXT:    v_add_i32_e32 v3, vcc, -1, v0
+; GCN-NEXT:    v_sub_i32_e32 v4, vcc, s8, v1
+; GCN-NEXT:    v_cmp_ge_u32_e32 vcc, s8, v1
+; GCN-NEXT:    v_cmp_le_u32_e64 s[0:1], s9, v4
+; GCN-NEXT:    s_and_b64 s[0:1], s[0:1], vcc
+; GCN-NEXT:    v_cndmask_b32_e64 v0, v0, v2, s[0:1]
+; GCN-NEXT:    v_cndmask_b32_e32 v0, v3, v0, vcc
+; GCN-NEXT:    buffer_store_dword v0, off, s[4:7], 0
+; GCN-NEXT:    s_endpgm
+  %shl.y = shl i32 4096, %y
+  %r = udiv i32 %x, %shl.y
+  store i32 %r, i32 addrspace(1)* %out
+  ret void
+}
+
+define amdgpu_kernel void @udiv_v2i32_pow2k_denom(<2 x i32> addrspace(1)* %out, <2 x i32> %x) {
+; CHECK-LABEL: @udiv_v2i32_pow2k_denom(
+; CHECK-NEXT:    [[TMP1:%.*]] = extractelement <2 x i32> [[X:%.*]], i64 0
+; CHECK-NEXT:    [[TMP2:%.*]] = udiv i32 [[TMP1]], 4096
+; CHECK-NEXT:    [[TMP3:%.*]] = insertelement <2 x i32> undef, i32 [[TMP2]], i64 0
+; CHECK-NEXT:    [[TMP4:%.*]] = extractelement <2 x i32> [[X]], i64 1
+; CHECK-NEXT:    [[TMP5:%.*]] = udiv i32 [[TMP4]], 4096
+; CHECK-NEXT:    [[TMP6:%.*]] = insertelement <2 x i32> [[TMP3]], i32 [[TMP5]], i64 1
+; CHECK-NEXT:    store <2 x i32> [[TMP6]], <2 x i32> addrspace(1)* [[OUT:%.*]]
+; CHECK-NEXT:    ret void
+;
+; GCN-LABEL: udiv_v2i32_pow2k_denom:
+; GCN:       ; %bb.0:
+; GCN-NEXT:    s_load_dwordx2 s[4:5], s[0:1], 0x9
+; GCN-NEXT:    s_load_dwordx2 s[0:1], s[0:1], 0xb
+; GCN-NEXT:    s_mov_b32 s7, 0xf000
+; GCN-NEXT:    s_mov_b32 s6, -1
+; GCN-NEXT:    s_waitcnt lgkmcnt(0)
+; GCN-NEXT:    s_lshr_b32 s0, s0, 12
+; GCN-NEXT:    s_lshr_b32 s1, s1, 12
+; GCN-NEXT:    v_mov_b32_e32 v0, s0
+; GCN-NEXT:    v_mov_b32_e32 v1, s1
+; GCN-NEXT:    buffer_store_dwordx2 v[0:1], off, s[4:7], 0
+; GCN-NEXT:    s_endpgm
+  %r = udiv <2 x i32> %x, <i32 4096, i32 4096>
+  store <2 x i32> %r, <2 x i32> addrspace(1)* %out
+  ret void
+}
+
+define amdgpu_kernel void @udiv_v2i32_mixed_pow2k_denom(<2 x i32> addrspace(1)* %out, <2 x i32> %x) {
+; CHECK-LABEL: @udiv_v2i32_mixed_pow2k_denom(
+; CHECK-NEXT:    [[TMP1:%.*]] = extractelement <2 x i32> [[X:%.*]], i64 0
+; CHECK-NEXT:    [[TMP2:%.*]] = udiv i32 [[TMP1]], 4096
+; CHECK-NEXT:    [[TMP3:%.*]] = insertelement <2 x i32> undef, i32 [[TMP2]], i64 0
+; CHECK-NEXT:    [[TMP4:%.*]] = extractelement <2 x i32> [[X]], i64 1
+; CHECK-NEXT:    [[TMP5:%.*]] = udiv i32 [[TMP4]], 4095
+; CHECK-NEXT:    [[TMP6:%.*]] = insertelement <2 x i32> [[TMP3]], i32 [[TMP5]], i64 1
+; CHECK-NEXT:    store <2 x i32> [[TMP6]], <2 x i32> addrspace(1)* [[OUT:%.*]]
+; CHECK-NEXT:    ret void
+;
+; GCN-LABEL: udiv_v2i32_mixed_pow2k_denom:
+; GCN:       ; %bb.0:
+; GCN-NEXT:    s_load_dwordx2 s[4:5], s[0:1], 0x9
+; GCN-NEXT:    s_load_dwordx2 s[0:1], s[0:1], 0xb
+; GCN-NEXT:    v_mov_b32_e32 v0, 0x100101
+; GCN-NEXT:    s_mov_b32 s7, 0xf000
+; GCN-NEXT:    s_mov_b32 s6, -1
+; GCN-NEXT:    s_waitcnt lgkmcnt(0)
+; GCN-NEXT:    v_mul_hi_u32 v0, s1, v0
+; GCN-NEXT:    s_lshr_b32 s0, s0, 12
+; GCN-NEXT:    v_sub_i32_e32 v1, vcc, s1, v0
+; GCN-NEXT:    v_lshrrev_b32_e32 v1, 1, v1
+; GCN-NEXT:    v_add_i32_e32 v0, vcc, v0, v1
+; GCN-NEXT:    v_lshrrev_b32_e32 v1, 11, v0
+; GCN-NEXT:    v_mov_b32_e32 v0, s0
+; GCN-NEXT:    buffer_store_dwordx2 v[0:1], off, s[4:7], 0
+; GCN-NEXT:    s_endpgm
+  %r = udiv <2 x i32> %x, <i32 4096, i32 4095>
+  store <2 x i32> %r, <2 x i32> addrspace(1)* %out
+  ret void
+}
+
+define amdgpu_kernel void @udiv_v2i32_pow2_shl_denom(<2 x i32> addrspace(1)* %out, <2 x i32> %x, <2 x i32> %y) {
+; CHECK-LABEL: @udiv_v2i32_pow2_shl_denom(
+; CHECK-NEXT:    [[SHL_Y:%.*]] = shl <2 x i32> <i32 4096, i32 4096>, [[Y:%.*]]
+; CHECK-NEXT:    [[TMP1:%.*]] = extractelement <2 x i32> [[X:%.*]], i64 0
+; CHECK-NEXT:    [[TMP2:%.*]] = extractelement <2 x i32> [[SHL_Y]], i64 0
+; CHECK-NEXT:    [[TMP3:%.*]] = uitofp i32 [[TMP2]] to float
+; CHECK-NEXT:    [[TMP4:%.*]] = call fast float @llvm.amdgcn.rcp.f32(float [[TMP3]])
+; CHECK-NEXT:    [[TMP5:%.*]] = fmul fast float [[TMP4]], 0x41F0000000000000
+; CHECK-NEXT:    [[TMP6:%.*]] = fptoui float [[TMP5]] to i32
+; CHECK-NEXT:    [[TMP7:%.*]] = zext i32 [[TMP6]] to i64
+; CHECK-NEXT:    [[TMP8:%.*]] = zext i32 [[TMP2]] to i64
+; CHECK-NEXT:    [[TMP9:%.*]] = mul i64 [[TMP7]], [[TMP8]]
+; CHECK-NEXT:    [[TMP10:%.*]] = trunc i64 [[TMP9]] to i32
+; CHECK-NEXT:    [[TMP11:%.*]] = lshr i64 [[TMP9]], 32
+; CHECK-NEXT:    [[TMP12:%.*]] = trunc i64 [[TMP11]] to i32
+; CHECK-NEXT:    [[TMP13:%.*]] = sub i32 0, [[TMP10]]
+; CHECK-NEXT:    [[TMP14:%.*]] = icmp eq i32 [[TMP12]], 0
+; CHECK-NEXT:    [[TMP15:%.*]] = select i1 [[TMP14]], i32 [[TMP13]], i32 [[TMP10]]
+; CHECK-NEXT:    [[TMP16:%.*]] = zext i32 [[TMP15]] to i64
+; CHECK-NEXT:    [[TMP17:%.*]] = zext i32 [[TMP6]] to i64
+; CHECK-NEXT:    [[TMP18:%.*]] = mul i64 [[TMP16]], [[TMP17]]
+; CHECK-NEXT:    [[TMP19:%.*]] = trunc i64 [[TMP18]] to i32
+; CHECK-NEXT:    [[TMP20:%.*]] = lshr i64 [[TMP18]], 32
+; CHECK-NEXT:    [[TMP21:%.*]] = trunc i64 [[TMP20]] to i32
+; CHECK-NEXT:    [[TMP22:%.*]] = add i32 [[TMP6]], [[TMP21]]
+; CHECK-NEXT:    [[TMP23:%.*]] = sub i32 [[TMP6]], [[TMP21]]
+; CHECK-NEXT:    [[TMP24:%.*]] = select i1 [[TMP14]], i32 [[TMP22]], i32 [[TMP23]]
+; CHECK-NEXT:    [[TMP25:%.*]] = zext i32 [[TMP24]] to i64
+; CHECK-NEXT:    [[TMP26:%.*]] = zext i32 [[TMP1]] to i64
+; CHECK-NEXT:    [[TMP27:%.*]] = mul i64 [[TMP25]], [[TMP26]]
+; CHECK-NEXT:    [[TMP28:%.*]] = trunc i64 [[TMP27]] to i32
+; CHECK-NEXT:    [[TMP29:%.*]] = lshr i64 [[TMP27]], 32
+; CHECK-NEXT:    [[TMP30:%.*]] = trunc i64 [[TMP29]] to i32
+; CHECK-NEXT:    [[TMP31:%.*]] = mul i32 [[TMP30]], [[TMP2]]
+; CHECK-NEXT:    [[TMP32:%.*]] = sub i32 [[TMP1]], [[TMP31]]
+; CHECK-NEXT:    [[TMP33:%.*]] = icmp uge i32 [[TMP32]], [[TMP2]]
+; CHECK-NEXT:    [[TMP34:%.*]] = select i1 [[TMP33]], i32 -1, i32 0
+; CHECK-NEXT:    [[TMP35:%.*]] = icmp uge i32 [[TMP1]], [[TMP31]]
+; CHECK-NEXT:    [[TMP36:%.*]] = select i1 [[TMP35]], i32 -1, i32 0
+; CHECK-NEXT:    [[TMP37:%.*]] = and i32 [[TMP34]], [[TMP36]]
+; CHECK-NEXT:    [[TMP38:%.*]] = icmp eq i32 [[TMP37]], 0
+; CHECK-NEXT:    [[TMP39:%.*]] = add i32 [[TMP30]], 1
+; CHECK-NEXT:    [[TMP40:%.*]] = sub i32 [[TMP30]], 1
+; CHECK-NEXT:    [[TMP41:%.*]] = select i1 [[TMP38]], i32 [[TMP30]], i32 [[TMP39]]
+; CHECK-NEXT:    [[TMP42:%.*]] = select i1 [[TMP35]], i32 [[TMP41]], i32 [[TMP40]]
+; CHECK-NEXT:    [[TMP43:%.*]] = insertelement <2 x i32> undef, i32 [[TMP42]], i64 0
+; CHECK-NEXT:    [[TMP44:%.*]] = extractelement <2 x i32> [[X]], i64 1
+; CHECK-NEXT:    [[TMP45:%.*]] = extractelement <2 x i32> [[SHL_Y]], i64 1
+; CHECK-NEXT:    [[TMP46:%.*]] = uitofp i32 [[TMP45]] to float
+; CHECK-NEXT:    [[TMP47:%.*]] = call fast float @llvm.amdgcn.rcp.f32(float [[TMP46]])
+; CHECK-NEXT:    [[TMP48:%.*]] = fmul fast float [[TMP47]], 0x41F0000000000000
+; CHECK-NEXT:    [[TMP49:%.*]] = fptoui float [[TMP48]] to i32
+; CHECK-NEXT:    [[TMP50:%.*]] = zext i32 [[TMP49]] to i64
+; CHECK-NEXT:    [[TMP51:%.*]] = zext i32 [[TMP45]] to i64
+; CHECK-NEXT:    [[TMP52:%.*]] = mul i64 [[TMP50]], [[TMP51]]
+; CHECK-NEXT:    [[TMP53:%.*]] = trunc i64 [[TMP52]] to i32
+; CHECK-NEXT:    [[TMP54:%.*]] = lshr i64 [[TMP52]], 32
+; CHECK-NEXT:    [[TMP55:%.*]] = trunc i64 [[TMP54]] to i32
+; CHECK-NEXT:    [[TMP56:%.*]] = sub i32 0, [[TMP53]]
+; CHECK-NEXT:    [[TMP57:%.*]] = icmp eq i32 [[TMP55]], 0
+; CHECK-NEXT:    [[TMP58:%.*]] = select i1 [[TMP57]], i32 [[TMP56]], i32 [[TMP53]]
+; CHECK-NEXT:    [[TMP59:%.*]] = zext i32 [[TMP58]] to i64
+; CHECK-NEXT:    [[TMP60:%.*]] = zext i32 [[TMP49]] to i64
+; CHECK-NEXT:    [[TMP61:%.*]] = mul i64 [[TMP59]], [[TMP60]]
+; CHECK-NEXT:    [[TMP62:%.*]] = trunc i64 [[TMP61]] to i32
+; CHECK-NEXT:    [[TMP63:%.*]] = lshr i64 [[TMP61]], 32
+; CHECK-NEXT:    [[TMP64:%.*]] = trunc i64 [[TMP63]] to i32
+; CHECK-NEXT:    [[TMP65:%.*]] = add i32 [[TMP49]], [[TMP64]]
+; CHECK-NEXT:    [[TMP66:%.*]] = sub i32 [[TMP49]], [[TMP64]]
+; CHECK-NEXT:    [[TMP67:%.*]] = select i1 [[TMP57]], i32 [[TMP65]], i32 [[TMP66]]
+; CHECK-NEXT:    [[TMP68:%.*]] = zext i32 [[TMP67]] to i64
+; CHECK-NEXT:    [[TMP69:%.*]] = zext i32 [[TMP44]] to i64
+; CHECK-NEXT:    [[TMP70:%.*]] = mul i64 [[TMP68]], [[TMP69]]
+; CHECK-NEXT:    [[TMP71:%.*]] = trunc i64 [[TMP70]] to i32
+; CHECK-NEXT:    [[TMP72:%.*]] = lshr i64 [[TMP70]], 32
+; CHECK-NEXT:    [[TMP73:%.*]] = trunc i64 [[TMP72]] to i32
+; CHECK-NEXT:    [[TMP74:%.*]] = mul i32 [[TMP73]], [[TMP45]]
+; CHECK-NEXT:    [[TMP75:%.*]] = sub i32 [[TMP44]], [[TMP74]]
+; CHECK-NEXT:    [[TMP76:%.*]] = icmp uge i32 [[TMP75]], [[TMP45]]
+; CHECK-NEXT:    [[TMP77:%.*]] = select i1 [[TMP76]], i32 -1, i32 0
+; CHECK-NEXT:    [[TMP78:%.*]] = icmp uge i32 [[TMP44]], [[TMP74]]
+; CHECK-NEXT:    [[TMP79:%.*]] = select i1 [[TMP78]], i32 -1, i32 0
+; CHECK-NEXT:    [[TMP80:%.*]] = and i32 [[TMP77]], [[TMP79]]
+; CHECK-NEXT:    [[TMP81:%.*]] = icmp eq i32 [[TMP80]], 0
+; CHECK-NEXT:    [[TMP82:%.*]] = add i32 [[TMP73]], 1
+; CHECK-NEXT:    [[TMP83:%.*]] = sub i32 [[TMP73]], 1
+; CHECK-NEXT:    [[TMP84:%.*]] = select i1 [[TMP81]], i32 [[TMP73]], i32 [[TMP82]]
+; CHECK-NEXT:    [[TMP85:%.*]] = select i1 [[TMP78]], i32 [[TMP84]], i32 [[TMP83]]
+; CHECK-NEXT:    [[TMP86:%.*]] = insertelement <2 x i32> [[TMP43]], i32 [[TMP85]], i64 1
+; CHECK-NEXT:    store <2 x i32> [[TMP86]], <2 x i32> addrspace(1)* [[OUT:%.*]]
+; CHECK-NEXT:    ret void
+;
+; GCN-LABEL: udiv_v2i32_pow2_shl_denom:
+; GCN:       ; %bb.0:
+; GCN-NEXT:    s_load_dwordx2 s[2:3], s[0:1], 0xd
+; GCN-NEXT:    s_movk_i32 s4, 0x1000
+; GCN-NEXT:    s_mov_b32 s7, 0xf000
+; GCN-NEXT:    s_mov_b32 s6, -1
+; GCN-NEXT:    s_waitcnt lgkmcnt(0)
+; GCN-NEXT:    s_lshl_b32 s2, s4, s2
+; GCN-NEXT:    v_cvt_f32_u32_e32 v0, s2
+; GCN-NEXT:    s_lshl_b32 s10, s4, s3
+; GCN-NEXT:    s_mov_b32 s3, 0x4f800000
+; GCN-NEXT:    v_cvt_f32_u32_e32 v1, s10
+; GCN-NEXT:    v_rcp_iflag_f32_e32 v0, v0
+; GCN-NEXT:    s_load_dwordx2 s[4:5], s[0:1], 0x9
+; GCN-NEXT:    s_load_dwordx2 s[8:9], s[0:1], 0xb
+; GCN-NEXT:    v_rcp_iflag_f32_e32 v1, v1
+; GCN-NEXT:    v_mul_f32_e32 v0, s3, v0
+; GCN-NEXT:    v_cvt_u32_f32_e32 v0, v0
+; GCN-NEXT:    v_mul_f32_e32 v1, s3, v1
+; GCN-NEXT:    v_cvt_u32_f32_e32 v1, v1
+; GCN-NEXT:    v_mul_lo_u32 v2, v0, s2
+; GCN-NEXT:    v_mul_hi_u32 v3, v0, s2
+; GCN-NEXT:    v_sub_i32_e32 v4, vcc, 0, v2
+; GCN-NEXT:    v_cmp_eq_u32_e64 s[0:1], 0, v3
+; GCN-NEXT:    v_cndmask_b32_e64 v2, v2, v4, s[0:1]
+; GCN-NEXT:    v_mul_hi_u32 v2, v2, v0
+; GCN-NEXT:    v_mul_lo_u32 v3, v1, s10
+; GCN-NEXT:    v_add_i32_e32 v4, vcc, v2, v0
+; GCN-NEXT:    v_subrev_i32_e32 v0, vcc, v2, v0
+; GCN-NEXT:    v_mul_hi_u32 v2, v1, s10
+; GCN-NEXT:    v_cndmask_b32_e64 v0, v0, v4, s[0:1]
+; GCN-NEXT:    v_sub_i32_e32 v4, vcc, 0, v3
+; GCN-NEXT:    s_waitcnt lgkmcnt(0)
+; GCN-NEXT:    v_mul_hi_u32 v0, v0, s8
+; GCN-NEXT:    v_cmp_eq_u32_e64 s[0:1], 0, v2
+; GCN-NEXT:    v_cndmask_b32_e64 v2, v3, v4, s[0:1]
+; GCN-NEXT:    v_mul_hi_u32 v2, v2, v1
+; GCN-NEXT:    v_mul_lo_u32 v5, v0, s2
+; GCN-NEXT:    v_add_i32_e32 v4, vcc, v2, v1
+; GCN-NEXT:    v_subrev_i32_e32 v1, vcc, v2, v1
+; GCN-NEXT:    v_cndmask_b32_e64 v1, v1, v4, s[0:1]
+; GCN-NEXT:    v_mul_hi_u32 v1, v1, s9
+; GCN-NEXT:    v_sub_i32_e32 v3, vcc, s8, v5
+; GCN-NEXT:    v_cmp_le_u32_e64 s[2:3], s2, v3
+; GCN-NEXT:    v_add_i32_e32 v3, vcc, -1, v0
+; GCN-NEXT:    v_mul_lo_u32 v4, v1, s10
+; GCN-NEXT:    v_cmp_ge_u32_e64 s[0:1], s8, v5
+; GCN-NEXT:    v_add_i32_e32 v2, vcc, 1, v0
+; GCN-NEXT:    s_and_b64 vcc, s[2:3], s[0:1]
+; GCN-NEXT:    v_cndmask_b32_e32 v0, v0, v2, vcc
+; GCN-NEXT:    v_sub_i32_e32 v2, vcc, s9, v4
+; GCN-NEXT:    v_cndmask_b32_e64 v0, v3, v0, s[0:1]
+; GCN-NEXT:    v_cmp_le_u32_e64 s[0:1], s10, v2
+; GCN-NEXT:    v_add_i32_e32 v2, vcc, -1, v1
+; GCN-NEXT:    v_cmp_ge_u32_e64 s[2:3], s9, v4
+; GCN-NEXT:    v_add_i32_e32 v3, vcc, 1, v1
+; GCN-NEXT:    s_and_b64 vcc, s[0:1], s[2:3]
+; GCN-NEXT:    v_cndmask_b32_e32 v1, v1, v3, vcc
+; GCN-NEXT:    v_cndmask_b32_e64 v1, v2, v1, s[2:3]
+; GCN-NEXT:    buffer_store_dwordx2 v[0:1], off, s[4:7], 0
+; GCN-NEXT:    s_endpgm
+  %shl.y = shl <2 x i32> <i32 4096, i32 4096>, %y
+  %r = udiv <2 x i32> %x, %shl.y
+  store <2 x i32> %r, <2 x i32> addrspace(1)* %out
+  ret void
+}
+
+define amdgpu_kernel void @urem_i32_oddk_denom(i32 addrspace(1)* %out, i32 %x) {
+; CHECK-LABEL: @urem_i32_oddk_denom(
+; CHECK-NEXT:    [[R:%.*]] = urem i32 [[X:%.*]], 1235195
+; CHECK-NEXT:    store i32 [[R]], i32 addrspace(1)* [[OUT:%.*]]
+; CHECK-NEXT:    ret void
+;
+; GCN-LABEL: urem_i32_oddk_denom:
+; GCN:       ; %bb.0:
+; GCN-NEXT:    s_load_dwordx2 s[4:5], s[0:1], 0x9
+; GCN-NEXT:    s_load_dword s0, s[0:1], 0xb
+; GCN-NEXT:    v_mov_b32_e32 v0, 0xb2a50881
+; GCN-NEXT:    s_mov_b32 s7, 0xf000
+; GCN-NEXT:    s_mov_b32 s6, -1
+; GCN-NEXT:    s_waitcnt lgkmcnt(0)
+; GCN-NEXT:    v_mul_hi_u32 v0, s0, v0
+; GCN-NEXT:    v_sub_i32_e32 v1, vcc, s0, v0
+; GCN-NEXT:    v_lshrrev_b32_e32 v1, 1, v1
+; GCN-NEXT:    v_add_i32_e32 v0, vcc, v0, v1
+; GCN-NEXT:    v_lshrrev_b32_e32 v0, 20, v0
+; GCN-NEXT:    v_mul_u32_u24_e32 v0, 0x12d8fb, v0
+; GCN-NEXT:    v_sub_i32_e32 v0, vcc, s0, v0
+; GCN-NEXT:    buffer_store_dword v0, off, s[4:7], 0
+; GCN-NEXT:    s_endpgm
+  %r = urem i32 %x, 1235195
+  store i32 %r, i32 addrspace(1)* %out
+  ret void
+}
+
+define amdgpu_kernel void @urem_i32_pow2k_denom(i32 addrspace(1)* %out, i32 %x) {
+; CHECK-LABEL: @urem_i32_pow2k_denom(
+; CHECK-NEXT:    [[R:%.*]] = urem i32 [[X:%.*]], 4096
+; CHECK-NEXT:    store i32 [[R]], i32 addrspace(1)* [[OUT:%.*]]
+; CHECK-NEXT:    ret void
+;
+; GCN-LABEL: urem_i32_pow2k_denom:
+; GCN:       ; %bb.0:
+; GCN-NEXT:    s_load_dwordx2 s[4:5], s[0:1], 0x9
+; GCN-NEXT:    s_load_dword s0, s[0:1], 0xb
+; GCN-NEXT:    s_mov_b32 s7, 0xf000
+; GCN-NEXT:    s_mov_b32 s6, -1
+; GCN-NEXT:    s_waitcnt lgkmcnt(0)
+; GCN-NEXT:    s_and_b32 s0, s0, 0xfff
+; GCN-NEXT:    v_mov_b32_e32 v0, s0
+; GCN-NEXT:    buffer_store_dword v0, off, s[4:7], 0
+; GCN-NEXT:    s_endpgm
+  %r = urem i32 %x, 4096
+  store i32 %r, i32 addrspace(1)* %out
+  ret void
+}
+
+define amdgpu_kernel void @urem_i32_pow2_shl_denom(i32 addrspace(1)* %out, i32 %x, i32 %y) {
+; CHECK-LABEL: @urem_i32_pow2_shl_denom(
+; CHECK-NEXT:    [[SHL_Y:%.*]] = shl i32 4096, [[Y:%.*]]
+; CHECK-NEXT:    [[TMP1:%.*]] = uitofp i32 [[SHL_Y]] to float
+; CHECK-NEXT:    [[TMP2:%.*]] = call fast float @llvm.amdgcn.rcp.f32(float [[TMP1]])
+; CHECK-NEXT:    [[TMP3:%.*]] = fmul fast float [[TMP2]], 0x41F0000000000000
+; CHECK-NEXT:    [[TMP4:%.*]] = fptoui float [[TMP3]] to i32
+; CHECK-NEXT:    [[TMP5:%.*]] = zext i32 [[TMP4]] to i64
+; CHECK-NEXT:    [[TMP6:%.*]] = zext i32 [[SHL_Y]] to i64
+; CHECK-NEXT:    [[TMP7:%.*]] = mul i64 [[TMP5]], [[TMP6]]
+; CHECK-NEXT:    [[TMP8:%.*]] = trunc i64 [[TMP7]] to i32
+; CHECK-NEXT:    [[TMP9:%.*]] = lshr i64 [[TMP7]], 32
+; CHECK-NEXT:    [[TMP10:%.*]] = trunc i64 [[TMP9]] to i32
+; CHECK-NEXT:    [[TMP11:%.*]] = sub i32 0, [[TMP8]]
+; CHECK-NEXT:    [[TMP12:%.*]] = icmp eq i32 [[TMP10]], 0
+; CHECK-NEXT:    [[TMP13:%.*]] = select i1 [[TMP12]], i32 [[TMP11]], i32 [[TMP8]]
+; CHECK-NEXT:    [[TMP14:%.*]] = zext i32 [[TMP13]] to i64
+; CHECK-NEXT:    [[TMP15:%.*]] = zext i32 [[TMP4]] to i64
+; CHECK-NEXT:    [[TMP16:%.*]] = mul i64 [[TMP14]], [[TMP15]]
+; CHECK-NEXT:    [[TMP17:%.*]] = trunc i64 [[TMP16]] to i32
+; CHECK-NEXT:    [[TMP18:%.*]] = lshr i64 [[TMP16]], 32
+; CHECK-NEXT:    [[TMP19:%.*]] = trunc i64 [[TMP18]] to i32
+; CHECK-NEXT:    [[TMP20:%.*]] = add i32 [[TMP4]], [[TMP19]]
+; CHECK-NEXT:    [[TMP21:%.*]] = sub i32 [[TMP4]], [[TMP19]]
+; CHECK-NEXT:    [[TMP22:%.*]] = select i1 [[TMP12]], i32 [[TMP20]], i32 [[TMP21]]
+; CHECK-NEXT:    [[TMP23:%.*]] = zext i32 [[TMP22]] to i64
+; CHECK-NEXT:    [[TMP24:%.*]] = zext i32 [[X:%.*]] to i64
+; CHECK-NEXT:    [[TMP25:%.*]] = mul i64 [[TMP23]], [[TMP24]]
+; CHECK-NEXT:    [[TMP26:%.*]] = trunc i64 [[TMP25]] to i32
+; CHECK-NEXT:    [[TMP27:%.*]] = lshr i64 [[TMP25]], 32
+; CHECK-NEXT:    [[TMP28:%.*]] = trunc i64 [[TMP27]] to i32
+; CHECK-NEXT:    [[TMP29:%.*]] = mul i32 [[TMP28]], [[SHL_Y]]
+; CHECK-NEXT:    [[TMP30:%.*]] = sub i32 [[X]], [[TMP29]]
+; CHECK-NEXT:    [[TMP31:%.*]] = icmp uge i32 [[TMP30]], [[SHL_Y]]
+; CHECK-NEXT:    [[TMP32:%.*]] = select i1 [[TMP31]], i32 -1, i32 0
+; CHECK-NEXT:    [[TMP33:%.*]] = icmp uge i32 [[X]], [[TMP29]]
+; CHECK-NEXT:    [[TMP34:%.*]] = select i1 [[TMP33]], i32 -1, i32 0
+; CHECK-NEXT:    [[TMP35:%.*]] = and i32 [[TMP32]], [[TMP34]]
+; CHECK-NEXT:    [[TMP36:%.*]] = icmp eq i32 [[TMP35]], 0
+; CHECK-NEXT:    [[TMP37:%.*]] = sub i32 [[TMP30]], [[SHL_Y]]
+; CHECK-NEXT:    [[TMP38:%.*]] = add i32 [[TMP30]], [[SHL_Y]]
+; CHECK-NEXT:    [[TMP39:%.*]] = select i1 [[TMP36]], i32 [[TMP30]], i32 [[TMP37]]
+; CHECK-NEXT:    [[TMP40:%.*]] = select i1 [[TMP33]], i32 [[TMP39]], i32 [[TMP38]]
+; CHECK-NEXT:    store i32 [[TMP40]], i32 addrspace(1)* [[OUT:%.*]]
+; CHECK-NEXT:    ret void
+;
+; GCN-LABEL: urem_i32_pow2_shl_denom:
+; GCN:       ; %bb.0:
+; GCN-NEXT:    s_load_dwordx2 s[8:9], s[0:1], 0xb
+; GCN-NEXT:    s_load_dwordx2 s[4:5], s[0:1], 0x9
+; GCN-NEXT:    s_mov_b32 s7, 0xf000
+; GCN-NEXT:    s_mov_b32 s6, -1
+; GCN-NEXT:    s_waitcnt lgkmcnt(0)
+; GCN-NEXT:    s_lshl_b32 s9, 0x1000, s9
+; GCN-NEXT:    v_cvt_f32_u32_e32 v0, s9
+; GCN-NEXT:    v_rcp_iflag_f32_e32 v0, v0
+; GCN-NEXT:    v_mul_f32_e32 v0, 0x4f800000, v0
+; GCN-NEXT:    v_cvt_u32_f32_e32 v0, v0
+; GCN-NEXT:    v_mul_lo_u32 v1, v0, s9
+; GCN-NEXT:    v_mul_hi_u32 v2, v0, s9
+; GCN-NEXT:    v_sub_i32_e32 v3, vcc, 0, v1
+; GCN-NEXT:    v_cmp_eq_u32_e64 s[2:3], 0, v2
+; GCN-NEXT:    v_cndmask_b32_e64 v1, v1, v3, s[2:3]
+; GCN-NEXT:    v_mul_hi_u32 v1, v1, v0
+; GCN-NEXT:    v_add_i32_e32 v2, vcc, v1, v0
+; GCN-NEXT:    v_subrev_i32_e32 v0, vcc, v1, v0
+; GCN-NEXT:    v_cndmask_b32_e64 v0, v0, v2, s[2:3]
+; GCN-NEXT:    v_mul_hi_u32 v0, v0, s8
+; GCN-NEXT:    v_mul_lo_u32 v0, v0, s9
+; GCN-NEXT:    v_sub_i32_e32 v1, vcc, s8, v0
+; GCN-NEXT:    v_cmp_ge_u32_e64 s[2:3], s8, v0
+; GCN-NEXT:    v_cmp_le_u32_e64 s[0:1], s9, v1
+; GCN-NEXT:    v_add_i32_e32 v2, vcc, s9, v1
+; GCN-NEXT:    v_subrev_i32_e32 v0, vcc, s9, v1
+; GCN-NEXT:    s_and_b64 vcc, s[0:1], s[2:3]
+; GCN-NEXT:    v_cndmask_b32_e32 v0, v1, v0, vcc
+; GCN-NEXT:    v_cndmask_b32_e64 v0, v2, v0, s[2:3]
+; GCN-NEXT:    buffer_store_dword v0, off, s[4:7], 0
+; GCN-NEXT:    s_endpgm
+  %shl.y = shl i32 4096, %y
+  %r = urem i32 %x, %shl.y
+  store i32 %r, i32 addrspace(1)* %out
+  ret void
+}
+
+define amdgpu_kernel void @urem_v2i32_pow2k_denom(<2 x i32> addrspace(1)* %out, <2 x i32> %x) {
+; CHECK-LABEL: @urem_v2i32_pow2k_denom(
+; CHECK-NEXT:    [[TMP1:%.*]] = extractelement <2 x i32> [[X:%.*]], i64 0
+; CHECK-NEXT:    [[TMP2:%.*]] = urem i32 [[TMP1]], 4096
+; CHECK-NEXT:    [[TMP3:%.*]] = insertelement <2 x i32> undef, i32 [[TMP2]], i64 0
+; CHECK-NEXT:    [[TMP4:%.*]] = extractelement <2 x i32> [[X]], i64 1
+; CHECK-NEXT:    [[TMP5:%.*]] = urem i32 [[TMP4]], 4096
+; CHECK-NEXT:    [[TMP6:%.*]] = insertelement <2 x i32> [[TMP3]], i32 [[TMP5]], i64 1
+; CHECK-NEXT:    store <2 x i32> [[TMP6]], <2 x i32> addrspace(1)* [[OUT:%.*]]
+; CHECK-NEXT:    ret void
+;
+; GCN-LABEL: urem_v2i32_pow2k_denom:
+; GCN:       ; %bb.0:
+; GCN-NEXT:    s_load_dwordx2 s[4:5], s[0:1], 0x9
+; GCN-NEXT:    s_load_dwordx2 s[0:1], s[0:1], 0xb
+; GCN-NEXT:    s_movk_i32 s2, 0xfff
+; GCN-NEXT:    s_mov_b32 s7, 0xf000
+; GCN-NEXT:    s_mov_b32 s6, -1
+; GCN-NEXT:    s_waitcnt lgkmcnt(0)
+; GCN-NEXT:    s_and_b32 s0, s0, s2
+; GCN-NEXT:    s_and_b32 s1, s1, s2
+; GCN-NEXT:    v_mov_b32_e32 v0, s0
+; GCN-NEXT:    v_mov_b32_e32 v1, s1
+; GCN-NEXT:    buffer_store_dwordx2 v[0:1], off, s[4:7], 0
+; GCN-NEXT:    s_endpgm
+  %r = urem <2 x i32> %x, <i32 4096, i32 4096>
+  store <2 x i32> %r, <2 x i32> addrspace(1)* %out
+  ret void
+}
+
+define amdgpu_kernel void @urem_v2i32_pow2_shl_denom(<2 x i32> addrspace(1)* %out, <2 x i32> %x, <2 x i32> %y) {
+; CHECK-LABEL: @urem_v2i32_pow2_shl_denom(
+; CHECK-NEXT:    [[SHL_Y:%.*]] = shl <2 x i32> <i32 4096, i32 4096>, [[Y:%.*]]
+; CHECK-NEXT:    [[TMP1:%.*]] = extractelement <2 x i32> [[X:%.*]], i64 0
+; CHECK-NEXT:    [[TMP2:%.*]] = extractelement <2 x i32> [[SHL_Y]], i64 0
+; CHECK-NEXT:    [[TMP3:%.*]] = uitofp i32 [[TMP2]] to float
+; CHECK-NEXT:    [[TMP4:%.*]] = call fast float @llvm.amdgcn.rcp.f32(float [[TMP3]])
+; CHECK-NEXT:    [[TMP5:%.*]] = fmul fast float [[TMP4]], 0x41F0000000000000
+; CHECK-NEXT:    [[TMP6:%.*]] = fptoui float [[TMP5]] to i32
+; CHECK-NEXT:    [[TMP7:%.*]] = zext i32 [[TMP6]] to i64
+; CHECK-NEXT:    [[TMP8:%.*]] = zext i32 [[TMP2]] to i64
+; CHECK-NEXT:    [[TMP9:%.*]] = mul i64 [[TMP7]], [[TMP8]]
+; CHECK-NEXT:    [[TMP10:%.*]] = trunc i64 [[TMP9]] to i32
+; CHECK-NEXT:    [[TMP11:%.*]] = lshr i64 [[TMP9]], 32
+; CHECK-NEXT:    [[TMP12:%.*]] = trunc i64 [[TMP11]] to i32
+; CHECK-NEXT:    [[TMP13:%.*]] = sub i32 0, [[TMP10]]
+; CHECK-NEXT:    [[TMP14:%.*]] = icmp eq i32 [[TMP12]], 0
+; CHECK-NEXT:    [[TMP15:%.*]] = select i1 [[TMP14]], i32 [[TMP13]], i32 [[TMP10]]
+; CHECK-NEXT:    [[TMP16:%.*]] = zext i32 [[TMP15]] to i64
+; CHECK-NEXT:    [[TMP17:%.*]] = zext i32 [[TMP6]] to i64
+; CHECK-NEXT:    [[TMP18:%.*]] = mul i64 [[TMP16]], [[TMP17]]
+; CHECK-NEXT:    [[TMP19:%.*]] = trunc i64 [[TMP18]] to i32
+; CHECK-NEXT:    [[TMP20:%.*]] = lshr i64 [[TMP18]], 32
+; CHECK-NEXT:    [[TMP21:%.*]] = trunc i64 [[TMP20]] to i32
+; CHECK-NEXT:    [[TMP22:%.*]] = add i32 [[TMP6]], [[TMP21]]
+; CHECK-NEXT:    [[TMP23:%.*]] = sub i32 [[TMP6]], [[TMP21]]
+; CHECK-NEXT:    [[TMP24:%.*]] = select i1 [[TMP14]], i32 [[TMP22]], i32 [[TMP23]]
+; CHECK-NEXT:    [[TMP25:%.*]] = zext i32 [[TMP24]] to i64
+; CHECK-NEXT:    [[TMP26:%.*]] = zext i32 [[TMP1]] to i64
+; CHECK-NEXT:    [[TMP27:%.*]] = mul i64 [[TMP25]], [[TMP26]]
+; CHECK-NEXT:    [[TMP28:%.*]] = trunc i64 [[TMP27]] to i32
+; CHECK-NEXT:    [[TMP29:%.*]] = lshr i64 [[TMP27]], 32
+; CHECK-NEXT:    [[TMP30:%.*]] = trunc i64 [[TMP29]] to i32
+; CHECK-NEXT:    [[TMP31:%.*]] = mul i32 [[TMP30]], [[TMP2]]
+; CHECK-NEXT:    [[TMP32:%.*]] = sub i32 [[TMP1]], [[TMP31]]
+; CHECK-NEXT:    [[TMP33:%.*]] = icmp uge i32 [[TMP32]], [[TMP2]]
+; CHECK-NEXT:    [[TMP34:%.*]] = select i1 [[TMP33]], i32 -1, i32 0
+; CHECK-NEXT:    [[TMP35:%.*]] = icmp uge i32 [[TMP1]], [[TMP31]]
+; CHECK-NEXT:    [[TMP36:%.*]] = select i1 [[TMP35]], i32 -1, i32 0
+; CHECK-NEXT:    [[TMP37:%.*]] = and i32 [[TMP34]], [[TMP36]]
+; CHECK-NEXT:    [[TMP38:%.*]] = icmp eq i32 [[TMP37]], 0
+; CHECK-NEXT:    [[TMP39:%.*]] = sub i32 [[TMP32]], [[TMP2]]
+; CHECK-NEXT:    [[TMP40:%.*]] = add i32 [[TMP32]], [[TMP2]]
+; CHECK-NEXT:    [[TMP41:%.*]] = select i1 [[TMP38]], i32 [[TMP32]], i32 [[TMP39]]
+; CHECK-NEXT:    [[TMP42:%.*]] = select i1 [[TMP35]], i32 [[TMP41]], i32 [[TMP40]]
+; CHECK-NEXT:    [[TMP43:%.*]] = insertelement <2 x i32> undef, i32 [[TMP42]], i64 0
+; CHECK-NEXT:    [[TMP44:%.*]] = extractelement <2 x i32> [[X]], i64 1
+; CHECK-NEXT:    [[TMP45:%.*]] = extractelement <2 x i32> [[SHL_Y]], i64 1
+; CHECK-NEXT:    [[TMP46:%.*]] = uitofp i32 [[TMP45]] to float
+; CHECK-NEXT:    [[TMP47:%.*]] = call fast float @llvm.amdgcn.rcp.f32(float [[TMP46]])
+; CHECK-NEXT:    [[TMP48:%.*]] = fmul fast float [[TMP47]], 0x41F0000000000000
+; CHECK-NEXT:    [[TMP49:%.*]] = fptoui float [[TMP48]] to i32
+; CHECK-NEXT:    [[TMP50:%.*]] = zext i32 [[TMP49]] to i64
+; CHECK-NEXT:    [[TMP51:%.*]] = zext i32 [[TMP45]] to i64
+; CHECK-NEXT:    [[TMP52:%.*]] = mul i64 [[TMP50]], [[TMP51]]
+; CHECK-NEXT:    [[TMP53:%.*]] = trunc i64 [[TMP52]] to i32
+; CHECK-NEXT:    [[TMP54:%.*]] = lshr i64 [[TMP52]], 32
+; CHECK-NEXT:    [[TMP55:%.*]] = trunc i64 [[TMP54]] to i32
+; CHECK-NEXT:    [[TMP56:%.*]] = sub i32 0, [[TMP53]]
+; CHECK-NEXT:    [[TMP57:%.*]] = icmp eq i32 [[TMP55]], 0
+; CHECK-NEXT:    [[TMP58:%.*]] = select i1 [[TMP57]], i32 [[TMP56]], i32 [[TMP53]]
+; CHECK-NEXT:    [[TMP59:%.*]] = zext i32 [[TMP58]] to i64
+; CHECK-NEXT:    [[TMP60:%.*]] = zext i32 [[TMP49]] to i64
+; CHECK-NEXT:    [[TMP61:%.*]] = mul i64 [[TMP59]], [[TMP60]]
+; CHECK-NEXT:    [[TMP62:%.*]] = trunc i64 [[TMP61]] to i32
+; CHECK-NEXT:    [[TMP63:%.*]] = lshr i64 [[TMP61]], 32
+; CHECK-NEXT:    [[TMP64:%.*]] = trunc i64 [[TMP63]] to i32
+; CHECK-NEXT:    [[TMP65:%.*]] = add i32 [[TMP49]], [[TMP64]]
+; CHECK-NEXT:    [[TMP66:%.*]] = sub i32 [[TMP49]], [[TMP64]]
+; CHECK-NEXT:    [[TMP67:%.*]] = select i1 [[TMP57]], i32 [[TMP65]], i32 [[TMP66]]
+; CHECK-NEXT:    [[TMP68:%.*]] = zext i32 [[TMP67]] to i64
+; CHECK-NEXT:    [[TMP69:%.*]] = zext i32 [[TMP44]] to i64
+; CHECK-NEXT:    [[TMP70:%.*]] = mul i64 [[TMP68]], [[TMP69]]
+; CHECK-NEXT:    [[TMP71:%.*]] = trunc i64 [[TMP70]] to i32
+; CHECK-NEXT:    [[TMP72:%.*]] = lshr i64 [[TMP70]], 32
+; CHECK-NEXT:    [[TMP73:%.*]] = trunc i64 [[TMP72]] to i32
+; CHECK-NEXT:    [[TMP74:%.*]] = mul i32 [[TMP73]], [[TMP45]]
+; CHECK-NEXT:    [[TMP75:%.*]] = sub i32 [[TMP44]], [[TMP74]]
+; CHECK-NEXT:    [[TMP76:%.*]] = icmp uge i32 [[TMP75]], [[TMP45]]
+; CHECK-NEXT:    [[TMP77:%.*]] = select i1 [[TMP76]], i32 -1, i32 0
+; CHECK-NEXT:    [[TMP78:%.*]] = icmp uge i32 [[TMP44]], [[TMP74]]
+; CHECK-NEXT:    [[TMP79:%.*]] = select i1 [[TMP78]], i32 -1, i32 0
+; CHECK-NEXT:    [[TMP80:%.*]] = and i32 [[TMP77]], [[TMP79]]
+; CHECK-NEXT:    [[TMP81:%.*]] = icmp eq i32 [[TMP80]], 0
+; CHECK-NEXT:    [[TMP82:%.*]] = sub i32 [[TMP75]], [[TMP45]]
+; CHECK-NEXT:    [[TMP83:%.*]] = add i32 [[TMP75]], [[TMP45]]
+; CHECK-NEXT:    [[TMP84:%.*]] = select i1 [[TMP81]], i32 [[TMP75]], i32 [[TMP82]]
+; CHECK-NEXT:    [[TMP85:%.*]] = select i1 [[TMP78]], i32 [[TMP84]], i32 [[TMP83]]
+; CHECK-NEXT:    [[TMP86:%.*]] = insertelement <2 x i32> [[TMP43]], i32 [[TMP85]], i64 1
+; CHECK-NEXT:    store <2 x i32> [[TMP86]], <2 x i32> addrspace(1)* [[OUT:%.*]]
+; CHECK-NEXT:    ret void
+;
+; GCN-LABEL: urem_v2i32_pow2_shl_denom:
+; GCN:       ; %bb.0:
+; GCN-NEXT:    s_load_dwordx2 s[2:3], s[0:1], 0xd
+; GCN-NEXT:    s_movk_i32 s4, 0x1000
+; GCN-NEXT:    s_mov_b32 s7, 0xf000
+; GCN-NEXT:    s_mov_b32 s6, -1
+; GCN-NEXT:    s_waitcnt lgkmcnt(0)
+; GCN-NEXT:    s_lshl_b32 s10, s4, s2
+; GCN-NEXT:    v_cvt_f32_u32_e32 v0, s10
+; GCN-NEXT:    s_mov_b32 s2, 0x4f800000
+; GCN-NEXT:    s_lshl_b32 s11, s4, s3
+; GCN-NEXT:    v_cvt_f32_u32_e32 v1, s11
+; GCN-NEXT:    v_rcp_iflag_f32_e32 v0, v0
+; GCN-NEXT:    s_load_dwordx2 s[4:5], s[0:1], 0x9
+; GCN-NEXT:    s_load_dwordx2 s[8:9], s[0:1], 0xb
+; GCN-NEXT:    v_rcp_iflag_f32_e32 v1, v1
+; GCN-NEXT:    v_mul_f32_e32 v0, s2, v0
+; GCN-NEXT:    v_cvt_u32_f32_e32 v0, v0
+; GCN-NEXT:    v_mul_f32_e32 v1, s2, v1
+; GCN-NEXT:    v_cvt_u32_f32_e32 v1, v1
+; GCN-NEXT:    v_mul_lo_u32 v2, v0, s10
+; GCN-NEXT:    v_mul_hi_u32 v3, v0, s10
+; GCN-NEXT:    v_sub_i32_e32 v4, vcc, 0, v2
+; GCN-NEXT:    v_cmp_eq_u32_e64 s[0:1], 0, v3
+; GCN-NEXT:    v_cndmask_b32_e64 v2, v2, v4, s[0:1]
+; GCN-NEXT:    v_mul_hi_u32 v2, v2, v0
+; GCN-NEXT:    v_mul_lo_u32 v3, v1, s11
+; GCN-NEXT:    v_add_i32_e32 v4, vcc, v2, v0
+; GCN-NEXT:    v_subrev_i32_e32 v0, vcc, v2, v0
+; GCN-NEXT:    v_mul_hi_u32 v2, v1, s11
+; GCN-NEXT:    v_cndmask_b32_e64 v0, v0, v4, s[0:1]
+; GCN-NEXT:    v_sub_i32_e32 v4, vcc, 0, v3
+; GCN-NEXT:    s_waitcnt lgkmcnt(0)
+; GCN-NEXT:    v_mul_hi_u32 v0, v0, s8
+; GCN-NEXT:    v_cmp_eq_u32_e64 s[0:1], 0, v2
+; GCN-NEXT:    v_cndmask_b32_e64 v2, v3, v4, s[0:1]
+; GCN-NEXT:    v_mul_hi_u32 v2, v2, v1
+; GCN-NEXT:    v_mul_lo_u32 v0, v0, s10
+; GCN-NEXT:    v_add_i32_e32 v5, vcc, v2, v1
+; GCN-NEXT:    v_subrev_i32_e32 v1, vcc, v2, v1
+; GCN-NEXT:    v_cndmask_b32_e64 v1, v1, v5, s[0:1]
+; GCN-NEXT:    v_mul_hi_u32 v1, v1, s9
+; GCN-NEXT:    v_sub_i32_e32 v3, vcc, s8, v0
+; GCN-NEXT:    v_cmp_ge_u32_e64 s[0:1], s8, v0
+; GCN-NEXT:    v_cmp_le_u32_e64 s[2:3], s10, v3
+; GCN-NEXT:    v_mul_lo_u32 v1, v1, s11
+; GCN-NEXT:    v_add_i32_e32 v4, vcc, s10, v3
+; GCN-NEXT:    v_subrev_i32_e32 v0, vcc, s10, v3
+; GCN-NEXT:    s_and_b64 vcc, s[2:3], s[0:1]
+; GCN-NEXT:    v_cndmask_b32_e32 v0, v3, v0, vcc
+; GCN-NEXT:    v_sub_i32_e32 v2, vcc, s9, v1
+; GCN-NEXT:    v_cndmask_b32_e64 v0, v4, v0, s[0:1]
+; GCN-NEXT:    v_cmp_ge_u32_e64 s[2:3], s9, v1
+; GCN-NEXT:    v_cmp_le_u32_e64 s[0:1], s11, v2
+; GCN-NEXT:    v_add_i32_e32 v3, vcc, s11, v2
+; GCN-NEXT:    v_subrev_i32_e32 v1, vcc, s11, v2
+; GCN-NEXT:    s_and_b64 vcc, s[0:1], s[2:3]
+; GCN-NEXT:    v_cndmask_b32_e32 v1, v2, v1, vcc
+; GCN-NEXT:    v_cndmask_b32_e64 v1, v3, v1, s[2:3]
+; GCN-NEXT:    buffer_store_dwordx2 v[0:1], off, s[4:7], 0
+; GCN-NEXT:    s_endpgm
+  %shl.y = shl <2 x i32> <i32 4096, i32 4096>, %y
+  %r = urem <2 x i32> %x, %shl.y
+  store <2 x i32> %r, <2 x i32> addrspace(1)* %out
+  ret void
+}
+
+define amdgpu_kernel void @sdiv_i32_oddk_denom(i32 addrspace(1)* %out, i32 %x) {
+; CHECK-LABEL: @sdiv_i32_oddk_denom(
+; CHECK-NEXT:    [[R:%.*]] = sdiv i32 [[X:%.*]], 1235195
+; CHECK-NEXT:    store i32 [[R]], i32 addrspace(1)* [[OUT:%.*]]
+; CHECK-NEXT:    ret void
+;
+; GCN-LABEL: sdiv_i32_oddk_denom:
+; GCN:       ; %bb.0:
+; GCN-NEXT:    s_load_dwordx2 s[4:5], s[0:1], 0x9
+; GCN-NEXT:    s_load_dword s0, s[0:1], 0xb
+; GCN-NEXT:    v_mov_b32_e32 v0, 0xd9528441
+; GCN-NEXT:    s_mov_b32 s7, 0xf000
+; GCN-NEXT:    s_mov_b32 s6, -1
+; GCN-NEXT:    s_waitcnt lgkmcnt(0)
+; GCN-NEXT:    v_mul_hi_i32 v0, s0, v0
+; GCN-NEXT:    v_add_i32_e32 v0, vcc, s0, v0
+; GCN-NEXT:    v_lshrrev_b32_e32 v1, 31, v0
+; GCN-NEXT:    v_ashrrev_i32_e32 v0, 20, v0
+; GCN-NEXT:    v_add_i32_e32 v0, vcc, v1, v0
+; GCN-NEXT:    buffer_store_dword v0, off, s[4:7], 0
+; GCN-NEXT:    s_endpgm
+  %r = sdiv i32 %x, 1235195
+  store i32 %r, i32 addrspace(1)* %out
+  ret void
+}
+
+define amdgpu_kernel void @sdiv_i32_pow2k_denom(i32 addrspace(1)* %out, i32 %x) {
+; CHECK-LABEL: @sdiv_i32_pow2k_denom(
+; CHECK-NEXT:    [[R:%.*]] = sdiv i32 [[X:%.*]], 4096
+; CHECK-NEXT:    store i32 [[R]], i32 addrspace(1)* [[OUT:%.*]]
+; CHECK-NEXT:    ret void
+;
+; GCN-LABEL: sdiv_i32_pow2k_denom:
+; GCN:       ; %bb.0:
+; GCN-NEXT:    s_load_dwordx2 s[4:5], s[0:1], 0x9
+; GCN-NEXT:    s_load_dword s0, s[0:1], 0xb
+; GCN-NEXT:    s_mov_b32 s7, 0xf000
+; GCN-NEXT:    s_mov_b32 s6, -1
+; GCN-NEXT:    s_waitcnt lgkmcnt(0)
+; GCN-NEXT:    s_ashr_i32 s1, s0, 31
+; GCN-NEXT:    s_lshr_b32 s1, s1, 20
+; GCN-NEXT:    s_add_i32 s0, s0, s1
+; GCN-NEXT:    s_ashr_i32 s0, s0, 12
+; GCN-NEXT:    v_mov_b32_e32 v0, s0
+; GCN-NEXT:    buffer_store_dword v0, off, s[4:7], 0
+; GCN-NEXT:    s_endpgm
+  %r = sdiv i32 %x, 4096
+  store i32 %r, i32 addrspace(1)* %out
+  ret void
+}
+
+define amdgpu_kernel void @sdiv_i32_pow2_shl_denom(i32 addrspace(1)* %out, i32 %x, i32 %y) {
+; CHECK-LABEL: @sdiv_i32_pow2_shl_denom(
+; CHECK-NEXT:    [[SHL_Y:%.*]] = shl i32 4096, [[Y:%.*]]
+; CHECK-NEXT:    [[TMP1:%.*]] = ashr i32 [[X:%.*]], 31
+; CHECK-NEXT:    [[TMP2:%.*]] = ashr i32 [[SHL_Y]], 31
+; CHECK-NEXT:    [[TMP3:%.*]] = xor i32 [[TMP1]], [[TMP2]]
+; CHECK-NEXT:    [[TMP4:%.*]] = add i32 [[X]], [[TMP1]]
+; CHECK-NEXT:    [[TMP5:%.*]] = add i32 [[SHL_Y]], [[TMP2]]
+; CHECK-NEXT:    [[TMP6:%.*]] = xor i32 [[TMP4]], [[TMP1]]
+; CHECK-NEXT:    [[TMP7:%.*]] = xor i32 [[TMP5]], [[TMP2]]
+; CHECK-NEXT:    [[TMP8:%.*]] = uitofp i32 [[TMP7]] to float
+; CHECK-NEXT:    [[TMP9:%.*]] = call fast float @llvm.amdgcn.rcp.f32(float [[TMP8]])
+; CHECK-NEXT:    [[TMP10:%.*]] = fmul fast float [[TMP9]], 0x41F0000000000000
+; CHECK-NEXT:    [[TMP11:%.*]] = fptoui float [[TMP10]] to i32
+; CHECK-NEXT:    [[TMP12:%.*]] = zext i32 [[TMP11]] to i64
+; CHECK-NEXT:    [[TMP13:%.*]] = zext i32 [[TMP7]] to i64
+; CHECK-NEXT:    [[TMP14:%.*]] = mul i64 [[TMP12]], [[TMP13]]
+; CHECK-NEXT:    [[TMP15:%.*]] = trunc i64 [[TMP14]] to i32
+; CHECK-NEXT:    [[TMP16:%.*]] = lshr i64 [[TMP14]], 32
+; CHECK-NEXT:    [[TMP17:%.*]] = trunc i64 [[TMP16]] to i32
+; CHECK-NEXT:    [[TMP18:%.*]] = sub i32 0, [[TMP15]]
+; CHECK-NEXT:    [[TMP19:%.*]] = icmp eq i32 [[TMP17]], 0
+; CHECK-NEXT:    [[TMP20:%.*]] = select i1 [[TMP19]], i32 [[TMP18]], i32 [[TMP15]]
+; CHECK-NEXT:    [[TMP21:%.*]] = zext i32 [[TMP20]] to i64
+; CHECK-NEXT:    [[TMP22:%.*]] = zext i32 [[TMP11]] to i64
+; CHECK-NEXT:    [[TMP23:%.*]] = mul i64 [[TMP21]], [[TMP22]]
+; CHECK-NEXT:    [[TMP24:%.*]] = trunc i64 [[TMP23]] to i32
+; CHECK-NEXT:    [[TMP25:%.*]] = lshr i64 [[TMP23]], 32
+; CHECK-NEXT:    [[TMP26:%.*]] = trunc i64 [[TMP25]] to i32
+; CHECK-NEXT:    [[TMP27:%.*]] = add i32 [[TMP11]], [[TMP26]]
+; CHECK-NEXT:    [[TMP28:%.*]] = sub i32 [[TMP11]], [[TMP26]]
+; CHECK-NEXT:    [[TMP29:%.*]] = select i1 [[TMP19]], i32 [[TMP27]], i32 [[TMP28]]
+; CHECK-NEXT:    [[TMP30:%.*]] = zext i32 [[TMP29]] to i64
+; CHECK-NEXT:    [[TMP31:%.*]] = zext i32 [[TMP6]] to i64
+; CHECK-NEXT:    [[TMP32:%.*]] = mul i64 [[TMP30]], [[TMP31]]
+; CHECK-NEXT:    [[TMP33:%.*]] = trunc i64 [[TMP32]] to i32
+; CHECK-NEXT:    [[TMP34:%.*]] = lshr i64 [[TMP32]], 32
+; CHECK-NEXT:    [[TMP35:%.*]] = trunc i64 [[TMP34]] to i32
+; CHECK-NEXT:    [[TMP36:%.*]] = mul i32 [[TMP35]], [[TMP7]]
+; CHECK-NEXT:    [[TMP37:%.*]] = sub i32 [[TMP6]], [[TMP36]]
+; CHECK-NEXT:    [[TMP38:%.*]] = icmp uge i32 [[TMP37]], [[TMP7]]
+; CHECK-NEXT:    [[TMP39:%.*]] = select i1 [[TMP38]], i32 -1, i32 0
+; CHECK-NEXT:    [[TMP40:%.*]] = icmp uge i32 [[TMP6]], [[TMP36]]
+; CHECK-NEXT:    [[TMP41:%.*]] = select i1 [[TMP40]], i32 -1, i32 0
+; CHECK-NEXT:    [[TMP42:%.*]] = and i32 [[TMP39]], [[TMP41]]
+; CHECK-NEXT:    [[TMP43:%.*]] = icmp eq i32 [[TMP42]], 0
+; CHECK-NEXT:    [[TMP44:%.*]] = add i32 [[TMP35]], 1
+; CHECK-NEXT:    [[TMP45:%.*]] = sub i32 [[TMP35]], 1
+; CHECK-NEXT:    [[TMP46:%.*]] = select i1 [[TMP43]], i32 [[TMP35]], i32 [[TMP44]]
+; CHECK-NEXT:    [[TMP47:%.*]] = select i1 [[TMP40]], i32 [[TMP46]], i32 [[TMP45]]
+; CHECK-NEXT:    [[TMP48:%.*]] = xor i32 [[TMP47]], [[TMP3]]
+; CHECK-NEXT:    [[TMP49:%.*]] = sub i32 [[TMP48]], [[TMP3]]
+; CHECK-NEXT:    store i32 [[TMP49]], i32 addrspace(1)* [[OUT:%.*]]
+; CHECK-NEXT:    ret void
+;
+; GCN-LABEL: sdiv_i32_pow2_shl_denom:
+; GCN:       ; %bb.0:
+; GCN-NEXT:    s_load_dwordx2 s[2:3], s[0:1], 0xb
+; GCN-NEXT:    s_load_dwordx2 s[4:5], s[0:1], 0x9
+; GCN-NEXT:    s_mov_b32 s7, 0xf000
+; GCN-NEXT:    s_mov_b32 s6, -1
+; GCN-NEXT:    s_waitcnt lgkmcnt(0)
+; GCN-NEXT:    s_lshl_b32 s3, 0x1000, s3
+; GCN-NEXT:    s_ashr_i32 s8, s3, 31
+; GCN-NEXT:    s_add_i32 s3, s3, s8
+; GCN-NEXT:    s_xor_b32 s9, s3, s8
+; GCN-NEXT:    v_cvt_f32_u32_e32 v0, s9
+; GCN-NEXT:    s_ashr_i32 s3, s2, 31
+; GCN-NEXT:    s_add_i32 s2, s2, s3
+; GCN-NEXT:    s_xor_b32 s2, s2, s3
+; GCN-NEXT:    v_rcp_iflag_f32_e32 v0, v0
+; GCN-NEXT:    s_xor_b32 s3, s3, s8
+; GCN-NEXT:    v_mul_f32_e32 v0, 0x4f800000, v0
+; GCN-NEXT:    v_cvt_u32_f32_e32 v0, v0
+; GCN-NEXT:    v_mul_lo_u32 v1, v0, s9
+; GCN-NEXT:    v_mul_hi_u32 v2, v0, s9
+; GCN-NEXT:    v_sub_i32_e32 v3, vcc, 0, v1
+; GCN-NEXT:    v_cmp_eq_u32_e64 s[0:1], 0, v2
+; GCN-NEXT:    v_cndmask_b32_e64 v1, v1, v3, s[0:1]
+; GCN-NEXT:    v_mul_hi_u32 v1, v1, v0
+; GCN-NEXT:    v_add_i32_e32 v2, vcc, v1, v0
+; GCN-NEXT:    v_subrev_i32_e32 v0, vcc, v1, v0
+; GCN-NEXT:    v_cndmask_b32_e64 v0, v0, v2, s[0:1]
+; GCN-NEXT:    v_mul_hi_u32 v0, v0, s2
+; GCN-NEXT:    v_mul_lo_u32 v1, v0, s9
+; GCN-NEXT:    v_add_i32_e32 v2, vcc, 1, v0
+; GCN-NEXT:    v_add_i32_e32 v3, vcc, -1, v0
+; GCN-NEXT:    v_sub_i32_e32 v4, vcc, s2, v1
+; GCN-NEXT:    v_cmp_ge_u32_e32 vcc, s2, v1
+; GCN-NEXT:    v_cmp_le_u32_e64 s[0:1], s9, v4
+; GCN-NEXT:    s_and_b64 s[0:1], s[0:1], vcc
+; GCN-NEXT:    v_cndmask_b32_e64 v0, v0, v2, s[0:1]
+; GCN-NEXT:    v_cndmask_b32_e32 v0, v3, v0, vcc
+; GCN-NEXT:    v_xor_b32_e32 v0, s3, v0
+; GCN-NEXT:    v_subrev_i32_e32 v0, vcc, s3, v0
+; GCN-NEXT:    buffer_store_dword v0, off, s[4:7], 0
+; GCN-NEXT:    s_endpgm
+  %shl.y = shl i32 4096, %y
+  %r = sdiv i32 %x, %shl.y
+  store i32 %r, i32 addrspace(1)* %out
+  ret void
+}
+
+define amdgpu_kernel void @sdiv_v2i32_pow2k_denom(<2 x i32> addrspace(1)* %out, <2 x i32> %x) {
+; CHECK-LABEL: @sdiv_v2i32_pow2k_denom(
+; CHECK-NEXT:    [[TMP1:%.*]] = extractelement <2 x i32> [[X:%.*]], i64 0
+; CHECK-NEXT:    [[TMP2:%.*]] = sdiv i32 [[TMP1]], 4096
+; CHECK-NEXT:    [[TMP3:%.*]] = insertelement <2 x i32> undef, i32 [[TMP2]], i64 0
+; CHECK-NEXT:    [[TMP4:%.*]] = extractelement <2 x i32> [[X]], i64 1
+; CHECK-NEXT:    [[TMP5:%.*]] = sdiv i32 [[TMP4]], 4096
+; CHECK-NEXT:    [[TMP6:%.*]] = insertelement <2 x i32> [[TMP3]], i32 [[TMP5]], i64 1
+; CHECK-NEXT:    store <2 x i32> [[TMP6]], <2 x i32> addrspace(1)* [[OUT:%.*]]
+; CHECK-NEXT:    ret void
+;
+; GCN-LABEL: sdiv_v2i32_pow2k_denom:
+; GCN:       ; %bb.0:
+; GCN-NEXT:    s_load_dwordx2 s[4:5], s[0:1], 0x9
+; GCN-NEXT:    s_load_dwordx2 s[0:1], s[0:1], 0xb
+; GCN-NEXT:    s_mov_b32 s7, 0xf000
+; GCN-NEXT:    s_mov_b32 s6, -1
+; GCN-NEXT:    s_waitcnt lgkmcnt(0)
+; GCN-NEXT:    s_ashr_i32 s2, s0, 31
+; GCN-NEXT:    s_lshr_b32 s2, s2, 20
+; GCN-NEXT:    s_ashr_i32 s3, s1, 31
+; GCN-NEXT:    s_add_i32 s0, s0, s2
+; GCN-NEXT:    s_lshr_b32 s2, s3, 20
+; GCN-NEXT:    s_add_i32 s1, s1, s2
+; GCN-NEXT:    s_ashr_i32 s0, s0, 12
+; GCN-NEXT:    s_ashr_i32 s1, s1, 12
+; GCN-NEXT:    v_mov_b32_e32 v0, s0
+; GCN-NEXT:    v_mov_b32_e32 v1, s1
+; GCN-NEXT:    buffer_store_dwordx2 v[0:1], off, s[4:7], 0
+; GCN-NEXT:    s_endpgm
+  %r = sdiv <2 x i32> %x, <i32 4096, i32 4096>
+  store <2 x i32> %r, <2 x i32> addrspace(1)* %out
+  ret void
+}
+
+define amdgpu_kernel void @ssdiv_v2i32_mixed_pow2k_denom(<2 x i32> addrspace(1)* %out, <2 x i32> %x) {
+; CHECK-LABEL: @ssdiv_v2i32_mixed_pow2k_denom(
+; CHECK-NEXT:    [[TMP1:%.*]] = extractelement <2 x i32> [[X:%.*]], i64 0
+; CHECK-NEXT:    [[TMP2:%.*]] = sdiv i32 [[TMP1]], 4096
+; CHECK-NEXT:    [[TMP3:%.*]] = insertelement <2 x i32> undef, i32 [[TMP2]], i64 0
+; CHECK-NEXT:    [[TMP4:%.*]] = extractelement <2 x i32> [[X]], i64 1
+; CHECK-NEXT:    [[TMP5:%.*]] = sdiv i32 [[TMP4]], 4095
+; CHECK-NEXT:    [[TMP6:%.*]] = insertelement <2 x i32> [[TMP3]], i32 [[TMP5]], i64 1
+; CHECK-NEXT:    store <2 x i32> [[TMP6]], <2 x i32> addrspace(1)* [[OUT:%.*]]
+; CHECK-NEXT:    ret void
+;
+; GCN-LABEL: ssdiv_v2i32_mixed_pow2k_denom:
+; GCN:       ; %bb.0:
+; GCN-NEXT:    s_load_dwordx2 s[4:5], s[0:1], 0x9
+; GCN-NEXT:    s_load_dwordx2 s[0:1], s[0:1], 0xb
+; GCN-NEXT:    v_mov_b32_e32 v0, 0x80080081
+; GCN-NEXT:    s_mov_b32 s7, 0xf000
+; GCN-NEXT:    s_mov_b32 s6, -1
+; GCN-NEXT:    s_waitcnt lgkmcnt(0)
+; GCN-NEXT:    v_mul_hi_i32 v0, s1, v0
+; GCN-NEXT:    s_ashr_i32 s2, s0, 31
+; GCN-NEXT:    s_lshr_b32 s2, s2, 20
+; GCN-NEXT:    s_add_i32 s0, s0, s2
+; GCN-NEXT:    v_add_i32_e32 v0, vcc, s1, v0
+; GCN-NEXT:    v_lshrrev_b32_e32 v1, 31, v0
+; GCN-NEXT:    v_ashrrev_i32_e32 v0, 11, v0
+; GCN-NEXT:    s_ashr_i32 s0, s0, 12
+; GCN-NEXT:    v_add_i32_e32 v1, vcc, v1, v0
+; GCN-NEXT:    v_mov_b32_e32 v0, s0
+; GCN-NEXT:    buffer_store_dwordx2 v[0:1], off, s[4:7], 0
+; GCN-NEXT:    s_endpgm
+  %r = sdiv <2 x i32> %x, <i32 4096, i32 4095>
+  store <2 x i32> %r, <2 x i32> addrspace(1)* %out
+  ret void
+}
+
+define amdgpu_kernel void @sdiv_v2i32_pow2_shl_denom(<2 x i32> addrspace(1)* %out, <2 x i32> %x, <2 x i32> %y) {
+; CHECK-LABEL: @sdiv_v2i32_pow2_shl_denom(
+; CHECK-NEXT:    [[SHL_Y:%.*]] = shl <2 x i32> <i32 4096, i32 4096>, [[Y:%.*]]
+; CHECK-NEXT:    [[TMP1:%.*]] = extractelement <2 x i32> [[X:%.*]], i64 0
+; CHECK-NEXT:    [[TMP2:%.*]] = extractelement <2 x i32> [[SHL_Y]], i64 0
+; CHECK-NEXT:    [[TMP3:%.*]] = ashr i32 [[TMP1]], 31
+; CHECK-NEXT:    [[TMP4:%.*]] = ashr i32 [[TMP2]], 31
+; CHECK-NEXT:    [[TMP5:%.*]] = xor i32 [[TMP3]], [[TMP4]]
+; CHECK-NEXT:    [[TMP6:%.*]] = add i32 [[TMP1]], [[TMP3]]
+; CHECK-NEXT:    [[TMP7:%.*]] = add i32 [[TMP2]], [[TMP4]]
+; CHECK-NEXT:    [[TMP8:%.*]] = xor i32 [[TMP6]], [[TMP3]]
+; CHECK-NEXT:    [[TMP9:%.*]] = xor i32 [[TMP7]], [[TMP4]]
+; CHECK-NEXT:    [[TMP10:%.*]] = uitofp i32 [[TMP9]] to float
+; CHECK-NEXT:    [[TMP11:%.*]] = call fast float @llvm.amdgcn.rcp.f32(float [[TMP10]])
+; CHECK-NEXT:    [[TMP12:%.*]] = fmul fast float [[TMP11]], 0x41F0000000000000
+; CHECK-NEXT:    [[TMP13:%.*]] = fptoui float [[TMP12]] to i32
+; CHECK-NEXT:    [[TMP14:%.*]] = zext i32 [[TMP13]] to i64
+; CHECK-NEXT:    [[TMP15:%.*]] = zext i32 [[TMP9]] to i64
+; CHECK-NEXT:    [[TMP16:%.*]] = mul i64 [[TMP14]], [[TMP15]]
+; CHECK-NEXT:    [[TMP17:%.*]] = trunc i64 [[TMP16]] to i32
+; CHECK-NEXT:    [[TMP18:%.*]] = lshr i64 [[TMP16]], 32
+; CHECK-NEXT:    [[TMP19:%.*]] = trunc i64 [[TMP18]] to i32
+; CHECK-NEXT:    [[TMP20:%.*]] = sub i32 0, [[TMP17]]
+; CHECK-NEXT:    [[TMP21:%.*]] = icmp eq i32 [[TMP19]], 0
+; CHECK-NEXT:    [[TMP22:%.*]] = select i1 [[TMP21]], i32 [[TMP20]], i32 [[TMP17]]
+; CHECK-NEXT:    [[TMP23:%.*]] = zext i32 [[TMP22]] to i64
+; CHECK-NEXT:    [[TMP24:%.*]] = zext i32 [[TMP13]] to i64
+; CHECK-NEXT:    [[TMP25:%.*]] = mul i64 [[TMP23]], [[TMP24]]
+; CHECK-NEXT:    [[TMP26:%.*]] = trunc i64 [[TMP25]] to i32
+; CHECK-NEXT:    [[TMP27:%.*]] = lshr i64 [[TMP25]], 32
+; CHECK-NEXT:    [[TMP28:%.*]] = trunc i64 [[TMP27]] to i32
+; CHECK-NEXT:    [[TMP29:%.*]] = add i32 [[TMP13]], [[TMP28]]
+; CHECK-NEXT:    [[TMP30:%.*]] = sub i32 [[TMP13]], [[TMP28]]
+; CHECK-NEXT:    [[TMP31:%.*]] = select i1 [[TMP21]], i32 [[TMP29]], i32 [[TMP30]]
+; CHECK-NEXT:    [[TMP32:%.*]] = zext i32 [[TMP31]] to i64
+; CHECK-NEXT:    [[TMP33:%.*]] = zext i32 [[TMP8]] to i64
+; CHECK-NEXT:    [[TMP34:%.*]] = mul i64 [[TMP32]], [[TMP33]]
+; CHECK-NEXT:    [[TMP35:%.*]] = trunc i64 [[TMP34]] to i32
+; CHECK-NEXT:    [[TMP36:%.*]] = lshr i64 [[TMP34]], 32
+; CHECK-NEXT:    [[TMP37:%.*]] = trunc i64 [[TMP36]] to i32
+; CHECK-NEXT:    [[TMP38:%.*]] = mul i32 [[TMP37]], [[TMP9]]
+; CHECK-NEXT:    [[TMP39:%.*]] = sub i32 [[TMP8]], [[TMP38]]
+; CHECK-NEXT:    [[TMP40:%.*]] = icmp uge i32 [[TMP39]], [[TMP9]]
+; CHECK-NEXT:    [[TMP41:%.*]] = select i1 [[TMP40]], i32 -1, i32 0
+; CHECK-NEXT:    [[TMP42:%.*]] = icmp uge i32 [[TMP8]], [[TMP38]]
+; CHECK-NEXT:    [[TMP43:%.*]] = select i1 [[TMP42]], i32 -1, i32 0
+; CHECK-NEXT:    [[TMP44:%.*]] = and i32 [[TMP41]], [[TMP43]]
+; CHECK-NEXT:    [[TMP45:%.*]] = icmp eq i32 [[TMP44]], 0
+; CHECK-NEXT:    [[TMP46:%.*]] = add i32 [[TMP37]], 1
+; CHECK-NEXT:    [[TMP47:%.*]] = sub i32 [[TMP37]], 1
+; CHECK-NEXT:    [[TMP48:%.*]] = select i1 [[TMP45]], i32 [[TMP37]], i32 [[TMP46]]
+; CHECK-NEXT:    [[TMP49:%.*]] = select i1 [[TMP42]], i32 [[TMP48]], i32 [[TMP47]]
+; CHECK-NEXT:    [[TMP50:%.*]] = xor i32 [[TMP49]], [[TMP5]]
+; CHECK-NEXT:    [[TMP51:%.*]] = sub i32 [[TMP50]], [[TMP5]]
+; CHECK-NEXT:    [[TMP52:%.*]] = insertelement <2 x i32> undef, i32 [[TMP51]], i64 0
+; CHECK-NEXT:    [[TMP53:%.*]] = extractelement <2 x i32> [[X]], i64 1
+; CHECK-NEXT:    [[TMP54:%.*]] = extractelement <2 x i32> [[SHL_Y]], i64 1
+; CHECK-NEXT:    [[TMP55:%.*]] = ashr i32 [[TMP53]], 31
+; CHECK-NEXT:    [[TMP56:%.*]] = ashr i32 [[TMP54]], 31
+; CHECK-NEXT:    [[TMP57:%.*]] = xor i32 [[TMP55]], [[TMP56]]
+; CHECK-NEXT:    [[TMP58:%.*]] = add i32 [[TMP53]], [[TMP55]]
+; CHECK-NEXT:    [[TMP59:%.*]] = add i32 [[TMP54]], [[TMP56]]
+; CHECK-NEXT:    [[TMP60:%.*]] = xor i32 [[TMP58]], [[TMP55]]
+; CHECK-NEXT:    [[TMP61:%.*]] = xor i32 [[TMP59]], [[TMP56]]
+; CHECK-NEXT:    [[TMP62:%.*]] = uitofp i32 [[TMP61]] to float
+; CHECK-NEXT:    [[TMP63:%.*]] = call fast float @llvm.amdgcn.rcp.f32(float [[TMP62]])
+; CHECK-NEXT:    [[TMP64:%.*]] = fmul fast float [[TMP63]], 0x41F0000000000000
+; CHECK-NEXT:    [[TMP65:%.*]] = fptoui float [[TMP64]] to i32
+; CHECK-NEXT:    [[TMP66:%.*]] = zext i32 [[TMP65]] to i64
+; CHECK-NEXT:    [[TMP67:%.*]] = zext i32 [[TMP61]] to i64
+; CHECK-NEXT:    [[TMP68:%.*]] = mul i64 [[TMP66]], [[TMP67]]
+; CHECK-NEXT:    [[TMP69:%.*]] = trunc i64 [[TMP68]] to i32
+; CHECK-NEXT:    [[TMP70:%.*]] = lshr i64 [[TMP68]], 32
+; CHECK-NEXT:    [[TMP71:%.*]] = trunc i64 [[TMP70]] to i32
+; CHECK-NEXT:    [[TMP72:%.*]] = sub i32 0, [[TMP69]]
+; CHECK-NEXT:    [[TMP73:%.*]] = icmp eq i32 [[TMP71]], 0
+; CHECK-NEXT:    [[TMP74:%.*]] = select i1 [[TMP73]], i32 [[TMP72]], i32 [[TMP69]]
+; CHECK-NEXT:    [[TMP75:%.*]] = zext i32 [[TMP74]] to i64
+; CHECK-NEXT:    [[TMP76:%.*]] = zext i32 [[TMP65]] to i64
+; CHECK-NEXT:    [[TMP77:%.*]] = mul i64 [[TMP75]], [[TMP76]]
+; CHECK-NEXT:    [[TMP78:%.*]] = trunc i64 [[TMP77]] to i32
+; CHECK-NEXT:    [[TMP79:%.*]] = lshr i64 [[TMP77]], 32
+; CHECK-NEXT:    [[TMP80:%.*]] = trunc i64 [[TMP79]] to i32
+; CHECK-NEXT:    [[TMP81:%.*]] = add i32 [[TMP65]], [[TMP80]]
+; CHECK-NEXT:    [[TMP82:%.*]] = sub i32 [[TMP65]], [[TMP80]]
+; CHECK-NEXT:    [[TMP83:%.*]] = select i1 [[TMP73]], i32 [[TMP81]], i32 [[TMP82]]
+; CHECK-NEXT:    [[TMP84:%.*]] = zext i32 [[TMP83]] to i64
+; CHECK-NEXT:    [[TMP85:%.*]] = zext i32 [[TMP60]] to i64
+; CHECK-NEXT:    [[TMP86:%.*]] = mul i64 [[TMP84]], [[TMP85]]
+; CHECK-NEXT:    [[TMP87:%.*]] = trunc i64 [[TMP86]] to i32
+; CHECK-NEXT:    [[TMP88:%.*]] = lshr i64 [[TMP86]], 32
+; CHECK-NEXT:    [[TMP89:%.*]] = trunc i64 [[TMP88]] to i32
+; CHECK-NEXT:    [[TMP90:%.*]] = mul i32 [[TMP89]], [[TMP61]]
+; CHECK-NEXT:    [[TMP91:%.*]] = sub i32 [[TMP60]], [[TMP90]]
+; CHECK-NEXT:    [[TMP92:%.*]] = icmp uge i32 [[TMP91]], [[TMP61]]
+; CHECK-NEXT:    [[TMP93:%.*]] = select i1 [[TMP92]], i32 -1, i32 0
+; CHECK-NEXT:    [[TMP94:%.*]] = icmp uge i32 [[TMP60]], [[TMP90]]
+; CHECK-NEXT:    [[TMP95:%.*]] = select i1 [[TMP94]], i32 -1, i32 0
+; CHECK-NEXT:    [[TMP96:%.*]] = and i32 [[TMP93]], [[TMP95]]
+; CHECK-NEXT:    [[TMP97:%.*]] = icmp eq i32 [[TMP96]], 0
+; CHECK-NEXT:    [[TMP98:%.*]] = add i32 [[TMP89]], 1
+; CHECK-NEXT:    [[TMP99:%.*]] = sub i32 [[TMP89]], 1
+; CHECK-NEXT:    [[TMP100:%.*]] = select i1 [[TMP97]], i32 [[TMP89]], i32 [[TMP98]]
+; CHECK-NEXT:    [[TMP101:%.*]] = select i1 [[TMP94]], i32 [[TMP100]], i32 [[TMP99]]
+; CHECK-NEXT:    [[TMP102:%.*]] = xor i32 [[TMP101]], [[TMP57]]
+; CHECK-NEXT:    [[TMP103:%.*]] = sub i32 [[TMP102]], [[TMP57]]
+; CHECK-NEXT:    [[TMP104:%.*]] = insertelement <2 x i32> [[TMP52]], i32 [[TMP103]], i64 1
+; CHECK-NEXT:    store <2 x i32> [[TMP104]], <2 x i32> addrspace(1)* [[OUT:%.*]]
+; CHECK-NEXT:    ret void
+;
+; GCN-LABEL: sdiv_v2i32_pow2_shl_denom:
+; GCN:       ; %bb.0:
+; GCN-NEXT:    s_load_dwordx2 s[2:3], s[0:1], 0xd
+; GCN-NEXT:    s_movk_i32 s4, 0x1000
+; GCN-NEXT:    s_mov_b32 s14, 0x4f800000
+; GCN-NEXT:    s_load_dwordx2 s[8:9], s[0:1], 0x9
+; GCN-NEXT:    s_load_dwordx2 s[6:7], s[0:1], 0xb
+; GCN-NEXT:    s_mov_b32 s11, 0xf000
+; GCN-NEXT:    s_waitcnt lgkmcnt(0)
+; GCN-NEXT:    s_lshl_b32 s2, s4, s2
+; GCN-NEXT:    s_ashr_i32 s5, s2, 31
+; GCN-NEXT:    s_add_i32 s2, s2, s5
+; GCN-NEXT:    s_xor_b32 s13, s2, s5
+; GCN-NEXT:    v_cvt_f32_u32_e32 v0, s13
+; GCN-NEXT:    s_ashr_i32 s2, s6, 31
+; GCN-NEXT:    s_lshl_b32 s0, s4, s3
+; GCN-NEXT:    s_add_i32 s1, s6, s2
+; GCN-NEXT:    v_rcp_iflag_f32_e32 v0, v0
+; GCN-NEXT:    s_ashr_i32 s6, s0, 31
+; GCN-NEXT:    s_add_i32 s4, s0, s6
+; GCN-NEXT:    s_xor_b32 s3, s1, s2
+; GCN-NEXT:    v_mul_f32_e32 v0, s14, v0
+; GCN-NEXT:    v_cvt_u32_f32_e32 v0, v0
+; GCN-NEXT:    s_xor_b32 s15, s4, s6
+; GCN-NEXT:    s_xor_b32 s12, s2, s5
+; GCN-NEXT:    s_mov_b32 s10, -1
+; GCN-NEXT:    v_mul_lo_u32 v1, v0, s13
+; GCN-NEXT:    v_mul_hi_u32 v2, v0, s13
+; GCN-NEXT:    v_sub_i32_e32 v3, vcc, 0, v1
+; GCN-NEXT:    v_cmp_eq_u32_e64 s[0:1], 0, v2
+; GCN-NEXT:    v_cndmask_b32_e64 v1, v1, v3, s[0:1]
+; GCN-NEXT:    v_mul_hi_u32 v1, v1, v0
+; GCN-NEXT:    v_cvt_f32_u32_e32 v2, s15
+; GCN-NEXT:    v_add_i32_e32 v3, vcc, v1, v0
+; GCN-NEXT:    v_subrev_i32_e32 v0, vcc, v1, v0
+; GCN-NEXT:    v_cndmask_b32_e64 v0, v0, v3, s[0:1]
+; GCN-NEXT:    v_rcp_iflag_f32_e32 v1, v2
+; GCN-NEXT:    v_mul_hi_u32 v0, v0, s3
+; GCN-NEXT:    v_mul_f32_e32 v1, s14, v1
+; GCN-NEXT:    v_mul_lo_u32 v2, v0, s13
+; GCN-NEXT:    v_cvt_u32_f32_e32 v1, v1
+; GCN-NEXT:    v_add_i32_e32 v3, vcc, -1, v0
+; GCN-NEXT:    v_sub_i32_e32 v4, vcc, s3, v2
+; GCN-NEXT:    v_cmp_le_u32_e64 s[0:1], s13, v4
+; GCN-NEXT:    v_mul_lo_u32 v4, v1, s15
+; GCN-NEXT:    v_mul_hi_u32 v5, v1, s15
+; GCN-NEXT:    s_ashr_i32 s13, s7, 31
+; GCN-NEXT:    s_add_i32 s7, s7, s13
+; GCN-NEXT:    v_sub_i32_e32 v6, vcc, 0, v4
+; GCN-NEXT:    v_cmp_eq_u32_e64 s[4:5], 0, v5
+; GCN-NEXT:    v_cndmask_b32_e64 v4, v4, v6, s[4:5]
+; GCN-NEXT:    v_mul_hi_u32 v4, v4, v1
+; GCN-NEXT:    s_xor_b32 s7, s7, s13
+; GCN-NEXT:    v_cmp_ge_u32_e64 s[2:3], s3, v2
+; GCN-NEXT:    v_add_i32_e32 v2, vcc, 1, v0
+; GCN-NEXT:    v_add_i32_e32 v5, vcc, v4, v1
+; GCN-NEXT:    v_subrev_i32_e32 v1, vcc, v4, v1
+; GCN-NEXT:    v_cndmask_b32_e64 v1, v1, v5, s[4:5]
+; GCN-NEXT:    v_mul_hi_u32 v1, v1, s7
+; GCN-NEXT:    s_and_b64 vcc, s[0:1], s[2:3]
+; GCN-NEXT:    v_cndmask_b32_e32 v0, v0, v2, vcc
+; GCN-NEXT:    v_cndmask_b32_e64 v0, v3, v0, s[2:3]
+; GCN-NEXT:    v_mul_lo_u32 v2, v1, s15
+; GCN-NEXT:    v_xor_b32_e32 v0, s12, v0
+; GCN-NEXT:    v_subrev_i32_e32 v0, vcc, s12, v0
+; GCN-NEXT:    s_xor_b32 s4, s13, s6
+; GCN-NEXT:    v_sub_i32_e32 v3, vcc, s7, v2
+; GCN-NEXT:    v_cmp_le_u32_e64 s[0:1], s15, v3
+; GCN-NEXT:    v_cmp_ge_u32_e64 s[2:3], s7, v2
+; GCN-NEXT:    v_add_i32_e32 v3, vcc, -1, v1
+; GCN-NEXT:    v_add_i32_e32 v2, vcc, 1, v1
+; GCN-NEXT:    s_and_b64 vcc, s[0:1], s[2:3]
+; GCN-NEXT:    v_cndmask_b32_e32 v1, v1, v2, vcc
+; GCN-NEXT:    v_cndmask_b32_e64 v1, v3, v1, s[2:3]
+; GCN-NEXT:    v_xor_b32_e32 v1, s4, v1
+; GCN-NEXT:    v_subrev_i32_e32 v1, vcc, s4, v1
+; GCN-NEXT:    buffer_store_dwordx2 v[0:1], off, s[8:11], 0
+; GCN-NEXT:    s_endpgm
+  %shl.y = shl <2 x i32> <i32 4096, i32 4096>, %y
+  %r = sdiv <2 x i32> %x, %shl.y
+  store <2 x i32> %r, <2 x i32> addrspace(1)* %out
+  ret void
+}
+
+define amdgpu_kernel void @srem_i32_oddk_denom(i32 addrspace(1)* %out, i32 %x) {
+; CHECK-LABEL: @srem_i32_oddk_denom(
+; CHECK-NEXT:    [[R:%.*]] = srem i32 [[X:%.*]], 1235195
+; CHECK-NEXT:    store i32 [[R]], i32 addrspace(1)* [[OUT:%.*]]
+; CHECK-NEXT:    ret void
+;
+; GCN-LABEL: srem_i32_oddk_denom:
+; GCN:       ; %bb.0:
+; GCN-NEXT:    s_load_dwordx2 s[4:5], s[0:1], 0x9
+; GCN-NEXT:    s_load_dword s0, s[0:1], 0xb
+; GCN-NEXT:    v_mov_b32_e32 v0, 0xd9528441
+; GCN-NEXT:    s_mov_b32 s7, 0xf000
+; GCN-NEXT:    s_mov_b32 s6, -1
+; GCN-NEXT:    s_waitcnt lgkmcnt(0)
+; GCN-NEXT:    v_mul_hi_i32 v0, s0, v0
+; GCN-NEXT:    v_add_i32_e32 v0, vcc, s0, v0
+; GCN-NEXT:    v_lshrrev_b32_e32 v1, 31, v0
+; GCN-NEXT:    v_ashrrev_i32_e32 v0, 20, v0
+; GCN-NEXT:    v_add_i32_e32 v0, vcc, v1, v0
+; GCN-NEXT:    v_mul_i32_i24_e32 v0, 0x12d8fb, v0
+; GCN-NEXT:    v_sub_i32_e32 v0, vcc, s0, v0
+; GCN-NEXT:    buffer_store_dword v0, off, s[4:7], 0
+; GCN-NEXT:    s_endpgm
+  %r = srem i32 %x, 1235195
+  store i32 %r, i32 addrspace(1)* %out
+  ret void
+}
+
+define amdgpu_kernel void @srem_i32_pow2k_denom(i32 addrspace(1)* %out, i32 %x) {
+; CHECK-LABEL: @srem_i32_pow2k_denom(
+; CHECK-NEXT:    [[R:%.*]] = srem i32 [[X:%.*]], 4096
+; CHECK-NEXT:    store i32 [[R]], i32 addrspace(1)* [[OUT:%.*]]
+; CHECK-NEXT:    ret void
+;
+; GCN-LABEL: srem_i32_pow2k_denom:
+; GCN:       ; %bb.0:
+; GCN-NEXT:    s_load_dwordx2 s[4:5], s[0:1], 0x9
+; GCN-NEXT:    s_load_dword s0, s[0:1], 0xb
+; GCN-NEXT:    s_mov_b32 s7, 0xf000
+; GCN-NEXT:    s_mov_b32 s6, -1
+; GCN-NEXT:    s_waitcnt lgkmcnt(0)
+; GCN-NEXT:    s_ashr_i32 s1, s0, 31
+; GCN-NEXT:    s_lshr_b32 s1, s1, 20
+; GCN-NEXT:    s_add_i32 s1, s0, s1
+; GCN-NEXT:    s_and_b32 s1, s1, 0xfffff000
+; GCN-NEXT:    s_sub_i32 s0, s0, s1
+; GCN-NEXT:    v_mov_b32_e32 v0, s0
+; GCN-NEXT:    buffer_store_dword v0, off, s[4:7], 0
+; GCN-NEXT:    s_endpgm
+  %r = srem i32 %x, 4096
+  store i32 %r, i32 addrspace(1)* %out
+  ret void
+}
+
+define amdgpu_kernel void @srem_i32_pow2_shl_denom(i32 addrspace(1)* %out, i32 %x, i32 %y) {
+; CHECK-LABEL: @srem_i32_pow2_shl_denom(
+; CHECK-NEXT:    [[SHL_Y:%.*]] = shl i32 4096, [[Y:%.*]]
+; CHECK-NEXT:    [[TMP1:%.*]] = ashr i32 [[X:%.*]], 31
+; CHECK-NEXT:    [[TMP2:%.*]] = ashr i32 [[SHL_Y]], 31
+; CHECK-NEXT:    [[TMP3:%.*]] = add i32 [[X]], [[TMP1]]
+; CHECK-NEXT:    [[TMP4:%.*]] = add i32 [[SHL_Y]], [[TMP2]]
+; CHECK-NEXT:    [[TMP5:%.*]] = xor i32 [[TMP3]], [[TMP1]]
+; CHECK-NEXT:    [[TMP6:%.*]] = xor i32 [[TMP4]], [[TMP2]]
+; CHECK-NEXT:    [[TMP7:%.*]] = uitofp i32 [[TMP6]] to float
+; CHECK-NEXT:    [[TMP8:%.*]] = call fast float @llvm.amdgcn.rcp.f32(float [[TMP7]])
+; CHECK-NEXT:    [[TMP9:%.*]] = fmul fast float [[TMP8]], 0x41F0000000000000
+; CHECK-NEXT:    [[TMP10:%.*]] = fptoui float [[TMP9]] to i32
+; CHECK-NEXT:    [[TMP11:%.*]] = zext i32 [[TMP10]] to i64
+; CHECK-NEXT:    [[TMP12:%.*]] = zext i32 [[TMP6]] to i64
+; CHECK-NEXT:    [[TMP13:%.*]] = mul i64 [[TMP11]], [[TMP12]]
+; CHECK-NEXT:    [[TMP14:%.*]] = trunc i64 [[TMP13]] to i32
+; CHECK-NEXT:    [[TMP15:%.*]] = lshr i64 [[TMP13]], 32
+; CHECK-NEXT:    [[TMP16:%.*]] = trunc i64 [[TMP15]] to i32
+; CHECK-NEXT:    [[TMP17:%.*]] = sub i32 0, [[TMP14]]
+; CHECK-NEXT:    [[TMP18:%.*]] = icmp eq i32 [[TMP16]], 0
+; CHECK-NEXT:    [[TMP19:%.*]] = select i1 [[TMP18]], i32 [[TMP17]], i32 [[TMP14]]
+; CHECK-NEXT:    [[TMP20:%.*]] = zext i32 [[TMP19]] to i64
+; CHECK-NEXT:    [[TMP21:%.*]] = zext i32 [[TMP10]] to i64
+; CHECK-NEXT:    [[TMP22:%.*]] = mul i64 [[TMP20]], [[TMP21]]
+; CHECK-NEXT:    [[TMP23:%.*]] = trunc i64 [[TMP22]] to i32
+; CHECK-NEXT:    [[TMP24:%.*]] = lshr i64 [[TMP22]], 32
+; CHECK-NEXT:    [[TMP25:%.*]] = trunc i64 [[TMP24]] to i32
+; CHECK-NEXT:    [[TMP26:%.*]] = add i32 [[TMP10]], [[TMP25]]
+; CHECK-NEXT:    [[TMP27:%.*]] = sub i32 [[TMP10]], [[TMP25]]
+; CHECK-NEXT:    [[TMP28:%.*]] = select i1 [[TMP18]], i32 [[TMP26]], i32 [[TMP27]]
+; CHECK-NEXT:    [[TMP29:%.*]] = zext i32 [[TMP28]] to i64
+; CHECK-NEXT:    [[TMP30:%.*]] = zext i32 [[TMP5]] to i64
+; CHECK-NEXT:    [[TMP31:%.*]] = mul i64 [[TMP29]], [[TMP30]]
+; CHECK-NEXT:    [[TMP32:%.*]] = trunc i64 [[TMP31]] to i32
+; CHECK-NEXT:    [[TMP33:%.*]] = lshr i64 [[TMP31]], 32
+; CHECK-NEXT:    [[TMP34:%.*]] = trunc i64 [[TMP33]] to i32
+; CHECK-NEXT:    [[TMP35:%.*]] = mul i32 [[TMP34]], [[TMP6]]
+; CHECK-NEXT:    [[TMP36:%.*]] = sub i32 [[TMP5]], [[TMP35]]
+; CHECK-NEXT:    [[TMP37:%.*]] = icmp uge i32 [[TMP36]], [[TMP6]]
+; CHECK-NEXT:    [[TMP38:%.*]] = select i1 [[TMP37]], i32 -1, i32 0
+; CHECK-NEXT:    [[TMP39:%.*]] = icmp uge i32 [[TMP5]], [[TMP35]]
+; CHECK-NEXT:    [[TMP40:%.*]] = select i1 [[TMP39]], i32 -1, i32 0
+; CHECK-NEXT:    [[TMP41:%.*]] = and i32 [[TMP38]], [[TMP40]]
+; CHECK-NEXT:    [[TMP42:%.*]] = icmp eq i32 [[TMP41]], 0
+; CHECK-NEXT:    [[TMP43:%.*]] = sub i32 [[TMP36]], [[TMP6]]
+; CHECK-NEXT:    [[TMP44:%.*]] = add i32 [[TMP36]], [[TMP6]]
+; CHECK-NEXT:    [[TMP45:%.*]] = select i1 [[TMP42]], i32 [[TMP36]], i32 [[TMP43]]
+; CHECK-NEXT:    [[TMP46:%.*]] = select i1 [[TMP39]], i32 [[TMP45]], i32 [[TMP44]]
+; CHECK-NEXT:    [[TMP47:%.*]] = xor i32 [[TMP46]], [[TMP1]]
+; CHECK-NEXT:    [[TMP48:%.*]] = sub i32 [[TMP47]], [[TMP1]]
+; CHECK-NEXT:    store i32 [[TMP48]], i32 addrspace(1)* [[OUT:%.*]]
+; CHECK-NEXT:    ret void
+;
+; GCN-LABEL: srem_i32_pow2_shl_denom:
+; GCN:       ; %bb.0:
+; GCN-NEXT:    s_load_dwordx2 s[4:5], s[0:1], 0xb
+; GCN-NEXT:    s_mov_b32 s7, 0xf000
+; GCN-NEXT:    s_mov_b32 s6, -1
+; GCN-NEXT:    s_waitcnt lgkmcnt(0)
+; GCN-NEXT:    s_lshl_b32 s2, 0x1000, s5
+; GCN-NEXT:    s_ashr_i32 s3, s2, 31
+; GCN-NEXT:    s_add_i32 s2, s2, s3
+; GCN-NEXT:    s_xor_b32 s10, s2, s3
+; GCN-NEXT:    v_cvt_f32_u32_e32 v0, s10
+; GCN-NEXT:    s_ashr_i32 s8, s4, 31
+; GCN-NEXT:    s_add_i32 s4, s4, s8
+; GCN-NEXT:    s_xor_b32 s9, s4, s8
+; GCN-NEXT:    v_rcp_iflag_f32_e32 v0, v0
+; GCN-NEXT:    s_load_dwordx2 s[4:5], s[0:1], 0x9
+; GCN-NEXT:    v_mul_f32_e32 v0, 0x4f800000, v0
+; GCN-NEXT:    v_cvt_u32_f32_e32 v0, v0
+; GCN-NEXT:    v_mul_lo_u32 v1, v0, s10
+; GCN-NEXT:    v_mul_hi_u32 v2, v0, s10
+; GCN-NEXT:    v_sub_i32_e32 v3, vcc, 0, v1
+; GCN-NEXT:    v_cmp_eq_u32_e64 s[2:3], 0, v2
+; GCN-NEXT:    v_cndmask_b32_e64 v1, v1, v3, s[2:3]
+; GCN-NEXT:    v_mul_hi_u32 v1, v1, v0
+; GCN-NEXT:    v_add_i32_e32 v2, vcc, v1, v0
+; GCN-NEXT:    v_subrev_i32_e32 v0, vcc, v1, v0
+; GCN-NEXT:    v_cndmask_b32_e64 v0, v0, v2, s[2:3]
+; GCN-NEXT:    v_mul_hi_u32 v0, v0, s9
+; GCN-NEXT:    v_mul_lo_u32 v0, v0, s10
+; GCN-NEXT:    v_sub_i32_e32 v1, vcc, s9, v0
+; GCN-NEXT:    v_cmp_ge_u32_e64 s[2:3], s9, v0
+; GCN-NEXT:    v_cmp_le_u32_e64 s[0:1], s10, v1
+; GCN-NEXT:    v_add_i32_e32 v2, vcc, s10, v1
+; GCN-NEXT:    v_subrev_i32_e32 v0, vcc, s10, v1
+; GCN-NEXT:    s_and_b64 vcc, s[0:1], s[2:3]
+; GCN-NEXT:    v_cndmask_b32_e32 v0, v1, v0, vcc
+; GCN-NEXT:    v_cndmask_b32_e64 v0, v2, v0, s[2:3]
+; GCN-NEXT:    v_xor_b32_e32 v0, s8, v0
+; GCN-NEXT:    v_subrev_i32_e32 v0, vcc, s8, v0
+; GCN-NEXT:    s_waitcnt lgkmcnt(0)
+; GCN-NEXT:    buffer_store_dword v0, off, s[4:7], 0
+; GCN-NEXT:    s_endpgm
+  %shl.y = shl i32 4096, %y
+  %r = srem i32 %x, %shl.y
+  store i32 %r, i32 addrspace(1)* %out
+  ret void
+}
+
+define amdgpu_kernel void @srem_v2i32_pow2k_denom(<2 x i32> addrspace(1)* %out, <2 x i32> %x) {
+; CHECK-LABEL: @srem_v2i32_pow2k_denom(
+; CHECK-NEXT:    [[TMP1:%.*]] = extractelement <2 x i32> [[X:%.*]], i64 0
+; CHECK-NEXT:    [[TMP2:%.*]] = srem i32 [[TMP1]], 4096
+; CHECK-NEXT:    [[TMP3:%.*]] = insertelement <2 x i32> undef, i32 [[TMP2]], i64 0
+; CHECK-NEXT:    [[TMP4:%.*]] = extractelement <2 x i32> [[X]], i64 1
+; CHECK-NEXT:    [[TMP5:%.*]] = srem i32 [[TMP4]], 4096
+; CHECK-NEXT:    [[TMP6:%.*]] = insertelement <2 x i32> [[TMP3]], i32 [[TMP5]], i64 1
+; CHECK-NEXT:    store <2 x i32> [[TMP6]], <2 x i32> addrspace(1)* [[OUT:%.*]]
+; CHECK-NEXT:    ret void
+;
+; GCN-LABEL: srem_v2i32_pow2k_denom:
+; GCN:       ; %bb.0:
+; GCN-NEXT:    s_load_dwordx2 s[4:5], s[0:1], 0x9
+; GCN-NEXT:    s_load_dwordx2 s[0:1], s[0:1], 0xb
+; GCN-NEXT:    s_movk_i32 s2, 0xf000
+; GCN-NEXT:    s_mov_b32 s7, 0xf000
+; GCN-NEXT:    s_mov_b32 s6, -1
+; GCN-NEXT:    s_waitcnt lgkmcnt(0)
+; GCN-NEXT:    s_ashr_i32 s3, s0, 31
+; GCN-NEXT:    s_lshr_b32 s3, s3, 20
+; GCN-NEXT:    s_add_i32 s3, s0, s3
+; GCN-NEXT:    s_and_b32 s3, s3, s2
+; GCN-NEXT:    s_sub_i32 s0, s0, s3
+; GCN-NEXT:    s_ashr_i32 s3, s1, 31
+; GCN-NEXT:    s_lshr_b32 s3, s3, 20
+; GCN-NEXT:    s_add_i32 s3, s1, s3
+; GCN-NEXT:    s_and_b32 s2, s3, s2
+; GCN-NEXT:    s_sub_i32 s1, s1, s2
+; GCN-NEXT:    v_mov_b32_e32 v0, s0
+; GCN-NEXT:    v_mov_b32_e32 v1, s1
+; GCN-NEXT:    buffer_store_dwordx2 v[0:1], off, s[4:7], 0
+; GCN-NEXT:    s_endpgm
+  %r = srem <2 x i32> %x, <i32 4096, i32 4096>
+  store <2 x i32> %r, <2 x i32> addrspace(1)* %out
+  ret void
+}
+
+define amdgpu_kernel void @srem_v2i32_pow2_shl_denom(<2 x i32> addrspace(1)* %out, <2 x i32> %x, <2 x i32> %y) {
+; CHECK-LABEL: @srem_v2i32_pow2_shl_denom(
+; CHECK-NEXT:    [[SHL_Y:%.*]] = shl <2 x i32> <i32 4096, i32 4096>, [[Y:%.*]]
+; CHECK-NEXT:    [[TMP1:%.*]] = extractelement <2 x i32> [[X:%.*]], i64 0
+; CHECK-NEXT:    [[TMP2:%.*]] = extractelement <2 x i32> [[SHL_Y]], i64 0
+; CHECK-NEXT:    [[TMP3:%.*]] = ashr i32 [[TMP1]], 31
+; CHECK-NEXT:    [[TMP4:%.*]] = ashr i32 [[TMP2]], 31
+; CHECK-NEXT:    [[TMP5:%.*]] = add i32 [[TMP1]], [[TMP3]]
+; CHECK-NEXT:    [[TMP6:%.*]] = add i32 [[TMP2]], [[TMP4]]
+; CHECK-NEXT:    [[TMP7:%.*]] = xor i32 [[TMP5]], [[TMP3]]
+; CHECK-NEXT:    [[TMP8:%.*]] = xor i32 [[TMP6]], [[TMP4]]
+; CHECK-NEXT:    [[TMP9:%.*]] = uitofp i32 [[TMP8]] to float
+; CHECK-NEXT:    [[TMP10:%.*]] = call fast float @llvm.amdgcn.rcp.f32(float [[TMP9]])
+; CHECK-NEXT:    [[TMP11:%.*]] = fmul fast float [[TMP10]], 0x41F0000000000000
+; CHECK-NEXT:    [[TMP12:%.*]] = fptoui float [[TMP11]] to i32
+; CHECK-NEXT:    [[TMP13:%.*]] = zext i32 [[TMP12]] to i64
+; CHECK-NEXT:    [[TMP14:%.*]] = zext i32 [[TMP8]] to i64
+; CHECK-NEXT:    [[TMP15:%.*]] = mul i64 [[TMP13]], [[TMP14]]
+; CHECK-NEXT:    [[TMP16:%.*]] = trunc i64 [[TMP15]] to i32
+; CHECK-NEXT:    [[TMP17:%.*]] = lshr i64 [[TMP15]], 32
+; CHECK-NEXT:    [[TMP18:%.*]] = trunc i64 [[TMP17]] to i32
+; CHECK-NEXT:    [[TMP19:%.*]] = sub i32 0, [[TMP16]]
+; CHECK-NEXT:    [[TMP20:%.*]] = icmp eq i32 [[TMP18]], 0
+; CHECK-NEXT:    [[TMP21:%.*]] = select i1 [[TMP20]], i32 [[TMP19]], i32 [[TMP16]]
+; CHECK-NEXT:    [[TMP22:%.*]] = zext i32 [[TMP21]] to i64
+; CHECK-NEXT:    [[TMP23:%.*]] = zext i32 [[TMP12]] to i64
+; CHECK-NEXT:    [[TMP24:%.*]] = mul i64 [[TMP22]], [[TMP23]]
+; CHECK-NEXT:    [[TMP25:%.*]] = trunc i64 [[TMP24]] to i32
+; CHECK-NEXT:    [[TMP26:%.*]] = lshr i64 [[TMP24]], 32
+; CHECK-NEXT:    [[TMP27:%.*]] = trunc i64 [[TMP26]] to i32
+; CHECK-NEXT:    [[TMP28:%.*]] = add i32 [[TMP12]], [[TMP27]]
+; CHECK-NEXT:    [[TMP29:%.*]] = sub i32 [[TMP12]], [[TMP27]]
+; CHECK-NEXT:    [[TMP30:%.*]] = select i1 [[TMP20]], i32 [[TMP28]], i32 [[TMP29]]
+; CHECK-NEXT:    [[TMP31:%.*]] = zext i32 [[TMP30]] to i64
+; CHECK-NEXT:    [[TMP32:%.*]] = zext i32 [[TMP7]] to i64
+; CHECK-NEXT:    [[TMP33:%.*]] = mul i64 [[TMP31]], [[TMP32]]
+; CHECK-NEXT:    [[TMP34:%.*]] = trunc i64 [[TMP33]] to i32
+; CHECK-NEXT:    [[TMP35:%.*]] = lshr i64 [[TMP33]], 32
+; CHECK-NEXT:    [[TMP36:%.*]] = trunc i64 [[TMP35]] to i32
+; CHECK-NEXT:    [[TMP37:%.*]] = mul i32 [[TMP36]], [[TMP8]]
+; CHECK-NEXT:    [[TMP38:%.*]] = sub i32 [[TMP7]], [[TMP37]]
+; CHECK-NEXT:    [[TMP39:%.*]] = icmp uge i32 [[TMP38]], [[TMP8]]
+; CHECK-NEXT:    [[TMP40:%.*]] = select i1 [[TMP39]], i32 -1, i32 0
+; CHECK-NEXT:    [[TMP41:%.*]] = icmp uge i32 [[TMP7]], [[TMP37]]
+; CHECK-NEXT:    [[TMP42:%.*]] = select i1 [[TMP41]], i32 -1, i32 0
+; CHECK-NEXT:    [[TMP43:%.*]] = and i32 [[TMP40]], [[TMP42]]
+; CHECK-NEXT:    [[TMP44:%.*]] = icmp eq i32 [[TMP43]], 0
+; CHECK-NEXT:    [[TMP45:%.*]] = sub i32 [[TMP38]], [[TMP8]]
+; CHECK-NEXT:    [[TMP46:%.*]] = add i32 [[TMP38]], [[TMP8]]
+; CHECK-NEXT:    [[TMP47:%.*]] = select i1 [[TMP44]], i32 [[TMP38]], i32 [[TMP45]]
+; CHECK-NEXT:    [[TMP48:%.*]] = select i1 [[TMP41]], i32 [[TMP47]], i32 [[TMP46]]
+; CHECK-NEXT:    [[TMP49:%.*]] = xor i32 [[TMP48]], [[TMP3]]
+; CHECK-NEXT:    [[TMP50:%.*]] = sub i32 [[TMP49]], [[TMP3]]
+; CHECK-NEXT:    [[TMP51:%.*]] = insertelement <2 x i32> undef, i32 [[TMP50]], i64 0
+; CHECK-NEXT:    [[TMP52:%.*]] = extractelement <2 x i32> [[X]], i64 1
+; CHECK-NEXT:    [[TMP53:%.*]] = extractelement <2 x i32> [[SHL_Y]], i64 1
+; CHECK-NEXT:    [[TMP54:%.*]] = ashr i32 [[TMP52]], 31
+; CHECK-NEXT:    [[TMP55:%.*]] = ashr i32 [[TMP53]], 31
+; CHECK-NEXT:    [[TMP56:%.*]] = add i32 [[TMP52]], [[TMP54]]
+; CHECK-NEXT:    [[TMP57:%.*]] = add i32 [[TMP53]], [[TMP55]]
+; CHECK-NEXT:    [[TMP58:%.*]] = xor i32 [[TMP56]], [[TMP54]]
+; CHECK-NEXT:    [[TMP59:%.*]] = xor i32 [[TMP57]], [[TMP55]]
+; CHECK-NEXT:    [[TMP60:%.*]] = uitofp i32 [[TMP59]] to float
+; CHECK-NEXT:    [[TMP61:%.*]] = call fast float @llvm.amdgcn.rcp.f32(float [[TMP60]])
+; CHECK-NEXT:    [[TMP62:%.*]] = fmul fast float [[TMP61]], 0x41F0000000000000
+; CHECK-NEXT:    [[TMP63:%.*]] = fptoui float [[TMP62]] to i32
+; CHECK-NEXT:    [[TMP64:%.*]] = zext i32 [[TMP63]] to i64
+; CHECK-NEXT:    [[TMP65:%.*]] = zext i32 [[TMP59]] to i64
+; CHECK-NEXT:    [[TMP66:%.*]] = mul i64 [[TMP64]], [[TMP65]]
+; CHECK-NEXT:    [[TMP67:%.*]] = trunc i64 [[TMP66]] to i32
+; CHECK-NEXT:    [[TMP68:%.*]] = lshr i64 [[TMP66]], 32
+; CHECK-NEXT:    [[TMP69:%.*]] = trunc i64 [[TMP68]] to i32
+; CHECK-NEXT:    [[TMP70:%.*]] = sub i32 0, [[TMP67]]
+; CHECK-NEXT:    [[TMP71:%.*]] = icmp eq i32 [[TMP69]], 0
+; CHECK-NEXT:    [[TMP72:%.*]] = select i1 [[TMP71]], i32 [[TMP70]], i32 [[TMP67]]
+; CHECK-NEXT:    [[TMP73:%.*]] = zext i32 [[TMP72]] to i64
+; CHECK-NEXT:    [[TMP74:%.*]] = zext i32 [[TMP63]] to i64
+; CHECK-NEXT:    [[TMP75:%.*]] = mul i64 [[TMP73]], [[TMP74]]
+; CHECK-NEXT:    [[TMP76:%.*]] = trunc i64 [[TMP75]] to i32
+; CHECK-NEXT:    [[TMP77:%.*]] = lshr i64 [[TMP75]], 32
+; CHECK-NEXT:    [[TMP78:%.*]] = trunc i64 [[TMP77]] to i32
+; CHECK-NEXT:    [[TMP79:%.*]] = add i32 [[TMP63]], [[TMP78]]
+; CHECK-NEXT:    [[TMP80:%.*]] = sub i32 [[TMP63]], [[TMP78]]
+; CHECK-NEXT:    [[TMP81:%.*]] = select i1 [[TMP71]], i32 [[TMP79]], i32 [[TMP80]]
+; CHECK-NEXT:    [[TMP82:%.*]] = zext i32 [[TMP81]] to i64
+; CHECK-NEXT:    [[TMP83:%.*]] = zext i32 [[TMP58]] to i64
+; CHECK-NEXT:    [[TMP84:%.*]] = mul i64 [[TMP82]], [[TMP83]]
+; CHECK-NEXT:    [[TMP85:%.*]] = trunc i64 [[TMP84]] to i32
+; CHECK-NEXT:    [[TMP86:%.*]] = lshr i64 [[TMP84]], 32
+; CHECK-NEXT:    [[TMP87:%.*]] = trunc i64 [[TMP86]] to i32
+; CHECK-NEXT:    [[TMP88:%.*]] = mul i32 [[TMP87]], [[TMP59]]
+; CHECK-NEXT:    [[TMP89:%.*]] = sub i32 [[TMP58]], [[TMP88]]
+; CHECK-NEXT:    [[TMP90:%.*]] = icmp uge i32 [[TMP89]], [[TMP59]]
+; CHECK-NEXT:    [[TMP91:%.*]] = select i1 [[TMP90]], i32 -1, i32 0
+; CHECK-NEXT:    [[TMP92:%.*]] = icmp uge i32 [[TMP58]], [[TMP88]]
+; CHECK-NEXT:    [[TMP93:%.*]] = select i1 [[TMP92]], i32 -1, i32 0
+; CHECK-NEXT:    [[TMP94:%.*]] = and i32 [[TMP91]], [[TMP93]]
+; CHECK-NEXT:    [[TMP95:%.*]] = icmp eq i32 [[TMP94]], 0
+; CHECK-NEXT:    [[TMP96:%.*]] = sub i32 [[TMP89]], [[TMP59]]
+; CHECK-NEXT:    [[TMP97:%.*]] = add i32 [[TMP89]], [[TMP59]]
+; CHECK-NEXT:    [[TMP98:%.*]] = select i1 [[TMP95]], i32 [[TMP89]], i32 [[TMP96]]
+; CHECK-NEXT:    [[TMP99:%.*]] = select i1 [[TMP92]], i32 [[TMP98]], i32 [[TMP97]]
+; CHECK-NEXT:    [[TMP100:%.*]] = xor i32 [[TMP99]], [[TMP54]]
+; CHECK-NEXT:    [[TMP101:%.*]] = sub i32 [[TMP100]], [[TMP54]]
+; CHECK-NEXT:    [[TMP102:%.*]] = insertelement <2 x i32> [[TMP51]], i32 [[TMP101]], i64 1
+; CHECK-NEXT:    store <2 x i32> [[TMP102]], <2 x i32> addrspace(1)* [[OUT:%.*]]
+; CHECK-NEXT:    ret void
+;
+; GCN-LABEL: srem_v2i32_pow2_shl_denom:
+; GCN:       ; %bb.0:
+; GCN-NEXT:    s_load_dwordx2 s[2:3], s[0:1], 0xd
+; GCN-NEXT:    s_movk_i32 s4, 0x1000
+; GCN-NEXT:    s_mov_b32 s14, 0x4f800000
+; GCN-NEXT:    s_load_dwordx2 s[6:7], s[0:1], 0xb
+; GCN-NEXT:    s_load_dwordx2 s[8:9], s[0:1], 0x9
+; GCN-NEXT:    s_waitcnt lgkmcnt(0)
+; GCN-NEXT:    s_lshl_b32 s2, s4, s2
+; GCN-NEXT:    s_ashr_i32 s5, s2, 31
+; GCN-NEXT:    s_add_i32 s2, s2, s5
+; GCN-NEXT:    s_xor_b32 s13, s2, s5
+; GCN-NEXT:    v_cvt_f32_u32_e32 v0, s13
+; GCN-NEXT:    s_lshl_b32 s2, s4, s3
+; GCN-NEXT:    s_ashr_i32 s12, s6, 31
+; GCN-NEXT:    s_add_i32 s3, s6, s12
+; GCN-NEXT:    v_rcp_iflag_f32_e32 v0, v0
+; GCN-NEXT:    s_ashr_i32 s4, s2, 31
+; GCN-NEXT:    s_add_i32 s6, s2, s4
+; GCN-NEXT:    s_xor_b32 s5, s3, s12
+; GCN-NEXT:    v_mul_f32_e32 v0, s14, v0
+; GCN-NEXT:    v_cvt_u32_f32_e32 v0, v0
+; GCN-NEXT:    s_xor_b32 s15, s6, s4
+; GCN-NEXT:    s_ashr_i32 s6, s7, 31
+; GCN-NEXT:    s_add_i32 s7, s7, s6
+; GCN-NEXT:    v_mul_lo_u32 v1, v0, s13
+; GCN-NEXT:    v_mul_hi_u32 v2, v0, s13
+; GCN-NEXT:    s_xor_b32 s7, s7, s6
+; GCN-NEXT:    s_mov_b32 s11, 0xf000
+; GCN-NEXT:    v_sub_i32_e32 v3, vcc, 0, v1
+; GCN-NEXT:    v_cmp_eq_u32_e64 s[2:3], 0, v2
+; GCN-NEXT:    v_cndmask_b32_e64 v1, v1, v3, s[2:3]
+; GCN-NEXT:    v_mul_hi_u32 v1, v1, v0
+; GCN-NEXT:    v_cvt_f32_u32_e32 v2, s15
+; GCN-NEXT:    s_mov_b32 s10, -1
+; GCN-NEXT:    v_add_i32_e32 v3, vcc, v1, v0
+; GCN-NEXT:    v_subrev_i32_e32 v0, vcc, v1, v0
+; GCN-NEXT:    v_rcp_iflag_f32_e32 v1, v2
+; GCN-NEXT:    v_cndmask_b32_e64 v0, v0, v3, s[2:3]
+; GCN-NEXT:    v_mul_hi_u32 v0, v0, s5
+; GCN-NEXT:    v_mul_f32_e32 v1, s14, v1
+; GCN-NEXT:    v_cvt_u32_f32_e32 v1, v1
+; GCN-NEXT:    v_mul_lo_u32 v0, v0, s13
+; GCN-NEXT:    v_mul_lo_u32 v4, v1, s15
+; GCN-NEXT:    v_mul_hi_u32 v5, v1, s15
+; GCN-NEXT:    v_sub_i32_e32 v2, vcc, s5, v0
+; GCN-NEXT:    v_cmp_ge_u32_e64 s[2:3], s5, v0
+; GCN-NEXT:    v_sub_i32_e32 v6, vcc, 0, v4
+; GCN-NEXT:    v_cmp_eq_u32_e64 s[4:5], 0, v5
+; GCN-NEXT:    v_cndmask_b32_e64 v4, v4, v6, s[4:5]
+; GCN-NEXT:    v_mul_hi_u32 v4, v4, v1
+; GCN-NEXT:    v_cmp_le_u32_e64 s[0:1], s13, v2
+; GCN-NEXT:    v_add_i32_e32 v3, vcc, s13, v2
+; GCN-NEXT:    v_subrev_i32_e32 v0, vcc, s13, v2
+; GCN-NEXT:    v_add_i32_e32 v5, vcc, v4, v1
+; GCN-NEXT:    v_subrev_i32_e32 v1, vcc, v4, v1
+; GCN-NEXT:    v_cndmask_b32_e64 v1, v1, v5, s[4:5]
+; GCN-NEXT:    v_mul_hi_u32 v1, v1, s7
+; GCN-NEXT:    s_and_b64 vcc, s[0:1], s[2:3]
+; GCN-NEXT:    v_cndmask_b32_e32 v0, v2, v0, vcc
+; GCN-NEXT:    v_cndmask_b32_e64 v0, v3, v0, s[2:3]
+; GCN-NEXT:    v_mul_lo_u32 v1, v1, s15
+; GCN-NEXT:    v_xor_b32_e32 v0, s12, v0
+; GCN-NEXT:    v_subrev_i32_e32 v0, vcc, s12, v0
+; GCN-NEXT:    v_sub_i32_e32 v2, vcc, s7, v1
+; GCN-NEXT:    v_cmp_ge_u32_e64 s[2:3], s7, v1
+; GCN-NEXT:    v_cmp_le_u32_e64 s[0:1], s15, v2
+; GCN-NEXT:    v_add_i32_e32 v3, vcc, s15, v2
+; GCN-NEXT:    v_subrev_i32_e32 v1, vcc, s15, v2
+; GCN-NEXT:    s_and_b64 vcc, s[0:1], s[2:3]
+; GCN-NEXT:    v_cndmask_b32_e32 v1, v2, v1, vcc
+; GCN-NEXT:    v_cndmask_b32_e64 v1, v3, v1, s[2:3]
+; GCN-NEXT:    v_xor_b32_e32 v1, s6, v1
+; GCN-NEXT:    v_subrev_i32_e32 v1, vcc, s6, v1
+; GCN-NEXT:    buffer_store_dwordx2 v[0:1], off, s[8:11], 0
+; GCN-NEXT:    s_endpgm
+  %shl.y = shl <2 x i32> <i32 4096, i32 4096>, %y
+  %r = srem <2 x i32> %x, %shl.y
+  store <2 x i32> %r, <2 x i32> addrspace(1)* %out
+  ret void
+}
+
+define amdgpu_kernel void @udiv_i64_oddk_denom(i64 addrspace(1)* %out, i64 %x) {
+; CHECK-LABEL: @udiv_i64_oddk_denom(
+; CHECK-NEXT:    [[R:%.*]] = udiv i64 [[X:%.*]], 1235195949943
+; CHECK-NEXT:    store i64 [[R]], i64 addrspace(1)* [[OUT:%.*]]
+; CHECK-NEXT:    ret void
+;
+; GCN-LABEL: udiv_i64_oddk_denom:
+; GCN:       ; %bb.0:
+; GCN-NEXT:    v_mov_b32_e32 v0, 0x4f176a73
+; GCN-NEXT:    v_mov_b32_e32 v1, 0x4f800000
+; GCN-NEXT:    v_madmk_f32 v0, v1, 0x438f8000, v0
+; GCN-NEXT:    v_rcp_f32_e32 v0, v0
+; GCN-NEXT:    s_movk_i32 s2, 0xfee0
+; GCN-NEXT:    s_mov_b32 s3, 0x68958c89
+; GCN-NEXT:    v_mov_b32_e32 v8, 0
+; GCN-NEXT:    v_mul_f32_e32 v0, 0x5f7ffffc, v0
+; GCN-NEXT:    v_mul_f32_e32 v1, 0x2f800000, v0
+; GCN-NEXT:    v_trunc_f32_e32 v1, v1
+; GCN-NEXT:    v_mac_f32_e32 v0, 0xcf800000, v1
+; GCN-NEXT:    v_cvt_u32_f32_e32 v0, v0
+; GCN-NEXT:    v_cvt_u32_f32_e32 v1, v1
+; GCN-NEXT:    v_mov_b32_e32 v7, 0
+; GCN-NEXT:    s_load_dwordx4 s[4:7], s[0:1], 0x9
+; GCN-NEXT:    v_mul_lo_u32 v2, v0, s2
+; GCN-NEXT:    v_mul_hi_u32 v3, v0, s3
+; GCN-NEXT:    v_mul_lo_u32 v4, v1, s3
+; GCN-NEXT:    s_mov_b32 s11, 0xf000
+; GCN-NEXT:    s_waitcnt lgkmcnt(0)
+; GCN-NEXT:    s_mov_b32 s8, s4
+; GCN-NEXT:    v_add_i32_e32 v2, vcc, v3, v2
+; GCN-NEXT:    v_mul_lo_u32 v3, v0, s3
+; GCN-NEXT:    v_add_i32_e32 v2, vcc, v4, v2
+; GCN-NEXT:    v_mul_lo_u32 v5, v0, v2
+; GCN-NEXT:    v_mul_hi_u32 v4, v0, v2
+; GCN-NEXT:    v_mul_hi_u32 v6, v0, v3
+; GCN-NEXT:    v_mul_hi_u32 v9, v1, v2
+; GCN-NEXT:    v_mul_lo_u32 v2, v1, v2
+; GCN-NEXT:    s_mov_b32 s4, 0x976a7376
+; GCN-NEXT:    v_add_i32_e32 v5, vcc, v6, v5
+; GCN-NEXT:    v_mul_lo_u32 v6, v1, v3
+; GCN-NEXT:    v_mul_hi_u32 v3, v1, v3
+; GCN-NEXT:    v_addc_u32_e32 v4, vcc, v8, v4, vcc
+; GCN-NEXT:    s_mov_b32 s10, -1
+; GCN-NEXT:    v_add_i32_e32 v5, vcc, v6, v5
+; GCN-NEXT:    v_addc_u32_e32 v3, vcc, v4, v3, vcc
+; GCN-NEXT:    v_addc_u32_e32 v4, vcc, v9, v7, vcc
+; GCN-NEXT:    v_add_i32_e32 v2, vcc, v3, v2
+; GCN-NEXT:    v_add_i32_e64 v0, s[0:1], v0, v2
+; GCN-NEXT:    v_addc_u32_e32 v3, vcc, v8, v4, vcc
+; GCN-NEXT:    v_mul_lo_u32 v4, v0, s2
+; GCN-NEXT:    v_mul_hi_u32 v5, v0, s3
+; GCN-NEXT:    v_addc_u32_e64 v2, vcc, v1, v3, s[0:1]
+; GCN-NEXT:    v_mul_lo_u32 v6, v2, s3
+; GCN-NEXT:    s_movk_i32 s2, 0x11f
+; GCN-NEXT:    v_add_i32_e32 v4, vcc, v5, v4
+; GCN-NEXT:    v_mul_lo_u32 v5, v0, s3
+; GCN-NEXT:    v_add_i32_e32 v4, vcc, v4, v6
+; GCN-NEXT:    v_mul_lo_u32 v6, v0, v4
+; GCN-NEXT:    v_mul_hi_u32 v10, v0, v4
+; GCN-NEXT:    v_mul_hi_u32 v9, v0, v5
+; GCN-NEXT:    v_mul_hi_u32 v11, v2, v4
+; GCN-NEXT:    s_mov_b32 s3, 0x976a7377
+; GCN-NEXT:    s_mov_b32 s9, s5
+; GCN-NEXT:    v_add_i32_e32 v6, vcc, v9, v6
+; GCN-NEXT:    v_addc_u32_e32 v9, vcc, v8, v10, vcc
+; GCN-NEXT:    v_mul_lo_u32 v10, v2, v5
+; GCN-NEXT:    v_mul_hi_u32 v5, v2, v5
+; GCN-NEXT:    v_mul_lo_u32 v2, v2, v4
+; GCN-NEXT:    v_add_i32_e32 v6, vcc, v10, v6
+; GCN-NEXT:    v_addc_u32_e32 v5, vcc, v9, v5, vcc
+; GCN-NEXT:    v_addc_u32_e32 v4, vcc, v11, v7, vcc
+; GCN-NEXT:    v_add_i32_e32 v2, vcc, v5, v2
+; GCN-NEXT:    v_addc_u32_e32 v4, vcc, v8, v4, vcc
+; GCN-NEXT:    v_add_i32_e32 v1, vcc, v1, v3
+; GCN-NEXT:    v_addc_u32_e64 v1, vcc, v1, v4, s[0:1]
+; GCN-NEXT:    v_add_i32_e32 v0, vcc, v0, v2
+; GCN-NEXT:    v_addc_u32_e32 v1, vcc, 0, v1, vcc
+; GCN-NEXT:    v_mul_lo_u32 v2, s6, v1
+; GCN-NEXT:    v_mul_hi_u32 v3, s6, v0
+; GCN-NEXT:    v_mul_hi_u32 v4, s6, v1
+; GCN-NEXT:    v_mul_hi_u32 v5, s7, v1
+; GCN-NEXT:    v_mul_lo_u32 v1, s7, v1
+; GCN-NEXT:    v_add_i32_e32 v2, vcc, v3, v2
+; GCN-NEXT:    v_addc_u32_e32 v3, vcc, v8, v4, vcc
+; GCN-NEXT:    v_mul_lo_u32 v4, s7, v0
+; GCN-NEXT:    v_mul_hi_u32 v0, s7, v0
+; GCN-NEXT:    v_add_i32_e32 v2, vcc, v4, v2
+; GCN-NEXT:    v_addc_u32_e32 v0, vcc, v3, v0, vcc
+; GCN-NEXT:    v_addc_u32_e32 v2, vcc, v5, v7, vcc
+; GCN-NEXT:    v_add_i32_e32 v0, vcc, v0, v1
+; GCN-NEXT:    v_addc_u32_e32 v1, vcc, v8, v2, vcc
+; GCN-NEXT:    v_mul_lo_u32 v2, v0, s2
+; GCN-NEXT:    v_mul_hi_u32 v3, v0, s3
+; GCN-NEXT:    v_mul_lo_u32 v4, v1, s3
+; GCN-NEXT:    v_mov_b32_e32 v5, s2
+; GCN-NEXT:    v_add_i32_e32 v2, vcc, v3, v2
+; GCN-NEXT:    v_mul_lo_u32 v3, v0, s3
+; GCN-NEXT:    v_add_i32_e32 v2, vcc, v2, v4
+; GCN-NEXT:    v_sub_i32_e32 v4, vcc, s7, v2
+; GCN-NEXT:    v_sub_i32_e32 v3, vcc, s6, v3
+; GCN-NEXT:    v_subb_u32_e64 v4, s[0:1], v4, v5, vcc
+; GCN-NEXT:    v_subrev_i32_e64 v5, s[0:1], s3, v3
+; GCN-NEXT:    v_subbrev_u32_e64 v4, s[0:1], 0, v4, s[0:1]
+; GCN-NEXT:    s_movk_i32 s3, 0x11e
+; GCN-NEXT:    v_cmp_lt_u32_e64 s[0:1], s3, v4
+; GCN-NEXT:    v_cndmask_b32_e64 v6, 0, -1, s[0:1]
+; GCN-NEXT:    v_cmp_lt_u32_e64 s[0:1], s4, v5
+; GCN-NEXT:    v_cndmask_b32_e64 v5, 0, -1, s[0:1]
+; GCN-NEXT:    v_cmp_eq_u32_e64 s[0:1], s2, v4
+; GCN-NEXT:    v_cndmask_b32_e64 v4, v6, v5, s[0:1]
+; GCN-NEXT:    v_add_i32_e64 v5, s[0:1], 2, v0
+; GCN-NEXT:    v_addc_u32_e64 v6, s[0:1], 0, v1, s[0:1]
+; GCN-NEXT:    v_add_i32_e64 v7, s[0:1], 1, v0
+; GCN-NEXT:    v_addc_u32_e64 v8, s[0:1], 0, v1, s[0:1]
+; GCN-NEXT:    v_cmp_ne_u32_e64 s[0:1], 0, v4
+; GCN-NEXT:    v_cndmask_b32_e64 v4, v8, v6, s[0:1]
+; GCN-NEXT:    v_mov_b32_e32 v6, s7
+; GCN-NEXT:    v_subb_u32_e32 v2, vcc, v6, v2, vcc
+; GCN-NEXT:    v_cmp_lt_u32_e32 vcc, s3, v2
+; GCN-NEXT:    v_cndmask_b32_e64 v6, 0, -1, vcc
+; GCN-NEXT:    v_cmp_lt_u32_e32 vcc, s4, v3
+; GCN-NEXT:    v_cndmask_b32_e64 v3, 0, -1, vcc
+; GCN-NEXT:    v_cmp_eq_u32_e32 vcc, s2, v2
+; GCN-NEXT:    v_cndmask_b32_e32 v2, v6, v3, vcc
+; GCN-NEXT:    v_cmp_ne_u32_e32 vcc, 0, v2
+; GCN-NEXT:    v_cndmask_b32_e64 v2, v7, v5, s[0:1]
+; GCN-NEXT:    v_cndmask_b32_e32 v1, v1, v4, vcc
+; GCN-NEXT:    v_cndmask_b32_e32 v0, v0, v2, vcc
+; GCN-NEXT:    buffer_store_dwordx2 v[0:1], off, s[8:11], 0
+; GCN-NEXT:    s_endpgm
+  %r = udiv i64 %x, 1235195949943
+  store i64 %r, i64 addrspace(1)* %out
+  ret void
+}
+
+define amdgpu_kernel void @udiv_i64_pow2k_denom(i64 addrspace(1)* %out, i64 %x) {
+; CHECK-LABEL: @udiv_i64_pow2k_denom(
+; CHECK-NEXT:    [[R:%.*]] = udiv i64 [[X:%.*]], 4096
+; CHECK-NEXT:    store i64 [[R]], i64 addrspace(1)* [[OUT:%.*]]
+; CHECK-NEXT:    ret void
+;
+; GCN-LABEL: udiv_i64_pow2k_denom:
+; GCN:       ; %bb.0:
+; GCN-NEXT:    s_load_dwordx4 s[4:7], s[0:1], 0x9
+; GCN-NEXT:    s_mov_b32 s3, 0xf000
+; GCN-NEXT:    s_mov_b32 s2, -1
+; GCN-NEXT:    s_waitcnt lgkmcnt(0)
+; GCN-NEXT:    s_mov_b32 s0, s4
+; GCN-NEXT:    s_mov_b32 s1, s5
+; GCN-NEXT:    s_lshr_b64 s[4:5], s[6:7], 12
+; GCN-NEXT:    v_mov_b32_e32 v0, s4
+; GCN-NEXT:    v_mov_b32_e32 v1, s5
+; GCN-NEXT:    buffer_store_dwordx2 v[0:1], off, s[0:3], 0
+; GCN-NEXT:    s_endpgm
+  %r = udiv i64 %x, 4096
+  store i64 %r, i64 addrspace(1)* %out
+  ret void
+}
+
+define amdgpu_kernel void @udiv_i64_pow2_shl_denom(i64 addrspace(1)* %out, i64 %x, i64 %y) {
+; CHECK-LABEL: @udiv_i64_pow2_shl_denom(
+; CHECK-NEXT:    [[SHL_Y:%.*]] = shl i64 4096, [[Y:%.*]]
+; CHECK-NEXT:    [[R:%.*]] = udiv i64 [[X:%.*]], [[SHL_Y]]
+; CHECK-NEXT:    store i64 [[R]], i64 addrspace(1)* [[OUT:%.*]]
+; CHECK-NEXT:    ret void
+;
+; GCN-LABEL: udiv_i64_pow2_shl_denom:
+; GCN:       ; %bb.0:
+; GCN-NEXT:    s_load_dwordx4 s[4:7], s[0:1], 0x9
+; GCN-NEXT:    s_load_dword s8, s[0:1], 0xd
+; GCN-NEXT:    s_mov_b32 s3, 0xf000
+; GCN-NEXT:    s_mov_b32 s2, -1
+; GCN-NEXT:    s_waitcnt lgkmcnt(0)
+; GCN-NEXT:    s_mov_b32 s0, s4
+; GCN-NEXT:    s_add_i32 s8, s8, 12
+; GCN-NEXT:    s_mov_b32 s1, s5
+; GCN-NEXT:    s_lshr_b64 s[4:5], s[6:7], s8
+; GCN-NEXT:    v_mov_b32_e32 v0, s4
+; GCN-NEXT:    v_mov_b32_e32 v1, s5
+; GCN-NEXT:    buffer_store_dwordx2 v[0:1], off, s[0:3], 0
+; GCN-NEXT:    s_endpgm
+  %shl.y = shl i64 4096, %y
+  %r = udiv i64 %x, %shl.y
+  store i64 %r, i64 addrspace(1)* %out
+  ret void
+}
+
+define amdgpu_kernel void @udiv_v2i64_pow2k_denom(<2 x i64> addrspace(1)* %out, <2 x i64> %x) {
+; CHECK-LABEL: @udiv_v2i64_pow2k_denom(
+; CHECK-NEXT:    [[R:%.*]] = udiv <2 x i64> [[X:%.*]], <i64 4096, i64 4096>
+; CHECK-NEXT:    store <2 x i64> [[R]], <2 x i64> addrspace(1)* [[OUT:%.*]]
+; CHECK-NEXT:    ret void
+;
+; GCN-LABEL: udiv_v2i64_pow2k_denom:
+; GCN:       ; %bb.0:
+; GCN-NEXT:    s_load_dwordx2 s[4:5], s[0:1], 0x9
+; GCN-NEXT:    s_load_dwordx4 s[0:3], s[0:1], 0xd
+; GCN-NEXT:    s_mov_b32 s7, 0xf000
+; GCN-NEXT:    s_mov_b32 s6, -1
+; GCN-NEXT:    s_waitcnt lgkmcnt(0)
+; GCN-NEXT:    s_lshr_b64 s[2:3], s[2:3], 12
+; GCN-NEXT:    s_lshr_b64 s[0:1], s[0:1], 12
+; GCN-NEXT:    v_mov_b32_e32 v0, s0
+; GCN-NEXT:    v_mov_b32_e32 v1, s1
+; GCN-NEXT:    v_mov_b32_e32 v2, s2
+; GCN-NEXT:    v_mov_b32_e32 v3, s3
+; GCN-NEXT:    buffer_store_dwordx4 v[0:3], off, s[4:7], 0
+; GCN-NEXT:    s_endpgm
+  %r = udiv <2 x i64> %x, <i64 4096, i64 4096>
+  store <2 x i64> %r, <2 x i64> addrspace(1)* %out
+  ret void
+}
+
+define amdgpu_kernel void @udiv_v2i64_mixed_pow2k_denom(<2 x i64> addrspace(1)* %out, <2 x i64> %x) {
+; CHECK-LABEL: @udiv_v2i64_mixed_pow2k_denom(
+; CHECK-NEXT:    [[R:%.*]] = udiv <2 x i64> [[X:%.*]], <i64 4096, i64 4095>
+; CHECK-NEXT:    store <2 x i64> [[R]], <2 x i64> addrspace(1)* [[OUT:%.*]]
+; CHECK-NEXT:    ret void
+;
+; GCN-LABEL: udiv_v2i64_mixed_pow2k_denom:
+; GCN:       ; %bb.0:
+; GCN-NEXT:    v_mov_b32_e32 v0, 0x4f800000
+; GCN-NEXT:    v_madak_f32 v0, 0, v0, 0x457ff000
+; GCN-NEXT:    v_rcp_f32_e32 v0, v0
+; GCN-NEXT:    s_movk_i32 s4, 0xf001
+; GCN-NEXT:    v_mov_b32_e32 v7, 0
+; GCN-NEXT:    v_mov_b32_e32 v2, 0
+; GCN-NEXT:    v_mul_f32_e32 v0, 0x5f7ffffc, v0
+; GCN-NEXT:    v_mul_f32_e32 v1, 0x2f800000, v0
+; GCN-NEXT:    v_trunc_f32_e32 v1, v1
+; GCN-NEXT:    v_mac_f32_e32 v0, 0xcf800000, v1
+; GCN-NEXT:    v_cvt_u32_f32_e32 v0, v0
+; GCN-NEXT:    v_cvt_u32_f32_e32 v1, v1
+; GCN-NEXT:    s_mov_b32 s7, 0xf000
+; GCN-NEXT:    s_mov_b32 s6, -1
+; GCN-NEXT:    v_mul_hi_u32 v3, v0, s4
+; GCN-NEXT:    v_mul_lo_u32 v5, v1, s4
+; GCN-NEXT:    v_mul_lo_u32 v4, v0, s4
+; GCN-NEXT:    v_subrev_i32_e32 v3, vcc, v0, v3
+; GCN-NEXT:    v_add_i32_e32 v3, vcc, v5, v3
+; GCN-NEXT:    v_mul_hi_u32 v6, v0, v4
+; GCN-NEXT:    v_mul_lo_u32 v5, v0, v3
+; GCN-NEXT:    v_mul_hi_u32 v8, v0, v3
+; GCN-NEXT:    v_mul_hi_u32 v9, v1, v3
+; GCN-NEXT:    v_mul_lo_u32 v3, v1, v3
+; GCN-NEXT:    v_add_i32_e32 v5, vcc, v6, v5
+; GCN-NEXT:    v_addc_u32_e32 v6, vcc, v7, v8, vcc
+; GCN-NEXT:    v_mul_lo_u32 v8, v1, v4
+; GCN-NEXT:    v_mul_hi_u32 v4, v1, v4
+; GCN-NEXT:    v_add_i32_e32 v5, vcc, v8, v5
+; GCN-NEXT:    v_addc_u32_e32 v4, vcc, v6, v4, vcc
+; GCN-NEXT:    v_addc_u32_e32 v5, vcc, v9, v2, vcc
+; GCN-NEXT:    v_add_i32_e32 v3, vcc, v4, v3
+; GCN-NEXT:    v_add_i32_e64 v0, s[2:3], v0, v3
+; GCN-NEXT:    v_addc_u32_e32 v4, vcc, v7, v5, vcc
+; GCN-NEXT:    v_mul_hi_u32 v5, v0, s4
+; GCN-NEXT:    v_addc_u32_e64 v3, vcc, v1, v4, s[2:3]
+; GCN-NEXT:    v_mul_lo_u32 v6, v3, s4
+; GCN-NEXT:    v_mul_lo_u32 v8, v0, s4
+; GCN-NEXT:    v_subrev_i32_e32 v5, vcc, v0, v5
+; GCN-NEXT:    s_load_dwordx2 s[4:5], s[0:1], 0x9
+; GCN-NEXT:    s_load_dwordx4 s[8:11], s[0:1], 0xd
+; GCN-NEXT:    v_add_i32_e32 v5, vcc, v5, v6
+; GCN-NEXT:    v_mul_lo_u32 v6, v0, v5
+; GCN-NEXT:    v_mul_hi_u32 v9, v0, v8
+; GCN-NEXT:    v_mul_hi_u32 v10, v0, v5
+; GCN-NEXT:    v_mul_hi_u32 v11, v3, v5
+; GCN-NEXT:    s_movk_i32 s0, 0xfff
+; GCN-NEXT:    v_add_i32_e32 v6, vcc, v9, v6
+; GCN-NEXT:    v_addc_u32_e32 v9, vcc, v7, v10, vcc
+; GCN-NEXT:    v_mul_lo_u32 v10, v3, v8
+; GCN-NEXT:    v_mul_hi_u32 v8, v3, v8
+; GCN-NEXT:    v_mul_lo_u32 v3, v3, v5
+; GCN-NEXT:    v_add_i32_e32 v6, vcc, v10, v6
+; GCN-NEXT:    v_addc_u32_e32 v6, vcc, v9, v8, vcc
+; GCN-NEXT:    v_addc_u32_e32 v5, vcc, v11, v2, vcc
+; GCN-NEXT:    v_add_i32_e32 v3, vcc, v6, v3
+; GCN-NEXT:    v_addc_u32_e32 v5, vcc, v7, v5, vcc
+; GCN-NEXT:    v_add_i32_e32 v1, vcc, v1, v4
+; GCN-NEXT:    v_addc_u32_e64 v1, vcc, v1, v5, s[2:3]
+; GCN-NEXT:    v_add_i32_e32 v0, vcc, v0, v3
+; GCN-NEXT:    v_addc_u32_e32 v1, vcc, 0, v1, vcc
+; GCN-NEXT:    s_waitcnt lgkmcnt(0)
+; GCN-NEXT:    v_mul_lo_u32 v3, s10, v1
+; GCN-NEXT:    v_mul_hi_u32 v4, s10, v0
+; GCN-NEXT:    v_mul_hi_u32 v5, s10, v1
+; GCN-NEXT:    v_mul_hi_u32 v6, s11, v1
+; GCN-NEXT:    v_mul_lo_u32 v1, s11, v1
+; GCN-NEXT:    v_add_i32_e32 v3, vcc, v4, v3
+; GCN-NEXT:    v_addc_u32_e32 v4, vcc, v7, v5, vcc
+; GCN-NEXT:    v_mul_lo_u32 v5, s11, v0
+; GCN-NEXT:    v_mul_hi_u32 v0, s11, v0
+; GCN-NEXT:    v_add_i32_e32 v3, vcc, v5, v3
+; GCN-NEXT:    v_addc_u32_e32 v0, vcc, v4, v0, vcc
+; GCN-NEXT:    v_addc_u32_e32 v2, vcc, v6, v2, vcc
+; GCN-NEXT:    v_add_i32_e32 v0, vcc, v0, v1
+; GCN-NEXT:    v_addc_u32_e32 v1, vcc, v7, v2, vcc
+; GCN-NEXT:    v_mul_lo_u32 v2, v1, s0
+; GCN-NEXT:    v_mul_hi_u32 v3, v0, s0
+; GCN-NEXT:    v_mul_lo_u32 v4, v0, s0
+; GCN-NEXT:    v_add_i32_e32 v2, vcc, v3, v2
+; GCN-NEXT:    v_mov_b32_e32 v3, s11
+; GCN-NEXT:    v_sub_i32_e32 v4, vcc, s10, v4
+; GCN-NEXT:    v_subb_u32_e32 v2, vcc, v3, v2, vcc
+; GCN-NEXT:    v_subrev_i32_e32 v3, vcc, s0, v4
+; GCN-NEXT:    v_subbrev_u32_e32 v5, vcc, 0, v2, vcc
+; GCN-NEXT:    s_movk_i32 s0, 0xffe
+; GCN-NEXT:    v_cmp_lt_u32_e32 vcc, s0, v3
+; GCN-NEXT:    v_cndmask_b32_e64 v3, 0, -1, vcc
+; GCN-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v5
+; GCN-NEXT:    v_cndmask_b32_e32 v3, -1, v3, vcc
+; GCN-NEXT:    v_add_i32_e32 v5, vcc, 2, v0
+; GCN-NEXT:    v_addc_u32_e32 v6, vcc, 0, v1, vcc
+; GCN-NEXT:    v_add_i32_e32 v7, vcc, 1, v0
+; GCN-NEXT:    v_cmp_lt_u32_e64 s[0:1], s0, v4
+; GCN-NEXT:    v_addc_u32_e32 v8, vcc, 0, v1, vcc
+; GCN-NEXT:    v_cndmask_b32_e64 v4, 0, -1, s[0:1]
+; GCN-NEXT:    v_cmp_eq_u32_e64 s[0:1], 0, v2
+; GCN-NEXT:    v_cmp_ne_u32_e32 vcc, 0, v3
+; GCN-NEXT:    v_cndmask_b32_e64 v2, -1, v4, s[0:1]
+; GCN-NEXT:    v_cndmask_b32_e32 v3, v8, v6, vcc
+; GCN-NEXT:    v_cmp_ne_u32_e64 s[0:1], 0, v2
+; GCN-NEXT:    v_cndmask_b32_e64 v3, v1, v3, s[0:1]
+; GCN-NEXT:    v_cndmask_b32_e32 v1, v7, v5, vcc
+; GCN-NEXT:    v_cndmask_b32_e64 v2, v0, v1, s[0:1]
+; GCN-NEXT:    s_lshr_b64 s[0:1], s[8:9], 12
+; GCN-NEXT:    v_mov_b32_e32 v0, s0
+; GCN-NEXT:    v_mov_b32_e32 v1, s1
+; GCN-NEXT:    buffer_store_dwordx4 v[0:3], off, s[4:7], 0
+; GCN-NEXT:    s_endpgm
+  %r = udiv <2 x i64> %x, <i64 4096, i64 4095>
+  store <2 x i64> %r, <2 x i64> addrspace(1)* %out
+  ret void
+}
+
+define amdgpu_kernel void @udiv_v2i64_pow2_shl_denom(<2 x i64> addrspace(1)* %out, <2 x i64> %x, <2 x i64> %y) {
+; CHECK-LABEL: @udiv_v2i64_pow2_shl_denom(
+; CHECK-NEXT:    [[SHL_Y:%.*]] = shl <2 x i64> <i64 4096, i64 4096>, [[Y:%.*]]
+; CHECK-NEXT:    [[R:%.*]] = udiv <2 x i64> [[X:%.*]], [[SHL_Y]]
+; CHECK-NEXT:    store <2 x i64> [[R]], <2 x i64> addrspace(1)* [[OUT:%.*]]
+; CHECK-NEXT:    ret void
+;
+; GCN-LABEL: udiv_v2i64_pow2_shl_denom:
+; GCN:       ; %bb.0:
+; GCN-NEXT:    s_load_dwordx2 s[4:5], s[0:1], 0x9
+; GCN-NEXT:    s_load_dwordx4 s[8:11], s[0:1], 0xd
+; GCN-NEXT:    s_load_dwordx4 s[0:3], s[0:1], 0x11
+; GCN-NEXT:    s_mov_b32 s7, 0xf000
+; GCN-NEXT:    s_mov_b32 s6, -1
+; GCN-NEXT:    s_waitcnt lgkmcnt(0)
+; GCN-NEXT:    s_add_i32 s1, s2, 12
+; GCN-NEXT:    s_add_i32 s0, s0, 12
+; GCN-NEXT:    s_lshr_b64 s[2:3], s[10:11], s1
+; GCN-NEXT:    s_lshr_b64 s[0:1], s[8:9], s0
+; GCN-NEXT:    v_mov_b32_e32 v0, s0
+; GCN-NEXT:    v_mov_b32_e32 v1, s1
+; GCN-NEXT:    v_mov_b32_e32 v2, s2
+; GCN-NEXT:    v_mov_b32_e32 v3, s3
+; GCN-NEXT:    buffer_store_dwordx4 v[0:3], off, s[4:7], 0
+; GCN-NEXT:    s_endpgm
+  %shl.y = shl <2 x i64> <i64 4096, i64 4096>, %y
+  %r = udiv <2 x i64> %x, %shl.y
+  store <2 x i64> %r, <2 x i64> addrspace(1)* %out
+  ret void
+}
+
+define amdgpu_kernel void @urem_i64_oddk_denom(i64 addrspace(1)* %out, i64 %x) {
+; CHECK-LABEL: @urem_i64_oddk_denom(
+; CHECK-NEXT:    [[R:%.*]] = urem i64 [[X:%.*]], 1235195393993
+; CHECK-NEXT:    store i64 [[R]], i64 addrspace(1)* [[OUT:%.*]]
+; CHECK-NEXT:    ret void
+;
+; GCN-LABEL: urem_i64_oddk_denom:
+; GCN:       ; %bb.0:
+; GCN-NEXT:    v_mov_b32_e32 v0, 0x4f1761f8
+; GCN-NEXT:    v_mov_b32_e32 v1, 0x4f800000
+; GCN-NEXT:    v_madmk_f32 v0, v1, 0x438f8000, v0
+; GCN-NEXT:    v_rcp_f32_e32 v0, v0
+; GCN-NEXT:    s_movk_i32 s2, 0xfee0
+; GCN-NEXT:    s_mov_b32 s3, 0x689e0837
+; GCN-NEXT:    v_mov_b32_e32 v8, 0
+; GCN-NEXT:    v_mul_f32_e32 v0, 0x5f7ffffc, v0
+; GCN-NEXT:    v_mul_f32_e32 v1, 0x2f800000, v0
+; GCN-NEXT:    v_trunc_f32_e32 v1, v1
+; GCN-NEXT:    v_mac_f32_e32 v0, 0xcf800000, v1
+; GCN-NEXT:    v_cvt_u32_f32_e32 v0, v0
+; GCN-NEXT:    v_cvt_u32_f32_e32 v1, v1
+; GCN-NEXT:    v_mov_b32_e32 v7, 0
+; GCN-NEXT:    s_load_dwordx4 s[4:7], s[0:1], 0x9
+; GCN-NEXT:    v_mul_lo_u32 v2, v0, s2
+; GCN-NEXT:    v_mul_hi_u32 v3, v0, s3
+; GCN-NEXT:    v_mul_lo_u32 v4, v1, s3
+; GCN-NEXT:    s_mov_b32 s12, 0x9761f7c9
+; GCN-NEXT:    s_waitcnt lgkmcnt(0)
+; GCN-NEXT:    s_mov_b32 s8, s4
+; GCN-NEXT:    v_add_i32_e32 v2, vcc, v3, v2
+; GCN-NEXT:    v_mul_lo_u32 v3, v0, s3
+; GCN-NEXT:    v_add_i32_e32 v2, vcc, v4, v2
+; GCN-NEXT:    v_mul_lo_u32 v5, v0, v2
+; GCN-NEXT:    v_mul_hi_u32 v4, v0, v2
+; GCN-NEXT:    v_mul_hi_u32 v6, v0, v3
+; GCN-NEXT:    v_mul_hi_u32 v9, v1, v2
+; GCN-NEXT:    v_mul_lo_u32 v2, v1, v2
+; GCN-NEXT:    s_movk_i32 s4, 0x11f
+; GCN-NEXT:    v_add_i32_e32 v5, vcc, v6, v5
+; GCN-NEXT:    v_mul_lo_u32 v6, v1, v3
+; GCN-NEXT:    v_mul_hi_u32 v3, v1, v3
+; GCN-NEXT:    v_addc_u32_e32 v4, vcc, v8, v4, vcc
+; GCN-NEXT:    s_mov_b32 s11, 0xf000
+; GCN-NEXT:    v_add_i32_e32 v5, vcc, v6, v5
+; GCN-NEXT:    v_addc_u32_e32 v3, vcc, v4, v3, vcc
+; GCN-NEXT:    v_addc_u32_e32 v4, vcc, v9, v7, vcc
+; GCN-NEXT:    v_add_i32_e32 v2, vcc, v3, v2
+; GCN-NEXT:    v_add_i32_e64 v0, s[0:1], v0, v2
+; GCN-NEXT:    v_addc_u32_e32 v3, vcc, v8, v4, vcc
+; GCN-NEXT:    v_mul_lo_u32 v4, v0, s2
+; GCN-NEXT:    v_mul_hi_u32 v5, v0, s3
+; GCN-NEXT:    v_addc_u32_e64 v2, vcc, v1, v3, s[0:1]
+; GCN-NEXT:    v_mul_lo_u32 v6, v2, s3
+; GCN-NEXT:    s_mov_b32 s10, -1
+; GCN-NEXT:    v_add_i32_e32 v4, vcc, v5, v4
+; GCN-NEXT:    v_mul_lo_u32 v5, v0, s3
+; GCN-NEXT:    v_add_i32_e32 v4, vcc, v4, v6
+; GCN-NEXT:    v_mul_lo_u32 v6, v0, v4
+; GCN-NEXT:    v_mul_hi_u32 v10, v0, v4
+; GCN-NEXT:    v_mul_hi_u32 v9, v0, v5
+; GCN-NEXT:    v_mul_hi_u32 v11, v2, v4
+; GCN-NEXT:    s_mov_b32 s9, s5
+; GCN-NEXT:    v_add_i32_e32 v6, vcc, v9, v6
+; GCN-NEXT:    v_addc_u32_e32 v9, vcc, v8, v10, vcc
+; GCN-NEXT:    v_mul_lo_u32 v10, v2, v5
+; GCN-NEXT:    v_mul_hi_u32 v5, v2, v5
+; GCN-NEXT:    v_mul_lo_u32 v2, v2, v4
+; GCN-NEXT:    v_add_i32_e32 v6, vcc, v10, v6
+; GCN-NEXT:    v_addc_u32_e32 v5, vcc, v9, v5, vcc
+; GCN-NEXT:    v_addc_u32_e32 v4, vcc, v11, v7, vcc
+; GCN-NEXT:    v_add_i32_e32 v2, vcc, v5, v2
+; GCN-NEXT:    v_addc_u32_e32 v4, vcc, v8, v4, vcc
+; GCN-NEXT:    v_add_i32_e32 v1, vcc, v1, v3
+; GCN-NEXT:    v_addc_u32_e64 v1, vcc, v1, v4, s[0:1]
+; GCN-NEXT:    v_add_i32_e32 v0, vcc, v0, v2
+; GCN-NEXT:    v_addc_u32_e32 v1, vcc, 0, v1, vcc
+; GCN-NEXT:    v_mul_lo_u32 v2, s6, v1
+; GCN-NEXT:    v_mul_hi_u32 v3, s6, v0
+; GCN-NEXT:    v_mul_hi_u32 v4, s6, v1
+; GCN-NEXT:    v_mul_hi_u32 v5, s7, v1
+; GCN-NEXT:    v_mul_lo_u32 v1, s7, v1
+; GCN-NEXT:    v_add_i32_e32 v2, vcc, v3, v2
+; GCN-NEXT:    v_addc_u32_e32 v3, vcc, v8, v4, vcc
+; GCN-NEXT:    v_mul_lo_u32 v4, s7, v0
+; GCN-NEXT:    v_mul_hi_u32 v0, s7, v0
+; GCN-NEXT:    v_add_i32_e32 v2, vcc, v4, v2
+; GCN-NEXT:    v_addc_u32_e32 v0, vcc, v3, v0, vcc
+; GCN-NEXT:    v_addc_u32_e32 v2, vcc, v5, v7, vcc
+; GCN-NEXT:    v_add_i32_e32 v0, vcc, v0, v1
+; GCN-NEXT:    v_addc_u32_e32 v1, vcc, v8, v2, vcc
+; GCN-NEXT:    v_mul_lo_u32 v2, v0, s4
+; GCN-NEXT:    v_mul_hi_u32 v3, v0, s12
+; GCN-NEXT:    v_mul_lo_u32 v1, v1, s12
+; GCN-NEXT:    v_mul_lo_u32 v0, v0, s12
+; GCN-NEXT:    v_add_i32_e32 v2, vcc, v3, v2
+; GCN-NEXT:    v_add_i32_e32 v1, vcc, v2, v1
+; GCN-NEXT:    v_sub_i32_e32 v2, vcc, s7, v1
+; GCN-NEXT:    v_mov_b32_e32 v3, s4
+; GCN-NEXT:    v_sub_i32_e32 v0, vcc, s6, v0
+; GCN-NEXT:    v_subb_u32_e64 v2, s[0:1], v2, v3, vcc
+; GCN-NEXT:    v_subrev_i32_e64 v4, s[0:1], s12, v0
+; GCN-NEXT:    v_subb_u32_e64 v3, s[2:3], v2, v3, s[0:1]
+; GCN-NEXT:    v_subbrev_u32_e64 v2, s[0:1], 0, v2, s[0:1]
+; GCN-NEXT:    s_movk_i32 s2, 0x11e
+; GCN-NEXT:    v_cmp_lt_u32_e64 s[0:1], s2, v2
+; GCN-NEXT:    s_mov_b32 s3, 0x9761f7c8
+; GCN-NEXT:    v_cndmask_b32_e64 v5, 0, -1, s[0:1]
+; GCN-NEXT:    v_cmp_lt_u32_e64 s[0:1], s3, v4
+; GCN-NEXT:    v_cndmask_b32_e64 v6, 0, -1, s[0:1]
+; GCN-NEXT:    v_cmp_eq_u32_e64 s[0:1], s4, v2
+; GCN-NEXT:    v_cndmask_b32_e64 v5, v5, v6, s[0:1]
+; GCN-NEXT:    v_subrev_i32_e64 v6, s[0:1], s12, v4
+; GCN-NEXT:    v_subbrev_u32_e64 v3, s[0:1], 0, v3, s[0:1]
+; GCN-NEXT:    v_cmp_ne_u32_e64 s[0:1], 0, v5
+; GCN-NEXT:    v_cndmask_b32_e64 v2, v2, v3, s[0:1]
+; GCN-NEXT:    v_mov_b32_e32 v3, s7
+; GCN-NEXT:    v_subb_u32_e32 v1, vcc, v3, v1, vcc
+; GCN-NEXT:    v_cmp_lt_u32_e32 vcc, s2, v1
+; GCN-NEXT:    v_cndmask_b32_e64 v3, 0, -1, vcc
+; GCN-NEXT:    v_cmp_lt_u32_e32 vcc, s3, v0
+; GCN-NEXT:    v_cndmask_b32_e64 v5, 0, -1, vcc
+; GCN-NEXT:    v_cmp_eq_u32_e32 vcc, s4, v1
+; GCN-NEXT:    v_cndmask_b32_e32 v3, v3, v5, vcc
+; GCN-NEXT:    v_cmp_ne_u32_e32 vcc, 0, v3
+; GCN-NEXT:    v_cndmask_b32_e32 v1, v1, v2, vcc
+; GCN-NEXT:    v_cndmask_b32_e64 v2, v4, v6, s[0:1]
+; GCN-NEXT:    v_cndmask_b32_e32 v0, v0, v2, vcc
+; GCN-NEXT:    buffer_store_dwordx2 v[0:1], off, s[8:11], 0
+; GCN-NEXT:    s_endpgm
+  %r = urem i64 %x, 1235195393993
+  store i64 %r, i64 addrspace(1)* %out
+  ret void
+}
+
+define amdgpu_kernel void @urem_i64_pow2k_denom(i64 addrspace(1)* %out, i64 %x) {
+; CHECK-LABEL: @urem_i64_pow2k_denom(
+; CHECK-NEXT:    [[R:%.*]] = urem i64 [[X:%.*]], 4096
+; CHECK-NEXT:    store i64 [[R]], i64 addrspace(1)* [[OUT:%.*]]
+; CHECK-NEXT:    ret void
+;
+; GCN-LABEL: urem_i64_pow2k_denom:
+; GCN:       ; %bb.0:
+; GCN-NEXT:    s_load_dwordx4 s[4:7], s[0:1], 0x9
+; GCN-NEXT:    s_mov_b32 s3, 0xf000
+; GCN-NEXT:    s_mov_b32 s2, -1
+; GCN-NEXT:    v_mov_b32_e32 v1, 0
+; GCN-NEXT:    s_waitcnt lgkmcnt(0)
+; GCN-NEXT:    s_mov_b32 s0, s4
+; GCN-NEXT:    s_and_b32 s4, s6, 0xfff
+; GCN-NEXT:    s_mov_b32 s1, s5
+; GCN-NEXT:    v_mov_b32_e32 v0, s4
+; GCN-NEXT:    buffer_store_dwordx2 v[0:1], off, s[0:3], 0
+; GCN-NEXT:    s_endpgm
+  %r = urem i64 %x, 4096
+  store i64 %r, i64 addrspace(1)* %out
+  ret void
+}
+
+define amdgpu_kernel void @urem_i64_pow2_shl_denom(i64 addrspace(1)* %out, i64 %x, i64 %y) {
+; CHECK-LABEL: @urem_i64_pow2_shl_denom(
+; CHECK-NEXT:    [[SHL_Y:%.*]] = shl i64 4096, [[Y:%.*]]
+; CHECK-NEXT:    [[R:%.*]] = urem i64 [[X:%.*]], [[SHL_Y]]
+; CHECK-NEXT:    store i64 [[R]], i64 addrspace(1)* [[OUT:%.*]]
+; CHECK-NEXT:    ret void
+;
+; GCN-LABEL: urem_i64_pow2_shl_denom:
+; GCN:       ; %bb.0:
+; GCN-NEXT:    s_load_dwordx4 s[4:7], s[0:1], 0x9
+; GCN-NEXT:    s_load_dword s8, s[0:1], 0xd
+; GCN-NEXT:    s_mov_b32 s3, 0xf000
+; GCN-NEXT:    s_mov_b32 s2, -1
+; GCN-NEXT:    s_waitcnt lgkmcnt(0)
+; GCN-NEXT:    s_mov_b32 s0, s4
+; GCN-NEXT:    s_mov_b32 s1, s5
+; GCN-NEXT:    s_mov_b32 s5, 0
+; GCN-NEXT:    s_movk_i32 s4, 0x1000
+; GCN-NEXT:    s_lshl_b64 s[4:5], s[4:5], s8
+; GCN-NEXT:    s_add_u32 s4, s4, -1
+; GCN-NEXT:    s_addc_u32 s5, s5, -1
+; GCN-NEXT:    s_and_b64 s[4:5], s[6:7], s[4:5]
+; GCN-NEXT:    v_mov_b32_e32 v0, s4
+; GCN-NEXT:    v_mov_b32_e32 v1, s5
+; GCN-NEXT:    buffer_store_dwordx2 v[0:1], off, s[0:3], 0
+; GCN-NEXT:    s_endpgm
+  %shl.y = shl i64 4096, %y
+  %r = urem i64 %x, %shl.y
+  store i64 %r, i64 addrspace(1)* %out
+  ret void
+}
+
+define amdgpu_kernel void @urem_v2i64_pow2k_denom(<2 x i64> addrspace(1)* %out, <2 x i64> %x) {
+; CHECK-LABEL: @urem_v2i64_pow2k_denom(
+; CHECK-NEXT:    [[R:%.*]] = urem <2 x i64> [[X:%.*]], <i64 4096, i64 4096>
+; CHECK-NEXT:    store <2 x i64> [[R]], <2 x i64> addrspace(1)* [[OUT:%.*]]
+; CHECK-NEXT:    ret void
+;
+; GCN-LABEL: urem_v2i64_pow2k_denom:
+; GCN:       ; %bb.0:
+; GCN-NEXT:    s_load_dwordx2 s[4:5], s[0:1], 0x9
+; GCN-NEXT:    s_load_dwordx4 s[0:3], s[0:1], 0xd
+; GCN-NEXT:    s_movk_i32 s8, 0xfff
+; GCN-NEXT:    v_mov_b32_e32 v1, 0
+; GCN-NEXT:    s_mov_b32 s7, 0xf000
+; GCN-NEXT:    s_mov_b32 s6, -1
+; GCN-NEXT:    s_waitcnt lgkmcnt(0)
+; GCN-NEXT:    s_and_b32 s1, s2, s8
+; GCN-NEXT:    s_and_b32 s0, s0, s8
+; GCN-NEXT:    v_mov_b32_e32 v0, s0
+; GCN-NEXT:    v_mov_b32_e32 v2, s1
+; GCN-NEXT:    v_mov_b32_e32 v3, v1
+; GCN-NEXT:    buffer_store_dwordx4 v[0:3], off, s[4:7], 0
+; GCN-NEXT:    s_endpgm
+  %r = urem <2 x i64> %x, <i64 4096, i64 4096>
+  store <2 x i64> %r, <2 x i64> addrspace(1)* %out
+  ret void
+}
+
+define amdgpu_kernel void @urem_v2i64_pow2_shl_denom(<2 x i64> addrspace(1)* %out, <2 x i64> %x, <2 x i64> %y) {
+; CHECK-LABEL: @urem_v2i64_pow2_shl_denom(
+; CHECK-NEXT:    [[SHL_Y:%.*]] = shl <2 x i64> <i64 4096, i64 4096>, [[Y:%.*]]
+; CHECK-NEXT:    [[R:%.*]] = urem <2 x i64> [[X:%.*]], [[SHL_Y]]
+; CHECK-NEXT:    store <2 x i64> [[R]], <2 x i64> addrspace(1)* [[OUT:%.*]]
+; CHECK-NEXT:    ret void
+;
+; GCN-LABEL: urem_v2i64_pow2_shl_denom:
+; GCN:       ; %bb.0:
+; GCN-NEXT:    s_load_dwordx2 s[4:5], s[0:1], 0x9
+; GCN-NEXT:    s_load_dwordx4 s[8:11], s[0:1], 0xd
+; GCN-NEXT:    s_load_dwordx4 s[0:3], s[0:1], 0x11
+; GCN-NEXT:    s_mov_b32 s13, 0
+; GCN-NEXT:    s_movk_i32 s12, 0x1000
+; GCN-NEXT:    s_mov_b32 s7, 0xf000
+; GCN-NEXT:    s_mov_b32 s6, -1
+; GCN-NEXT:    s_waitcnt lgkmcnt(0)
+; GCN-NEXT:    s_lshl_b64 s[0:1], s[12:13], s0
+; GCN-NEXT:    s_lshl_b64 s[2:3], s[12:13], s2
+; GCN-NEXT:    s_add_u32 s2, s2, -1
+; GCN-NEXT:    s_addc_u32 s3, s3, -1
+; GCN-NEXT:    s_and_b64 s[2:3], s[10:11], s[2:3]
+; GCN-NEXT:    s_add_u32 s0, s0, -1
+; GCN-NEXT:    s_addc_u32 s1, s1, -1
+; GCN-NEXT:    s_and_b64 s[0:1], s[8:9], s[0:1]
+; GCN-NEXT:    v_mov_b32_e32 v0, s0
+; GCN-NEXT:    v_mov_b32_e32 v1, s1
+; GCN-NEXT:    v_mov_b32_e32 v2, s2
+; GCN-NEXT:    v_mov_b32_e32 v3, s3
+; GCN-NEXT:    buffer_store_dwordx4 v[0:3], off, s[4:7], 0
+; GCN-NEXT:    s_endpgm
+  %shl.y = shl <2 x i64> <i64 4096, i64 4096>, %y
+  %r = urem <2 x i64> %x, %shl.y
+  store <2 x i64> %r, <2 x i64> addrspace(1)* %out
+  ret void
+}
+
+define amdgpu_kernel void @sdiv_i64_oddk_denom(i64 addrspace(1)* %out, i64 %x) {
+; CHECK-LABEL: @sdiv_i64_oddk_denom(
+; CHECK-NEXT:    [[R:%.*]] = sdiv i64 [[X:%.*]], 1235195
+; CHECK-NEXT:    store i64 [[R]], i64 addrspace(1)* [[OUT:%.*]]
+; CHECK-NEXT:    ret void
+;
+; GCN-LABEL: sdiv_i64_oddk_denom:
+; GCN:       ; %bb.0:
+; GCN-NEXT:    v_mov_b32_e32 v0, 0x4f800000
+; GCN-NEXT:    v_madak_f32 v0, 0, v0, 0x4996c7d8
+; GCN-NEXT:    v_rcp_f32_e32 v0, v0
+; GCN-NEXT:    s_mov_b32 s2, 0xffed2705
+; GCN-NEXT:    v_mov_b32_e32 v8, 0
+; GCN-NEXT:    v_mov_b32_e32 v7, 0
+; GCN-NEXT:    v_mul_f32_e32 v0, 0x5f7ffffc, v0
+; GCN-NEXT:    v_mul_f32_e32 v1, 0x2f800000, v0
+; GCN-NEXT:    v_trunc_f32_e32 v1, v1
+; GCN-NEXT:    v_mac_f32_e32 v0, 0xcf800000, v1
+; GCN-NEXT:    v_cvt_u32_f32_e32 v0, v0
+; GCN-NEXT:    v_cvt_u32_f32_e32 v1, v1
+; GCN-NEXT:    s_load_dwordx4 s[8:11], s[0:1], 0x9
+; GCN-NEXT:    s_mov_b32 s7, 0xf000
+; GCN-NEXT:    v_mul_hi_u32 v3, s2, v0
+; GCN-NEXT:    v_mul_lo_u32 v2, v1, s2
+; GCN-NEXT:    v_mul_lo_u32 v4, v0, s2
+; GCN-NEXT:    s_mov_b32 s6, -1
+; GCN-NEXT:    s_waitcnt lgkmcnt(0)
+; GCN-NEXT:    s_mov_b32 s4, s8
+; GCN-NEXT:    v_add_i32_e32 v2, vcc, v3, v2
+; GCN-NEXT:    v_subrev_i32_e32 v2, vcc, v0, v2
+; GCN-NEXT:    v_mul_lo_u32 v5, v0, v2
+; GCN-NEXT:    v_mul_hi_u32 v6, v0, v4
+; GCN-NEXT:    v_mul_hi_u32 v3, v0, v2
+; GCN-NEXT:    v_mul_hi_u32 v9, v1, v2
+; GCN-NEXT:    v_mul_lo_u32 v2, v1, v2
+; GCN-NEXT:    v_add_i32_e32 v5, vcc, v6, v5
+; GCN-NEXT:    v_mul_lo_u32 v6, v1, v4
+; GCN-NEXT:    v_mul_hi_u32 v4, v1, v4
+; GCN-NEXT:    v_addc_u32_e32 v3, vcc, v8, v3, vcc
+; GCN-NEXT:    s_mov_b32 s5, s9
+; GCN-NEXT:    v_add_i32_e32 v5, vcc, v6, v5
+; GCN-NEXT:    v_addc_u32_e32 v3, vcc, v3, v4, vcc
+; GCN-NEXT:    v_addc_u32_e32 v4, vcc, v9, v7, vcc
+; GCN-NEXT:    v_add_i32_e32 v2, vcc, v3, v2
+; GCN-NEXT:    v_add_i32_e64 v0, s[0:1], v0, v2
+; GCN-NEXT:    v_addc_u32_e32 v3, vcc, v8, v4, vcc
+; GCN-NEXT:    v_addc_u32_e64 v2, vcc, v1, v3, s[0:1]
+; GCN-NEXT:    v_mul_lo_u32 v4, v2, s2
+; GCN-NEXT:    v_mul_hi_u32 v5, s2, v0
+; GCN-NEXT:    v_add_i32_e32 v4, vcc, v5, v4
+; GCN-NEXT:    v_mul_lo_u32 v5, v0, s2
+; GCN-NEXT:    v_subrev_i32_e32 v4, vcc, v0, v4
+; GCN-NEXT:    v_mul_lo_u32 v10, v0, v4
+; GCN-NEXT:    v_mul_hi_u32 v12, v0, v4
+; GCN-NEXT:    v_mul_hi_u32 v11, v0, v5
+; GCN-NEXT:    v_mul_hi_u32 v9, v2, v5
+; GCN-NEXT:    v_mul_lo_u32 v5, v2, v5
+; GCN-NEXT:    v_mul_hi_u32 v6, v2, v4
+; GCN-NEXT:    v_add_i32_e32 v10, vcc, v11, v10
+; GCN-NEXT:    v_addc_u32_e32 v11, vcc, v8, v12, vcc
+; GCN-NEXT:    v_mul_lo_u32 v2, v2, v4
+; GCN-NEXT:    v_add_i32_e32 v5, vcc, v5, v10
+; GCN-NEXT:    v_addc_u32_e32 v5, vcc, v11, v9, vcc
+; GCN-NEXT:    v_addc_u32_e32 v4, vcc, v6, v7, vcc
+; GCN-NEXT:    v_add_i32_e32 v2, vcc, v5, v2
+; GCN-NEXT:    v_addc_u32_e32 v4, vcc, v8, v4, vcc
+; GCN-NEXT:    v_add_i32_e32 v1, vcc, v1, v3
+; GCN-NEXT:    s_ashr_i32 s2, s11, 31
+; GCN-NEXT:    v_addc_u32_e64 v1, vcc, v1, v4, s[0:1]
+; GCN-NEXT:    s_add_u32 s0, s10, s2
+; GCN-NEXT:    v_add_i32_e32 v0, vcc, v0, v2
+; GCN-NEXT:    s_mov_b32 s3, s2
+; GCN-NEXT:    s_addc_u32 s1, s11, s2
+; GCN-NEXT:    s_xor_b64 s[0:1], s[0:1], s[2:3]
+; GCN-NEXT:    v_addc_u32_e32 v1, vcc, 0, v1, vcc
+; GCN-NEXT:    v_mul_lo_u32 v2, s0, v1
+; GCN-NEXT:    v_mul_hi_u32 v3, s0, v0
+; GCN-NEXT:    v_mul_hi_u32 v4, s0, v1
+; GCN-NEXT:    v_mul_hi_u32 v5, s1, v1
+; GCN-NEXT:    v_mul_lo_u32 v1, s1, v1
+; GCN-NEXT:    v_add_i32_e32 v2, vcc, v3, v2
+; GCN-NEXT:    v_addc_u32_e32 v3, vcc, v8, v4, vcc
+; GCN-NEXT:    v_mul_lo_u32 v4, s1, v0
+; GCN-NEXT:    v_mul_hi_u32 v0, s1, v0
+; GCN-NEXT:    s_mov_b32 s3, 0x12d8fb
+; GCN-NEXT:    v_add_i32_e32 v2, vcc, v4, v2
+; GCN-NEXT:    v_addc_u32_e32 v0, vcc, v3, v0, vcc
+; GCN-NEXT:    v_addc_u32_e32 v2, vcc, v5, v7, vcc
+; GCN-NEXT:    v_add_i32_e32 v0, vcc, v0, v1
+; GCN-NEXT:    v_addc_u32_e32 v1, vcc, v8, v2, vcc
+; GCN-NEXT:    v_mul_lo_u32 v2, v1, s3
+; GCN-NEXT:    v_mul_hi_u32 v3, s3, v0
+; GCN-NEXT:    v_mul_lo_u32 v4, v0, s3
+; GCN-NEXT:    v_add_i32_e32 v2, vcc, v3, v2
+; GCN-NEXT:    v_sub_i32_e32 v4, vcc, s0, v4
+; GCN-NEXT:    v_mov_b32_e32 v3, s1
+; GCN-NEXT:    v_subb_u32_e32 v2, vcc, v3, v2, vcc
+; GCN-NEXT:    v_subrev_i32_e32 v3, vcc, s3, v4
+; GCN-NEXT:    v_subbrev_u32_e32 v5, vcc, 0, v2, vcc
+; GCN-NEXT:    s_mov_b32 s0, 0x12d8fa
+; GCN-NEXT:    v_cmp_lt_u32_e32 vcc, s0, v3
+; GCN-NEXT:    v_cndmask_b32_e64 v3, 0, -1, vcc
+; GCN-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v5
+; GCN-NEXT:    v_cndmask_b32_e32 v3, -1, v3, vcc
+; GCN-NEXT:    v_add_i32_e32 v5, vcc, 2, v0
+; GCN-NEXT:    v_addc_u32_e32 v6, vcc, 0, v1, vcc
+; GCN-NEXT:    v_add_i32_e32 v7, vcc, 1, v0
+; GCN-NEXT:    v_cmp_lt_u32_e64 s[0:1], s0, v4
+; GCN-NEXT:    v_addc_u32_e32 v8, vcc, 0, v1, vcc
+; GCN-NEXT:    v_cndmask_b32_e64 v4, 0, -1, s[0:1]
+; GCN-NEXT:    v_cmp_eq_u32_e64 s[0:1], 0, v2
+; GCN-NEXT:    v_cmp_ne_u32_e32 vcc, 0, v3
+; GCN-NEXT:    v_cndmask_b32_e64 v2, -1, v4, s[0:1]
+; GCN-NEXT:    v_cmp_ne_u32_e64 s[0:1], 0, v2
+; GCN-NEXT:    v_cndmask_b32_e32 v2, v7, v5, vcc
+; GCN-NEXT:    v_cndmask_b32_e64 v0, v0, v2, s[0:1]
+; GCN-NEXT:    v_cndmask_b32_e32 v3, v8, v6, vcc
+; GCN-NEXT:    v_cndmask_b32_e64 v1, v1, v3, s[0:1]
+; GCN-NEXT:    v_xor_b32_e32 v0, s2, v0
+; GCN-NEXT:    v_xor_b32_e32 v1, s2, v1
+; GCN-NEXT:    v_mov_b32_e32 v2, s2
+; GCN-NEXT:    v_subrev_i32_e32 v0, vcc, s2, v0
+; GCN-NEXT:    v_subb_u32_e32 v1, vcc, v1, v2, vcc
+; GCN-NEXT:    buffer_store_dwordx2 v[0:1], off, s[4:7], 0
+; GCN-NEXT:    s_endpgm
+  %r = sdiv i64 %x, 1235195
+  store i64 %r, i64 addrspace(1)* %out
+  ret void
+}
+
+define amdgpu_kernel void @sdiv_i64_pow2k_denom(i64 addrspace(1)* %out, i64 %x) {
+; CHECK-LABEL: @sdiv_i64_pow2k_denom(
+; CHECK-NEXT:    [[R:%.*]] = sdiv i64 [[X:%.*]], 4096
+; CHECK-NEXT:    store i64 [[R]], i64 addrspace(1)* [[OUT:%.*]]
+; CHECK-NEXT:    ret void
+;
+; GCN-LABEL: sdiv_i64_pow2k_denom:
+; GCN:       ; %bb.0:
+; GCN-NEXT:    s_load_dwordx4 s[4:7], s[0:1], 0x9
+; GCN-NEXT:    s_mov_b32 s3, 0xf000
+; GCN-NEXT:    s_mov_b32 s2, -1
+; GCN-NEXT:    s_waitcnt lgkmcnt(0)
+; GCN-NEXT:    s_mov_b32 s0, s4
+; GCN-NEXT:    s_ashr_i32 s4, s7, 31
+; GCN-NEXT:    s_lshr_b32 s4, s4, 20
+; GCN-NEXT:    s_add_u32 s4, s6, s4
+; GCN-NEXT:    s_mov_b32 s1, s5
+; GCN-NEXT:    s_addc_u32 s5, s7, 0
+; GCN-NEXT:    s_ashr_i64 s[4:5], s[4:5], 12
+; GCN-NEXT:    v_mov_b32_e32 v0, s4
+; GCN-NEXT:    v_mov_b32_e32 v1, s5
+; GCN-NEXT:    buffer_store_dwordx2 v[0:1], off, s[0:3], 0
+; GCN-NEXT:    s_endpgm
+  %r = sdiv i64 %x, 4096
+  store i64 %r, i64 addrspace(1)* %out
+  ret void
+}
+
+define amdgpu_kernel void @sdiv_i64_pow2_shl_denom(i64 addrspace(1)* %out, i64 %x, i64 %y) {
+; CHECK-LABEL: @sdiv_i64_pow2_shl_denom(
+; CHECK-NEXT:    [[SHL_Y:%.*]] = shl i64 4096, [[Y:%.*]]
+; CHECK-NEXT:    [[R:%.*]] = sdiv i64 [[X:%.*]], [[SHL_Y]]
+; CHECK-NEXT:    store i64 [[R]], i64 addrspace(1)* [[OUT:%.*]]
+; CHECK-NEXT:    ret void
+;
+; GCN-LABEL: sdiv_i64_pow2_shl_denom:
+; GCN:       ; %bb.0:
+; GCN-NEXT:    s_load_dword s4, s[0:1], 0xd
+; GCN-NEXT:    s_mov_b32 s3, 0
+; GCN-NEXT:    s_movk_i32 s2, 0x1000
+; GCN-NEXT:    s_load_dwordx4 s[8:11], s[0:1], 0x9
+; GCN-NEXT:    s_mov_b32 s7, 0xf000
+; GCN-NEXT:    s_waitcnt lgkmcnt(0)
+; GCN-NEXT:    s_lshl_b64 s[2:3], s[2:3], s4
+; GCN-NEXT:    s_ashr_i32 s12, s3, 31
+; GCN-NEXT:    s_add_u32 s2, s2, s12
+; GCN-NEXT:    s_mov_b32 s13, s12
+; GCN-NEXT:    s_addc_u32 s3, s3, s12
+; GCN-NEXT:    s_xor_b64 s[2:3], s[2:3], s[12:13]
+; GCN-NEXT:    v_cvt_f32_u32_e32 v0, s2
+; GCN-NEXT:    v_cvt_f32_u32_e32 v1, s3
+; GCN-NEXT:    s_sub_u32 s4, 0, s2
+; GCN-NEXT:    s_subb_u32 s5, 0, s3
+; GCN-NEXT:    s_ashr_i32 s14, s11, 31
+; GCN-NEXT:    v_mac_f32_e32 v0, 0x4f800000, v1
+; GCN-NEXT:    v_rcp_f32_e32 v0, v0
+; GCN-NEXT:    s_mov_b32 s15, s14
+; GCN-NEXT:    s_mov_b32 s6, -1
+; GCN-NEXT:    v_mul_f32_e32 v0, 0x5f7ffffc, v0
+; GCN-NEXT:    v_mul_f32_e32 v1, 0x2f800000, v0
+; GCN-NEXT:    v_trunc_f32_e32 v1, v1
+; GCN-NEXT:    v_mac_f32_e32 v0, 0xcf800000, v1
+; GCN-NEXT:    v_cvt_u32_f32_e32 v0, v0
+; GCN-NEXT:    v_cvt_u32_f32_e32 v1, v1
+; GCN-NEXT:    v_mul_hi_u32 v3, s4, v0
+; GCN-NEXT:    v_mul_lo_u32 v2, s4, v1
+; GCN-NEXT:    v_mul_lo_u32 v5, s5, v0
+; GCN-NEXT:    v_mul_lo_u32 v4, s4, v0
+; GCN-NEXT:    v_add_i32_e32 v2, vcc, v3, v2
+; GCN-NEXT:    v_add_i32_e32 v2, vcc, v2, v5
+; GCN-NEXT:    v_mul_hi_u32 v3, v0, v4
+; GCN-NEXT:    v_mul_lo_u32 v5, v0, v2
+; GCN-NEXT:    v_mul_hi_u32 v6, v0, v2
+; GCN-NEXT:    v_mul_hi_u32 v7, v1, v2
+; GCN-NEXT:    v_mul_lo_u32 v2, v1, v2
+; GCN-NEXT:    v_add_i32_e32 v3, vcc, v3, v5
+; GCN-NEXT:    v_addc_u32_e32 v5, vcc, 0, v6, vcc
+; GCN-NEXT:    v_mul_lo_u32 v6, v1, v4
+; GCN-NEXT:    v_mul_hi_u32 v4, v1, v4
+; GCN-NEXT:    v_add_i32_e32 v3, vcc, v6, v3
+; GCN-NEXT:    v_addc_u32_e32 v3, vcc, v5, v4, vcc
+; GCN-NEXT:    v_mov_b32_e32 v4, 0
+; GCN-NEXT:    v_addc_u32_e32 v5, vcc, v7, v4, vcc
+; GCN-NEXT:    v_add_i32_e32 v2, vcc, v3, v2
+; GCN-NEXT:    v_mov_b32_e32 v6, 0
+; GCN-NEXT:    v_add_i32_e64 v0, s[0:1], v0, v2
+; GCN-NEXT:    v_addc_u32_e32 v3, vcc, v6, v5, vcc
+; GCN-NEXT:    v_addc_u32_e64 v2, vcc, v1, v3, s[0:1]
+; GCN-NEXT:    v_mul_lo_u32 v5, s4, v2
+; GCN-NEXT:    v_mul_hi_u32 v7, s4, v0
+; GCN-NEXT:    v_mul_lo_u32 v8, s5, v0
+; GCN-NEXT:    s_mov_b32 s5, s9
+; GCN-NEXT:    v_add_i32_e32 v5, vcc, v7, v5
+; GCN-NEXT:    v_mul_lo_u32 v7, s4, v0
+; GCN-NEXT:    v_add_i32_e32 v5, vcc, v8, v5
+; GCN-NEXT:    v_mul_lo_u32 v10, v0, v5
+; GCN-NEXT:    v_mul_hi_u32 v12, v0, v5
+; GCN-NEXT:    v_mul_hi_u32 v11, v0, v7
+; GCN-NEXT:    v_mul_hi_u32 v9, v2, v7
+; GCN-NEXT:    v_mul_lo_u32 v7, v2, v7
+; GCN-NEXT:    v_mul_hi_u32 v8, v2, v5
+; GCN-NEXT:    v_add_i32_e32 v10, vcc, v11, v10
+; GCN-NEXT:    v_addc_u32_e32 v11, vcc, 0, v12, vcc
+; GCN-NEXT:    v_mul_lo_u32 v2, v2, v5
+; GCN-NEXT:    v_add_i32_e32 v7, vcc, v7, v10
+; GCN-NEXT:    v_addc_u32_e32 v7, vcc, v11, v9, vcc
+; GCN-NEXT:    v_addc_u32_e32 v5, vcc, v8, v4, vcc
+; GCN-NEXT:    v_add_i32_e32 v2, vcc, v7, v2
+; GCN-NEXT:    v_addc_u32_e32 v5, vcc, v6, v5, vcc
+; GCN-NEXT:    v_add_i32_e32 v1, vcc, v1, v3
+; GCN-NEXT:    v_addc_u32_e64 v1, vcc, v1, v5, s[0:1]
+; GCN-NEXT:    s_add_u32 s0, s10, s14
+; GCN-NEXT:    s_addc_u32 s1, s11, s14
+; GCN-NEXT:    v_add_i32_e32 v0, vcc, v0, v2
+; GCN-NEXT:    s_xor_b64 s[10:11], s[0:1], s[14:15]
+; GCN-NEXT:    v_addc_u32_e32 v1, vcc, 0, v1, vcc
+; GCN-NEXT:    v_mul_lo_u32 v2, s10, v1
+; GCN-NEXT:    v_mul_hi_u32 v3, s10, v0
+; GCN-NEXT:    v_mul_hi_u32 v5, s10, v1
+; GCN-NEXT:    v_mul_hi_u32 v7, s11, v1
+; GCN-NEXT:    v_mul_lo_u32 v1, s11, v1
+; GCN-NEXT:    v_add_i32_e32 v2, vcc, v3, v2
+; GCN-NEXT:    v_addc_u32_e32 v3, vcc, 0, v5, vcc
+; GCN-NEXT:    v_mul_lo_u32 v5, s11, v0
+; GCN-NEXT:    v_mul_hi_u32 v0, s11, v0
+; GCN-NEXT:    s_mov_b32 s4, s8
+; GCN-NEXT:    v_add_i32_e32 v2, vcc, v5, v2
+; GCN-NEXT:    v_addc_u32_e32 v0, vcc, v3, v0, vcc
+; GCN-NEXT:    v_addc_u32_e32 v2, vcc, v7, v4, vcc
+; GCN-NEXT:    v_add_i32_e32 v0, vcc, v0, v1
+; GCN-NEXT:    v_addc_u32_e32 v1, vcc, v6, v2, vcc
+; GCN-NEXT:    v_mul_lo_u32 v2, s2, v1
+; GCN-NEXT:    v_mul_hi_u32 v3, s2, v0
+; GCN-NEXT:    v_mul_lo_u32 v4, s3, v0
+; GCN-NEXT:    v_mov_b32_e32 v5, s3
+; GCN-NEXT:    v_add_i32_e32 v2, vcc, v3, v2
+; GCN-NEXT:    v_mul_lo_u32 v3, s2, v0
+; GCN-NEXT:    v_add_i32_e32 v2, vcc, v2, v4
+; GCN-NEXT:    v_sub_i32_e32 v4, vcc, s11, v2
+; GCN-NEXT:    v_sub_i32_e32 v3, vcc, s10, v3
+; GCN-NEXT:    v_subb_u32_e64 v4, s[0:1], v4, v5, vcc
+; GCN-NEXT:    v_subrev_i32_e64 v5, s[0:1], s2, v3
+; GCN-NEXT:    v_subbrev_u32_e64 v4, s[0:1], 0, v4, s[0:1]
+; GCN-NEXT:    v_cmp_le_u32_e64 s[0:1], s3, v4
+; GCN-NEXT:    v_cndmask_b32_e64 v6, 0, -1, s[0:1]
+; GCN-NEXT:    v_cmp_le_u32_e64 s[0:1], s2, v5
+; GCN-NEXT:    v_cndmask_b32_e64 v5, 0, -1, s[0:1]
+; GCN-NEXT:    v_cmp_eq_u32_e64 s[0:1], s3, v4
+; GCN-NEXT:    v_cndmask_b32_e64 v4, v6, v5, s[0:1]
+; GCN-NEXT:    v_add_i32_e64 v5, s[0:1], 2, v0
+; GCN-NEXT:    v_addc_u32_e64 v6, s[0:1], 0, v1, s[0:1]
+; GCN-NEXT:    v_add_i32_e64 v7, s[0:1], 1, v0
+; GCN-NEXT:    v_addc_u32_e64 v8, s[0:1], 0, v1, s[0:1]
+; GCN-NEXT:    v_cmp_ne_u32_e64 s[0:1], 0, v4
+; GCN-NEXT:    v_cndmask_b32_e64 v4, v8, v6, s[0:1]
+; GCN-NEXT:    v_mov_b32_e32 v6, s11
+; GCN-NEXT:    v_subb_u32_e32 v2, vcc, v6, v2, vcc
+; GCN-NEXT:    v_cmp_le_u32_e32 vcc, s3, v2
+; GCN-NEXT:    v_cndmask_b32_e64 v6, 0, -1, vcc
+; GCN-NEXT:    v_cmp_le_u32_e32 vcc, s2, v3
+; GCN-NEXT:    v_cndmask_b32_e64 v3, 0, -1, vcc
+; GCN-NEXT:    v_cmp_eq_u32_e32 vcc, s3, v2
+; GCN-NEXT:    v_cndmask_b32_e32 v2, v6, v3, vcc
+; GCN-NEXT:    v_cmp_ne_u32_e32 vcc, 0, v2
+; GCN-NEXT:    v_cndmask_b32_e64 v2, v7, v5, s[0:1]
+; GCN-NEXT:    v_cndmask_b32_e32 v0, v0, v2, vcc
+; GCN-NEXT:    s_xor_b64 s[0:1], s[14:15], s[12:13]
+; GCN-NEXT:    v_cndmask_b32_e32 v1, v1, v4, vcc
+; GCN-NEXT:    v_xor_b32_e32 v0, s0, v0
+; GCN-NEXT:    v_xor_b32_e32 v1, s1, v1
+; GCN-NEXT:    v_mov_b32_e32 v2, s1
+; GCN-NEXT:    v_subrev_i32_e32 v0, vcc, s0, v0
+; GCN-NEXT:    v_subb_u32_e32 v1, vcc, v1, v2, vcc
+; GCN-NEXT:    buffer_store_dwordx2 v[0:1], off, s[4:7], 0
+; GCN-NEXT:    s_endpgm
+  %shl.y = shl i64 4096, %y
+  %r = sdiv i64 %x, %shl.y
+  store i64 %r, i64 addrspace(1)* %out
+  ret void
+}
+
+define amdgpu_kernel void @sdiv_v2i64_pow2k_denom(<2 x i64> addrspace(1)* %out, <2 x i64> %x) {
+; CHECK-LABEL: @sdiv_v2i64_pow2k_denom(
+; CHECK-NEXT:    [[R:%.*]] = sdiv <2 x i64> [[X:%.*]], <i64 4096, i64 4096>
+; CHECK-NEXT:    store <2 x i64> [[R]], <2 x i64> addrspace(1)* [[OUT:%.*]]
+; CHECK-NEXT:    ret void
+;
+; GCN-LABEL: sdiv_v2i64_pow2k_denom:
+; GCN:       ; %bb.0:
+; GCN-NEXT:    s_load_dwordx2 s[4:5], s[0:1], 0x9
+; GCN-NEXT:    s_load_dwordx4 s[0:3], s[0:1], 0xd
+; GCN-NEXT:    s_mov_b32 s7, 0xf000
+; GCN-NEXT:    s_mov_b32 s6, -1
+; GCN-NEXT:    s_waitcnt lgkmcnt(0)
+; GCN-NEXT:    s_ashr_i32 s8, s3, 31
+; GCN-NEXT:    s_lshr_b32 s8, s8, 20
+; GCN-NEXT:    s_add_u32 s2, s2, s8
+; GCN-NEXT:    s_addc_u32 s3, s3, 0
+; GCN-NEXT:    s_ashr_i32 s8, s1, 31
+; GCN-NEXT:    s_ashr_i64 s[2:3], s[2:3], 12
+; GCN-NEXT:    s_lshr_b32 s8, s8, 20
+; GCN-NEXT:    s_add_u32 s0, s0, s8
+; GCN-NEXT:    s_addc_u32 s1, s1, 0
+; GCN-NEXT:    s_ashr_i64 s[0:1], s[0:1], 12
+; GCN-NEXT:    v_mov_b32_e32 v0, s0
+; GCN-NEXT:    v_mov_b32_e32 v1, s1
+; GCN-NEXT:    v_mov_b32_e32 v2, s2
+; GCN-NEXT:    v_mov_b32_e32 v3, s3
+; GCN-NEXT:    buffer_store_dwordx4 v[0:3], off, s[4:7], 0
+; GCN-NEXT:    s_endpgm
+  %r = sdiv <2 x i64> %x, <i64 4096, i64 4096>
+  store <2 x i64> %r, <2 x i64> addrspace(1)* %out
+  ret void
+}
+
+define amdgpu_kernel void @ssdiv_v2i64_mixed_pow2k_denom(<2 x i64> addrspace(1)* %out, <2 x i64> %x) {
+; CHECK-LABEL: @ssdiv_v2i64_mixed_pow2k_denom(
+; CHECK-NEXT:    [[R:%.*]] = sdiv <2 x i64> [[X:%.*]], <i64 4096, i64 4095>
+; CHECK-NEXT:    store <2 x i64> [[R]], <2 x i64> addrspace(1)* [[OUT:%.*]]
+; CHECK-NEXT:    ret void
+;
+; GCN-LABEL: ssdiv_v2i64_mixed_pow2k_denom:
+; GCN:       ; %bb.0:
+; GCN-NEXT:    v_mov_b32_e32 v0, 0x4f800000
+; GCN-NEXT:    v_madak_f32 v0, 0, v0, 0x457ff000
+; GCN-NEXT:    v_rcp_f32_e32 v0, v0
+; GCN-NEXT:    s_movk_i32 s6, 0xf001
+; GCN-NEXT:    v_mov_b32_e32 v7, 0
+; GCN-NEXT:    v_mov_b32_e32 v5, 0
+; GCN-NEXT:    v_mul_f32_e32 v0, 0x5f7ffffc, v0
+; GCN-NEXT:    v_mul_f32_e32 v1, 0x2f800000, v0
+; GCN-NEXT:    v_trunc_f32_e32 v1, v1
+; GCN-NEXT:    v_mac_f32_e32 v0, 0xcf800000, v1
+; GCN-NEXT:    v_cvt_u32_f32_e32 v0, v0
+; GCN-NEXT:    v_cvt_u32_f32_e32 v1, v1
+; GCN-NEXT:    s_load_dwordx2 s[4:5], s[0:1], 0x9
+; GCN-NEXT:    s_load_dwordx4 s[8:11], s[0:1], 0xd
+; GCN-NEXT:    s_mov_b32 s7, 0xf000
+; GCN-NEXT:    v_mul_hi_u32 v3, s6, v0
+; GCN-NEXT:    v_mul_lo_u32 v2, v1, s6
+; GCN-NEXT:    v_mul_lo_u32 v4, v0, s6
+; GCN-NEXT:    v_add_i32_e32 v2, vcc, v3, v2
+; GCN-NEXT:    v_subrev_i32_e32 v2, vcc, v0, v2
+; GCN-NEXT:    v_mul_hi_u32 v3, v0, v4
+; GCN-NEXT:    v_mul_lo_u32 v6, v0, v2
+; GCN-NEXT:    v_mul_hi_u32 v8, v0, v2
+; GCN-NEXT:    v_mul_hi_u32 v9, v1, v2
+; GCN-NEXT:    v_mul_lo_u32 v2, v1, v2
+; GCN-NEXT:    v_add_i32_e32 v3, vcc, v3, v6
+; GCN-NEXT:    v_addc_u32_e32 v6, vcc, v7, v8, vcc
+; GCN-NEXT:    v_mul_lo_u32 v8, v1, v4
+; GCN-NEXT:    v_mul_hi_u32 v4, v1, v4
+; GCN-NEXT:    v_add_i32_e32 v3, vcc, v8, v3
+; GCN-NEXT:    v_addc_u32_e32 v3, vcc, v6, v4, vcc
+; GCN-NEXT:    v_addc_u32_e32 v4, vcc, v9, v5, vcc
+; GCN-NEXT:    v_add_i32_e32 v2, vcc, v3, v2
+; GCN-NEXT:    v_add_i32_e64 v0, s[2:3], v0, v2
+; GCN-NEXT:    v_addc_u32_e32 v3, vcc, v7, v4, vcc
+; GCN-NEXT:    v_addc_u32_e64 v2, vcc, v1, v3, s[2:3]
+; GCN-NEXT:    v_mul_lo_u32 v4, v2, s6
+; GCN-NEXT:    v_mul_hi_u32 v6, s6, v0
+; GCN-NEXT:    v_add_i32_e32 v4, vcc, v6, v4
+; GCN-NEXT:    v_mul_lo_u32 v6, v0, s6
+; GCN-NEXT:    v_subrev_i32_e32 v4, vcc, v0, v4
+; GCN-NEXT:    v_mul_lo_u32 v10, v0, v4
+; GCN-NEXT:    v_mul_hi_u32 v12, v0, v4
+; GCN-NEXT:    v_mul_hi_u32 v11, v0, v6
+; GCN-NEXT:    v_mul_hi_u32 v9, v2, v6
+; GCN-NEXT:    v_mul_lo_u32 v6, v2, v6
+; GCN-NEXT:    v_mul_hi_u32 v8, v2, v4
+; GCN-NEXT:    v_add_i32_e32 v10, vcc, v11, v10
+; GCN-NEXT:    v_addc_u32_e32 v11, vcc, v7, v12, vcc
+; GCN-NEXT:    v_mul_lo_u32 v2, v2, v4
+; GCN-NEXT:    v_add_i32_e32 v6, vcc, v6, v10
+; GCN-NEXT:    v_addc_u32_e32 v6, vcc, v11, v9, vcc
+; GCN-NEXT:    v_addc_u32_e32 v4, vcc, v8, v5, vcc
+; GCN-NEXT:    v_add_i32_e32 v2, vcc, v6, v2
+; GCN-NEXT:    v_addc_u32_e32 v4, vcc, v7, v4, vcc
+; GCN-NEXT:    v_add_i32_e32 v1, vcc, v1, v3
+; GCN-NEXT:    v_addc_u32_e64 v1, vcc, v1, v4, s[2:3]
+; GCN-NEXT:    s_waitcnt lgkmcnt(0)
+; GCN-NEXT:    s_ashr_i32 s2, s11, 31
+; GCN-NEXT:    s_add_u32 s0, s10, s2
+; GCN-NEXT:    v_add_i32_e32 v0, vcc, v0, v2
+; GCN-NEXT:    s_mov_b32 s3, s2
+; GCN-NEXT:    s_addc_u32 s1, s11, s2
+; GCN-NEXT:    s_xor_b64 s[0:1], s[0:1], s[2:3]
+; GCN-NEXT:    v_addc_u32_e32 v1, vcc, 0, v1, vcc
+; GCN-NEXT:    v_mul_lo_u32 v2, s0, v1
+; GCN-NEXT:    v_mul_hi_u32 v3, s0, v0
+; GCN-NEXT:    v_mul_hi_u32 v4, s0, v1
+; GCN-NEXT:    v_mul_hi_u32 v6, s1, v1
+; GCN-NEXT:    v_mul_lo_u32 v1, s1, v1
+; GCN-NEXT:    v_add_i32_e32 v2, vcc, v3, v2
+; GCN-NEXT:    v_addc_u32_e32 v3, vcc, v7, v4, vcc
+; GCN-NEXT:    v_mul_lo_u32 v4, s1, v0
+; GCN-NEXT:    v_mul_hi_u32 v0, s1, v0
+; GCN-NEXT:    s_movk_i32 s3, 0xfff
+; GCN-NEXT:    s_mov_b32 s6, -1
+; GCN-NEXT:    v_add_i32_e32 v2, vcc, v4, v2
+; GCN-NEXT:    v_addc_u32_e32 v0, vcc, v3, v0, vcc
+; GCN-NEXT:    v_addc_u32_e32 v2, vcc, v6, v5, vcc
+; GCN-NEXT:    v_add_i32_e32 v0, vcc, v0, v1
+; GCN-NEXT:    v_addc_u32_e32 v1, vcc, v7, v2, vcc
+; GCN-NEXT:    v_mul_lo_u32 v2, v1, s3
+; GCN-NEXT:    v_mul_hi_u32 v3, s3, v0
+; GCN-NEXT:    v_mul_lo_u32 v4, v0, s3
+; GCN-NEXT:    v_add_i32_e32 v2, vcc, v3, v2
+; GCN-NEXT:    v_sub_i32_e32 v4, vcc, s0, v4
+; GCN-NEXT:    v_mov_b32_e32 v3, s1
+; GCN-NEXT:    v_subb_u32_e32 v2, vcc, v3, v2, vcc
+; GCN-NEXT:    v_subrev_i32_e32 v3, vcc, s3, v4
+; GCN-NEXT:    v_subbrev_u32_e32 v5, vcc, 0, v2, vcc
+; GCN-NEXT:    s_movk_i32 s0, 0xffe
+; GCN-NEXT:    v_cmp_lt_u32_e32 vcc, s0, v3
+; GCN-NEXT:    v_cndmask_b32_e64 v3, 0, -1, vcc
+; GCN-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v5
+; GCN-NEXT:    v_cndmask_b32_e32 v3, -1, v3, vcc
+; GCN-NEXT:    v_add_i32_e32 v5, vcc, 2, v0
+; GCN-NEXT:    v_addc_u32_e32 v6, vcc, 0, v1, vcc
+; GCN-NEXT:    v_add_i32_e32 v7, vcc, 1, v0
+; GCN-NEXT:    v_cmp_lt_u32_e64 s[0:1], s0, v4
+; GCN-NEXT:    v_addc_u32_e32 v8, vcc, 0, v1, vcc
+; GCN-NEXT:    v_cndmask_b32_e64 v4, 0, -1, s[0:1]
+; GCN-NEXT:    v_cmp_eq_u32_e64 s[0:1], 0, v2
+; GCN-NEXT:    v_cmp_ne_u32_e32 vcc, 0, v3
+; GCN-NEXT:    v_cndmask_b32_e64 v2, -1, v4, s[0:1]
+; GCN-NEXT:    v_cmp_ne_u32_e64 s[0:1], 0, v2
+; GCN-NEXT:    v_cndmask_b32_e32 v3, v8, v6, vcc
+; GCN-NEXT:    v_cndmask_b32_e32 v2, v7, v5, vcc
+; GCN-NEXT:    v_cndmask_b32_e64 v1, v1, v3, s[0:1]
+; GCN-NEXT:    v_cndmask_b32_e64 v0, v0, v2, s[0:1]
+; GCN-NEXT:    s_ashr_i32 s0, s9, 31
+; GCN-NEXT:    s_lshr_b32 s0, s0, 20
+; GCN-NEXT:    s_add_u32 s0, s8, s0
+; GCN-NEXT:    s_addc_u32 s1, s9, 0
+; GCN-NEXT:    v_xor_b32_e32 v0, s2, v0
+; GCN-NEXT:    v_xor_b32_e32 v1, s2, v1
+; GCN-NEXT:    v_mov_b32_e32 v3, s2
+; GCN-NEXT:    v_subrev_i32_e32 v2, vcc, s2, v0
+; GCN-NEXT:    s_ashr_i64 s[0:1], s[0:1], 12
+; GCN-NEXT:    v_subb_u32_e32 v3, vcc, v1, v3, vcc
+; GCN-NEXT:    v_mov_b32_e32 v0, s0
+; GCN-NEXT:    v_mov_b32_e32 v1, s1
+; GCN-NEXT:    buffer_store_dwordx4 v[0:3], off, s[4:7], 0
+; GCN-NEXT:    s_endpgm
+  %r = sdiv <2 x i64> %x, <i64 4096, i64 4095>
+  store <2 x i64> %r, <2 x i64> addrspace(1)* %out
+  ret void
+}
+
+define amdgpu_kernel void @sdiv_v2i64_pow2_shl_denom(<2 x i64> addrspace(1)* %out, <2 x i64> %x, <2 x i64> %y) {
+; CHECK-LABEL: @sdiv_v2i64_pow2_shl_denom(
+; CHECK-NEXT:    [[SHL_Y:%.*]] = shl <2 x i64> <i64 4096, i64 4096>, [[Y:%.*]]
+; CHECK-NEXT:    [[R:%.*]] = sdiv <2 x i64> [[X:%.*]], [[SHL_Y]]
+; CHECK-NEXT:    store <2 x i64> [[R]], <2 x i64> addrspace(1)* [[OUT:%.*]]
+; CHECK-NEXT:    ret void
+;
+; GCN-LABEL: sdiv_v2i64_pow2_shl_denom:
+; GCN:       ; %bb.0:
+; GCN-NEXT:    s_load_dwordx4 s[4:7], s[0:1], 0x11
+; GCN-NEXT:    s_mov_b32 s3, 0
+; GCN-NEXT:    s_movk_i32 s2, 0x1000
+; GCN-NEXT:    s_mov_b32 s18, 0x4f800000
+; GCN-NEXT:    s_mov_b32 s19, 0x5f7ffffc
+; GCN-NEXT:    s_waitcnt lgkmcnt(0)
+; GCN-NEXT:    s_lshl_b64 s[12:13], s[2:3], s4
+; GCN-NEXT:    s_lshl_b64 s[2:3], s[2:3], s6
+; GCN-NEXT:    s_ashr_i32 s16, s3, 31
+; GCN-NEXT:    s_add_u32 s2, s2, s16
+; GCN-NEXT:    s_mov_b32 s17, s16
+; GCN-NEXT:    s_addc_u32 s3, s3, s16
+; GCN-NEXT:    s_xor_b64 s[14:15], s[2:3], s[16:17]
+; GCN-NEXT:    v_cvt_f32_u32_e32 v0, s14
+; GCN-NEXT:    v_cvt_f32_u32_e32 v1, s15
+; GCN-NEXT:    s_mov_b32 s20, 0x2f800000
+; GCN-NEXT:    s_mov_b32 s21, 0xcf800000
+; GCN-NEXT:    s_sub_u32 s6, 0, s14
+; GCN-NEXT:    v_mac_f32_e32 v0, s18, v1
+; GCN-NEXT:    v_rcp_f32_e32 v0, v0
+; GCN-NEXT:    s_subb_u32 s7, 0, s15
+; GCN-NEXT:    s_load_dwordx2 s[4:5], s[0:1], 0x9
+; GCN-NEXT:    s_load_dwordx4 s[8:11], s[0:1], 0xd
+; GCN-NEXT:    v_mul_f32_e32 v0, s19, v0
+; GCN-NEXT:    v_mul_f32_e32 v1, s20, v0
+; GCN-NEXT:    v_trunc_f32_e32 v1, v1
+; GCN-NEXT:    v_mac_f32_e32 v0, s21, v1
+; GCN-NEXT:    v_cvt_u32_f32_e32 v0, v0
+; GCN-NEXT:    v_cvt_u32_f32_e32 v1, v1
+; GCN-NEXT:    v_mul_hi_u32 v3, s6, v0
+; GCN-NEXT:    v_mul_lo_u32 v2, s6, v1
+; GCN-NEXT:    v_mul_lo_u32 v4, s7, v0
+; GCN-NEXT:    v_mul_lo_u32 v5, s6, v0
+; GCN-NEXT:    v_add_i32_e32 v2, vcc, v3, v2
+; GCN-NEXT:    v_add_i32_e32 v2, vcc, v2, v4
+; GCN-NEXT:    v_mul_lo_u32 v3, v0, v2
+; GCN-NEXT:    v_mul_hi_u32 v4, v0, v5
+; GCN-NEXT:    v_mul_hi_u32 v6, v0, v2
+; GCN-NEXT:    v_mul_hi_u32 v7, v1, v2
+; GCN-NEXT:    v_mul_lo_u32 v2, v1, v2
+; GCN-NEXT:    v_add_i32_e32 v3, vcc, v4, v3
+; GCN-NEXT:    v_addc_u32_e32 v4, vcc, 0, v6, vcc
+; GCN-NEXT:    v_mul_lo_u32 v6, v1, v5
+; GCN-NEXT:    v_mul_hi_u32 v5, v1, v5
+; GCN-NEXT:    v_add_i32_e32 v3, vcc, v6, v3
+; GCN-NEXT:    v_addc_u32_e32 v3, vcc, v4, v5, vcc
+; GCN-NEXT:    v_mov_b32_e32 v4, 0
+; GCN-NEXT:    v_addc_u32_e32 v5, vcc, v7, v4, vcc
+; GCN-NEXT:    v_add_i32_e32 v2, vcc, v3, v2
+; GCN-NEXT:    v_mov_b32_e32 v6, 0
+; GCN-NEXT:    v_add_i32_e64 v0, s[2:3], v0, v2
+; GCN-NEXT:    v_addc_u32_e32 v3, vcc, v6, v5, vcc
+; GCN-NEXT:    v_addc_u32_e64 v2, vcc, v1, v3, s[2:3]
+; GCN-NEXT:    v_mul_lo_u32 v5, s6, v2
+; GCN-NEXT:    v_mul_hi_u32 v7, s6, v0
+; GCN-NEXT:    v_mul_lo_u32 v8, s7, v0
+; GCN-NEXT:    s_mov_b32 s7, 0xf000
+; GCN-NEXT:    v_add_i32_e32 v5, vcc, v7, v5
+; GCN-NEXT:    v_mul_lo_u32 v7, s6, v0
+; GCN-NEXT:    v_add_i32_e32 v5, vcc, v8, v5
+; GCN-NEXT:    v_mul_lo_u32 v10, v0, v5
+; GCN-NEXT:    v_mul_hi_u32 v12, v0, v5
+; GCN-NEXT:    v_mul_hi_u32 v11, v0, v7
+; GCN-NEXT:    v_mul_hi_u32 v9, v2, v7
+; GCN-NEXT:    v_mul_lo_u32 v7, v2, v7
+; GCN-NEXT:    v_mul_hi_u32 v8, v2, v5
+; GCN-NEXT:    v_add_i32_e32 v10, vcc, v11, v10
+; GCN-NEXT:    v_addc_u32_e32 v11, vcc, 0, v12, vcc
+; GCN-NEXT:    v_mul_lo_u32 v2, v2, v5
+; GCN-NEXT:    v_add_i32_e32 v7, vcc, v7, v10
+; GCN-NEXT:    v_addc_u32_e32 v7, vcc, v11, v9, vcc
+; GCN-NEXT:    v_addc_u32_e32 v5, vcc, v8, v4, vcc
+; GCN-NEXT:    v_add_i32_e32 v2, vcc, v7, v2
+; GCN-NEXT:    v_addc_u32_e32 v5, vcc, v6, v5, vcc
+; GCN-NEXT:    v_add_i32_e32 v1, vcc, v1, v3
+; GCN-NEXT:    v_addc_u32_e64 v1, vcc, v1, v5, s[2:3]
+; GCN-NEXT:    s_waitcnt lgkmcnt(0)
+; GCN-NEXT:    s_ashr_i32 s2, s11, 31
+; GCN-NEXT:    s_add_u32 s0, s10, s2
+; GCN-NEXT:    v_add_i32_e32 v0, vcc, v0, v2
+; GCN-NEXT:    s_mov_b32 s3, s2
+; GCN-NEXT:    s_addc_u32 s1, s11, s2
+; GCN-NEXT:    s_xor_b64 s[10:11], s[0:1], s[2:3]
+; GCN-NEXT:    v_addc_u32_e32 v1, vcc, 0, v1, vcc
+; GCN-NEXT:    v_mul_lo_u32 v2, s10, v1
+; GCN-NEXT:    v_mul_hi_u32 v3, s10, v0
+; GCN-NEXT:    v_mul_hi_u32 v5, s10, v1
+; GCN-NEXT:    v_mul_hi_u32 v7, s11, v1
+; GCN-NEXT:    v_mul_lo_u32 v1, s11, v1
+; GCN-NEXT:    v_add_i32_e32 v2, vcc, v3, v2
+; GCN-NEXT:    v_addc_u32_e32 v3, vcc, 0, v5, vcc
+; GCN-NEXT:    v_mul_lo_u32 v5, s11, v0
+; GCN-NEXT:    v_mul_hi_u32 v0, s11, v0
+; GCN-NEXT:    s_xor_b64 s[2:3], s[2:3], s[16:17]
+; GCN-NEXT:    s_mov_b32 s6, -1
+; GCN-NEXT:    v_add_i32_e32 v2, vcc, v5, v2
+; GCN-NEXT:    v_addc_u32_e32 v0, vcc, v3, v0, vcc
+; GCN-NEXT:    v_addc_u32_e32 v2, vcc, v7, v4, vcc
+; GCN-NEXT:    v_add_i32_e32 v0, vcc, v0, v1
+; GCN-NEXT:    v_addc_u32_e32 v1, vcc, v6, v2, vcc
+; GCN-NEXT:    v_mul_lo_u32 v2, s14, v1
+; GCN-NEXT:    v_mul_hi_u32 v3, s14, v0
+; GCN-NEXT:    v_mul_lo_u32 v5, s15, v0
+; GCN-NEXT:    v_mov_b32_e32 v7, s15
+; GCN-NEXT:    v_add_i32_e32 v2, vcc, v3, v2
+; GCN-NEXT:    v_mul_lo_u32 v3, s14, v0
+; GCN-NEXT:    v_add_i32_e32 v2, vcc, v2, v5
+; GCN-NEXT:    v_sub_i32_e32 v5, vcc, s11, v2
+; GCN-NEXT:    v_sub_i32_e32 v3, vcc, s10, v3
+; GCN-NEXT:    v_subb_u32_e64 v5, s[0:1], v5, v7, vcc
+; GCN-NEXT:    v_subrev_i32_e64 v7, s[0:1], s14, v3
+; GCN-NEXT:    v_subbrev_u32_e64 v5, s[0:1], 0, v5, s[0:1]
+; GCN-NEXT:    v_cmp_le_u32_e64 s[0:1], s15, v5
+; GCN-NEXT:    v_cndmask_b32_e64 v8, 0, -1, s[0:1]
+; GCN-NEXT:    v_cmp_le_u32_e64 s[0:1], s14, v7
+; GCN-NEXT:    v_cndmask_b32_e64 v7, 0, -1, s[0:1]
+; GCN-NEXT:    v_cmp_eq_u32_e64 s[0:1], s15, v5
+; GCN-NEXT:    v_cndmask_b32_e64 v5, v8, v7, s[0:1]
+; GCN-NEXT:    v_add_i32_e64 v7, s[0:1], 2, v0
+; GCN-NEXT:    v_addc_u32_e64 v8, s[0:1], 0, v1, s[0:1]
+; GCN-NEXT:    v_add_i32_e64 v9, s[0:1], 1, v0
+; GCN-NEXT:    v_addc_u32_e64 v10, s[0:1], 0, v1, s[0:1]
+; GCN-NEXT:    s_ashr_i32 s10, s13, 31
+; GCN-NEXT:    v_cmp_ne_u32_e64 s[0:1], 0, v5
+; GCN-NEXT:    s_add_u32 s12, s12, s10
+; GCN-NEXT:    v_cndmask_b32_e64 v5, v10, v8, s[0:1]
+; GCN-NEXT:    v_mov_b32_e32 v8, s11
+; GCN-NEXT:    s_mov_b32 s11, s10
+; GCN-NEXT:    s_addc_u32 s13, s13, s10
+; GCN-NEXT:    s_xor_b64 s[12:13], s[12:13], s[10:11]
+; GCN-NEXT:    v_cvt_f32_u32_e32 v10, s12
+; GCN-NEXT:    v_cvt_f32_u32_e32 v11, s13
+; GCN-NEXT:    v_subb_u32_e32 v2, vcc, v8, v2, vcc
+; GCN-NEXT:    v_cmp_le_u32_e32 vcc, s15, v2
+; GCN-NEXT:    v_cndmask_b32_e64 v8, 0, -1, vcc
+; GCN-NEXT:    v_cmp_le_u32_e32 vcc, s14, v3
+; GCN-NEXT:    v_cndmask_b32_e64 v3, 0, -1, vcc
+; GCN-NEXT:    v_cmp_eq_u32_e32 vcc, s15, v2
+; GCN-NEXT:    v_mac_f32_e32 v10, s18, v11
+; GCN-NEXT:    v_cndmask_b32_e32 v2, v8, v3, vcc
+; GCN-NEXT:    v_rcp_f32_e32 v3, v10
+; GCN-NEXT:    v_cmp_ne_u32_e32 vcc, 0, v2
+; GCN-NEXT:    v_cndmask_b32_e32 v1, v1, v5, vcc
+; GCN-NEXT:    s_sub_u32 s14, 0, s12
+; GCN-NEXT:    v_mul_f32_e32 v3, s19, v3
+; GCN-NEXT:    v_mul_f32_e32 v5, s20, v3
+; GCN-NEXT:    v_trunc_f32_e32 v5, v5
+; GCN-NEXT:    v_mac_f32_e32 v3, s21, v5
+; GCN-NEXT:    v_cvt_u32_f32_e32 v3, v3
+; GCN-NEXT:    v_cvt_u32_f32_e32 v5, v5
+; GCN-NEXT:    v_cndmask_b32_e64 v2, v9, v7, s[0:1]
+; GCN-NEXT:    v_cndmask_b32_e32 v0, v0, v2, vcc
+; GCN-NEXT:    v_mul_hi_u32 v2, s14, v3
+; GCN-NEXT:    v_mul_lo_u32 v7, s14, v5
+; GCN-NEXT:    s_subb_u32 s15, 0, s13
+; GCN-NEXT:    v_mul_lo_u32 v8, s15, v3
+; GCN-NEXT:    v_xor_b32_e32 v0, s2, v0
+; GCN-NEXT:    v_add_i32_e32 v2, vcc, v2, v7
+; GCN-NEXT:    v_mul_lo_u32 v7, s14, v3
+; GCN-NEXT:    v_add_i32_e32 v2, vcc, v2, v8
+; GCN-NEXT:    v_mul_lo_u32 v8, v3, v2
+; GCN-NEXT:    v_mul_hi_u32 v10, v3, v2
+; GCN-NEXT:    v_mul_hi_u32 v9, v3, v7
+; GCN-NEXT:    v_mul_hi_u32 v11, v5, v2
+; GCN-NEXT:    v_mul_lo_u32 v2, v5, v2
+; GCN-NEXT:    v_xor_b32_e32 v1, s3, v1
+; GCN-NEXT:    v_add_i32_e32 v8, vcc, v9, v8
+; GCN-NEXT:    v_addc_u32_e32 v9, vcc, 0, v10, vcc
+; GCN-NEXT:    v_mul_lo_u32 v10, v5, v7
+; GCN-NEXT:    v_mul_hi_u32 v7, v5, v7
+; GCN-NEXT:    v_add_i32_e32 v8, vcc, v10, v8
+; GCN-NEXT:    v_addc_u32_e32 v7, vcc, v9, v7, vcc
+; GCN-NEXT:    v_addc_u32_e32 v8, vcc, v11, v4, vcc
+; GCN-NEXT:    v_add_i32_e32 v2, vcc, v7, v2
+; GCN-NEXT:    v_add_i32_e64 v2, s[0:1], v3, v2
+; GCN-NEXT:    v_addc_u32_e32 v7, vcc, v6, v8, vcc
+; GCN-NEXT:    v_addc_u32_e64 v3, vcc, v5, v7, s[0:1]
+; GCN-NEXT:    v_mul_lo_u32 v8, s14, v3
+; GCN-NEXT:    v_mul_hi_u32 v9, s14, v2
+; GCN-NEXT:    v_mul_lo_u32 v10, s15, v2
+; GCN-NEXT:    v_add_i32_e32 v8, vcc, v9, v8
+; GCN-NEXT:    v_mul_lo_u32 v9, s14, v2
+; GCN-NEXT:    v_add_i32_e32 v8, vcc, v10, v8
+; GCN-NEXT:    v_mul_lo_u32 v12, v2, v8
+; GCN-NEXT:    v_mul_hi_u32 v14, v2, v8
+; GCN-NEXT:    v_mul_hi_u32 v13, v2, v9
+; GCN-NEXT:    v_mul_hi_u32 v11, v3, v9
+; GCN-NEXT:    v_mul_lo_u32 v9, v3, v9
+; GCN-NEXT:    v_mul_hi_u32 v10, v3, v8
+; GCN-NEXT:    v_add_i32_e32 v12, vcc, v13, v12
+; GCN-NEXT:    v_addc_u32_e32 v13, vcc, 0, v14, vcc
+; GCN-NEXT:    v_mul_lo_u32 v3, v3, v8
+; GCN-NEXT:    v_add_i32_e32 v9, vcc, v9, v12
+; GCN-NEXT:    v_addc_u32_e32 v9, vcc, v13, v11, vcc
+; GCN-NEXT:    v_addc_u32_e32 v8, vcc, v10, v4, vcc
+; GCN-NEXT:    v_add_i32_e32 v3, vcc, v9, v3
+; GCN-NEXT:    v_addc_u32_e32 v8, vcc, v6, v8, vcc
+; GCN-NEXT:    v_add_i32_e32 v5, vcc, v5, v7
+; GCN-NEXT:    s_ashr_i32 s14, s9, 31
+; GCN-NEXT:    v_addc_u32_e64 v5, vcc, v5, v8, s[0:1]
+; GCN-NEXT:    s_add_u32 s0, s8, s14
+; GCN-NEXT:    v_add_i32_e32 v2, vcc, v2, v3
+; GCN-NEXT:    s_mov_b32 s15, s14
+; GCN-NEXT:    s_addc_u32 s1, s9, s14
+; GCN-NEXT:    s_xor_b64 s[8:9], s[0:1], s[14:15]
+; GCN-NEXT:    v_addc_u32_e32 v3, vcc, 0, v5, vcc
+; GCN-NEXT:    v_mul_lo_u32 v5, s8, v3
+; GCN-NEXT:    v_mul_hi_u32 v7, s8, v2
+; GCN-NEXT:    v_mul_hi_u32 v9, s8, v3
+; GCN-NEXT:    v_mul_hi_u32 v10, s9, v3
+; GCN-NEXT:    v_mul_lo_u32 v3, s9, v3
+; GCN-NEXT:    v_add_i32_e32 v5, vcc, v7, v5
+; GCN-NEXT:    v_addc_u32_e32 v7, vcc, 0, v9, vcc
+; GCN-NEXT:    v_mul_lo_u32 v9, s9, v2
+; GCN-NEXT:    v_mul_hi_u32 v2, s9, v2
+; GCN-NEXT:    v_mov_b32_e32 v8, s3
+; GCN-NEXT:    v_add_i32_e32 v5, vcc, v9, v5
+; GCN-NEXT:    v_addc_u32_e32 v2, vcc, v7, v2, vcc
+; GCN-NEXT:    v_addc_u32_e32 v4, vcc, v10, v4, vcc
+; GCN-NEXT:    v_add_i32_e32 v5, vcc, v2, v3
+; GCN-NEXT:    v_addc_u32_e32 v4, vcc, v6, v4, vcc
+; GCN-NEXT:    v_mul_lo_u32 v6, s12, v4
+; GCN-NEXT:    v_mul_hi_u32 v7, s12, v5
+; GCN-NEXT:    v_subrev_i32_e32 v2, vcc, s2, v0
+; GCN-NEXT:    v_mul_lo_u32 v0, s13, v5
+; GCN-NEXT:    v_subb_u32_e32 v3, vcc, v1, v8, vcc
+; GCN-NEXT:    v_add_i32_e32 v1, vcc, v7, v6
+; GCN-NEXT:    v_mov_b32_e32 v7, s13
+; GCN-NEXT:    v_add_i32_e32 v0, vcc, v1, v0
+; GCN-NEXT:    v_mul_lo_u32 v1, s12, v5
+; GCN-NEXT:    v_sub_i32_e32 v6, vcc, s9, v0
+; GCN-NEXT:    v_sub_i32_e32 v1, vcc, s8, v1
+; GCN-NEXT:    v_subb_u32_e64 v6, s[0:1], v6, v7, vcc
+; GCN-NEXT:    v_subrev_i32_e64 v7, s[0:1], s12, v1
+; GCN-NEXT:    v_subbrev_u32_e64 v6, s[0:1], 0, v6, s[0:1]
+; GCN-NEXT:    v_cmp_le_u32_e64 s[0:1], s13, v6
+; GCN-NEXT:    v_cndmask_b32_e64 v8, 0, -1, s[0:1]
+; GCN-NEXT:    v_cmp_le_u32_e64 s[0:1], s12, v7
+; GCN-NEXT:    v_cndmask_b32_e64 v7, 0, -1, s[0:1]
+; GCN-NEXT:    v_cmp_eq_u32_e64 s[0:1], s13, v6
+; GCN-NEXT:    v_cndmask_b32_e64 v6, v8, v7, s[0:1]
+; GCN-NEXT:    v_add_i32_e64 v7, s[0:1], 2, v5
+; GCN-NEXT:    v_addc_u32_e64 v8, s[0:1], 0, v4, s[0:1]
+; GCN-NEXT:    v_add_i32_e64 v9, s[0:1], 1, v5
+; GCN-NEXT:    v_addc_u32_e64 v10, s[0:1], 0, v4, s[0:1]
+; GCN-NEXT:    v_cmp_ne_u32_e64 s[0:1], 0, v6
+; GCN-NEXT:    v_cndmask_b32_e64 v6, v10, v8, s[0:1]
+; GCN-NEXT:    v_mov_b32_e32 v8, s9
+; GCN-NEXT:    v_subb_u32_e32 v0, vcc, v8, v0, vcc
+; GCN-NEXT:    v_cmp_le_u32_e32 vcc, s13, v0
+; GCN-NEXT:    v_cndmask_b32_e64 v8, 0, -1, vcc
+; GCN-NEXT:    v_cmp_le_u32_e32 vcc, s12, v1
+; GCN-NEXT:    v_cndmask_b32_e64 v1, 0, -1, vcc
+; GCN-NEXT:    v_cmp_eq_u32_e32 vcc, s13, v0
+; GCN-NEXT:    v_cndmask_b32_e32 v0, v8, v1, vcc
+; GCN-NEXT:    v_cmp_ne_u32_e32 vcc, 0, v0
+; GCN-NEXT:    v_cndmask_b32_e64 v1, v9, v7, s[0:1]
+; GCN-NEXT:    v_cndmask_b32_e32 v1, v5, v1, vcc
+; GCN-NEXT:    s_xor_b64 s[0:1], s[14:15], s[10:11]
+; GCN-NEXT:    v_cndmask_b32_e32 v0, v4, v6, vcc
+; GCN-NEXT:    v_xor_b32_e32 v1, s0, v1
+; GCN-NEXT:    v_xor_b32_e32 v4, s1, v0
+; GCN-NEXT:    v_mov_b32_e32 v5, s1
+; GCN-NEXT:    v_subrev_i32_e32 v0, vcc, s0, v1
+; GCN-NEXT:    v_subb_u32_e32 v1, vcc, v4, v5, vcc
+; GCN-NEXT:    buffer_store_dwordx4 v[0:3], off, s[4:7], 0
+; GCN-NEXT:    s_endpgm
+  %shl.y = shl <2 x i64> <i64 4096, i64 4096>, %y
+  %r = sdiv <2 x i64> %x, %shl.y
+  store <2 x i64> %r, <2 x i64> addrspace(1)* %out
+  ret void
+}
+
+define amdgpu_kernel void @srem_i64_oddk_denom(i64 addrspace(1)* %out, i64 %x) {
+; CHECK-LABEL: @srem_i64_oddk_denom(
+; CHECK-NEXT:    [[R:%.*]] = srem i64 [[X:%.*]], 1235195
+; CHECK-NEXT:    store i64 [[R]], i64 addrspace(1)* [[OUT:%.*]]
+; CHECK-NEXT:    ret void
+;
+; GCN-LABEL: srem_i64_oddk_denom:
+; GCN:       ; %bb.0:
+; GCN-NEXT:    v_mov_b32_e32 v0, 0x4f800000
+; GCN-NEXT:    v_madak_f32 v0, 0, v0, 0x4996c7d8
+; GCN-NEXT:    v_rcp_f32_e32 v0, v0
+; GCN-NEXT:    s_mov_b32 s2, 0xffed2705
+; GCN-NEXT:    v_mov_b32_e32 v8, 0
+; GCN-NEXT:    v_mov_b32_e32 v7, 0
+; GCN-NEXT:    v_mul_f32_e32 v0, 0x5f7ffffc, v0
+; GCN-NEXT:    v_mul_f32_e32 v1, 0x2f800000, v0
+; GCN-NEXT:    v_trunc_f32_e32 v1, v1
+; GCN-NEXT:    v_mac_f32_e32 v0, 0xcf800000, v1
+; GCN-NEXT:    v_cvt_u32_f32_e32 v0, v0
+; GCN-NEXT:    v_cvt_u32_f32_e32 v1, v1
+; GCN-NEXT:    s_load_dwordx4 s[8:11], s[0:1], 0x9
+; GCN-NEXT:    s_mov_b32 s7, 0xf000
+; GCN-NEXT:    v_mul_hi_u32 v3, s2, v0
+; GCN-NEXT:    v_mul_lo_u32 v2, v1, s2
+; GCN-NEXT:    v_mul_lo_u32 v4, v0, s2
+; GCN-NEXT:    s_mov_b32 s6, -1
+; GCN-NEXT:    s_waitcnt lgkmcnt(0)
+; GCN-NEXT:    s_mov_b32 s4, s8
+; GCN-NEXT:    v_add_i32_e32 v2, vcc, v3, v2
+; GCN-NEXT:    v_subrev_i32_e32 v2, vcc, v0, v2
+; GCN-NEXT:    v_mul_lo_u32 v5, v0, v2
+; GCN-NEXT:    v_mul_hi_u32 v6, v0, v4
+; GCN-NEXT:    v_mul_hi_u32 v3, v0, v2
+; GCN-NEXT:    v_mul_hi_u32 v9, v1, v2
+; GCN-NEXT:    v_mul_lo_u32 v2, v1, v2
+; GCN-NEXT:    v_add_i32_e32 v5, vcc, v6, v5
+; GCN-NEXT:    v_mul_lo_u32 v6, v1, v4
+; GCN-NEXT:    v_mul_hi_u32 v4, v1, v4
+; GCN-NEXT:    v_addc_u32_e32 v3, vcc, v8, v3, vcc
+; GCN-NEXT:    s_mov_b32 s5, s9
+; GCN-NEXT:    v_add_i32_e32 v5, vcc, v6, v5
+; GCN-NEXT:    v_addc_u32_e32 v3, vcc, v3, v4, vcc
+; GCN-NEXT:    v_addc_u32_e32 v4, vcc, v9, v7, vcc
+; GCN-NEXT:    v_add_i32_e32 v2, vcc, v3, v2
+; GCN-NEXT:    v_add_i32_e64 v0, s[0:1], v0, v2
+; GCN-NEXT:    v_addc_u32_e32 v3, vcc, v8, v4, vcc
+; GCN-NEXT:    v_addc_u32_e64 v2, vcc, v1, v3, s[0:1]
+; GCN-NEXT:    v_mul_lo_u32 v4, v2, s2
+; GCN-NEXT:    v_mul_hi_u32 v5, s2, v0
+; GCN-NEXT:    v_add_i32_e32 v4, vcc, v5, v4
+; GCN-NEXT:    v_mul_lo_u32 v5, v0, s2
+; GCN-NEXT:    v_subrev_i32_e32 v4, vcc, v0, v4
+; GCN-NEXT:    v_mul_lo_u32 v10, v0, v4
+; GCN-NEXT:    v_mul_hi_u32 v12, v0, v4
+; GCN-NEXT:    v_mul_hi_u32 v11, v0, v5
+; GCN-NEXT:    v_mul_hi_u32 v9, v2, v5
+; GCN-NEXT:    v_mul_lo_u32 v5, v2, v5
+; GCN-NEXT:    v_mul_hi_u32 v6, v2, v4
+; GCN-NEXT:    v_add_i32_e32 v10, vcc, v11, v10
+; GCN-NEXT:    v_addc_u32_e32 v11, vcc, v8, v12, vcc
+; GCN-NEXT:    v_mul_lo_u32 v2, v2, v4
+; GCN-NEXT:    v_add_i32_e32 v5, vcc, v5, v10
+; GCN-NEXT:    v_addc_u32_e32 v5, vcc, v11, v9, vcc
+; GCN-NEXT:    v_addc_u32_e32 v4, vcc, v6, v7, vcc
+; GCN-NEXT:    v_add_i32_e32 v2, vcc, v5, v2
+; GCN-NEXT:    v_addc_u32_e32 v4, vcc, v8, v4, vcc
+; GCN-NEXT:    v_add_i32_e32 v1, vcc, v1, v3
+; GCN-NEXT:    s_ashr_i32 s2, s11, 31
+; GCN-NEXT:    v_addc_u32_e64 v1, vcc, v1, v4, s[0:1]
+; GCN-NEXT:    s_add_u32 s0, s10, s2
+; GCN-NEXT:    v_add_i32_e32 v0, vcc, v0, v2
+; GCN-NEXT:    s_mov_b32 s3, s2
+; GCN-NEXT:    s_addc_u32 s1, s11, s2
+; GCN-NEXT:    s_xor_b64 s[0:1], s[0:1], s[2:3]
+; GCN-NEXT:    v_addc_u32_e32 v1, vcc, 0, v1, vcc
+; GCN-NEXT:    v_mul_lo_u32 v2, s0, v1
+; GCN-NEXT:    v_mul_hi_u32 v3, s0, v0
+; GCN-NEXT:    v_mul_hi_u32 v4, s0, v1
+; GCN-NEXT:    v_mul_hi_u32 v5, s1, v1
+; GCN-NEXT:    v_mul_lo_u32 v1, s1, v1
+; GCN-NEXT:    v_add_i32_e32 v2, vcc, v3, v2
+; GCN-NEXT:    v_addc_u32_e32 v3, vcc, v8, v4, vcc
+; GCN-NEXT:    v_mul_lo_u32 v4, s1, v0
+; GCN-NEXT:    v_mul_hi_u32 v0, s1, v0
+; GCN-NEXT:    s_mov_b32 s3, 0x12d8fb
+; GCN-NEXT:    v_add_i32_e32 v2, vcc, v4, v2
+; GCN-NEXT:    v_addc_u32_e32 v0, vcc, v3, v0, vcc
+; GCN-NEXT:    v_addc_u32_e32 v2, vcc, v5, v7, vcc
+; GCN-NEXT:    v_add_i32_e32 v0, vcc, v0, v1
+; GCN-NEXT:    v_addc_u32_e32 v1, vcc, v8, v2, vcc
+; GCN-NEXT:    v_mul_hi_u32 v2, s3, v0
+; GCN-NEXT:    v_mul_lo_u32 v1, v1, s3
+; GCN-NEXT:    v_mul_lo_u32 v0, v0, s3
+; GCN-NEXT:    v_add_i32_e32 v1, vcc, v2, v1
+; GCN-NEXT:    v_sub_i32_e32 v0, vcc, s0, v0
+; GCN-NEXT:    v_mov_b32_e32 v2, s1
+; GCN-NEXT:    v_subb_u32_e32 v1, vcc, v2, v1, vcc
+; GCN-NEXT:    v_subrev_i32_e32 v2, vcc, s3, v0
+; GCN-NEXT:    v_subbrev_u32_e32 v3, vcc, 0, v1, vcc
+; GCN-NEXT:    v_subrev_i32_e32 v4, vcc, s3, v2
+; GCN-NEXT:    v_subbrev_u32_e32 v5, vcc, 0, v3, vcc
+; GCN-NEXT:    s_mov_b32 s0, 0x12d8fa
+; GCN-NEXT:    v_cmp_lt_u32_e32 vcc, s0, v2
+; GCN-NEXT:    v_cndmask_b32_e64 v6, 0, -1, vcc
+; GCN-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v3
+; GCN-NEXT:    v_cndmask_b32_e32 v6, -1, v6, vcc
+; GCN-NEXT:    v_cmp_ne_u32_e32 vcc, 0, v6
+; GCN-NEXT:    v_cmp_lt_u32_e64 s[0:1], s0, v0
+; GCN-NEXT:    v_cndmask_b32_e32 v3, v3, v5, vcc
+; GCN-NEXT:    v_cndmask_b32_e64 v5, 0, -1, s[0:1]
+; GCN-NEXT:    v_cmp_eq_u32_e64 s[0:1], 0, v1
+; GCN-NEXT:    v_cndmask_b32_e64 v5, -1, v5, s[0:1]
+; GCN-NEXT:    v_cmp_ne_u32_e64 s[0:1], 0, v5
+; GCN-NEXT:    v_cndmask_b32_e32 v2, v2, v4, vcc
+; GCN-NEXT:    v_cndmask_b32_e64 v0, v0, v2, s[0:1]
+; GCN-NEXT:    v_cndmask_b32_e64 v1, v1, v3, s[0:1]
+; GCN-NEXT:    v_xor_b32_e32 v0, s2, v0
+; GCN-NEXT:    v_xor_b32_e32 v1, s2, v1
+; GCN-NEXT:    v_mov_b32_e32 v2, s2
+; GCN-NEXT:    v_subrev_i32_e32 v0, vcc, s2, v0
+; GCN-NEXT:    v_subb_u32_e32 v1, vcc, v1, v2, vcc
+; GCN-NEXT:    buffer_store_dwordx2 v[0:1], off, s[4:7], 0
+; GCN-NEXT:    s_endpgm
+  %r = srem i64 %x, 1235195
+  store i64 %r, i64 addrspace(1)* %out
+  ret void
+}
+
+define amdgpu_kernel void @srem_i64_pow2k_denom(i64 addrspace(1)* %out, i64 %x) {
+; CHECK-LABEL: @srem_i64_pow2k_denom(
+; CHECK-NEXT:    [[R:%.*]] = srem i64 [[X:%.*]], 4096
+; CHECK-NEXT:    store i64 [[R]], i64 addrspace(1)* [[OUT:%.*]]
+; CHECK-NEXT:    ret void
+;
+; GCN-LABEL: srem_i64_pow2k_denom:
+; GCN:       ; %bb.0:
+; GCN-NEXT:    s_load_dwordx4 s[4:7], s[0:1], 0x9
+; GCN-NEXT:    s_mov_b32 s3, 0xf000
+; GCN-NEXT:    s_mov_b32 s2, -1
+; GCN-NEXT:    s_waitcnt lgkmcnt(0)
+; GCN-NEXT:    s_mov_b32 s0, s4
+; GCN-NEXT:    s_ashr_i32 s4, s7, 31
+; GCN-NEXT:    s_lshr_b32 s4, s4, 20
+; GCN-NEXT:    s_add_u32 s4, s6, s4
+; GCN-NEXT:    s_mov_b32 s1, s5
+; GCN-NEXT:    s_addc_u32 s5, s7, 0
+; GCN-NEXT:    s_and_b32 s4, s4, 0xfffff000
+; GCN-NEXT:    s_sub_u32 s4, s6, s4
+; GCN-NEXT:    s_subb_u32 s5, s7, s5
+; GCN-NEXT:    v_mov_b32_e32 v0, s4
+; GCN-NEXT:    v_mov_b32_e32 v1, s5
+; GCN-NEXT:    buffer_store_dwordx2 v[0:1], off, s[0:3], 0
+; GCN-NEXT:    s_endpgm
+  %r = srem i64 %x, 4096
+  store i64 %r, i64 addrspace(1)* %out
+  ret void
+}
+
+define amdgpu_kernel void @srem_i64_pow2_shl_denom(i64 addrspace(1)* %out, i64 %x, i64 %y) {
+; CHECK-LABEL: @srem_i64_pow2_shl_denom(
+; CHECK-NEXT:    [[SHL_Y:%.*]] = shl i64 4096, [[Y:%.*]]
+; CHECK-NEXT:    [[R:%.*]] = srem i64 [[X:%.*]], [[SHL_Y]]
+; CHECK-NEXT:    store i64 [[R]], i64 addrspace(1)* [[OUT:%.*]]
+; CHECK-NEXT:    ret void
+;
+; GCN-LABEL: srem_i64_pow2_shl_denom:
+; GCN:       ; %bb.0:
+; GCN-NEXT:    s_load_dword s4, s[0:1], 0xd
+; GCN-NEXT:    s_mov_b32 s3, 0
+; GCN-NEXT:    s_movk_i32 s2, 0x1000
+; GCN-NEXT:    s_load_dwordx4 s[8:11], s[0:1], 0x9
+; GCN-NEXT:    s_mov_b32 s7, 0xf000
+; GCN-NEXT:    s_waitcnt lgkmcnt(0)
+; GCN-NEXT:    s_lshl_b64 s[2:3], s[2:3], s4
+; GCN-NEXT:    s_ashr_i32 s4, s3, 31
+; GCN-NEXT:    s_add_u32 s2, s2, s4
+; GCN-NEXT:    s_mov_b32 s5, s4
+; GCN-NEXT:    s_addc_u32 s3, s3, s4
+; GCN-NEXT:    s_xor_b64 s[12:13], s[2:3], s[4:5]
+; GCN-NEXT:    v_cvt_f32_u32_e32 v0, s12
+; GCN-NEXT:    v_cvt_f32_u32_e32 v1, s13
+; GCN-NEXT:    s_sub_u32 s2, 0, s12
+; GCN-NEXT:    s_subb_u32 s3, 0, s13
+; GCN-NEXT:    s_ashr_i32 s14, s11, 31
+; GCN-NEXT:    v_mac_f32_e32 v0, 0x4f800000, v1
+; GCN-NEXT:    v_rcp_f32_e32 v0, v0
+; GCN-NEXT:    s_mov_b32 s15, s14
+; GCN-NEXT:    s_mov_b32 s6, -1
+; GCN-NEXT:    s_mov_b32 s4, s8
+; GCN-NEXT:    v_mul_f32_e32 v0, 0x5f7ffffc, v0
+; GCN-NEXT:    v_mul_f32_e32 v1, 0x2f800000, v0
+; GCN-NEXT:    v_trunc_f32_e32 v1, v1
+; GCN-NEXT:    v_mac_f32_e32 v0, 0xcf800000, v1
+; GCN-NEXT:    v_cvt_u32_f32_e32 v0, v0
+; GCN-NEXT:    v_cvt_u32_f32_e32 v1, v1
+; GCN-NEXT:    s_mov_b32 s5, s9
+; GCN-NEXT:    v_mul_hi_u32 v3, s2, v0
+; GCN-NEXT:    v_mul_lo_u32 v2, s2, v1
+; GCN-NEXT:    v_mul_lo_u32 v5, s3, v0
+; GCN-NEXT:    v_mul_lo_u32 v4, s2, v0
+; GCN-NEXT:    v_add_i32_e32 v2, vcc, v3, v2
+; GCN-NEXT:    v_add_i32_e32 v2, vcc, v2, v5
+; GCN-NEXT:    v_mul_hi_u32 v3, v0, v4
+; GCN-NEXT:    v_mul_lo_u32 v5, v0, v2
+; GCN-NEXT:    v_mul_hi_u32 v6, v0, v2
+; GCN-NEXT:    v_mul_hi_u32 v7, v1, v2
+; GCN-NEXT:    v_mul_lo_u32 v2, v1, v2
+; GCN-NEXT:    v_add_i32_e32 v3, vcc, v3, v5
+; GCN-NEXT:    v_addc_u32_e32 v5, vcc, 0, v6, vcc
+; GCN-NEXT:    v_mul_lo_u32 v6, v1, v4
+; GCN-NEXT:    v_mul_hi_u32 v4, v1, v4
+; GCN-NEXT:    v_add_i32_e32 v3, vcc, v6, v3
+; GCN-NEXT:    v_addc_u32_e32 v3, vcc, v5, v4, vcc
+; GCN-NEXT:    v_mov_b32_e32 v4, 0
+; GCN-NEXT:    v_addc_u32_e32 v5, vcc, v7, v4, vcc
+; GCN-NEXT:    v_add_i32_e32 v2, vcc, v3, v2
+; GCN-NEXT:    v_mov_b32_e32 v6, 0
+; GCN-NEXT:    v_add_i32_e64 v0, s[0:1], v0, v2
+; GCN-NEXT:    v_addc_u32_e32 v3, vcc, v6, v5, vcc
+; GCN-NEXT:    v_addc_u32_e64 v2, vcc, v1, v3, s[0:1]
+; GCN-NEXT:    v_mul_lo_u32 v5, s2, v2
+; GCN-NEXT:    v_mul_hi_u32 v7, s2, v0
+; GCN-NEXT:    v_mul_lo_u32 v8, s3, v0
+; GCN-NEXT:    v_add_i32_e32 v5, vcc, v7, v5
+; GCN-NEXT:    v_mul_lo_u32 v7, s2, v0
+; GCN-NEXT:    v_add_i32_e32 v5, vcc, v8, v5
+; GCN-NEXT:    v_mul_lo_u32 v10, v0, v5
+; GCN-NEXT:    v_mul_hi_u32 v12, v0, v5
+; GCN-NEXT:    v_mul_hi_u32 v11, v0, v7
+; GCN-NEXT:    v_mul_hi_u32 v9, v2, v7
+; GCN-NEXT:    v_mul_lo_u32 v7, v2, v7
+; GCN-NEXT:    v_mul_hi_u32 v8, v2, v5
+; GCN-NEXT:    v_add_i32_e32 v10, vcc, v11, v10
+; GCN-NEXT:    v_addc_u32_e32 v11, vcc, 0, v12, vcc
+; GCN-NEXT:    v_mul_lo_u32 v2, v2, v5
+; GCN-NEXT:    v_add_i32_e32 v7, vcc, v7, v10
+; GCN-NEXT:    v_addc_u32_e32 v7, vcc, v11, v9, vcc
+; GCN-NEXT:    v_addc_u32_e32 v5, vcc, v8, v4, vcc
+; GCN-NEXT:    v_add_i32_e32 v2, vcc, v7, v2
+; GCN-NEXT:    v_addc_u32_e32 v5, vcc, v6, v5, vcc
+; GCN-NEXT:    v_add_i32_e32 v1, vcc, v1, v3
+; GCN-NEXT:    v_addc_u32_e64 v1, vcc, v1, v5, s[0:1]
+; GCN-NEXT:    s_add_u32 s0, s10, s14
+; GCN-NEXT:    s_addc_u32 s1, s11, s14
+; GCN-NEXT:    v_add_i32_e32 v0, vcc, v0, v2
+; GCN-NEXT:    s_xor_b64 s[10:11], s[0:1], s[14:15]
+; GCN-NEXT:    v_addc_u32_e32 v1, vcc, 0, v1, vcc
+; GCN-NEXT:    v_mul_lo_u32 v2, s10, v1
+; GCN-NEXT:    v_mul_hi_u32 v3, s10, v0
+; GCN-NEXT:    v_mul_hi_u32 v5, s10, v1
+; GCN-NEXT:    v_mul_hi_u32 v7, s11, v1
+; GCN-NEXT:    v_mul_lo_u32 v1, s11, v1
+; GCN-NEXT:    v_add_i32_e32 v2, vcc, v3, v2
+; GCN-NEXT:    v_addc_u32_e32 v3, vcc, 0, v5, vcc
+; GCN-NEXT:    v_mul_lo_u32 v5, s11, v0
+; GCN-NEXT:    v_mul_hi_u32 v0, s11, v0
+; GCN-NEXT:    v_add_i32_e32 v2, vcc, v5, v2
+; GCN-NEXT:    v_addc_u32_e32 v0, vcc, v3, v0, vcc
+; GCN-NEXT:    v_addc_u32_e32 v2, vcc, v7, v4, vcc
+; GCN-NEXT:    v_add_i32_e32 v0, vcc, v0, v1
+; GCN-NEXT:    v_addc_u32_e32 v1, vcc, v6, v2, vcc
+; GCN-NEXT:    v_mul_lo_u32 v1, s12, v1
+; GCN-NEXT:    v_mul_hi_u32 v2, s12, v0
+; GCN-NEXT:    v_mul_lo_u32 v3, s13, v0
+; GCN-NEXT:    v_mul_lo_u32 v0, s12, v0
+; GCN-NEXT:    v_add_i32_e32 v1, vcc, v2, v1
+; GCN-NEXT:    v_add_i32_e32 v1, vcc, v1, v3
+; GCN-NEXT:    v_sub_i32_e32 v2, vcc, s11, v1
+; GCN-NEXT:    v_mov_b32_e32 v3, s13
+; GCN-NEXT:    v_sub_i32_e32 v0, vcc, s10, v0
+; GCN-NEXT:    v_subb_u32_e64 v2, s[0:1], v2, v3, vcc
+; GCN-NEXT:    v_subrev_i32_e64 v4, s[0:1], s12, v0
+; GCN-NEXT:    v_subb_u32_e64 v3, s[2:3], v2, v3, s[0:1]
+; GCN-NEXT:    v_subbrev_u32_e64 v2, s[0:1], 0, v2, s[0:1]
+; GCN-NEXT:    v_cmp_le_u32_e64 s[0:1], s13, v2
+; GCN-NEXT:    v_cndmask_b32_e64 v5, 0, -1, s[0:1]
+; GCN-NEXT:    v_cmp_le_u32_e64 s[0:1], s12, v4
+; GCN-NEXT:    v_cndmask_b32_e64 v6, 0, -1, s[0:1]
+; GCN-NEXT:    v_cmp_eq_u32_e64 s[0:1], s13, v2
+; GCN-NEXT:    v_cndmask_b32_e64 v5, v5, v6, s[0:1]
+; GCN-NEXT:    v_subrev_i32_e64 v6, s[0:1], s12, v4
+; GCN-NEXT:    v_subbrev_u32_e64 v3, s[0:1], 0, v3, s[0:1]
+; GCN-NEXT:    v_cmp_ne_u32_e64 s[0:1], 0, v5
+; GCN-NEXT:    v_cndmask_b32_e64 v2, v2, v3, s[0:1]
+; GCN-NEXT:    v_mov_b32_e32 v3, s11
+; GCN-NEXT:    v_subb_u32_e32 v1, vcc, v3, v1, vcc
+; GCN-NEXT:    v_cmp_le_u32_e32 vcc, s13, v1
+; GCN-NEXT:    v_cndmask_b32_e64 v3, 0, -1, vcc
+; GCN-NEXT:    v_cmp_le_u32_e32 vcc, s12, v0
+; GCN-NEXT:    v_cndmask_b32_e64 v5, 0, -1, vcc
+; GCN-NEXT:    v_cmp_eq_u32_e32 vcc, s13, v1
+; GCN-NEXT:    v_cndmask_b32_e32 v3, v3, v5, vcc
+; GCN-NEXT:    v_cmp_ne_u32_e32 vcc, 0, v3
+; GCN-NEXT:    v_cndmask_b32_e32 v1, v1, v2, vcc
+; GCN-NEXT:    v_cndmask_b32_e64 v2, v4, v6, s[0:1]
+; GCN-NEXT:    v_cndmask_b32_e32 v0, v0, v2, vcc
+; GCN-NEXT:    v_xor_b32_e32 v0, s14, v0
+; GCN-NEXT:    v_xor_b32_e32 v1, s14, v1
+; GCN-NEXT:    v_mov_b32_e32 v2, s14
+; GCN-NEXT:    v_subrev_i32_e32 v0, vcc, s14, v0
+; GCN-NEXT:    v_subb_u32_e32 v1, vcc, v1, v2, vcc
+; GCN-NEXT:    buffer_store_dwordx2 v[0:1], off, s[4:7], 0
+; GCN-NEXT:    s_endpgm
+  %shl.y = shl i64 4096, %y
+  %r = srem i64 %x, %shl.y
+  store i64 %r, i64 addrspace(1)* %out
+  ret void
+}
+
+define amdgpu_kernel void @srem_v2i64_pow2k_denom(<2 x i64> addrspace(1)* %out, <2 x i64> %x) {
+; CHECK-LABEL: @srem_v2i64_pow2k_denom(
+; CHECK-NEXT:    [[R:%.*]] = srem <2 x i64> [[X:%.*]], <i64 4096, i64 4096>
+; CHECK-NEXT:    store <2 x i64> [[R]], <2 x i64> addrspace(1)* [[OUT:%.*]]
+; CHECK-NEXT:    ret void
+;
+; GCN-LABEL: srem_v2i64_pow2k_denom:
+; GCN:       ; %bb.0:
+; GCN-NEXT:    s_load_dwordx2 s[4:5], s[0:1], 0x9
+; GCN-NEXT:    s_load_dwordx4 s[0:3], s[0:1], 0xd
+; GCN-NEXT:    s_movk_i32 s8, 0xf000
+; GCN-NEXT:    s_mov_b32 s7, 0xf000
+; GCN-NEXT:    s_mov_b32 s6, -1
+; GCN-NEXT:    s_waitcnt lgkmcnt(0)
+; GCN-NEXT:    s_ashr_i32 s9, s3, 31
+; GCN-NEXT:    s_lshr_b32 s9, s9, 20
+; GCN-NEXT:    s_add_u32 s9, s2, s9
+; GCN-NEXT:    s_addc_u32 s10, s3, 0
+; GCN-NEXT:    s_and_b32 s9, s9, s8
+; GCN-NEXT:    s_sub_u32 s2, s2, s9
+; GCN-NEXT:    s_subb_u32 s3, s3, s10
+; GCN-NEXT:    s_ashr_i32 s9, s1, 31
+; GCN-NEXT:    s_lshr_b32 s9, s9, 20
+; GCN-NEXT:    s_add_u32 s9, s0, s9
+; GCN-NEXT:    s_addc_u32 s10, s1, 0
+; GCN-NEXT:    s_and_b32 s8, s9, s8
+; GCN-NEXT:    s_sub_u32 s0, s0, s8
+; GCN-NEXT:    s_subb_u32 s1, s1, s10
+; GCN-NEXT:    v_mov_b32_e32 v0, s0
+; GCN-NEXT:    v_mov_b32_e32 v1, s1
+; GCN-NEXT:    v_mov_b32_e32 v2, s2
+; GCN-NEXT:    v_mov_b32_e32 v3, s3
+; GCN-NEXT:    buffer_store_dwordx4 v[0:3], off, s[4:7], 0
+; GCN-NEXT:    s_endpgm
+  %r = srem <2 x i64> %x, <i64 4096, i64 4096>
+  store <2 x i64> %r, <2 x i64> addrspace(1)* %out
+  ret void
+}
+
+define amdgpu_kernel void @srem_v2i64_pow2_shl_denom(<2 x i64> addrspace(1)* %out, <2 x i64> %x, <2 x i64> %y) {
+; CHECK-LABEL: @srem_v2i64_pow2_shl_denom(
+; CHECK-NEXT:    [[SHL_Y:%.*]] = shl <2 x i64> <i64 4096, i64 4096>, [[Y:%.*]]
+; CHECK-NEXT:    [[R:%.*]] = srem <2 x i64> [[X:%.*]], [[SHL_Y]]
+; CHECK-NEXT:    store <2 x i64> [[R]], <2 x i64> addrspace(1)* [[OUT:%.*]]
+; CHECK-NEXT:    ret void
+;
+; GCN-LABEL: srem_v2i64_pow2_shl_denom:
+; GCN:       ; %bb.0:
+; GCN-NEXT:    s_load_dwordx4 s[4:7], s[0:1], 0x11
+; GCN-NEXT:    s_mov_b32 s3, 0
+; GCN-NEXT:    s_movk_i32 s2, 0x1000
+; GCN-NEXT:    s_mov_b32 s18, 0x4f800000
+; GCN-NEXT:    s_mov_b32 s19, 0x5f7ffffc
+; GCN-NEXT:    s_waitcnt lgkmcnt(0)
+; GCN-NEXT:    s_lshl_b64 s[14:15], s[2:3], s4
+; GCN-NEXT:    s_lshl_b64 s[2:3], s[2:3], s6
+; GCN-NEXT:    s_ashr_i32 s4, s3, 31
+; GCN-NEXT:    s_add_u32 s2, s2, s4
+; GCN-NEXT:    s_mov_b32 s5, s4
+; GCN-NEXT:    s_addc_u32 s3, s3, s4
+; GCN-NEXT:    s_xor_b64 s[16:17], s[2:3], s[4:5]
+; GCN-NEXT:    v_cvt_f32_u32_e32 v0, s16
+; GCN-NEXT:    v_cvt_f32_u32_e32 v1, s17
+; GCN-NEXT:    s_mov_b32 s20, 0x2f800000
+; GCN-NEXT:    s_mov_b32 s21, 0xcf800000
+; GCN-NEXT:    s_sub_u32 s6, 0, s16
+; GCN-NEXT:    v_mac_f32_e32 v0, s18, v1
+; GCN-NEXT:    v_rcp_f32_e32 v0, v0
+; GCN-NEXT:    s_subb_u32 s7, 0, s17
+; GCN-NEXT:    s_load_dwordx2 s[4:5], s[0:1], 0x9
+; GCN-NEXT:    s_load_dwordx4 s[8:11], s[0:1], 0xd
+; GCN-NEXT:    v_mul_f32_e32 v0, s19, v0
+; GCN-NEXT:    v_mul_f32_e32 v1, s20, v0
+; GCN-NEXT:    v_trunc_f32_e32 v1, v1
+; GCN-NEXT:    v_mac_f32_e32 v0, s21, v1
+; GCN-NEXT:    v_cvt_u32_f32_e32 v0, v0
+; GCN-NEXT:    v_cvt_u32_f32_e32 v1, v1
+; GCN-NEXT:    s_waitcnt lgkmcnt(0)
+; GCN-NEXT:    s_ashr_i32 s12, s11, 31
+; GCN-NEXT:    s_add_u32 s0, s10, s12
+; GCN-NEXT:    v_mul_hi_u32 v3, s6, v0
+; GCN-NEXT:    v_mul_lo_u32 v2, s6, v1
+; GCN-NEXT:    v_mul_lo_u32 v4, s7, v0
+; GCN-NEXT:    v_mul_lo_u32 v5, s6, v0
+; GCN-NEXT:    s_mov_b32 s13, s12
+; GCN-NEXT:    v_add_i32_e32 v2, vcc, v3, v2
+; GCN-NEXT:    v_add_i32_e32 v2, vcc, v2, v4
+; GCN-NEXT:    v_mul_lo_u32 v3, v0, v2
+; GCN-NEXT:    v_mul_hi_u32 v4, v0, v5
+; GCN-NEXT:    v_mul_hi_u32 v6, v0, v2
+; GCN-NEXT:    v_mul_hi_u32 v7, v1, v2
+; GCN-NEXT:    v_mul_lo_u32 v2, v1, v2
+; GCN-NEXT:    v_add_i32_e32 v3, vcc, v4, v3
+; GCN-NEXT:    v_addc_u32_e32 v4, vcc, 0, v6, vcc
+; GCN-NEXT:    v_mul_lo_u32 v6, v1, v5
+; GCN-NEXT:    v_mul_hi_u32 v5, v1, v5
+; GCN-NEXT:    s_addc_u32 s1, s11, s12
+; GCN-NEXT:    s_xor_b64 s[10:11], s[0:1], s[12:13]
+; GCN-NEXT:    v_add_i32_e32 v3, vcc, v6, v3
+; GCN-NEXT:    v_addc_u32_e32 v3, vcc, v4, v5, vcc
+; GCN-NEXT:    v_mov_b32_e32 v4, 0
+; GCN-NEXT:    v_addc_u32_e32 v5, vcc, v7, v4, vcc
+; GCN-NEXT:    v_add_i32_e32 v2, vcc, v3, v2
+; GCN-NEXT:    v_mov_b32_e32 v6, 0
+; GCN-NEXT:    v_add_i32_e64 v0, s[2:3], v0, v2
+; GCN-NEXT:    v_addc_u32_e32 v3, vcc, v6, v5, vcc
+; GCN-NEXT:    v_addc_u32_e64 v2, vcc, v1, v3, s[2:3]
+; GCN-NEXT:    v_mul_lo_u32 v5, s6, v2
+; GCN-NEXT:    v_mul_hi_u32 v7, s6, v0
+; GCN-NEXT:    v_mul_lo_u32 v8, s7, v0
+; GCN-NEXT:    s_mov_b32 s7, 0xf000
+; GCN-NEXT:    v_add_i32_e32 v5, vcc, v7, v5
+; GCN-NEXT:    v_mul_lo_u32 v7, s6, v0
+; GCN-NEXT:    v_add_i32_e32 v5, vcc, v8, v5
+; GCN-NEXT:    v_mul_lo_u32 v10, v0, v5
+; GCN-NEXT:    v_mul_hi_u32 v12, v0, v5
+; GCN-NEXT:    v_mul_hi_u32 v11, v0, v7
+; GCN-NEXT:    v_mul_hi_u32 v9, v2, v7
+; GCN-NEXT:    v_mul_lo_u32 v7, v2, v7
+; GCN-NEXT:    v_mul_hi_u32 v8, v2, v5
+; GCN-NEXT:    v_add_i32_e32 v10, vcc, v11, v10
+; GCN-NEXT:    v_addc_u32_e32 v11, vcc, 0, v12, vcc
+; GCN-NEXT:    v_mul_lo_u32 v2, v2, v5
+; GCN-NEXT:    v_add_i32_e32 v7, vcc, v7, v10
+; GCN-NEXT:    v_addc_u32_e32 v7, vcc, v11, v9, vcc
+; GCN-NEXT:    v_addc_u32_e32 v5, vcc, v8, v4, vcc
+; GCN-NEXT:    v_add_i32_e32 v2, vcc, v7, v2
+; GCN-NEXT:    v_addc_u32_e32 v5, vcc, v6, v5, vcc
+; GCN-NEXT:    v_add_i32_e32 v1, vcc, v1, v3
+; GCN-NEXT:    v_addc_u32_e64 v1, vcc, v1, v5, s[2:3]
+; GCN-NEXT:    v_add_i32_e32 v0, vcc, v0, v2
+; GCN-NEXT:    v_addc_u32_e32 v1, vcc, 0, v1, vcc
+; GCN-NEXT:    v_mul_lo_u32 v2, s10, v1
+; GCN-NEXT:    v_mul_hi_u32 v3, s10, v0
+; GCN-NEXT:    v_mul_hi_u32 v5, s10, v1
+; GCN-NEXT:    v_mul_hi_u32 v7, s11, v1
+; GCN-NEXT:    v_mul_lo_u32 v1, s11, v1
+; GCN-NEXT:    v_add_i32_e32 v2, vcc, v3, v2
+; GCN-NEXT:    v_addc_u32_e32 v3, vcc, 0, v5, vcc
+; GCN-NEXT:    v_mul_lo_u32 v5, s11, v0
+; GCN-NEXT:    v_mul_hi_u32 v0, s11, v0
+; GCN-NEXT:    s_mov_b32 s6, -1
+; GCN-NEXT:    v_add_i32_e32 v2, vcc, v5, v2
+; GCN-NEXT:    v_addc_u32_e32 v0, vcc, v3, v0, vcc
+; GCN-NEXT:    v_addc_u32_e32 v2, vcc, v7, v4, vcc
+; GCN-NEXT:    v_add_i32_e32 v0, vcc, v0, v1
+; GCN-NEXT:    v_addc_u32_e32 v1, vcc, v6, v2, vcc
+; GCN-NEXT:    v_mul_lo_u32 v1, s16, v1
+; GCN-NEXT:    v_mul_hi_u32 v2, s16, v0
+; GCN-NEXT:    v_mul_lo_u32 v3, s17, v0
+; GCN-NEXT:    v_mul_lo_u32 v0, s16, v0
+; GCN-NEXT:    v_add_i32_e32 v1, vcc, v2, v1
+; GCN-NEXT:    v_add_i32_e32 v1, vcc, v1, v3
+; GCN-NEXT:    v_sub_i32_e32 v2, vcc, s11, v1
+; GCN-NEXT:    v_mov_b32_e32 v3, s17
+; GCN-NEXT:    v_sub_i32_e32 v0, vcc, s10, v0
+; GCN-NEXT:    v_subb_u32_e64 v2, s[0:1], v2, v3, vcc
+; GCN-NEXT:    v_subrev_i32_e64 v5, s[0:1], s16, v0
+; GCN-NEXT:    v_subb_u32_e64 v3, s[2:3], v2, v3, s[0:1]
+; GCN-NEXT:    v_subbrev_u32_e64 v2, s[0:1], 0, v2, s[0:1]
+; GCN-NEXT:    v_cmp_le_u32_e64 s[0:1], s17, v2
+; GCN-NEXT:    v_cndmask_b32_e64 v7, 0, -1, s[0:1]
+; GCN-NEXT:    v_cmp_le_u32_e64 s[0:1], s16, v5
+; GCN-NEXT:    v_cndmask_b32_e64 v8, 0, -1, s[0:1]
+; GCN-NEXT:    v_cmp_eq_u32_e64 s[0:1], s17, v2
+; GCN-NEXT:    v_cndmask_b32_e64 v7, v7, v8, s[0:1]
+; GCN-NEXT:    v_subrev_i32_e64 v8, s[0:1], s16, v5
+; GCN-NEXT:    s_ashr_i32 s2, s15, 31
+; GCN-NEXT:    v_subbrev_u32_e64 v3, s[0:1], 0, v3, s[0:1]
+; GCN-NEXT:    v_cmp_ne_u32_e64 s[0:1], 0, v7
+; GCN-NEXT:    s_add_u32 s10, s14, s2
+; GCN-NEXT:    v_cndmask_b32_e64 v2, v2, v3, s[0:1]
+; GCN-NEXT:    v_mov_b32_e32 v3, s11
+; GCN-NEXT:    s_mov_b32 s3, s2
+; GCN-NEXT:    s_addc_u32 s11, s15, s2
+; GCN-NEXT:    s_xor_b64 s[10:11], s[10:11], s[2:3]
+; GCN-NEXT:    v_cvt_f32_u32_e32 v7, s10
+; GCN-NEXT:    v_cvt_f32_u32_e32 v9, s11
+; GCN-NEXT:    v_subb_u32_e32 v1, vcc, v3, v1, vcc
+; GCN-NEXT:    v_cmp_le_u32_e32 vcc, s17, v1
+; GCN-NEXT:    v_cndmask_b32_e64 v3, 0, -1, vcc
+; GCN-NEXT:    v_mac_f32_e32 v7, s18, v9
+; GCN-NEXT:    v_rcp_f32_e32 v7, v7
+; GCN-NEXT:    v_cmp_le_u32_e32 vcc, s16, v0
+; GCN-NEXT:    v_cndmask_b32_e64 v10, 0, -1, vcc
+; GCN-NEXT:    v_cmp_eq_u32_e32 vcc, s17, v1
+; GCN-NEXT:    v_cndmask_b32_e32 v3, v3, v10, vcc
+; GCN-NEXT:    v_cmp_ne_u32_e32 vcc, 0, v3
+; GCN-NEXT:    v_mul_f32_e32 v3, s19, v7
+; GCN-NEXT:    v_cndmask_b32_e32 v1, v1, v2, vcc
+; GCN-NEXT:    v_cndmask_b32_e64 v2, v5, v8, s[0:1]
+; GCN-NEXT:    v_mul_f32_e32 v5, s20, v3
+; GCN-NEXT:    v_trunc_f32_e32 v5, v5
+; GCN-NEXT:    v_mac_f32_e32 v3, s21, v5
+; GCN-NEXT:    v_cvt_u32_f32_e32 v3, v3
+; GCN-NEXT:    v_cvt_u32_f32_e32 v5, v5
+; GCN-NEXT:    s_sub_u32 s2, 0, s10
+; GCN-NEXT:    v_cndmask_b32_e32 v0, v0, v2, vcc
+; GCN-NEXT:    v_mul_hi_u32 v2, s2, v3
+; GCN-NEXT:    v_mul_lo_u32 v7, s2, v5
+; GCN-NEXT:    s_subb_u32 s3, 0, s11
+; GCN-NEXT:    v_mul_lo_u32 v8, s3, v3
+; GCN-NEXT:    s_ashr_i32 s14, s9, 31
+; GCN-NEXT:    v_add_i32_e32 v2, vcc, v2, v7
+; GCN-NEXT:    v_mul_lo_u32 v7, s2, v3
+; GCN-NEXT:    v_add_i32_e32 v2, vcc, v2, v8
+; GCN-NEXT:    v_mul_lo_u32 v8, v3, v2
+; GCN-NEXT:    v_mul_hi_u32 v10, v3, v2
+; GCN-NEXT:    v_mul_hi_u32 v9, v3, v7
+; GCN-NEXT:    v_mul_hi_u32 v11, v5, v2
+; GCN-NEXT:    v_mul_lo_u32 v2, v5, v2
+; GCN-NEXT:    s_mov_b32 s15, s14
+; GCN-NEXT:    v_add_i32_e32 v8, vcc, v9, v8
+; GCN-NEXT:    v_addc_u32_e32 v9, vcc, 0, v10, vcc
+; GCN-NEXT:    v_mul_lo_u32 v10, v5, v7
+; GCN-NEXT:    v_mul_hi_u32 v7, v5, v7
+; GCN-NEXT:    v_xor_b32_e32 v0, s12, v0
+; GCN-NEXT:    v_xor_b32_e32 v1, s12, v1
+; GCN-NEXT:    v_add_i32_e32 v8, vcc, v10, v8
+; GCN-NEXT:    v_addc_u32_e32 v7, vcc, v9, v7, vcc
+; GCN-NEXT:    v_addc_u32_e32 v8, vcc, v11, v4, vcc
+; GCN-NEXT:    v_add_i32_e32 v2, vcc, v7, v2
+; GCN-NEXT:    v_add_i32_e64 v2, s[0:1], v3, v2
+; GCN-NEXT:    v_addc_u32_e32 v7, vcc, v6, v8, vcc
+; GCN-NEXT:    v_addc_u32_e64 v3, vcc, v5, v7, s[0:1]
+; GCN-NEXT:    v_mul_lo_u32 v8, s2, v3
+; GCN-NEXT:    v_mul_hi_u32 v9, s2, v2
+; GCN-NEXT:    v_mul_lo_u32 v10, s3, v2
+; GCN-NEXT:    v_add_i32_e32 v8, vcc, v9, v8
+; GCN-NEXT:    v_mul_lo_u32 v9, s2, v2
+; GCN-NEXT:    v_add_i32_e32 v8, vcc, v10, v8
+; GCN-NEXT:    v_mul_lo_u32 v12, v2, v8
+; GCN-NEXT:    v_mul_hi_u32 v14, v2, v8
+; GCN-NEXT:    v_mul_hi_u32 v13, v2, v9
+; GCN-NEXT:    v_mul_hi_u32 v11, v3, v9
+; GCN-NEXT:    v_mul_lo_u32 v9, v3, v9
+; GCN-NEXT:    v_mul_hi_u32 v10, v3, v8
+; GCN-NEXT:    v_add_i32_e32 v12, vcc, v13, v12
+; GCN-NEXT:    v_addc_u32_e32 v13, vcc, 0, v14, vcc
+; GCN-NEXT:    v_mul_lo_u32 v3, v3, v8
+; GCN-NEXT:    v_add_i32_e32 v9, vcc, v9, v12
+; GCN-NEXT:    v_addc_u32_e32 v9, vcc, v13, v11, vcc
+; GCN-NEXT:    v_addc_u32_e32 v8, vcc, v10, v4, vcc
+; GCN-NEXT:    v_add_i32_e32 v3, vcc, v9, v3
+; GCN-NEXT:    v_addc_u32_e32 v8, vcc, v6, v8, vcc
+; GCN-NEXT:    v_add_i32_e32 v5, vcc, v5, v7
+; GCN-NEXT:    v_addc_u32_e64 v5, vcc, v5, v8, s[0:1]
+; GCN-NEXT:    s_add_u32 s0, s8, s14
+; GCN-NEXT:    v_add_i32_e32 v2, vcc, v2, v3
+; GCN-NEXT:    s_addc_u32 s1, s9, s14
+; GCN-NEXT:    s_xor_b64 s[8:9], s[0:1], s[14:15]
+; GCN-NEXT:    v_addc_u32_e32 v3, vcc, 0, v5, vcc
+; GCN-NEXT:    v_mul_lo_u32 v5, s8, v3
+; GCN-NEXT:    v_mul_hi_u32 v7, s8, v2
+; GCN-NEXT:    v_mul_hi_u32 v9, s8, v3
+; GCN-NEXT:    v_mul_hi_u32 v10, s9, v3
+; GCN-NEXT:    v_mul_lo_u32 v3, s9, v3
+; GCN-NEXT:    v_add_i32_e32 v5, vcc, v7, v5
+; GCN-NEXT:    v_addc_u32_e32 v7, vcc, 0, v9, vcc
+; GCN-NEXT:    v_mul_lo_u32 v9, s9, v2
+; GCN-NEXT:    v_mul_hi_u32 v2, s9, v2
+; GCN-NEXT:    v_mov_b32_e32 v8, s12
+; GCN-NEXT:    v_add_i32_e32 v5, vcc, v9, v5
+; GCN-NEXT:    v_addc_u32_e32 v2, vcc, v7, v2, vcc
+; GCN-NEXT:    v_addc_u32_e32 v4, vcc, v10, v4, vcc
+; GCN-NEXT:    v_add_i32_e32 v5, vcc, v2, v3
+; GCN-NEXT:    v_addc_u32_e32 v2, vcc, v6, v4, vcc
+; GCN-NEXT:    v_mul_lo_u32 v4, s10, v2
+; GCN-NEXT:    v_mul_hi_u32 v6, s10, v5
+; GCN-NEXT:    v_subrev_i32_e32 v2, vcc, s12, v0
+; GCN-NEXT:    v_mul_lo_u32 v0, s11, v5
+; GCN-NEXT:    v_subb_u32_e32 v3, vcc, v1, v8, vcc
+; GCN-NEXT:    v_add_i32_e32 v1, vcc, v6, v4
+; GCN-NEXT:    v_add_i32_e32 v0, vcc, v1, v0
+; GCN-NEXT:    v_mul_lo_u32 v1, s10, v5
+; GCN-NEXT:    v_sub_i32_e32 v4, vcc, s9, v0
+; GCN-NEXT:    v_mov_b32_e32 v5, s11
+; GCN-NEXT:    v_sub_i32_e32 v1, vcc, s8, v1
+; GCN-NEXT:    v_subb_u32_e64 v4, s[0:1], v4, v5, vcc
+; GCN-NEXT:    v_subrev_i32_e64 v6, s[0:1], s10, v1
+; GCN-NEXT:    v_subb_u32_e64 v5, s[2:3], v4, v5, s[0:1]
+; GCN-NEXT:    v_subbrev_u32_e64 v4, s[0:1], 0, v4, s[0:1]
+; GCN-NEXT:    v_cmp_le_u32_e64 s[0:1], s11, v4
+; GCN-NEXT:    v_cndmask_b32_e64 v7, 0, -1, s[0:1]
+; GCN-NEXT:    v_cmp_le_u32_e64 s[0:1], s10, v6
+; GCN-NEXT:    v_cndmask_b32_e64 v8, 0, -1, s[0:1]
+; GCN-NEXT:    v_cmp_eq_u32_e64 s[0:1], s11, v4
+; GCN-NEXT:    v_cndmask_b32_e64 v7, v7, v8, s[0:1]
+; GCN-NEXT:    v_subrev_i32_e64 v8, s[0:1], s10, v6
+; GCN-NEXT:    v_subbrev_u32_e64 v5, s[0:1], 0, v5, s[0:1]
+; GCN-NEXT:    v_cmp_ne_u32_e64 s[0:1], 0, v7
+; GCN-NEXT:    v_cndmask_b32_e64 v4, v4, v5, s[0:1]
+; GCN-NEXT:    v_mov_b32_e32 v5, s9
+; GCN-NEXT:    v_subb_u32_e32 v0, vcc, v5, v0, vcc
+; GCN-NEXT:    v_cmp_le_u32_e32 vcc, s11, v0
+; GCN-NEXT:    v_cndmask_b32_e64 v5, 0, -1, vcc
+; GCN-NEXT:    v_cmp_le_u32_e32 vcc, s10, v1
+; GCN-NEXT:    v_cndmask_b32_e64 v7, 0, -1, vcc
+; GCN-NEXT:    v_cmp_eq_u32_e32 vcc, s11, v0
+; GCN-NEXT:    v_cndmask_b32_e32 v5, v5, v7, vcc
+; GCN-NEXT:    v_cmp_ne_u32_e32 vcc, 0, v5
+; GCN-NEXT:    v_cndmask_b32_e32 v0, v0, v4, vcc
+; GCN-NEXT:    v_cndmask_b32_e64 v4, v6, v8, s[0:1]
+; GCN-NEXT:    v_cndmask_b32_e32 v1, v1, v4, vcc
+; GCN-NEXT:    v_xor_b32_e32 v1, s14, v1
+; GCN-NEXT:    v_xor_b32_e32 v4, s14, v0
+; GCN-NEXT:    v_mov_b32_e32 v5, s14
+; GCN-NEXT:    v_subrev_i32_e32 v0, vcc, s14, v1
+; GCN-NEXT:    v_subb_u32_e32 v1, vcc, v4, v5, vcc
+; GCN-NEXT:    buffer_store_dwordx4 v[0:3], off, s[4:7], 0
+; GCN-NEXT:    s_endpgm
+  %shl.y = shl <2 x i64> <i64 4096, i64 4096>, %y
+  %r = srem <2 x i64> %x, %shl.y
+  store <2 x i64> %r, <2 x i64> addrspace(1)* %out
+  ret void
+}


        


More information about the llvm-commits mailing list