[llvm-branch-commits] [llvm] release/23.x: [DAG] foldSelectToABD - ensure -Constant negation doesn't overflow (#235279) (PR #235757)

via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Mon Oct 26 05:53:03 PDT 2026


https://github.com/llvmbot created https://github.com/llvm/llvm-project/pull/235757

Backport f570d92b57c8c8137c5859e1c6a60518de6d3b3e

Requested by: @RKSimon

>From b0db4937e29caeaebe7cbf497e2cee98468a7d02 Mon Sep 17 00:00:00 2001
From: Simon Pilgrim <llvm-dev at redking.me.uk>
Date: Mon, 26 Oct 2026 07:01:59 +0000
Subject: [PATCH] [DAG] foldSelectToABD - ensure -Constant negation doesn't
 overflow (#235279)

The (setcc (add nsw A, Const), 0, sets??) --> (setcc A, -Const, sets??)
fold is only valid if Const isn't MIN_SIGNED_INT

Fixes #235263

(cherry picked from commit f570d92b57c8c8137c5859e1c6a60518de6d3b3e)
---
 llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp |  5 +-
 llvm/test/CodeGen/AArch64/abds.ll             | 15 +++++
 llvm/test/CodeGen/X86/abds-vector-128.ll      | 66 +++++++++++++++++++
 3 files changed, 85 insertions(+), 1 deletion(-)

diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index 478685084d4de8..6cb73f3d1eb62d 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -13052,10 +13052,13 @@ SDValue DAGCombiner::foldSelectToABD(SDValue LHS, SDValue RHS, SDValue True,
   }
 
   // (setcc (add nsw A, Const), 0, sets??) --> (setcc A, -Const, sets??)
+  // Ensure -Const doesn't overflow.
   SDValue A, B;
   if (ISD::isSignedIntSetCC(CC) && LHS->getFlags().hasNoSignedWrap() &&
       isZeroOrZeroSplat(RHS) && sd_match(LHS, m_Add(m_Value(A), m_Value(B))) &&
-      DAG.isConstantIntBuildVectorOrConstantInt(B)) {
+      ISD::matchUnaryPredicate(B, [](ConstantSDNode *C) {
+        return !C->getAPIntValue().isMinSignedValue();
+      })) {
     RHS = DAG.getNegative(B, LHS, B.getValueType());
     LHS = A;
   }
diff --git a/llvm/test/CodeGen/AArch64/abds.ll b/llvm/test/CodeGen/AArch64/abds.ll
index d0c390c2f06327..c8f26dcf0505ff 100644
--- a/llvm/test/CodeGen/AArch64/abds.ll
+++ b/llvm/test/CodeGen/AArch64/abds.ll
@@ -653,6 +653,21 @@ define i128 @abd_select_i128(i128 %a, i128 %b) nounwind {
   ret i128 %sub
 }
 
+define i32 @PR235263(i32 %x) {
+; CHECK-LABEL: PR235263:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    mov w8, #-2147483648 // =0x80000000
+; CHECK-NEXT:    adds w9, w0, w8
+; CHECK-NEXT:    sub w8, w8, w0
+; CHECK-NEXT:    csel w0, w9, w8, gt
+; CHECK-NEXT:    ret
+  %add = add nsw i32 %x, -2147483648
+  %cmp = icmp sgt i32 %add, 0
+  %sub = sub i32 -2147483648, %x
+  %sel = select i1 %cmp, i32 %add, i32 %sub
+  ret i32 %sel
+}
+
 declare i8 @llvm.abs.i8(i8, i1)
 declare i16 @llvm.abs.i16(i16, i1)
 declare i32 @llvm.abs.i32(i32, i1)
diff --git a/llvm/test/CodeGen/X86/abds-vector-128.ll b/llvm/test/CodeGen/X86/abds-vector-128.ll
index 148be83892b721..3a87dcbfad8180 100644
--- a/llvm/test/CodeGen/X86/abds-vector-128.ll
+++ b/llvm/test/CodeGen/X86/abds-vector-128.ll
@@ -846,6 +846,72 @@ define <8 x i16> @abd_cmp_v8i16_multiuse_sub(<8 x i16> %a, <8 x i16> %b) nounwin
   ret <8 x i16> %res
 }
 
+define <2 x i32> @PR235263(<2 x i32> %x) {
+; SSE2-LABEL: PR235263:
+; SSE2:       # %bb.0:
+; SSE2-NEXT:    movq {{.*#+}} xmm2 = [5,2147483648,0,0]
+; SSE2-NEXT:    paddd %xmm0, %xmm2
+; SSE2-NEXT:    pxor %xmm3, %xmm3
+; SSE2-NEXT:    movdqa %xmm2, %xmm1
+; SSE2-NEXT:    pcmpgtd %xmm3, %xmm1
+; SSE2-NEXT:    movq {{.*#+}} xmm3 = [4294967291,2147483648,0,0]
+; SSE2-NEXT:    psubd %xmm0, %xmm3
+; SSE2-NEXT:    pand %xmm1, %xmm2
+; SSE2-NEXT:    pandn %xmm3, %xmm1
+; SSE2-NEXT:    por %xmm2, %xmm1
+; SSE2-NEXT:    movdqa %xmm1, %xmm0
+; SSE2-NEXT:    retq
+;
+; SSE42-LABEL: PR235263:
+; SSE42:       # %bb.0:
+; SSE42-NEXT:    movq {{.*#+}} xmm3 = [5,2147483648,0,0]
+; SSE42-NEXT:    paddd %xmm0, %xmm3
+; SSE42-NEXT:    pxor %xmm2, %xmm2
+; SSE42-NEXT:    movdqa %xmm3, %xmm1
+; SSE42-NEXT:    pcmpgtd %xmm2, %xmm1
+; SSE42-NEXT:    movq {{.*#+}} xmm2 = [4294967291,2147483648,0,0]
+; SSE42-NEXT:    psubd %xmm0, %xmm2
+; SSE42-NEXT:    movdqa %xmm1, %xmm0
+; SSE42-NEXT:    blendvps %xmm0, %xmm3, %xmm2
+; SSE42-NEXT:    movaps %xmm2, %xmm0
+; SSE42-NEXT:    retq
+;
+; AVX1-LABEL: PR235263:
+; AVX1:       # %bb.0:
+; AVX1-NEXT:    vpaddd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm1 # [5,2147483648,u,u]
+; AVX1-NEXT:    vpxor %xmm2, %xmm2, %xmm2
+; AVX1-NEXT:    vpcmpgtd %xmm2, %xmm1, %xmm2
+; AVX1-NEXT:    vmovq {{.*#+}} xmm3 = [4294967291,2147483648,0,0]
+; AVX1-NEXT:    vpsubd %xmm0, %xmm3, %xmm0
+; AVX1-NEXT:    vblendvps %xmm2, %xmm1, %xmm0, %xmm0
+; AVX1-NEXT:    retq
+;
+; AVX2-LABEL: PR235263:
+; AVX2:       # %bb.0:
+; AVX2-NEXT:    vpaddd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm1 # [5,2147483648,u,u]
+; AVX2-NEXT:    vpxor %xmm2, %xmm2, %xmm2
+; AVX2-NEXT:    vpcmpgtd %xmm2, %xmm1, %xmm2
+; AVX2-NEXT:    vmovq {{.*#+}} xmm3 = [4294967291,2147483648,0,0]
+; AVX2-NEXT:    vpsubd %xmm0, %xmm3, %xmm0
+; AVX2-NEXT:    vblendvps %xmm2, %xmm1, %xmm0, %xmm0
+; AVX2-NEXT:    retq
+;
+; AVX512-LABEL: PR235263:
+; AVX512:       # %bb.0:
+; AVX512-NEXT:    vpaddd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm1 # [5,2147483648,u,u]
+; AVX512-NEXT:    vpxor %xmm2, %xmm2, %xmm2
+; AVX512-NEXT:    vpcmpled %xmm2, %xmm1, %k1
+; AVX512-NEXT:    vmovq {{.*#+}} xmm2 = [4294967291,2147483648,0,0]
+; AVX512-NEXT:    vpsubd %xmm0, %xmm2, %xmm1 {%k1}
+; AVX512-NEXT:    vmovdqa %xmm1, %xmm0
+; AVX512-NEXT:    retq
+  %add = add nsw <2 x i32> %x, <i32 5, i32 -2147483648>
+  %cmp = icmp sgt <2 x i32> %add, zeroinitializer
+  %sub = sub <2 x i32> <i32 -5, i32 -2147483648>, %x
+  %sel = select <2 x i1> %cmp, <2 x i32> %add, <2 x i32> %sub
+  ret <2 x i32> %sel
+}
+
 declare <16 x i8> @llvm.abs.v16i8(<16 x i8>, i1)
 declare <8 x i16> @llvm.abs.v8i16(<8 x i16>, i1)
 declare <4 x i32> @llvm.abs.v4i32(<4 x i32>, i1)



More information about the llvm-branch-commits mailing list