[llvm] [DAG] canCreateUndefOrPoison - add handling for ADD/SUB overflow nodes (PR #146322)
Simon Pilgrim via llvm-commits
llvm-commits at lists.llvm.org
Mon Jun 30 03:28:42 PDT 2025
https://github.com/RKSimon updated https://github.com/llvm/llvm-project/pull/146322
>From 1b14a2c837a7c0594a790e9a2917fb0ecc11abf8 Mon Sep 17 00:00:00 2001
From: Simon Pilgrim <llvm-dev at redking.me.uk>
Date: Mon, 30 Jun 2025 10:43:23 +0100
Subject: [PATCH 1/2] [DAG] canCreateUndefOrPoison - add handling for ADD/SUB
overflow nodes
Neither the arithmetic value or overflow result can create undef/poison from regular operands values.
We have complete test coverage for all ADDO/SUBO nodes, 32-bit codegen handles the _CARRY variants but until #145939 lands AND DAGCombiner::visitFREEZE handles multiple results we can't see any codegen change.
The SMULO/UMULO nodes can be added as well, but I'm struggling to create any test coverage for them.
Pulled out of #145939
---
.../lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 16 ++++++++++++++
llvm/test/CodeGen/X86/freeze-binary.ll | 22 +++++--------------
2 files changed, 22 insertions(+), 16 deletions(-)
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index fe9a6ea3e77e6..699da5286d13f 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -5557,6 +5557,22 @@ bool SelectionDAG::canCreateUndefOrPoison(SDValue Op, const APInt &DemandedElts,
case ISD::SPLAT_VECTOR:
return false;
+ case ISD::ADDC:
+ case ISD::SUBC:
+ case ISD::ADDE:
+ case ISD::SUBE:
+ case ISD::SADDO:
+ case ISD::SSUBO:
+ case ISD::SADDO_CARRY:
+ case ISD::SSUBO_CARRY:
+ case ISD::UADDO:
+ case ISD::USUBO:
+ case ISD::UADDO_CARRY:
+ case ISD::USUBO_CARRY:
+ // No poison on result or overflow flags.
+ // TODO: Add SMULO/UMULO with test coverage.
+ return false;
+
case ISD::SELECT_CC:
case ISD::SETCC: {
// Integer setcc cannot create undef or poison.
diff --git a/llvm/test/CodeGen/X86/freeze-binary.ll b/llvm/test/CodeGen/X86/freeze-binary.ll
index 4b25fd8a536b2..189de051011d2 100644
--- a/llvm/test/CodeGen/X86/freeze-binary.ll
+++ b/llvm/test/CodeGen/X86/freeze-binary.ll
@@ -814,11 +814,9 @@ define i32 @freeze_saddo(i32 %a0, i32 %a1, i8 %a2, i8 %a3) nounwind {
;
; X64-LABEL: freeze_saddo:
; X64: # %bb.0:
-; X64-NEXT: # kill: def $esi killed $esi def $rsi
-; X64-NEXT: # kill: def $edi killed $edi def $rdi
+; X64-NEXT: movl %edi, %eax
; X64-NEXT: addb %cl, %dl
-; X64-NEXT: adcl $0, %edi
-; X64-NEXT: leal (%rdi,%rsi), %eax
+; X64-NEXT: adcl %esi, %eax
; X64-NEXT: retq
%b = call {i8, i1} @llvm.uadd.with.overflow.i8(i8 %a2, i8 %a3)
%b.o = extractvalue {i8, i1} %b, 1
@@ -844,11 +842,9 @@ define i32 @freeze_uaddo(i32 %a0, i32 %a1, i8 %a2, i8 %a3) nounwind {
;
; X64-LABEL: freeze_uaddo:
; X64: # %bb.0:
-; X64-NEXT: # kill: def $esi killed $esi def $rsi
-; X64-NEXT: # kill: def $edi killed $edi def $rdi
+; X64-NEXT: movl %edi, %eax
; X64-NEXT: addb %cl, %dl
-; X64-NEXT: adcl $0, %edi
-; X64-NEXT: leal (%rdi,%rsi), %eax
+; X64-NEXT: adcl %esi, %eax
; X64-NEXT: retq
%b = call {i8, i1} @llvm.uadd.with.overflow.i8(i8 %a2, i8 %a3)
%b.o = extractvalue {i8, i1} %b, 1
@@ -878,11 +874,8 @@ define i32 @freeze_ssubo(i32 %a0, i32 %a1, i8 %a2, i8 %a3) nounwind {
; X64-LABEL: freeze_ssubo:
; X64: # %bb.0:
; X64-NEXT: movl %edi, %eax
-; X64-NEXT: xorl %edi, %edi
; X64-NEXT: addb %cl, %dl
-; X64-NEXT: setb %dil
-; X64-NEXT: andl $1, %edi
-; X64-NEXT: subl %edi, %eax
+; X64-NEXT: sbbl $0, %eax
; X64-NEXT: subl %esi, %eax
; X64-NEXT: retq
%b = call {i8, i1} @llvm.uadd.with.overflow.i8(i8 %a2, i8 %a3)
@@ -913,11 +906,8 @@ define i32 @freeze_usubo(i32 %a0, i32 %a1, i8 %a2, i8 %a3) nounwind {
; X64-LABEL: freeze_usubo:
; X64: # %bb.0:
; X64-NEXT: movl %edi, %eax
-; X64-NEXT: xorl %edi, %edi
; X64-NEXT: addb %cl, %dl
-; X64-NEXT: setb %dil
-; X64-NEXT: andl $1, %edi
-; X64-NEXT: subl %edi, %eax
+; X64-NEXT: sbbl $0, %eax
; X64-NEXT: subl %esi, %eax
; X64-NEXT: retq
%b = call {i8, i1} @llvm.uadd.with.overflow.i8(i8 %a2, i8 %a3)
>From c9ef1417d5cb382d8e2a119784e2561e75d9e1cb Mon Sep 17 00:00:00 2001
From: Simon Pilgrim <llvm-dev at redking.me.uk>
Date: Mon, 30 Jun 2025 11:28:25 +0100
Subject: [PATCH 2/2] Add SMULO/UMULO handling
---
llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index 699da5286d13f..93cfe6f02bc84 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -5563,14 +5563,15 @@ bool SelectionDAG::canCreateUndefOrPoison(SDValue Op, const APInt &DemandedElts,
case ISD::SUBE:
case ISD::SADDO:
case ISD::SSUBO:
+ case ISD::SMULO:
case ISD::SADDO_CARRY:
case ISD::SSUBO_CARRY:
case ISD::UADDO:
case ISD::USUBO:
+ case ISD::UMULO:
case ISD::UADDO_CARRY:
case ISD::USUBO_CARRY:
// No poison on result or overflow flags.
- // TODO: Add SMULO/UMULO with test coverage.
return false;
case ISD::SELECT_CC:
More information about the llvm-commits
mailing list