[llvm] 4f0b96f - [AMDGPU][ISelLowering] Handle large constants in `select + cmp` fold (#195286)

via llvm-commits llvm-commits at lists.llvm.org
Fri May 1 11:38:17 PDT 2026


Author: Zach Goldthorpe
Date: 2026-05-01T12:38:12-06:00
New Revision: 4f0b96f643d3aeefdcdc37f34bbfb38b2d53432e

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

LOG: [AMDGPU][ISelLowering] Handle large constants in `select + cmp` fold (#195286)

Adds guard to avoid `getSExtValue()` asserting when constant operand
exceeds a signed 64-bit integer.

Added: 
    

Modified: 
    llvm/lib/Target/AMDGPU/SIISelLowering.cpp
    llvm/test/CodeGen/AMDGPU/select-cmp-shared-constant-int.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/AMDGPU/SIISelLowering.cpp b/llvm/lib/Target/AMDGPU/SIISelLowering.cpp
index 1d9c084292e6b..200b5aec77a85 100644
--- a/llvm/lib/Target/AMDGPU/SIISelLowering.cpp
+++ b/llvm/lib/Target/AMDGPU/SIISelLowering.cpp
@@ -18319,8 +18319,9 @@ SDValue SITargetLowering::performSelectCombine(SDNode *N,
     if (!Val.isNormal() || Subtarget->getInstrInfo()->isInlineConstant(Val))
       return SDValue();
   } else {
-    if (AMDGPU::isInlinableIntLiteral(
-            cast<ConstantSDNode>(ConstVal)->getSExtValue()))
+    const std::optional<int64_t> Val =
+        cast<ConstantSDNode>(ConstVal)->getAPIntValue().trySExtValue();
+    if (Val && AMDGPU::isInlinableIntLiteral(*Val))
       return SDValue();
   }
 

diff  --git a/llvm/test/CodeGen/AMDGPU/select-cmp-shared-constant-int.ll b/llvm/test/CodeGen/AMDGPU/select-cmp-shared-constant-int.ll
index 4383cfd36f945..1a59ad5856d55 100644
--- a/llvm/test/CodeGen/AMDGPU/select-cmp-shared-constant-int.ll
+++ b/llvm/test/CodeGen/AMDGPU/select-cmp-shared-constant-int.ll
@@ -953,3 +953,128 @@ entry:
   %sel = select i1 %cmp, i8 %other, i8 -5
   ret i8 %sel
 }
+
+;------------------------------------------------------------------------------
+; I128 Tests
+;------------------------------------------------------------------------------
+
+; Should be folded: icmp eq + select with constant in true value
+define i128 @icmp_select_fold_eq_imm_i128(i128 %arg, i128 %other) {
+; GFX900-LABEL: icmp_select_fold_eq_imm_i128:
+; GFX900:       ; %bb.0: ; %entry
+; GFX900-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX900-NEXT:    v_xor_b32_e32 v8, 0xa0a0a0a0, v3
+; GFX900-NEXT:    v_xor_b32_e32 v10, 0xb0b0b0b0, v2
+; GFX900-NEXT:    v_xor_b32_e32 v9, 0xc0c0c0c0, v1
+; GFX900-NEXT:    v_xor_b32_e32 v11, 0xd0d0d0d0, v0
+; GFX900-NEXT:    v_or_b32_e32 v9, v9, v8
+; GFX900-NEXT:    v_or_b32_e32 v8, v11, v10
+; GFX900-NEXT:    v_cmp_eq_u64_e32 vcc, 0, v[8:9]
+; GFX900-NEXT:    v_cndmask_b32_e32 v0, v4, v0, vcc
+; GFX900-NEXT:    v_cndmask_b32_e32 v1, v5, v1, vcc
+; GFX900-NEXT:    v_cndmask_b32_e32 v2, v6, v2, vcc
+; GFX900-NEXT:    v_cndmask_b32_e32 v3, v7, v3, vcc
+; GFX900-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX1010-LABEL: icmp_select_fold_eq_imm_i128:
+; GFX1010:       ; %bb.0: ; %entry
+; GFX1010-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX1010-NEXT:    v_xor_b32_e32 v8, 0xa0a0a0a0, v3
+; GFX1010-NEXT:    v_xor_b32_e32 v10, 0xb0b0b0b0, v2
+; GFX1010-NEXT:    v_xor_b32_e32 v9, 0xc0c0c0c0, v1
+; GFX1010-NEXT:    v_xor_b32_e32 v11, 0xd0d0d0d0, v0
+; GFX1010-NEXT:    v_or_b32_e32 v9, v9, v8
+; GFX1010-NEXT:    v_or_b32_e32 v8, v11, v10
+; GFX1010-NEXT:    v_cmp_eq_u64_e32 vcc_lo, 0, v[8:9]
+; GFX1010-NEXT:    v_cndmask_b32_e32 v0, v4, v0, vcc_lo
+; GFX1010-NEXT:    v_cndmask_b32_e32 v1, v5, v1, vcc_lo
+; GFX1010-NEXT:    v_cndmask_b32_e32 v2, v6, v2, vcc_lo
+; GFX1010-NEXT:    v_cndmask_b32_e32 v3, v7, v3, vcc_lo
+; GFX1010-NEXT:    s_setpc_b64 s[30:31]
+entry:
+  %cmp = icmp eq i128 %arg, u0xa0a0a0a0b0b0b0b0c0c0c0c0d0d0d0d0
+  %sel = select i1 %cmp, i128 u0xa0a0a0a0b0b0b0b0c0c0c0c0d0d0d0d0, i128 %other
+  ret i128 %sel
+}
+
+; Should be folded: icmp ne + select with constant in false value
+define i128 @icmp_select_fold_ne_imm_i128(i128 %arg, i128 %other) {
+; GFX900-LABEL: icmp_select_fold_ne_imm_i128:
+; GFX900:       ; %bb.0: ; %entry
+; GFX900-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX900-NEXT:    v_xor_b32_e32 v8, 0xa0a0a0a0, v3
+; GFX900-NEXT:    v_xor_b32_e32 v10, 0xb0b0b0b0, v2
+; GFX900-NEXT:    v_xor_b32_e32 v9, 0xc0c0c0c0, v1
+; GFX900-NEXT:    v_xor_b32_e32 v11, 0xd0d0d0d0, v0
+; GFX900-NEXT:    v_or_b32_e32 v9, v9, v8
+; GFX900-NEXT:    v_or_b32_e32 v8, v11, v10
+; GFX900-NEXT:    v_cmp_ne_u64_e32 vcc, 0, v[8:9]
+; GFX900-NEXT:    v_cndmask_b32_e32 v0, v0, v4, vcc
+; GFX900-NEXT:    v_cndmask_b32_e32 v1, v1, v5, vcc
+; GFX900-NEXT:    v_cndmask_b32_e32 v2, v2, v6, vcc
+; GFX900-NEXT:    v_cndmask_b32_e32 v3, v3, v7, vcc
+; GFX900-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX1010-LABEL: icmp_select_fold_ne_imm_i128:
+; GFX1010:       ; %bb.0: ; %entry
+; GFX1010-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX1010-NEXT:    v_xor_b32_e32 v8, 0xa0a0a0a0, v3
+; GFX1010-NEXT:    v_xor_b32_e32 v10, 0xb0b0b0b0, v2
+; GFX1010-NEXT:    v_xor_b32_e32 v9, 0xc0c0c0c0, v1
+; GFX1010-NEXT:    v_xor_b32_e32 v11, 0xd0d0d0d0, v0
+; GFX1010-NEXT:    v_or_b32_e32 v9, v9, v8
+; GFX1010-NEXT:    v_or_b32_e32 v8, v11, v10
+; GFX1010-NEXT:    v_cmp_ne_u64_e32 vcc_lo, 0, v[8:9]
+; GFX1010-NEXT:    v_cndmask_b32_e32 v0, v0, v4, vcc_lo
+; GFX1010-NEXT:    v_cndmask_b32_e32 v1, v1, v5, vcc_lo
+; GFX1010-NEXT:    v_cndmask_b32_e32 v2, v2, v6, vcc_lo
+; GFX1010-NEXT:    v_cndmask_b32_e32 v3, v3, v7, vcc_lo
+; GFX1010-NEXT:    s_setpc_b64 s[30:31]
+entry:
+  %cmp = icmp ne i128 %arg, u0xa0a0a0a0b0b0b0b0c0c0c0c0d0d0d0d0
+  %sel = select i1 %cmp, i128 %other, i128 u0xa0a0a0a0b0b0b0b0c0c0c0c0d0d0d0d0
+  ret i128 %sel
+}
+
+; Should be folded: icmp eq + select with constant in true value
+define i128 @icmp_select_no_fold_i128_other_pos(i128 %arg, i128 %other) {
+; GFX900-LABEL: icmp_select_no_fold_i128_other_pos:
+; GFX900:       ; %bb.0: ; %entry
+; GFX900-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX900-NEXT:    v_xor_b32_e32 v3, 0xa0a0a0a0, v3
+; GFX900-NEXT:    v_xor_b32_e32 v2, 0xb0b0b0b0, v2
+; GFX900-NEXT:    v_xor_b32_e32 v1, 0xc0c0c0c0, v1
+; GFX900-NEXT:    v_xor_b32_e32 v0, 0xd0d0d0d0, v0
+; GFX900-NEXT:    v_or_b32_e32 v1, v1, v3
+; GFX900-NEXT:    v_or_b32_e32 v0, v0, v2
+; GFX900-NEXT:    v_cmp_eq_u64_e32 vcc, 0, v[0:1]
+; GFX900-NEXT:    v_mov_b32_e32 v2, 0xd0d0d0d0
+; GFX900-NEXT:    v_cndmask_b32_e32 v0, v2, v4, vcc
+; GFX900-NEXT:    v_mov_b32_e32 v1, 0xc0c0c0c0
+; GFX900-NEXT:    v_mov_b32_e32 v2, 0xb0b0b0b0
+; GFX900-NEXT:    v_mov_b32_e32 v3, 0xa0a0a0a0
+; GFX900-NEXT:    v_cndmask_b32_e32 v1, v1, v5, vcc
+; GFX900-NEXT:    v_cndmask_b32_e32 v2, v2, v6, vcc
+; GFX900-NEXT:    v_cndmask_b32_e32 v3, v3, v7, vcc
+; GFX900-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX1010-LABEL: icmp_select_no_fold_i128_other_pos:
+; GFX1010:       ; %bb.0: ; %entry
+; GFX1010-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX1010-NEXT:    v_xor_b32_e32 v3, 0xa0a0a0a0, v3
+; GFX1010-NEXT:    v_xor_b32_e32 v2, 0xb0b0b0b0, v2
+; GFX1010-NEXT:    v_xor_b32_e32 v1, 0xc0c0c0c0, v1
+; GFX1010-NEXT:    v_xor_b32_e32 v0, 0xd0d0d0d0, v0
+; GFX1010-NEXT:    v_or_b32_e32 v1, v1, v3
+; GFX1010-NEXT:    v_or_b32_e32 v0, v0, v2
+; GFX1010-NEXT:    v_cmp_eq_u64_e32 vcc_lo, 0, v[0:1]
+; GFX1010-NEXT:    v_cndmask_b32_e32 v0, 0xd0d0d0d0, v4, vcc_lo
+; GFX1010-NEXT:    v_cndmask_b32_e32 v1, 0xc0c0c0c0, v5, vcc_lo
+; GFX1010-NEXT:    v_cndmask_b32_e32 v2, 0xb0b0b0b0, v6, vcc_lo
+; GFX1010-NEXT:    v_cndmask_b32_e32 v3, 0xa0a0a0a0, v7, vcc_lo
+; GFX1010-NEXT:    s_setpc_b64 s[30:31]
+entry:
+  %cmp = icmp eq i128 %arg, u0xa0a0a0a0b0b0b0b0c0c0c0c0d0d0d0d0
+  %sel = select i1 %cmp, i128 %other, i128 u0xa0a0a0a0b0b0b0b0c0c0c0c0d0d0d0d0
+  ret i128 %sel
+}


        


More information about the llvm-commits mailing list