[llvm] [DAG] canCreateUndefOrPoison - add handling for ISD::ABS nodes (PR #148791)

Simon Pilgrim via llvm-commits llvm-commits at lists.llvm.org
Tue Jul 15 00:46:30 PDT 2025


https://github.com/RKSimon updated https://github.com/llvm/llvm-project/pull/148791

>From 59f14bb8b5f8d8a99de4d4b2a61fb6fce5ff75b7 Mon Sep 17 00:00:00 2001
From: Simon Pilgrim <llvm-dev at redking.me.uk>
Date: Tue, 15 Jul 2025 08:12:16 +0100
Subject: [PATCH 1/3] [DAG] canCreateUndefOrPoison - add handling for ISD::ABS
 nodes

Unlike the abs intrinsic, the ISD::ABS node defines ABS(INT_MIN) -> INT_MIN, so no undef/poison is created by the node itself
---
 .../lib/CodeGen/SelectionDAG/SelectionDAG.cpp |  1 +
 llvm/test/CodeGen/X86/freeze-unary.ll         | 34 ++++---------------
 2 files changed, 7 insertions(+), 28 deletions(-)

diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index 3656500ddf5ff..0915755d7f315 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -5550,6 +5550,7 @@ bool SelectionDAG::canCreateUndefOrPoison(SDValue Op, const APInt &DemandedElts,
   case ISD::UMAX:
   case ISD::AND:
   case ISD::XOR:
+  case ISD::ABS:
   case ISD::ROTL:
   case ISD::ROTR:
   case ISD::FSHL:
diff --git a/llvm/test/CodeGen/X86/freeze-unary.ll b/llvm/test/CodeGen/X86/freeze-unary.ll
index 2cbcd0e04e100..bc9e29957c74a 100644
--- a/llvm/test/CodeGen/X86/freeze-unary.ll
+++ b/llvm/test/CodeGen/X86/freeze-unary.ll
@@ -73,10 +73,7 @@ define <2 x i64> @freeze_zext_vec(<2 x i16> %a0) nounwind {
 define i32 @freeze_abs(i32 %a0) nounwind {
 ; X86-LABEL: freeze_abs:
 ; X86:       # %bb.0:
-; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
-; X86-NEXT:    movl %eax, %ecx
-; X86-NEXT:    negl %ecx
-; X86-NEXT:    cmovsl %eax, %ecx
+; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
 ; X86-NEXT:    movl %ecx, %eax
 ; X86-NEXT:    negl %eax
 ; X86-NEXT:    cmovsl %ecx, %eax
@@ -84,12 +81,9 @@ define i32 @freeze_abs(i32 %a0) nounwind {
 ;
 ; X64-LABEL: freeze_abs:
 ; X64:       # %bb.0:
-; X64-NEXT:    movl %edi, %ecx
-; X64-NEXT:    negl %ecx
-; X64-NEXT:    cmovsl %edi, %ecx
-; X64-NEXT:    movl %ecx, %eax
+; X64-NEXT:    movl %edi, %eax
 ; X64-NEXT:    negl %eax
-; X64-NEXT:    cmovsl %ecx, %eax
+; X64-NEXT:    cmovsl %edi, %eax
 ; X64-NEXT:    retq
   %x = call i32 @llvm.abs.i32(i32 %a0, i1 0)
   %f = freeze i32 %x
@@ -104,16 +98,11 @@ define <4 x i32> @freeze_abs_vec(<4 x i32> %a0) nounwind {
 ; X86-NEXT:    psrad $31, %xmm1
 ; X86-NEXT:    pxor %xmm1, %xmm0
 ; X86-NEXT:    psubd %xmm1, %xmm0
-; X86-NEXT:    movdqa %xmm0, %xmm1
-; X86-NEXT:    psrad $31, %xmm1
-; X86-NEXT:    pxor %xmm1, %xmm0
-; X86-NEXT:    psubd %xmm1, %xmm0
 ; X86-NEXT:    retl
 ;
 ; X64-LABEL: freeze_abs_vec:
 ; X64:       # %bb.0:
 ; X64-NEXT:    pabsd %xmm0, %xmm0
-; X64-NEXT:    pabsd %xmm0, %xmm0
 ; X64-NEXT:    retq
   %x = call <4 x i32> @llvm.abs.v4i32(<4 x i32> %a0, i1 0)
   %f = freeze <4 x i32> %x
@@ -124,10 +113,7 @@ define <4 x i32> @freeze_abs_vec(<4 x i32> %a0) nounwind {
 define i32 @freeze_abs_undef(i32 %a0) nounwind {
 ; X86-LABEL: freeze_abs_undef:
 ; X86:       # %bb.0:
-; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
-; X86-NEXT:    movl %eax, %ecx
-; X86-NEXT:    negl %ecx
-; X86-NEXT:    cmovsl %eax, %ecx
+; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
 ; X86-NEXT:    movl %ecx, %eax
 ; X86-NEXT:    negl %eax
 ; X86-NEXT:    cmovsl %ecx, %eax
@@ -135,12 +121,9 @@ define i32 @freeze_abs_undef(i32 %a0) nounwind {
 ;
 ; X64-LABEL: freeze_abs_undef:
 ; X64:       # %bb.0:
-; X64-NEXT:    movl %edi, %ecx
-; X64-NEXT:    negl %ecx
-; X64-NEXT:    cmovsl %edi, %ecx
-; X64-NEXT:    movl %ecx, %eax
+; X64-NEXT:    movl %edi, %eax
 ; X64-NEXT:    negl %eax
-; X64-NEXT:    cmovsl %ecx, %eax
+; X64-NEXT:    cmovsl %edi, %eax
 ; X64-NEXT:    retq
   %x = call i32 @llvm.abs.i32(i32 %a0, i1 -1)
   %f = freeze i32 %x
@@ -155,16 +138,11 @@ define <4 x i32> @freeze_abs_undef_vec(<4 x i32> %a0) nounwind {
 ; X86-NEXT:    psrad $31, %xmm1
 ; X86-NEXT:    pxor %xmm1, %xmm0
 ; X86-NEXT:    psubd %xmm1, %xmm0
-; X86-NEXT:    movdqa %xmm0, %xmm1
-; X86-NEXT:    psrad $31, %xmm1
-; X86-NEXT:    pxor %xmm1, %xmm0
-; X86-NEXT:    psubd %xmm1, %xmm0
 ; X86-NEXT:    retl
 ;
 ; X64-LABEL: freeze_abs_undef_vec:
 ; X64:       # %bb.0:
 ; X64-NEXT:    pabsd %xmm0, %xmm0
-; X64-NEXT:    pabsd %xmm0, %xmm0
 ; X64-NEXT:    retq
   %x = call <4 x i32> @llvm.abs.v4i32(<4 x i32> %a0, i1 -1)
   %f = freeze <4 x i32> %x

>From 95796549a9c02c3d3de9038249f563d0997e0c8c Mon Sep 17 00:00:00 2001
From: Simon Pilgrim <llvm-dev at redking.me.uk>
Date: Tue, 15 Jul 2025 08:40:14 +0100
Subject: [PATCH 2/3] Pull out ISD::ABS case and add explanatory comment

---
 llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index 0915755d7f315..856d60cc13d8b 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -5550,7 +5550,6 @@ bool SelectionDAG::canCreateUndefOrPoison(SDValue Op, const APInt &DemandedElts,
   case ISD::UMAX:
   case ISD::AND:
   case ISD::XOR:
-  case ISD::ABS:
   case ISD::ROTL:
   case ISD::ROTR:
   case ISD::FSHL:
@@ -5572,6 +5571,11 @@ bool SelectionDAG::canCreateUndefOrPoison(SDValue Op, const APInt &DemandedElts,
   case ISD::SPLAT_VECTOR:
     return false;
 
+  case ISD::ABS:
+    // ISD::ABD defines abs(INT_MIN) -> INT_MIN and never generates poison.
+    // Different to Intrinsic::abs.
+    return false;
+
   case ISD::ADDC:
   case ISD::SUBC:
   case ISD::ADDE:

>From 084e692495e9eba4a5975a562a42f41cadc87676 Mon Sep 17 00:00:00 2001
From: Simon Pilgrim <llvm-dev at redking.me.uk>
Date: Tue, 15 Jul 2025 08:46:15 +0100
Subject: [PATCH 3/3] Fix typo

---
 llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index 856d60cc13d8b..70a39eab1e720 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -5572,7 +5572,7 @@ bool SelectionDAG::canCreateUndefOrPoison(SDValue Op, const APInt &DemandedElts,
     return false;
 
   case ISD::ABS:
-    // ISD::ABD defines abs(INT_MIN) -> INT_MIN and never generates poison.
+    // ISD::ABS defines abs(INT_MIN) -> INT_MIN and never generates poison.
     // Different to Intrinsic::abs.
     return false;
 



More information about the llvm-commits mailing list