[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