[llvm] a908adb - [AMDGPU] Fix unsaturated add when moving 64-bit ctlz/cttz to the VALU (#216707)

via llvm-commits llvm-commits at lists.llvm.org
Wed Aug 26 05:05:12 PDT 2026


Author: Arseniy Obolenskiy
Date: 2026-08-26T14:05:07+02:00
New Revision: a908adb93db53c0d630232a5bdab8817495c17eb

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

LOG: [AMDGPU] Fix unsaturated add when moving 64-bit ctlz/cttz to the VALU (#216707)

The ffbh/ffbl add is saturated via a clamp modifier, but on gfx6/7/8 it
lowers to V_ADD_CO_U32_e32, which has no clamp operand, so
ctlz/cttz.i64(0, false) returns 31 instead of 64 there

ffbh/ffbl only produce 0..31 or -1, so uaddsat(x, 32) is just x | 32

Use V_OR_B32_e32 instead, which needs no clamp and works everywhere

Added: 
    

Modified: 
    llvm/lib/Target/AMDGPU/SIInstrInfo.cpp
    llvm/test/CodeGen/AMDGPU/ctlz_zero_poison.ll
    llvm/test/CodeGen/AMDGPU/cttz_zero_poison.ll
    llvm/test/CodeGen/AMDGPU/move-to-valu-ctlz-cttz.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp b/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp
index f5000ff582282..bc419d813f171 100644
--- a/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp
+++ b/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp
@@ -9663,9 +9663,9 @@ void SIInstrInfo::splitScalar64BitCountOp(SIInstrWorklist &Worklist,
                                           MachineInstr &Inst, unsigned Opcode,
                                           MachineDominatorTree *MDT) const {
   //  (S_FLBIT_I32_B64 hi:lo) ->
-  // -> (umin (V_FFBH_U32_e32 hi), (uaddsat (V_FFBH_U32_e32 lo), 32))
+  // -> (umin (V_FFBH_U32_e32 hi), (or (V_FFBH_U32_e32 lo), 32))
   //  (S_FF1_I32_B64 hi:lo) ->
-  // ->(umin (uaddsat (V_FFBL_B32_e32 hi), 32) (V_FFBL_B32_e32 lo))
+  // ->(umin (or (V_FFBL_B32_e32 hi), 32) (V_FFBL_B32_e32 lo))
 
   MachineBasicBlock &MBB = *Inst.getParent();
   MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo();
@@ -9678,8 +9678,6 @@ void SIInstrInfo::splitScalar64BitCountOp(SIInstrWorklist &Worklist,
   const MCInstrDesc &InstDesc = get(Opcode);
 
   bool IsCtlz = Opcode == AMDGPU::V_FFBH_U32_e32;
-  unsigned OpcodeAdd = ST.hasAddNoCarryInsts() ? AMDGPU::V_ADD_U32_e64
-                                               : AMDGPU::V_ADD_CO_U32_e32;
 
   const TargetRegisterClass *SrcRC =
       Src.isReg() ? MRI.getRegClass(Src.getReg()) : &AMDGPU::SGPR_32RegClass;
@@ -9700,10 +9698,9 @@ void SIInstrInfo::splitScalar64BitCountOp(SIInstrWorklist &Worklist,
 
   BuildMI(MBB, MII, DL, InstDesc, MidReg2).add(SrcRegSub1);
 
-  BuildMI(MBB, MII, DL, get(OpcodeAdd), MidReg3)
-      .addReg(IsCtlz ? MidReg1 : MidReg2)
+  BuildMI(MBB, MII, DL, get(AMDGPU::V_OR_B32_e32), MidReg3)
       .addImm(32)
-      .addImm(1); // enable clamp
+      .addReg(IsCtlz ? MidReg1 : MidReg2);
 
   BuildMI(MBB, MII, DL, get(AMDGPU::V_MIN_U32_e64), MidReg4)
       .addReg(MidReg3)

diff  --git a/llvm/test/CodeGen/AMDGPU/ctlz_zero_poison.ll b/llvm/test/CodeGen/AMDGPU/ctlz_zero_poison.ll
index b9a47766cb089..d38a473a9a31f 100644
--- a/llvm/test/CodeGen/AMDGPU/ctlz_zero_poison.ll
+++ b/llvm/test/CodeGen/AMDGPU/ctlz_zero_poison.ll
@@ -955,7 +955,7 @@ define amdgpu_kernel void @v_ctlz_zero_poison_i64_with_select(ptr addrspace(1) n
 ; SI-NEXT:    v_or_b32_e32 v1, v3, v2
 ; SI-NEXT:    v_ffbh_u32_e32 v1, v1
 ; SI-NEXT:    v_ffbh_u32_e32 v0, v0
-; SI-NEXT:    v_add_i32_e32 v1, vcc, 32, v1
+; SI-NEXT:    v_or_b32_e32 v1, 32, v1
 ; SI-NEXT:    v_min_u32_e32 v0, v1, v0
 ; SI-NEXT:    v_min_u32_e32 v0, 64, v0
 ; SI-NEXT:    v_mov_b32_e32 v1, 0
@@ -1026,7 +1026,7 @@ define amdgpu_kernel void @v_ctlz_zero_poison_i64_with_select(ptr addrspace(1) n
 ; VI-NEXT:    v_or_b32_sdwa v2, v2, v3 dst_sel:WORD_1 dst_unused:UNUSED_PAD src0_sel:DWORD src1_sel:DWORD
 ; VI-NEXT:    v_or_b32_e32 v2, v2, v5
 ; VI-NEXT:    v_ffbh_u32_e32 v2, v2
-; VI-NEXT:    v_add_u32_e32 v2, vcc, 32, v2
+; VI-NEXT:    v_or_b32_e32 v2, 32, v2
 ; VI-NEXT:    v_min_u32_e32 v2, v2, v4
 ; VI-NEXT:    v_min_u32_e32 v2, 64, v2
 ; VI-NEXT:    v_mov_b32_e32 v3, 0

diff  --git a/llvm/test/CodeGen/AMDGPU/cttz_zero_poison.ll b/llvm/test/CodeGen/AMDGPU/cttz_zero_poison.ll
index 8cce8f0c143ca..eb66afedb3670 100644
--- a/llvm/test/CodeGen/AMDGPU/cttz_zero_poison.ll
+++ b/llvm/test/CodeGen/AMDGPU/cttz_zero_poison.ll
@@ -919,7 +919,7 @@ define amdgpu_kernel void @v_cttz_zero_poison_i64_with_select(ptr addrspace(1) n
 ; SI-NEXT:    v_or_b32_e32 v1, v3, v2
 ; SI-NEXT:    v_ffbl_b32_e32 v0, v0
 ; SI-NEXT:    v_ffbl_b32_e32 v1, v1
-; SI-NEXT:    v_add_i32_e32 v0, vcc, 32, v0
+; SI-NEXT:    v_or_b32_e32 v0, 32, v0
 ; SI-NEXT:    v_min_u32_e32 v0, v0, v1
 ; SI-NEXT:    v_min_u32_e32 v0, 64, v0
 ; SI-NEXT:    v_mov_b32_e32 v1, 0
@@ -984,7 +984,7 @@ define amdgpu_kernel void @v_cttz_zero_poison_i64_with_select(ptr addrspace(1) n
 ; VI-NEXT:    s_waitcnt vmcnt(2)
 ; VI-NEXT:    v_or_b32_e32 v4, v4, v7
 ; VI-NEXT:    v_ffbl_b32_e32 v3, v3
-; VI-NEXT:    v_add_u32_e32 v3, vcc, 32, v3
+; VI-NEXT:    v_or_b32_e32 v3, 32, v3
 ; VI-NEXT:    s_waitcnt vmcnt(1)
 ; VI-NEXT:    v_lshlrev_b32_e32 v5, 8, v8
 ; VI-NEXT:    s_waitcnt vmcnt(0)

diff  --git a/llvm/test/CodeGen/AMDGPU/move-to-valu-ctlz-cttz.ll b/llvm/test/CodeGen/AMDGPU/move-to-valu-ctlz-cttz.ll
index d416048942304..dd28f1459ad05 100644
--- a/llvm/test/CodeGen/AMDGPU/move-to-valu-ctlz-cttz.ll
+++ b/llvm/test/CodeGen/AMDGPU/move-to-valu-ctlz-cttz.ll
@@ -1,4 +1,6 @@
 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc -mtriple=amdgpu6.00 < %s | FileCheck --check-prefixes=GCN,GFX6 %s
+; RUN: llc -mtriple=amdgpu8.03 < %s | FileCheck --check-prefixes=GCN,GFX8 %s
 ; RUN: llc -mtriple=amdgpu9.00 < %s | FileCheck --check-prefixes=GCN,GFX9 %s
 ; RUN: llc -mtriple=amdgpu10.10 < %s | FileCheck -check-prefixes=GCN,GFX10 %s
 
@@ -6,6 +8,124 @@ declare i64 @llvm.ctlz.i64(i64, i1) nounwind readnone
 declare i64 @llvm.cttz.i64(i64, i1) nounwind readnone
 
 define amdgpu_kernel void @ctlz_i64_poison(ptr addrspace(1) noalias %out, ptr addrspace(1) nocapture readonly %arrayidx) nounwind {
+; GFX6-LABEL: ctlz_i64_poison:
+; GFX6:       ; %bb.0:
+; GFX6-NEXT:    s_load_dwordx4 s[4:7], s[4:5], 0x9
+; GFX6-NEXT:    s_mov_b32 s3, 0xf000
+; GFX6-NEXT:    s_mov_b32 s2, -1
+; GFX6-NEXT:    s_mov_b32 s10, s2
+; GFX6-NEXT:    s_mov_b32 s11, s3
+; GFX6-NEXT:    s_waitcnt lgkmcnt(0)
+; GFX6-NEXT:    s_mov_b32 s8, s6
+; GFX6-NEXT:    s_mov_b32 s9, s7
+; GFX6-NEXT:    buffer_load_ubyte v0, off, s[8:11], 0 offset:5
+; GFX6-NEXT:    buffer_load_ubyte v1, off, s[8:11], 0 offset:7
+; GFX6-NEXT:    buffer_load_ubyte v2, off, s[8:11], 0 offset:1
+; GFX6-NEXT:    buffer_load_ubyte v3, off, s[8:11], 0 offset:3
+; GFX6-NEXT:    buffer_load_ubyte v4, off, s[8:11], 0 offset:4
+; GFX6-NEXT:    buffer_load_ubyte v5, off, s[8:11], 0 offset:6
+; GFX6-NEXT:    buffer_load_ubyte v6, off, s[8:11], 0
+; GFX6-NEXT:    buffer_load_ubyte v7, off, s[8:11], 0 offset:2
+; GFX6-NEXT:    s_mov_b32 s0, s4
+; GFX6-NEXT:    s_mov_b32 s1, s5
+; GFX6-NEXT:    s_waitcnt vmcnt(7)
+; GFX6-NEXT:    v_lshlrev_b32_e32 v0, 8, v0
+; GFX6-NEXT:    s_waitcnt vmcnt(6)
+; GFX6-NEXT:    v_lshlrev_b32_e32 v1, 8, v1
+; GFX6-NEXT:    s_waitcnt vmcnt(5)
+; GFX6-NEXT:    v_lshlrev_b32_e32 v2, 8, v2
+; GFX6-NEXT:    s_waitcnt vmcnt(4)
+; GFX6-NEXT:    v_lshlrev_b32_e32 v3, 8, v3
+; GFX6-NEXT:    s_waitcnt vmcnt(3)
+; GFX6-NEXT:    v_or_b32_e32 v0, v0, v4
+; GFX6-NEXT:    s_waitcnt vmcnt(2)
+; GFX6-NEXT:    v_or_b32_e32 v1, v1, v5
+; GFX6-NEXT:    s_waitcnt vmcnt(1)
+; GFX6-NEXT:    v_or_b32_e32 v2, v2, v6
+; GFX6-NEXT:    s_waitcnt vmcnt(0)
+; GFX6-NEXT:    v_or_b32_e32 v3, v3, v7
+; GFX6-NEXT:    v_lshlrev_b32_e32 v1, 16, v1
+; GFX6-NEXT:    v_lshlrev_b32_e32 v3, 16, v3
+; GFX6-NEXT:    v_or_b32_e32 v0, v1, v0
+; GFX6-NEXT:    v_or_b32_e32 v1, v3, v2
+; GFX6-NEXT:    v_ffbh_u32_e32 v1, v1
+; GFX6-NEXT:    v_ffbh_u32_e32 v0, v0
+; GFX6-NEXT:    v_or_b32_e32 v1, 32, v1
+; GFX6-NEXT:    v_min_u32_e32 v0, v1, v0
+; GFX6-NEXT:    v_mov_b32_e32 v1, 0
+; GFX6-NEXT:    buffer_store_dwordx2 v[0:1], off, s[0:3], 0
+; GFX6-NEXT:    s_endpgm
+;
+; GFX8-LABEL: ctlz_i64_poison:
+; GFX8:       ; %bb.0:
+; GFX8-NEXT:    s_load_dwordx4 s[0:3], s[4:5], 0x24
+; GFX8-NEXT:    s_waitcnt lgkmcnt(0)
+; GFX8-NEXT:    s_add_u32 s4, s2, 5
+; GFX8-NEXT:    s_addc_u32 s5, s3, 0
+; GFX8-NEXT:    v_mov_b32_e32 v0, s4
+; GFX8-NEXT:    v_mov_b32_e32 v1, s5
+; GFX8-NEXT:    s_add_u32 s4, s2, 4
+; GFX8-NEXT:    s_addc_u32 s5, s3, 0
+; GFX8-NEXT:    v_mov_b32_e32 v2, s4
+; GFX8-NEXT:    v_mov_b32_e32 v3, s5
+; GFX8-NEXT:    s_add_u32 s4, s2, 7
+; GFX8-NEXT:    s_addc_u32 s5, s3, 0
+; GFX8-NEXT:    v_mov_b32_e32 v4, s4
+; GFX8-NEXT:    v_mov_b32_e32 v5, s5
+; GFX8-NEXT:    s_add_u32 s4, s2, 6
+; GFX8-NEXT:    s_addc_u32 s5, s3, 0
+; GFX8-NEXT:    v_mov_b32_e32 v7, s5
+; GFX8-NEXT:    v_mov_b32_e32 v6, s4
+; GFX8-NEXT:    s_add_u32 s4, s2, 1
+; GFX8-NEXT:    s_addc_u32 s5, s3, 0
+; GFX8-NEXT:    v_mov_b32_e32 v9, s5
+; GFX8-NEXT:    v_mov_b32_e32 v8, s4
+; GFX8-NEXT:    s_add_u32 s4, s2, 3
+; GFX8-NEXT:    s_addc_u32 s5, s3, 0
+; GFX8-NEXT:    flat_load_ubyte v10, v[0:1]
+; GFX8-NEXT:    flat_load_ubyte v11, v[2:3]
+; GFX8-NEXT:    flat_load_ubyte v12, v[4:5]
+; GFX8-NEXT:    flat_load_ubyte v6, v[6:7]
+; GFX8-NEXT:    flat_load_ubyte v7, v[8:9]
+; GFX8-NEXT:    v_mov_b32_e32 v0, s2
+; GFX8-NEXT:    v_mov_b32_e32 v1, s3
+; GFX8-NEXT:    s_add_u32 s2, s2, 2
+; GFX8-NEXT:    v_mov_b32_e32 v2, s4
+; GFX8-NEXT:    v_mov_b32_e32 v3, s5
+; GFX8-NEXT:    s_addc_u32 s3, s3, 0
+; GFX8-NEXT:    v_mov_b32_e32 v5, s3
+; GFX8-NEXT:    v_mov_b32_e32 v4, s2
+; GFX8-NEXT:    flat_load_ubyte v8, v[0:1]
+; GFX8-NEXT:    flat_load_ubyte v2, v[2:3]
+; GFX8-NEXT:    flat_load_ubyte v3, v[4:5]
+; GFX8-NEXT:    v_mov_b32_e32 v0, s0
+; GFX8-NEXT:    v_mov_b32_e32 v1, s1
+; GFX8-NEXT:    s_waitcnt vmcnt(7)
+; GFX8-NEXT:    v_lshlrev_b32_e32 v4, 8, v10
+; GFX8-NEXT:    s_waitcnt vmcnt(6)
+; GFX8-NEXT:    v_or_b32_e32 v4, v4, v11
+; GFX8-NEXT:    s_waitcnt vmcnt(5)
+; GFX8-NEXT:    v_lshlrev_b32_e32 v5, 8, v12
+; GFX8-NEXT:    s_waitcnt vmcnt(4)
+; GFX8-NEXT:    v_or_b32_sdwa v5, v5, v6 dst_sel:WORD_1 dst_unused:UNUSED_PAD src0_sel:DWORD src1_sel:DWORD
+; GFX8-NEXT:    v_or_b32_e32 v4, v5, v4
+; GFX8-NEXT:    s_waitcnt vmcnt(3)
+; GFX8-NEXT:    v_lshlrev_b32_e32 v5, 8, v7
+; GFX8-NEXT:    v_ffbh_u32_e32 v4, v4
+; GFX8-NEXT:    s_waitcnt vmcnt(2)
+; GFX8-NEXT:    v_or_b32_e32 v5, v5, v8
+; GFX8-NEXT:    s_waitcnt vmcnt(1)
+; GFX8-NEXT:    v_lshlrev_b32_e32 v2, 8, v2
+; GFX8-NEXT:    s_waitcnt vmcnt(0)
+; GFX8-NEXT:    v_or_b32_sdwa v2, v2, v3 dst_sel:WORD_1 dst_unused:UNUSED_PAD src0_sel:DWORD src1_sel:DWORD
+; GFX8-NEXT:    v_or_b32_e32 v2, v2, v5
+; GFX8-NEXT:    v_ffbh_u32_e32 v2, v2
+; GFX8-NEXT:    v_or_b32_e32 v2, 32, v2
+; GFX8-NEXT:    v_min_u32_e32 v2, v2, v4
+; GFX8-NEXT:    v_mov_b32_e32 v3, 0
+; GFX8-NEXT:    flat_store_dwordx2 v[0:1], v[2:3]
+; GFX8-NEXT:    s_endpgm
+;
 ; GFX9-LABEL: ctlz_i64_poison:
 ; GFX9:       ; %bb.0:
 ; GFX9-NEXT:    s_load_dwordx4 s[0:3], s[4:5], 0x24
@@ -38,7 +158,7 @@ define amdgpu_kernel void @ctlz_i64_poison(ptr addrspace(1) noalias %out, ptr ad
 ; GFX9-NEXT:    v_or_b32_e32 v2, v4, v3
 ; GFX9-NEXT:    v_ffbh_u32_e32 v2, v2
 ; GFX9-NEXT:    v_ffbh_u32_e32 v0, v0
-; GFX9-NEXT:    v_add_u32_e64 v2, v2, 32 clamp
+; GFX9-NEXT:    v_or_b32_e32 v2, 32, v2
 ; GFX9-NEXT:    v_min_u32_e32 v0, v2, v0
 ; GFX9-NEXT:    global_store_dwordx2 v1, v[0:1], s[0:1]
 ; GFX9-NEXT:    s_endpgm
@@ -74,7 +194,7 @@ define amdgpu_kernel void @ctlz_i64_poison(ptr addrspace(1) noalias %out, ptr ad
 ; GFX10-NEXT:    v_or_b32_e32 v0, v2, v0
 ; GFX10-NEXT:    v_ffbh_u32_e32 v2, v3
 ; GFX10-NEXT:    v_ffbh_u32_e32 v0, v0
-; GFX10-NEXT:    v_add_nc_u32_e64 v2, v2, 32 clamp
+; GFX10-NEXT:    v_or_b32_e32 v2, 32, v2
 ; GFX10-NEXT:    v_min_u32_e32 v0, v2, v0
 ; GFX10-NEXT:    global_store_dwordx2 v1, v[0:1], s[0:1]
 ; GFX10-NEXT:    s_endpgm
@@ -85,6 +205,126 @@ define amdgpu_kernel void @ctlz_i64_poison(ptr addrspace(1) noalias %out, ptr ad
 }
 
 define amdgpu_kernel void @ctlz_i64(ptr addrspace(1) noalias %out, ptr addrspace(1) nocapture readonly %arrayidx) nounwind {
+; GFX6-LABEL: ctlz_i64:
+; GFX6:       ; %bb.0:
+; GFX6-NEXT:    s_load_dwordx4 s[4:7], s[4:5], 0x9
+; GFX6-NEXT:    s_mov_b32 s3, 0xf000
+; GFX6-NEXT:    s_mov_b32 s2, -1
+; GFX6-NEXT:    s_mov_b32 s10, s2
+; GFX6-NEXT:    s_mov_b32 s11, s3
+; GFX6-NEXT:    s_waitcnt lgkmcnt(0)
+; GFX6-NEXT:    s_mov_b32 s8, s6
+; GFX6-NEXT:    s_mov_b32 s9, s7
+; GFX6-NEXT:    buffer_load_ubyte v0, off, s[8:11], 0 offset:5
+; GFX6-NEXT:    buffer_load_ubyte v1, off, s[8:11], 0 offset:7
+; GFX6-NEXT:    buffer_load_ubyte v2, off, s[8:11], 0 offset:1
+; GFX6-NEXT:    buffer_load_ubyte v3, off, s[8:11], 0 offset:3
+; GFX6-NEXT:    buffer_load_ubyte v4, off, s[8:11], 0 offset:4
+; GFX6-NEXT:    buffer_load_ubyte v5, off, s[8:11], 0 offset:6
+; GFX6-NEXT:    buffer_load_ubyte v6, off, s[8:11], 0
+; GFX6-NEXT:    buffer_load_ubyte v7, off, s[8:11], 0 offset:2
+; GFX6-NEXT:    s_mov_b32 s0, s4
+; GFX6-NEXT:    s_mov_b32 s1, s5
+; GFX6-NEXT:    s_waitcnt vmcnt(7)
+; GFX6-NEXT:    v_lshlrev_b32_e32 v0, 8, v0
+; GFX6-NEXT:    s_waitcnt vmcnt(6)
+; GFX6-NEXT:    v_lshlrev_b32_e32 v1, 8, v1
+; GFX6-NEXT:    s_waitcnt vmcnt(5)
+; GFX6-NEXT:    v_lshlrev_b32_e32 v2, 8, v2
+; GFX6-NEXT:    s_waitcnt vmcnt(4)
+; GFX6-NEXT:    v_lshlrev_b32_e32 v3, 8, v3
+; GFX6-NEXT:    s_waitcnt vmcnt(3)
+; GFX6-NEXT:    v_or_b32_e32 v0, v0, v4
+; GFX6-NEXT:    s_waitcnt vmcnt(2)
+; GFX6-NEXT:    v_or_b32_e32 v1, v1, v5
+; GFX6-NEXT:    s_waitcnt vmcnt(1)
+; GFX6-NEXT:    v_or_b32_e32 v2, v2, v6
+; GFX6-NEXT:    s_waitcnt vmcnt(0)
+; GFX6-NEXT:    v_or_b32_e32 v3, v3, v7
+; GFX6-NEXT:    v_lshlrev_b32_e32 v1, 16, v1
+; GFX6-NEXT:    v_lshlrev_b32_e32 v3, 16, v3
+; GFX6-NEXT:    v_or_b32_e32 v0, v1, v0
+; GFX6-NEXT:    v_or_b32_e32 v1, v3, v2
+; GFX6-NEXT:    v_ffbh_u32_e32 v1, v1
+; GFX6-NEXT:    v_ffbh_u32_e32 v0, v0
+; GFX6-NEXT:    v_or_b32_e32 v1, 32, v1
+; GFX6-NEXT:    v_min_u32_e32 v0, v1, v0
+; GFX6-NEXT:    v_min_u32_e32 v0, 64, v0
+; GFX6-NEXT:    v_mov_b32_e32 v1, 0
+; GFX6-NEXT:    buffer_store_dwordx2 v[0:1], off, s[0:3], 0
+; GFX6-NEXT:    s_endpgm
+;
+; GFX8-LABEL: ctlz_i64:
+; GFX8:       ; %bb.0:
+; GFX8-NEXT:    s_load_dwordx4 s[0:3], s[4:5], 0x24
+; GFX8-NEXT:    s_waitcnt lgkmcnt(0)
+; GFX8-NEXT:    s_add_u32 s4, s2, 5
+; GFX8-NEXT:    s_addc_u32 s5, s3, 0
+; GFX8-NEXT:    v_mov_b32_e32 v0, s4
+; GFX8-NEXT:    v_mov_b32_e32 v1, s5
+; GFX8-NEXT:    s_add_u32 s4, s2, 4
+; GFX8-NEXT:    s_addc_u32 s5, s3, 0
+; GFX8-NEXT:    v_mov_b32_e32 v2, s4
+; GFX8-NEXT:    v_mov_b32_e32 v3, s5
+; GFX8-NEXT:    s_add_u32 s4, s2, 7
+; GFX8-NEXT:    s_addc_u32 s5, s3, 0
+; GFX8-NEXT:    v_mov_b32_e32 v4, s4
+; GFX8-NEXT:    v_mov_b32_e32 v5, s5
+; GFX8-NEXT:    s_add_u32 s4, s2, 6
+; GFX8-NEXT:    s_addc_u32 s5, s3, 0
+; GFX8-NEXT:    v_mov_b32_e32 v7, s5
+; GFX8-NEXT:    v_mov_b32_e32 v6, s4
+; GFX8-NEXT:    s_add_u32 s4, s2, 1
+; GFX8-NEXT:    s_addc_u32 s5, s3, 0
+; GFX8-NEXT:    v_mov_b32_e32 v9, s5
+; GFX8-NEXT:    v_mov_b32_e32 v8, s4
+; GFX8-NEXT:    s_add_u32 s4, s2, 3
+; GFX8-NEXT:    s_addc_u32 s5, s3, 0
+; GFX8-NEXT:    flat_load_ubyte v10, v[0:1]
+; GFX8-NEXT:    flat_load_ubyte v11, v[2:3]
+; GFX8-NEXT:    flat_load_ubyte v12, v[4:5]
+; GFX8-NEXT:    flat_load_ubyte v6, v[6:7]
+; GFX8-NEXT:    flat_load_ubyte v7, v[8:9]
+; GFX8-NEXT:    v_mov_b32_e32 v0, s2
+; GFX8-NEXT:    v_mov_b32_e32 v1, s3
+; GFX8-NEXT:    s_add_u32 s2, s2, 2
+; GFX8-NEXT:    v_mov_b32_e32 v2, s4
+; GFX8-NEXT:    v_mov_b32_e32 v3, s5
+; GFX8-NEXT:    s_addc_u32 s3, s3, 0
+; GFX8-NEXT:    v_mov_b32_e32 v5, s3
+; GFX8-NEXT:    v_mov_b32_e32 v4, s2
+; GFX8-NEXT:    flat_load_ubyte v8, v[0:1]
+; GFX8-NEXT:    flat_load_ubyte v2, v[2:3]
+; GFX8-NEXT:    flat_load_ubyte v3, v[4:5]
+; GFX8-NEXT:    v_mov_b32_e32 v0, s0
+; GFX8-NEXT:    v_mov_b32_e32 v1, s1
+; GFX8-NEXT:    s_waitcnt vmcnt(7)
+; GFX8-NEXT:    v_lshlrev_b32_e32 v4, 8, v10
+; GFX8-NEXT:    s_waitcnt vmcnt(6)
+; GFX8-NEXT:    v_or_b32_e32 v4, v4, v11
+; GFX8-NEXT:    s_waitcnt vmcnt(5)
+; GFX8-NEXT:    v_lshlrev_b32_e32 v5, 8, v12
+; GFX8-NEXT:    s_waitcnt vmcnt(4)
+; GFX8-NEXT:    v_or_b32_sdwa v5, v5, v6 dst_sel:WORD_1 dst_unused:UNUSED_PAD src0_sel:DWORD src1_sel:DWORD
+; GFX8-NEXT:    v_or_b32_e32 v4, v5, v4
+; GFX8-NEXT:    s_waitcnt vmcnt(3)
+; GFX8-NEXT:    v_lshlrev_b32_e32 v5, 8, v7
+; GFX8-NEXT:    v_ffbh_u32_e32 v4, v4
+; GFX8-NEXT:    s_waitcnt vmcnt(2)
+; GFX8-NEXT:    v_or_b32_e32 v5, v5, v8
+; GFX8-NEXT:    s_waitcnt vmcnt(1)
+; GFX8-NEXT:    v_lshlrev_b32_e32 v2, 8, v2
+; GFX8-NEXT:    s_waitcnt vmcnt(0)
+; GFX8-NEXT:    v_or_b32_sdwa v2, v2, v3 dst_sel:WORD_1 dst_unused:UNUSED_PAD src0_sel:DWORD src1_sel:DWORD
+; GFX8-NEXT:    v_or_b32_e32 v2, v2, v5
+; GFX8-NEXT:    v_ffbh_u32_e32 v2, v2
+; GFX8-NEXT:    v_or_b32_e32 v2, 32, v2
+; GFX8-NEXT:    v_min_u32_e32 v2, v2, v4
+; GFX8-NEXT:    v_min_u32_e32 v2, 64, v2
+; GFX8-NEXT:    v_mov_b32_e32 v3, 0
+; GFX8-NEXT:    flat_store_dwordx2 v[0:1], v[2:3]
+; GFX8-NEXT:    s_endpgm
+;
 ; GFX9-LABEL: ctlz_i64:
 ; GFX9:       ; %bb.0:
 ; GFX9-NEXT:    s_load_dwordx4 s[0:3], s[4:5], 0x24
@@ -117,7 +357,7 @@ define amdgpu_kernel void @ctlz_i64(ptr addrspace(1) noalias %out, ptr addrspace
 ; GFX9-NEXT:    v_or_b32_e32 v2, v4, v3
 ; GFX9-NEXT:    v_ffbh_u32_e32 v2, v2
 ; GFX9-NEXT:    v_ffbh_u32_e32 v0, v0
-; GFX9-NEXT:    v_add_u32_e64 v2, v2, 32 clamp
+; GFX9-NEXT:    v_or_b32_e32 v2, 32, v2
 ; GFX9-NEXT:    v_min_u32_e32 v0, v2, v0
 ; GFX9-NEXT:    v_min_u32_e32 v0, 64, v0
 ; GFX9-NEXT:    global_store_dwordx2 v1, v[0:1], s[0:1]
@@ -154,7 +394,7 @@ define amdgpu_kernel void @ctlz_i64(ptr addrspace(1) noalias %out, ptr addrspace
 ; GFX10-NEXT:    v_or_b32_e32 v0, v2, v0
 ; GFX10-NEXT:    v_ffbh_u32_e32 v2, v3
 ; GFX10-NEXT:    v_ffbh_u32_e32 v0, v0
-; GFX10-NEXT:    v_add_nc_u32_e64 v2, v2, 32 clamp
+; GFX10-NEXT:    v_or_b32_e32 v2, 32, v2
 ; GFX10-NEXT:    v_min_u32_e32 v0, v2, v0
 ; GFX10-NEXT:    v_min_u32_e32 v0, 64, v0
 ; GFX10-NEXT:    global_store_dwordx2 v1, v[0:1], s[0:1]
@@ -166,6 +406,123 @@ define amdgpu_kernel void @ctlz_i64(ptr addrspace(1) noalias %out, ptr addrspace
 }
 
 define amdgpu_kernel void @cttz_i64_poison(ptr addrspace(1) noalias %out, ptr addrspace(1) nocapture readonly %arrayidx) nounwind {
+; GFX6-LABEL: cttz_i64_poison:
+; GFX6:       ; %bb.0:
+; GFX6-NEXT:    s_load_dwordx4 s[4:7], s[4:5], 0x9
+; GFX6-NEXT:    s_mov_b32 s3, 0xf000
+; GFX6-NEXT:    s_mov_b32 s2, -1
+; GFX6-NEXT:    s_mov_b32 s10, s2
+; GFX6-NEXT:    s_mov_b32 s11, s3
+; GFX6-NEXT:    s_waitcnt lgkmcnt(0)
+; GFX6-NEXT:    s_mov_b32 s8, s6
+; GFX6-NEXT:    s_mov_b32 s9, s7
+; GFX6-NEXT:    buffer_load_ubyte v0, off, s[8:11], 0 offset:5
+; GFX6-NEXT:    buffer_load_ubyte v1, off, s[8:11], 0 offset:7
+; GFX6-NEXT:    buffer_load_ubyte v2, off, s[8:11], 0 offset:1
+; GFX6-NEXT:    buffer_load_ubyte v3, off, s[8:11], 0 offset:3
+; GFX6-NEXT:    buffer_load_ubyte v4, off, s[8:11], 0 offset:4
+; GFX6-NEXT:    buffer_load_ubyte v5, off, s[8:11], 0 offset:6
+; GFX6-NEXT:    buffer_load_ubyte v6, off, s[8:11], 0
+; GFX6-NEXT:    buffer_load_ubyte v7, off, s[8:11], 0 offset:2
+; GFX6-NEXT:    s_mov_b32 s0, s4
+; GFX6-NEXT:    s_mov_b32 s1, s5
+; GFX6-NEXT:    s_waitcnt vmcnt(7)
+; GFX6-NEXT:    v_lshlrev_b32_e32 v0, 8, v0
+; GFX6-NEXT:    s_waitcnt vmcnt(6)
+; GFX6-NEXT:    v_lshlrev_b32_e32 v1, 8, v1
+; GFX6-NEXT:    s_waitcnt vmcnt(5)
+; GFX6-NEXT:    v_lshlrev_b32_e32 v2, 8, v2
+; GFX6-NEXT:    s_waitcnt vmcnt(4)
+; GFX6-NEXT:    v_lshlrev_b32_e32 v3, 8, v3
+; GFX6-NEXT:    s_waitcnt vmcnt(3)
+; GFX6-NEXT:    v_or_b32_e32 v0, v0, v4
+; GFX6-NEXT:    s_waitcnt vmcnt(2)
+; GFX6-NEXT:    v_or_b32_e32 v1, v1, v5
+; GFX6-NEXT:    v_lshlrev_b32_e32 v1, 16, v1
+; GFX6-NEXT:    s_waitcnt vmcnt(0)
+; GFX6-NEXT:    v_or_b32_e32 v3, v3, v7
+; GFX6-NEXT:    v_or_b32_e32 v2, v2, v6
+; GFX6-NEXT:    v_lshlrev_b32_e32 v3, 16, v3
+; GFX6-NEXT:    v_or_b32_e32 v0, v1, v0
+; GFX6-NEXT:    v_or_b32_e32 v1, v3, v2
+; GFX6-NEXT:    v_ffbl_b32_e32 v0, v0
+; GFX6-NEXT:    v_ffbl_b32_e32 v1, v1
+; GFX6-NEXT:    v_or_b32_e32 v0, 32, v0
+; GFX6-NEXT:    v_min_u32_e32 v0, v0, v1
+; GFX6-NEXT:    v_mov_b32_e32 v1, 0
+; GFX6-NEXT:    buffer_store_dwordx2 v[0:1], off, s[0:3], 0
+; GFX6-NEXT:    s_endpgm
+;
+; GFX8-LABEL: cttz_i64_poison:
+; GFX8:       ; %bb.0:
+; GFX8-NEXT:    s_load_dwordx4 s[0:3], s[4:5], 0x24
+; GFX8-NEXT:    s_waitcnt lgkmcnt(0)
+; GFX8-NEXT:    s_add_u32 s4, s2, 5
+; GFX8-NEXT:    s_addc_u32 s5, s3, 0
+; GFX8-NEXT:    v_mov_b32_e32 v0, s4
+; GFX8-NEXT:    v_mov_b32_e32 v1, s5
+; GFX8-NEXT:    s_add_u32 s4, s2, 4
+; GFX8-NEXT:    s_addc_u32 s5, s3, 0
+; GFX8-NEXT:    v_mov_b32_e32 v2, s4
+; GFX8-NEXT:    v_mov_b32_e32 v3, s5
+; GFX8-NEXT:    s_add_u32 s4, s2, 7
+; GFX8-NEXT:    s_addc_u32 s5, s3, 0
+; GFX8-NEXT:    v_mov_b32_e32 v4, s4
+; GFX8-NEXT:    v_mov_b32_e32 v5, s5
+; GFX8-NEXT:    s_add_u32 s4, s2, 6
+; GFX8-NEXT:    s_addc_u32 s5, s3, 0
+; GFX8-NEXT:    v_mov_b32_e32 v7, s5
+; GFX8-NEXT:    v_mov_b32_e32 v6, s4
+; GFX8-NEXT:    s_add_u32 s4, s2, 1
+; GFX8-NEXT:    s_addc_u32 s5, s3, 0
+; GFX8-NEXT:    v_mov_b32_e32 v9, s5
+; GFX8-NEXT:    v_mov_b32_e32 v8, s4
+; GFX8-NEXT:    s_add_u32 s4, s2, 3
+; GFX8-NEXT:    s_addc_u32 s5, s3, 0
+; GFX8-NEXT:    v_mov_b32_e32 v11, s3
+; GFX8-NEXT:    v_mov_b32_e32 v10, s2
+; GFX8-NEXT:    s_add_u32 s2, s2, 2
+; GFX8-NEXT:    flat_load_ubyte v12, v[0:1]
+; GFX8-NEXT:    flat_load_ubyte v13, v[2:3]
+; GFX8-NEXT:    flat_load_ubyte v4, v[4:5]
+; GFX8-NEXT:    flat_load_ubyte v5, v[6:7]
+; GFX8-NEXT:    flat_load_ubyte v6, v[8:9]
+; GFX8-NEXT:    flat_load_ubyte v7, v[10:11]
+; GFX8-NEXT:    v_mov_b32_e32 v0, s4
+; GFX8-NEXT:    v_mov_b32_e32 v1, s5
+; GFX8-NEXT:    s_addc_u32 s3, s3, 0
+; GFX8-NEXT:    v_mov_b32_e32 v2, s2
+; GFX8-NEXT:    v_mov_b32_e32 v3, s3
+; GFX8-NEXT:    flat_load_ubyte v8, v[0:1]
+; GFX8-NEXT:    flat_load_ubyte v2, v[2:3]
+; GFX8-NEXT:    v_mov_b32_e32 v0, s0
+; GFX8-NEXT:    v_mov_b32_e32 v1, s1
+; GFX8-NEXT:    s_waitcnt vmcnt(7)
+; GFX8-NEXT:    v_lshlrev_b32_e32 v3, 8, v12
+; GFX8-NEXT:    s_waitcnt vmcnt(6)
+; GFX8-NEXT:    v_or_b32_e32 v3, v3, v13
+; GFX8-NEXT:    s_waitcnt vmcnt(5)
+; GFX8-NEXT:    v_lshlrev_b32_e32 v4, 8, v4
+; GFX8-NEXT:    s_waitcnt vmcnt(4)
+; GFX8-NEXT:    v_or_b32_sdwa v4, v4, v5 dst_sel:WORD_1 dst_unused:UNUSED_PAD src0_sel:DWORD src1_sel:DWORD
+; GFX8-NEXT:    v_or_b32_e32 v3, v4, v3
+; GFX8-NEXT:    s_waitcnt vmcnt(3)
+; GFX8-NEXT:    v_lshlrev_b32_e32 v4, 8, v6
+; GFX8-NEXT:    s_waitcnt vmcnt(2)
+; GFX8-NEXT:    v_or_b32_e32 v4, v4, v7
+; GFX8-NEXT:    v_ffbl_b32_e32 v3, v3
+; GFX8-NEXT:    v_or_b32_e32 v3, 32, v3
+; GFX8-NEXT:    s_waitcnt vmcnt(1)
+; GFX8-NEXT:    v_lshlrev_b32_e32 v5, 8, v8
+; GFX8-NEXT:    s_waitcnt vmcnt(0)
+; GFX8-NEXT:    v_or_b32_sdwa v2, v5, v2 dst_sel:WORD_1 dst_unused:UNUSED_PAD src0_sel:DWORD src1_sel:DWORD
+; GFX8-NEXT:    v_or_b32_e32 v2, v2, v4
+; GFX8-NEXT:    v_ffbl_b32_e32 v2, v2
+; GFX8-NEXT:    v_min_u32_e32 v2, v3, v2
+; GFX8-NEXT:    v_mov_b32_e32 v3, 0
+; GFX8-NEXT:    flat_store_dwordx2 v[0:1], v[2:3]
+; GFX8-NEXT:    s_endpgm
+;
 ; GFX9-LABEL: cttz_i64_poison:
 ; GFX9:       ; %bb.0:
 ; GFX9-NEXT:    s_load_dwordx4 s[0:3], s[4:5], 0x24
@@ -198,7 +555,7 @@ define amdgpu_kernel void @cttz_i64_poison(ptr addrspace(1) noalias %out, ptr ad
 ; GFX9-NEXT:    v_or_b32_e32 v2, v4, v3
 ; GFX9-NEXT:    v_ffbl_b32_e32 v0, v0
 ; GFX9-NEXT:    v_ffbl_b32_e32 v2, v2
-; GFX9-NEXT:    v_add_u32_e64 v0, v0, 32 clamp
+; GFX9-NEXT:    v_or_b32_e32 v0, 32, v0
 ; GFX9-NEXT:    v_min_u32_e32 v0, v0, v2
 ; GFX9-NEXT:    global_store_dwordx2 v1, v[0:1], s[0:1]
 ; GFX9-NEXT:    s_endpgm
@@ -236,7 +593,7 @@ define amdgpu_kernel void @cttz_i64_poison(ptr addrspace(1) noalias %out, ptr ad
 ; GFX10-NEXT:    v_or_b32_e32 v2, v4, v3
 ; GFX10-NEXT:    v_ffbl_b32_e32 v0, v0
 ; GFX10-NEXT:    v_ffbl_b32_e32 v2, v2
-; GFX10-NEXT:    v_add_nc_u32_e64 v0, v0, 32 clamp
+; GFX10-NEXT:    v_or_b32_e32 v0, 32, v0
 ; GFX10-NEXT:    v_min_u32_e32 v0, v0, v2
 ; GFX10-NEXT:    global_store_dwordx2 v1, v[0:1], s[0:1]
 ; GFX10-NEXT:    s_endpgm
@@ -247,6 +604,125 @@ define amdgpu_kernel void @cttz_i64_poison(ptr addrspace(1) noalias %out, ptr ad
 }
 
 define amdgpu_kernel void @cttz_i64(ptr addrspace(1) noalias %out, ptr addrspace(1) nocapture readonly %arrayidx) nounwind {
+; GFX6-LABEL: cttz_i64:
+; GFX6:       ; %bb.0:
+; GFX6-NEXT:    s_load_dwordx4 s[4:7], s[4:5], 0x9
+; GFX6-NEXT:    s_mov_b32 s3, 0xf000
+; GFX6-NEXT:    s_mov_b32 s2, -1
+; GFX6-NEXT:    s_mov_b32 s10, s2
+; GFX6-NEXT:    s_mov_b32 s11, s3
+; GFX6-NEXT:    s_waitcnt lgkmcnt(0)
+; GFX6-NEXT:    s_mov_b32 s8, s6
+; GFX6-NEXT:    s_mov_b32 s9, s7
+; GFX6-NEXT:    buffer_load_ubyte v0, off, s[8:11], 0 offset:5
+; GFX6-NEXT:    buffer_load_ubyte v1, off, s[8:11], 0 offset:7
+; GFX6-NEXT:    buffer_load_ubyte v2, off, s[8:11], 0 offset:1
+; GFX6-NEXT:    buffer_load_ubyte v3, off, s[8:11], 0 offset:3
+; GFX6-NEXT:    buffer_load_ubyte v4, off, s[8:11], 0 offset:4
+; GFX6-NEXT:    buffer_load_ubyte v5, off, s[8:11], 0 offset:6
+; GFX6-NEXT:    buffer_load_ubyte v6, off, s[8:11], 0
+; GFX6-NEXT:    buffer_load_ubyte v7, off, s[8:11], 0 offset:2
+; GFX6-NEXT:    s_mov_b32 s0, s4
+; GFX6-NEXT:    s_mov_b32 s1, s5
+; GFX6-NEXT:    s_waitcnt vmcnt(7)
+; GFX6-NEXT:    v_lshlrev_b32_e32 v0, 8, v0
+; GFX6-NEXT:    s_waitcnt vmcnt(6)
+; GFX6-NEXT:    v_lshlrev_b32_e32 v1, 8, v1
+; GFX6-NEXT:    s_waitcnt vmcnt(5)
+; GFX6-NEXT:    v_lshlrev_b32_e32 v2, 8, v2
+; GFX6-NEXT:    s_waitcnt vmcnt(4)
+; GFX6-NEXT:    v_lshlrev_b32_e32 v3, 8, v3
+; GFX6-NEXT:    s_waitcnt vmcnt(3)
+; GFX6-NEXT:    v_or_b32_e32 v0, v0, v4
+; GFX6-NEXT:    s_waitcnt vmcnt(2)
+; GFX6-NEXT:    v_or_b32_e32 v1, v1, v5
+; GFX6-NEXT:    v_lshlrev_b32_e32 v1, 16, v1
+; GFX6-NEXT:    s_waitcnt vmcnt(0)
+; GFX6-NEXT:    v_or_b32_e32 v3, v3, v7
+; GFX6-NEXT:    v_or_b32_e32 v2, v2, v6
+; GFX6-NEXT:    v_lshlrev_b32_e32 v3, 16, v3
+; GFX6-NEXT:    v_or_b32_e32 v0, v1, v0
+; GFX6-NEXT:    v_or_b32_e32 v1, v3, v2
+; GFX6-NEXT:    v_ffbl_b32_e32 v0, v0
+; GFX6-NEXT:    v_ffbl_b32_e32 v1, v1
+; GFX6-NEXT:    v_or_b32_e32 v0, 32, v0
+; GFX6-NEXT:    v_min_u32_e32 v0, v0, v1
+; GFX6-NEXT:    v_min_u32_e32 v0, 64, v0
+; GFX6-NEXT:    v_mov_b32_e32 v1, 0
+; GFX6-NEXT:    buffer_store_dwordx2 v[0:1], off, s[0:3], 0
+; GFX6-NEXT:    s_endpgm
+;
+; GFX8-LABEL: cttz_i64:
+; GFX8:       ; %bb.0:
+; GFX8-NEXT:    s_load_dwordx4 s[0:3], s[4:5], 0x24
+; GFX8-NEXT:    s_waitcnt lgkmcnt(0)
+; GFX8-NEXT:    s_add_u32 s4, s2, 5
+; GFX8-NEXT:    s_addc_u32 s5, s3, 0
+; GFX8-NEXT:    v_mov_b32_e32 v0, s4
+; GFX8-NEXT:    v_mov_b32_e32 v1, s5
+; GFX8-NEXT:    s_add_u32 s4, s2, 4
+; GFX8-NEXT:    s_addc_u32 s5, s3, 0
+; GFX8-NEXT:    v_mov_b32_e32 v2, s4
+; GFX8-NEXT:    v_mov_b32_e32 v3, s5
+; GFX8-NEXT:    s_add_u32 s4, s2, 7
+; GFX8-NEXT:    s_addc_u32 s5, s3, 0
+; GFX8-NEXT:    v_mov_b32_e32 v4, s4
+; GFX8-NEXT:    v_mov_b32_e32 v5, s5
+; GFX8-NEXT:    s_add_u32 s4, s2, 6
+; GFX8-NEXT:    s_addc_u32 s5, s3, 0
+; GFX8-NEXT:    v_mov_b32_e32 v7, s5
+; GFX8-NEXT:    v_mov_b32_e32 v6, s4
+; GFX8-NEXT:    s_add_u32 s4, s2, 1
+; GFX8-NEXT:    s_addc_u32 s5, s3, 0
+; GFX8-NEXT:    v_mov_b32_e32 v9, s5
+; GFX8-NEXT:    v_mov_b32_e32 v8, s4
+; GFX8-NEXT:    s_add_u32 s4, s2, 3
+; GFX8-NEXT:    s_addc_u32 s5, s3, 0
+; GFX8-NEXT:    v_mov_b32_e32 v11, s3
+; GFX8-NEXT:    v_mov_b32_e32 v10, s2
+; GFX8-NEXT:    s_add_u32 s2, s2, 2
+; GFX8-NEXT:    flat_load_ubyte v12, v[0:1]
+; GFX8-NEXT:    flat_load_ubyte v13, v[2:3]
+; GFX8-NEXT:    flat_load_ubyte v4, v[4:5]
+; GFX8-NEXT:    flat_load_ubyte v5, v[6:7]
+; GFX8-NEXT:    flat_load_ubyte v6, v[8:9]
+; GFX8-NEXT:    flat_load_ubyte v7, v[10:11]
+; GFX8-NEXT:    v_mov_b32_e32 v0, s4
+; GFX8-NEXT:    v_mov_b32_e32 v1, s5
+; GFX8-NEXT:    s_addc_u32 s3, s3, 0
+; GFX8-NEXT:    v_mov_b32_e32 v2, s2
+; GFX8-NEXT:    v_mov_b32_e32 v3, s3
+; GFX8-NEXT:    flat_load_ubyte v8, v[0:1]
+; GFX8-NEXT:    flat_load_ubyte v2, v[2:3]
+; GFX8-NEXT:    v_mov_b32_e32 v0, s0
+; GFX8-NEXT:    v_mov_b32_e32 v1, s1
+; GFX8-NEXT:    s_waitcnt vmcnt(7)
+; GFX8-NEXT:    v_lshlrev_b32_e32 v3, 8, v12
+; GFX8-NEXT:    s_waitcnt vmcnt(6)
+; GFX8-NEXT:    v_or_b32_e32 v3, v3, v13
+; GFX8-NEXT:    s_waitcnt vmcnt(5)
+; GFX8-NEXT:    v_lshlrev_b32_e32 v4, 8, v4
+; GFX8-NEXT:    s_waitcnt vmcnt(4)
+; GFX8-NEXT:    v_or_b32_sdwa v4, v4, v5 dst_sel:WORD_1 dst_unused:UNUSED_PAD src0_sel:DWORD src1_sel:DWORD
+; GFX8-NEXT:    v_or_b32_e32 v3, v4, v3
+; GFX8-NEXT:    s_waitcnt vmcnt(3)
+; GFX8-NEXT:    v_lshlrev_b32_e32 v4, 8, v6
+; GFX8-NEXT:    s_waitcnt vmcnt(2)
+; GFX8-NEXT:    v_or_b32_e32 v4, v4, v7
+; GFX8-NEXT:    v_ffbl_b32_e32 v3, v3
+; GFX8-NEXT:    v_or_b32_e32 v3, 32, v3
+; GFX8-NEXT:    s_waitcnt vmcnt(1)
+; GFX8-NEXT:    v_lshlrev_b32_e32 v5, 8, v8
+; GFX8-NEXT:    s_waitcnt vmcnt(0)
+; GFX8-NEXT:    v_or_b32_sdwa v2, v5, v2 dst_sel:WORD_1 dst_unused:UNUSED_PAD src0_sel:DWORD src1_sel:DWORD
+; GFX8-NEXT:    v_or_b32_e32 v2, v2, v4
+; GFX8-NEXT:    v_ffbl_b32_e32 v2, v2
+; GFX8-NEXT:    v_min_u32_e32 v2, v3, v2
+; GFX8-NEXT:    v_min_u32_e32 v2, 64, v2
+; GFX8-NEXT:    v_mov_b32_e32 v3, 0
+; GFX8-NEXT:    flat_store_dwordx2 v[0:1], v[2:3]
+; GFX8-NEXT:    s_endpgm
+;
 ; GFX9-LABEL: cttz_i64:
 ; GFX9:       ; %bb.0:
 ; GFX9-NEXT:    s_load_dwordx4 s[0:3], s[4:5], 0x24
@@ -279,7 +755,7 @@ define amdgpu_kernel void @cttz_i64(ptr addrspace(1) noalias %out, ptr addrspace
 ; GFX9-NEXT:    v_or_b32_e32 v2, v4, v3
 ; GFX9-NEXT:    v_ffbl_b32_e32 v0, v0
 ; GFX9-NEXT:    v_ffbl_b32_e32 v2, v2
-; GFX9-NEXT:    v_add_u32_e64 v0, v0, 32 clamp
+; GFX9-NEXT:    v_or_b32_e32 v0, 32, v0
 ; GFX9-NEXT:    v_min_u32_e32 v0, v0, v2
 ; GFX9-NEXT:    v_min_u32_e32 v0, 64, v0
 ; GFX9-NEXT:    global_store_dwordx2 v1, v[0:1], s[0:1]
@@ -318,7 +794,7 @@ define amdgpu_kernel void @cttz_i64(ptr addrspace(1) noalias %out, ptr addrspace
 ; GFX10-NEXT:    v_or_b32_e32 v2, v4, v3
 ; GFX10-NEXT:    v_ffbl_b32_e32 v0, v0
 ; GFX10-NEXT:    v_ffbl_b32_e32 v2, v2
-; GFX10-NEXT:    v_add_nc_u32_e64 v0, v0, 32 clamp
+; GFX10-NEXT:    v_or_b32_e32 v0, 32, v0
 ; GFX10-NEXT:    v_min_u32_e32 v0, v0, v2
 ; GFX10-NEXT:    v_min_u32_e32 v0, 64, v0
 ; GFX10-NEXT:    global_store_dwordx2 v1, v[0:1], s[0:1]


        


More information about the llvm-commits mailing list