[llvm] [AMDGPU] Remove unnecessary and broken sign/zero extension in fastdiv (PR #210348)
via llvm-commits
llvm-commits at lists.llvm.org
Fri Jul 17 07:40:24 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-backend-amdgpu
Author: LU-JOHN
<details>
<summary>Changes</summary>
Remove unnecessary and broken sign/zero-extension when using float-point reciprocal to implement division/remainder. This change is analogous to the change done in https://github.com/llvm/llvm-project/pull/203436 but in AMDGPUISelLowering.cpp.
---
Full diff: https://github.com/llvm/llvm-project/pull/210348.diff
5 Files Affected:
- (modified) llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp (-12)
- (modified) llvm/test/CodeGen/AMDGPU/div-rem-fast-path.ll (+81-4)
- (modified) llvm/test/CodeGen/AMDGPU/med3-knownbits.ll (-1)
- (modified) llvm/test/CodeGen/AMDGPU/sdiv.ll (+4-7)
- (modified) llvm/test/CodeGen/AMDGPU/udiv.ll (+8-10)
``````````diff
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp b/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp
index 4858009fecff5..1682739773b82 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp
@@ -2133,18 +2133,6 @@ SDValue AMDGPUTargetLowering::LowerDIVREMToFloat(SDValue Op, SelectionDAG &DAG,
SDValue Rem = DAG.getNode(ISD::MUL, DL, VT, Div, RHS);
Rem = DAG.getNode(ISD::SUB, DL, VT, LHS, Rem);
- // Truncate to number of bits this divide really is.
- if (Sign) {
- SDValue InRegSize
- = DAG.getValueType(EVT::getIntegerVT(*DAG.getContext(), DivBits));
- Div = DAG.getNode(ISD::SIGN_EXTEND_INREG, DL, VT, Div, InRegSize);
- Rem = DAG.getNode(ISD::SIGN_EXTEND_INREG, DL, VT, Rem, InRegSize);
- } else {
- SDValue TruncMask = DAG.getConstant((UINT64_C(1) << DivBits) - 1, DL, VT);
- Div = DAG.getNode(ISD::AND, DL, VT, Div, TruncMask);
- Rem = DAG.getNode(ISD::AND, DL, VT, Rem, TruncMask);
- }
-
return DAG.getMergeValues({ Div, Rem }, DL);
}
diff --git a/llvm/test/CodeGen/AMDGPU/div-rem-fast-path.ll b/llvm/test/CodeGen/AMDGPU/div-rem-fast-path.ll
index 4aa8a8e1c9275..cc75eb64878e8 100644
--- a/llvm/test/CodeGen/AMDGPU/div-rem-fast-path.ll
+++ b/llvm/test/CodeGen/AMDGPU/div-rem-fast-path.ll
@@ -329,7 +329,6 @@ define amdgpu_kernel void @sdiv_i32_i16_fast_path(ptr addrspace(1) %out, i32 %in
; GFX950-NEXT: s_cselect_b32 s2, s2, s3
; GFX950-NEXT: v_cvt_i32_f32_e64 v1, v1
; GFX950-NEXT: v_add_u32_e64 v1, v1, s2
-; GFX950-NEXT: v_bfe_i32 v1, v1, 0, 16
; GFX950-NEXT: global_store_dword v0, v1, s[0:1]
; GFX950-NEXT: s_endpgm
;
@@ -362,7 +361,6 @@ define amdgpu_kernel void @sdiv_i32_i16_fast_path(ptr addrspace(1) %out, i32 %in
; GFX90A-NEXT: s_cselect_b32 s2, s2, s3
; GFX90A-NEXT: v_cvt_i32_f32_e64 v1, v1
; GFX90A-NEXT: v_add_u32_e64 v1, v1, s2
-; GFX90A-NEXT: v_bfe_i32 v1, v1, 0, 16
; GFX90A-NEXT: global_store_dword v0, v1, s[0:1]
; GFX90A-NEXT: s_endpgm
%trunc_i16 = trunc i32 %input to i16
@@ -373,6 +371,87 @@ define amdgpu_kernel void @sdiv_i32_i16_fast_path(ptr addrspace(1) %out, i32 %in
ret void
}
+define amdgpu_kernel void @sdiv_i32_i16_i16_fast_path(ptr addrspace(1) %out, i16 %dividend16, i16 %divisor16) {
+; GFX950-LABEL: sdiv_i32_i16_i16_fast_path:
+; GFX950: ; %bb.0:
+; GFX950-NEXT: v_mov_b32_e32 v0, 0
+; GFX950-NEXT: global_load_ushort v1, v0, s[4:5] offset:44
+; GFX950-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x24
+; GFX950-NEXT: s_waitcnt lgkmcnt(0)
+; GFX950-NEXT: s_load_dword s0, s[4:5], 0x2c
+; GFX950-NEXT: s_waitcnt lgkmcnt(0)
+; GFX950-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x24
+; GFX950-NEXT: s_load_dword s3, s[4:5], 0x2c
+; GFX950-NEXT: s_waitcnt lgkmcnt(0)
+; GFX950-NEXT: s_mov_b32 s2, s3
+; GFX950-NEXT: s_mov_b32 s4, 16
+; GFX950-NEXT: s_lshr_b32 s3, s3, s4
+; GFX950-NEXT: s_sext_i32_i16 s2, s2
+; GFX950-NEXT: s_sext_i32_i16 s3, s3
+; GFX950-NEXT: v_cvt_f32_i32_e64 v3, s3
+; GFX950-NEXT: s_waitcnt vmcnt(0)
+; GFX950-NEXT: v_rcp_f32_e64 v1, v3
+; GFX950-NEXT: v_cvt_f32_i32_e64 v2, s2
+; GFX950-NEXT: v_mul_f32_e64 v1, v2, v1
+; GFX950-NEXT: v_trunc_f32_e64 v1, v1
+; GFX950-NEXT: v_fma_f32 v2, -v1, v3, v2
+; GFX950-NEXT: v_cmp_ge_f32_e64 s[4:5], |v2|, |v3|
+; GFX950-NEXT: s_xor_b32 s2, s2, s3
+; GFX950-NEXT: s_mov_b32 s3, 30
+; GFX950-NEXT: s_ashr_i32 s2, s2, s3
+; GFX950-NEXT: s_mov_b32 s3, 1
+; GFX950-NEXT: s_or_b32 s2, s2, s3
+; GFX950-NEXT: s_mov_b32 s3, 0
+; GFX950-NEXT: s_and_b64 s[4:5], s[4:5], exec
+; GFX950-NEXT: s_cselect_b32 s2, s2, s3
+; GFX950-NEXT: v_cvt_i32_f32_e64 v1, v1
+; GFX950-NEXT: v_add_u32_e64 v1, v1, s2
+; GFX950-NEXT: global_store_dword v0, v1, s[0:1]
+; GFX950-NEXT: s_endpgm
+;
+; GFX90A-LABEL: sdiv_i32_i16_i16_fast_path:
+; GFX90A: ; %bb.0:
+; GFX90A-NEXT: v_mov_b32_e32 v0, 0
+; GFX90A-NEXT: global_load_ushort v1, v0, s[4:5] offset:44
+; GFX90A-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x24
+; GFX90A-NEXT: s_waitcnt lgkmcnt(0)
+; GFX90A-NEXT: s_load_dword s0, s[4:5], 0x2c
+; GFX90A-NEXT: s_waitcnt lgkmcnt(0)
+; GFX90A-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x24
+; GFX90A-NEXT: s_load_dword s3, s[4:5], 0x2c
+; GFX90A-NEXT: s_waitcnt lgkmcnt(0)
+; GFX90A-NEXT: s_mov_b32 s2, s3
+; GFX90A-NEXT: s_mov_b32 s4, 16
+; GFX90A-NEXT: s_lshr_b32 s3, s3, s4
+; GFX90A-NEXT: s_sext_i32_i16 s2, s2
+; GFX90A-NEXT: s_sext_i32_i16 s3, s3
+; GFX90A-NEXT: v_cvt_f32_i32_e64 v3, s3
+; GFX90A-NEXT: s_waitcnt vmcnt(0)
+; GFX90A-NEXT: v_rcp_f32_e64 v1, v3
+; GFX90A-NEXT: v_cvt_f32_i32_e64 v2, s2
+; GFX90A-NEXT: v_mul_f32_e64 v1, v2, v1
+; GFX90A-NEXT: v_trunc_f32_e64 v1, v1
+; GFX90A-NEXT: v_mad_f32 v2, -v1, v3, v2
+; GFX90A-NEXT: v_cmp_ge_f32_e64 s[4:5], |v2|, |v3|
+; GFX90A-NEXT: s_xor_b32 s2, s2, s3
+; GFX90A-NEXT: s_mov_b32 s3, 30
+; GFX90A-NEXT: s_ashr_i32 s2, s2, s3
+; GFX90A-NEXT: s_mov_b32 s3, 1
+; GFX90A-NEXT: s_or_b32 s2, s2, s3
+; GFX90A-NEXT: s_mov_b32 s3, 0
+; GFX90A-NEXT: s_and_b64 s[4:5], s[4:5], exec
+; GFX90A-NEXT: s_cselect_b32 s2, s2, s3
+; GFX90A-NEXT: v_cvt_i32_f32_e64 v1, v1
+; GFX90A-NEXT: v_add_u32_e64 v1, v1, s2
+; GFX90A-NEXT: global_store_dword v0, v1, s[0:1]
+; GFX90A-NEXT: s_endpgm
+ %dividend32 = sext i16 %dividend16 to i32
+ %divisor32 = sext i16 %divisor16 to i32
+ %result = sdiv i32 %dividend32, %divisor32
+ store i32 %result, ptr addrspace(1) %out, align 4
+ ret void
+}
+
define amdgpu_kernel void @urem_i32_i16_no_fast_path(ptr addrspace(1) %out, i32 %input) {
; GFX950-LABEL: urem_i32_i16_no_fast_path:
; GFX950: ; %bb.0:
@@ -578,7 +657,6 @@ define amdgpu_kernel void @srem_i32_i16_fast_path(ptr addrspace(1) %out, i32 %in
; GFX950-NEXT: v_add_u32_e64 v1, v1, s4
; GFX950-NEXT: v_mul_lo_u32 v1, v1, s3
; GFX950-NEXT: v_sub_u32_e64 v1, s2, v1
-; GFX950-NEXT: v_bfe_i32 v1, v1, 0, 16
; GFX950-NEXT: global_store_dword v0, v1, s[0:1]
; GFX950-NEXT: s_endpgm
;
@@ -613,7 +691,6 @@ define amdgpu_kernel void @srem_i32_i16_fast_path(ptr addrspace(1) %out, i32 %in
; GFX90A-NEXT: v_add_u32_e64 v1, v1, s4
; GFX90A-NEXT: v_mul_lo_u32 v1, v1, s3
; GFX90A-NEXT: v_sub_u32_e64 v1, s2, v1
-; GFX90A-NEXT: v_bfe_i32 v1, v1, 0, 16
; GFX90A-NEXT: global_store_dword v0, v1, s[0:1]
; GFX90A-NEXT: s_endpgm
%trunc_i16 = trunc i32 %input to i16
diff --git a/llvm/test/CodeGen/AMDGPU/med3-knownbits.ll b/llvm/test/CodeGen/AMDGPU/med3-knownbits.ll
index 2d67d211e3be4..e799974bd5670 100644
--- a/llvm/test/CodeGen/AMDGPU/med3-knownbits.ll
+++ b/llvm/test/CodeGen/AMDGPU/med3-knownbits.ll
@@ -59,7 +59,6 @@ define i32 @v_known_signbits_smed3(i16 %a, i16 %b) {
; SI-SDAG-NEXT: v_cmp_ge_f32_e64 vcc, |v3|, |v2|
; SI-SDAG-NEXT: v_cndmask_b32_e32 v0, 0, v0, vcc
; SI-SDAG-NEXT: v_add_i32_e32 v0, vcc, v1, v0
-; SI-SDAG-NEXT: v_bfe_i32 v0, v0, 0, 16
; SI-SDAG-NEXT: s_setpc_b64 s[30:31]
;
; SI-GISEL-LABEL: v_known_signbits_smed3:
diff --git a/llvm/test/CodeGen/AMDGPU/sdiv.ll b/llvm/test/CodeGen/AMDGPU/sdiv.ll
index bab5998eeba01..6eed45c29daf7 100644
--- a/llvm/test/CodeGen/AMDGPU/sdiv.ll
+++ b/llvm/test/CodeGen/AMDGPU/sdiv.ll
@@ -253,7 +253,7 @@ define amdgpu_kernel void @s_test_sdiv22_32(ptr addrspace(1) %out, i32 %x, i32 %
;
; EG-LABEL: s_test_sdiv22_32:
; EG: ; %bb.0:
-; EG-NEXT: ALU 23, @4, KC0[CB0:0-32], KC1[]
+; EG-NEXT: ALU 20, @4, KC0[CB0:0-32], KC1[]
; EG-NEXT: MEM_RAT_CACHELESS STORE_RAW T0.X, T1.X, 1
; EG-NEXT: CF_END
; EG-NEXT: PAD
@@ -276,12 +276,9 @@ define amdgpu_kernel void @s_test_sdiv22_32(ptr addrspace(1) %out, i32 %x, i32 %
; EG-NEXT: OR_INT * T0.W, PV.W, 1,
; EG-NEXT: CNDE T0.W, PV.W, 0.0, PS,
; EG-NEXT: FLT_TO_INT * T1.W, PV.Z,
-; EG-NEXT: ADD_INT * T0.W, PS, PV.W,
-; EG-NEXT: LSHL * T0.W, PV.W, literal.x,
-; EG-NEXT: 10(1.401298e-44), 0(0.000000e+00)
-; EG-NEXT: ASHR T0.X, PV.W, literal.x,
-; EG-NEXT: LSHR * T1.X, KC0[2].Y, literal.y,
-; EG-NEXT: 10(1.401298e-44), 2(2.802597e-45)
+; EG-NEXT: ADD_INT T0.X, PS, PV.W,
+; EG-NEXT: LSHR * T1.X, KC0[2].Y, literal.x,
+; EG-NEXT: 2(2.802597e-45), 0(0.000000e+00)
%1 = ashr i32 %x, 10
%2 = ashr i32 %y, 10
%result = sdiv i32 %1, %2
diff --git a/llvm/test/CodeGen/AMDGPU/udiv.ll b/llvm/test/CodeGen/AMDGPU/udiv.ll
index 8275349de722e..16e48ed80347e 100644
--- a/llvm/test/CodeGen/AMDGPU/udiv.ll
+++ b/llvm/test/CodeGen/AMDGPU/udiv.ll
@@ -1488,7 +1488,7 @@ define amdgpu_kernel void @v_udiv_i8(ptr addrspace(1) %out, ptr addrspace(1) %in
; EG: ; %bb.0:
; EG-NEXT: ALU 0, @10, KC0[CB0:0-32], KC1[]
; EG-NEXT: TEX 1 @6
-; EG-NEXT: ALU 14, @11, KC0[CB0:0-32], KC1[]
+; EG-NEXT: ALU 13, @11, KC0[CB0:0-32], KC1[]
; EG-NEXT: MEM_RAT_CACHELESS STORE_RAW T0.X, T1.X, 1
; EG-NEXT: CF_END
; EG-NEXT: PAD
@@ -1509,10 +1509,9 @@ define amdgpu_kernel void @v_udiv_i8(ptr addrspace(1) %out, ptr addrspace(1) %in
; EG-NEXT: CNDE T1.W, PV.W, 0.0, literal.x,
; EG-NEXT: FLT_TO_UINT * T0.X, T0.W,
; EG-NEXT: 1(1.401298e-45), 0(0.000000e+00)
-; EG-NEXT: ADD_INT * T0.W, PS, PV.W,
-; EG-NEXT: AND_INT T0.X, PV.W, literal.x,
-; EG-NEXT: LSHR * T1.X, KC0[2].Y, literal.y,
-; EG-NEXT: 255(3.573311e-43), 2(2.802597e-45)
+; EG-NEXT: ADD_INT T0.X, PS, PV.W,
+; EG-NEXT: LSHR * T1.X, KC0[2].Y, literal.x,
+; EG-NEXT: 2(2.802597e-45), 0(0.000000e+00)
%den_ptr = getelementptr i8, ptr addrspace(1) %in, i8 1
%num = load i8, ptr addrspace(1) %in
%den = load i8, ptr addrspace(1) %den_ptr
@@ -1623,7 +1622,7 @@ define amdgpu_kernel void @v_udiv_i16(ptr addrspace(1) %out, ptr addrspace(1) %i
; EG: ; %bb.0:
; EG-NEXT: ALU 0, @10, KC0[CB0:0-32], KC1[]
; EG-NEXT: TEX 1 @6
-; EG-NEXT: ALU 14, @11, KC0[CB0:0-32], KC1[]
+; EG-NEXT: ALU 13, @11, KC0[CB0:0-32], KC1[]
; EG-NEXT: MEM_RAT_CACHELESS STORE_RAW T0.X, T1.X, 1
; EG-NEXT: CF_END
; EG-NEXT: PAD
@@ -1644,10 +1643,9 @@ define amdgpu_kernel void @v_udiv_i16(ptr addrspace(1) %out, ptr addrspace(1) %i
; EG-NEXT: CNDE T1.W, PV.W, 0.0, literal.x,
; EG-NEXT: FLT_TO_UINT * T0.X, T0.W,
; EG-NEXT: 1(1.401298e-45), 0(0.000000e+00)
-; EG-NEXT: ADD_INT * T0.W, PS, PV.W,
-; EG-NEXT: AND_INT T0.X, PV.W, literal.x,
-; EG-NEXT: LSHR * T1.X, KC0[2].Y, literal.y,
-; EG-NEXT: 65535(9.183409e-41), 2(2.802597e-45)
+; EG-NEXT: ADD_INT T0.X, PS, PV.W,
+; EG-NEXT: LSHR * T1.X, KC0[2].Y, literal.x,
+; EG-NEXT: 2(2.802597e-45), 0(0.000000e+00)
%den_ptr = getelementptr i16, ptr addrspace(1) %in, i16 1
%num = load i16, ptr addrspace(1) %in
%den = load i16, ptr addrspace(1) %den_ptr
``````````
</details>
https://github.com/llvm/llvm-project/pull/210348
More information about the llvm-commits
mailing list