[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