[llvm] [DAG] SelectionDAG::canCreateUndefOrPoison - add ISD::SCMP/UCMP handling + tests (PR #154127)

via llvm-commits llvm-commits at lists.llvm.org
Mon Aug 18 11:51:53 PDT 2025


https://github.com/Temperz87 updated https://github.com/llvm/llvm-project/pull/154127

>From 23ba9158317fa6a7988031cf9abc4b7f39b42e75 Mon Sep 17 00:00:00 2001
From: Temperz87 <= temperz871 at gmail.com>
Date: Mon, 18 Aug 2025 09:26:44 -0400
Subject: [PATCH 1/6] [SelectionDAG] Add SCMP and UCMP to
 canCreateUnDefOrPoison

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

diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index 61f114411cd0d..4334d5017979a 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -5622,6 +5622,8 @@ bool SelectionDAG::canCreateUndefOrPoison(SDValue Op, const APInt &DemandedElts,
   case ISD::FDIV:
   case ISD::FREM:
   case ISD::FCOPYSIGN:
+  case ISD::SCMP:
+  case ISD::UCMP:
     // No poison except from flags (which is handled above)
     return false;
 

>From addb5a5abd9d31c7d94df6639111f19d2619b5be Mon Sep 17 00:00:00 2001
From: Temperz87 <= temperz871 at gmail.com>
Date: Mon, 18 Aug 2025 09:27:55 -0400
Subject: [PATCH 2/6] Add test for issues/152144

---
 llvm/test/CodeGen/X86/freeze-binary.ll | 114 +++++++++++++++++++++----
 1 file changed, 96 insertions(+), 18 deletions(-)

diff --git a/llvm/test/CodeGen/X86/freeze-binary.ll b/llvm/test/CodeGen/X86/freeze-binary.ll
index 962ffe47d0d51..91c8b7f21ff14 100644
--- a/llvm/test/CodeGen/X86/freeze-binary.ll
+++ b/llvm/test/CodeGen/X86/freeze-binary.ll
@@ -490,19 +490,18 @@ define i32 @freeze_ashr_exact(i32 %a0) nounwind {
 define i32 @freeze_ashr_exact_extra_use(i32 %a0, ptr %escape) nounwind {
 ; X86-LABEL: freeze_ashr_exact_extra_use:
 ; X86:       # %bb.0:
-; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
-; X86-NEXT:    sarl $3, %ecx
-; X86-NEXT:    movl %ecx, (%eax)
-; X86-NEXT:    movl %ecx, %eax
+; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; X86-NEXT:    sarl $3, %eax
+; X86-NEXT:    movl %eax, (%ecx)
 ; X86-NEXT:    sarl $6, %eax
 ; X86-NEXT:    retl
 ;
 ; X64-LABEL: freeze_ashr_exact_extra_use:
 ; X64:       # %bb.0:
-; X64-NEXT:    sarl $3, %edi
-; X64-NEXT:    movl %edi, (%rsi)
 ; X64-NEXT:    movl %edi, %eax
+; X64-NEXT:    sarl $3, %eax
+; X64-NEXT:    movl %eax, (%rsi)
 ; X64-NEXT:    sarl $6, %eax
 ; X64-NEXT:    retq
   %x = ashr exact i32 %a0, 3
@@ -604,19 +603,18 @@ define i32 @freeze_lshr_exact(i32 %a0) nounwind {
 define i32 @freeze_lshr_exact_extra_use(i32 %a0, ptr %escape) nounwind {
 ; X86-LABEL: freeze_lshr_exact_extra_use:
 ; X86:       # %bb.0:
-; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
-; X86-NEXT:    shrl $3, %ecx
-; X86-NEXT:    movl %ecx, (%eax)
-; X86-NEXT:    movl %ecx, %eax
+; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; X86-NEXT:    shrl $3, %eax
+; X86-NEXT:    movl %eax, (%ecx)
 ; X86-NEXT:    shrl $5, %eax
 ; X86-NEXT:    retl
 ;
 ; X64-LABEL: freeze_lshr_exact_extra_use:
 ; X64:       # %bb.0:
-; X64-NEXT:    shrl $3, %edi
-; X64-NEXT:    movl %edi, (%rsi)
 ; X64-NEXT:    movl %edi, %eax
+; X64-NEXT:    shrl $3, %eax
+; X64-NEXT:    movl %eax, (%rsi)
 ; X64-NEXT:    shrl $5, %eax
 ; X64-NEXT:    retq
   %x = lshr exact i32 %a0, 3
@@ -816,9 +814,11 @@ define i32 @freeze_saddo(i32 %a0, i32 %a1, i8 %a2, i8 %a3) nounwind {
 ;
 ; X64-LABEL: freeze_saddo:
 ; X64:       # %bb.0:
-; X64-NEXT:    movl %edi, %eax
+; X64-NEXT:    # kill: def $esi killed $esi def $rsi
+; X64-NEXT:    # kill: def $edi killed $edi def $rdi
 ; X64-NEXT:    addb %cl, %dl
-; X64-NEXT:    adcl %esi, %eax
+; X64-NEXT:    adcl $0, %edi
+; X64-NEXT:    leal (%rdi,%rsi), %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,9 +844,11 @@ define i32 @freeze_uaddo(i32 %a0, i32 %a1, i8 %a2, i8 %a3) nounwind {
 ;
 ; X64-LABEL: freeze_uaddo:
 ; X64:       # %bb.0:
-; X64-NEXT:    movl %edi, %eax
+; X64-NEXT:    # kill: def $esi killed $esi def $rsi
+; X64-NEXT:    # kill: def $edi killed $edi def $rdi
 ; X64-NEXT:    addb %cl, %dl
-; X64-NEXT:    adcl %esi, %eax
+; X64-NEXT:    adcl $0, %edi
+; X64-NEXT:    leal (%rdi,%rsi), %eax
 ; X64-NEXT:    retq
   %b = call {i8, i1} @llvm.uadd.with.overflow.i8(i8 %a2, i8 %a3)
   %b.o = extractvalue {i8, i1} %b, 1
@@ -876,8 +878,11 @@ 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:    sbbl $0, %eax
+; X64-NEXT:    setb %dil
+; X64-NEXT:    andl $1, %edi
+; X64-NEXT:    subl %edi, %eax
 ; X64-NEXT:    subl %esi, %eax
 ; X64-NEXT:    retq
   %b = call {i8, i1} @llvm.uadd.with.overflow.i8(i8 %a2, i8 %a3)
@@ -908,8 +913,11 @@ 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:    sbbl $0, %eax
+; X64-NEXT:    setb %dil
+; X64-NEXT:    andl $1, %edi
+; X64-NEXT:    subl %edi, %eax
 ; X64-NEXT:    subl %esi, %eax
 ; X64-NEXT:    retq
   %b = call {i8, i1} @llvm.uadd.with.overflow.i8(i8 %a2, i8 %a3)
@@ -924,6 +932,76 @@ define i32 @freeze_usubo(i32 %a0, i32 %a1, i8 %a2, i8 %a3) nounwind {
   ret i32 %r
 }
 
+define i32 @freeze_scmp(i32 %a0) nounwind {
+; X86-LABEL: freeze_scmp:
+; X86:       # %bb.0:
+; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; X86-NEXT:    cmpl $2, %eax
+; X86-NEXT:    setl %al
+; X86-NEXT:    setg %cl
+; X86-NEXT:    subb %al, %cl
+; X86-NEXT:    movsbl %cl, %eax
+; X86-NEXT:    cmpl $2, %eax
+; X86-NEXT:    setl %al
+; X86-NEXT:    setg %cl
+; X86-NEXT:    subb %al, %cl
+; X86-NEXT:    movsbl %cl, %eax
+; X86-NEXT:    retl
+;
+; X64-LABEL: freeze_scmp:
+; X64:       # %bb.0:
+; X64-NEXT:    cmpl $2, %edi
+; X64-NEXT:    setl %al
+; X64-NEXT:    setg %cl
+; X64-NEXT:    subb %al, %cl
+; X64-NEXT:    movsbl %cl, %eax
+; X64-NEXT:    cmpl $2, %eax
+; X64-NEXT:    setl %al
+; X64-NEXT:    setg %cl
+; X64-NEXT:    subb %al, %cl
+; X64-NEXT:    movsbl %cl, %eax
+; X64-NEXT:    retq
+  %x = call i32 @llvm.scmp.i32(i32 %a0, i32 2)
+  %y = freeze i32 %x
+  %z = call i32 @llvm.scmp.i32(i32 %y, i32 2)
+  ret i32 %z
+}
+
+define i32 @freeze_ucmp(i32 %a0) nounwind {
+; X86-LABEL: freeze_ucmp:
+; X86:       # %bb.0:
+; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; X86-NEXT:    cmpl $3, %eax
+; X86-NEXT:    setae %cl
+; X86-NEXT:    cmpl $2, %eax
+; X86-NEXT:    sbbb $0, %cl
+; X86-NEXT:    movsbl %cl, %eax
+; X86-NEXT:    cmpl $3, %eax
+; X86-NEXT:    setae %cl
+; X86-NEXT:    cmpl $2, %eax
+; X86-NEXT:    sbbb $0, %cl
+; X86-NEXT:    movsbl %cl, %eax
+; X86-NEXT:    retl
+;
+; X64-LABEL: freeze_ucmp:
+; X64:       # %bb.0:
+; X64-NEXT:    cmpl $3, %edi
+; X64-NEXT:    setae %al
+; X64-NEXT:    cmpl $2, %edi
+; X64-NEXT:    sbbb $0, %al
+; X64-NEXT:    movsbl %al, %eax
+; X64-NEXT:    cmpl $3, %eax
+; X64-NEXT:    setae %cl
+; X64-NEXT:    cmpl $2, %eax
+; X64-NEXT:    sbbb $0, %cl
+; X64-NEXT:    movsbl %cl, %eax
+; X64-NEXT:    retq
+  %x = call i32 @llvm.ucmp.i32(i32 %a0, i32 2)
+  %y = freeze i32 %x
+  %z = call i32 @llvm.ucmp.i32(i32 %y, i32 2)
+  ret i32 %z
+}
+
 define void @pr59676_frozen(ptr %dst, i32 %x.orig) {
 ; X86-LABEL: pr59676_frozen:
 ; X86:       # %bb.0:

>From e4ec670cfb07ed6139ff7942a8938288a2e85b23 Mon Sep 17 00:00:00 2001
From: Temperz87 <= temperz871 at gmail.com>
Date: Mon, 18 Aug 2025 10:35:20 -0400
Subject: [PATCH 3/6] Fix freeze-binary.ll unit test

---
 llvm/test/CodeGen/X86/freeze-binary.ll | 47 +++++++++++---------------
 1 file changed, 20 insertions(+), 27 deletions(-)

diff --git a/llvm/test/CodeGen/X86/freeze-binary.ll b/llvm/test/CodeGen/X86/freeze-binary.ll
index 91c8b7f21ff14..af5b26f6e2dd9 100644
--- a/llvm/test/CodeGen/X86/freeze-binary.ll
+++ b/llvm/test/CodeGen/X86/freeze-binary.ll
@@ -490,18 +490,19 @@ define i32 @freeze_ashr_exact(i32 %a0) nounwind {
 define i32 @freeze_ashr_exact_extra_use(i32 %a0, ptr %escape) nounwind {
 ; X86-LABEL: freeze_ashr_exact_extra_use:
 ; X86:       # %bb.0:
-; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
-; X86-NEXT:    sarl $3, %eax
-; X86-NEXT:    movl %eax, (%ecx)
+; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; X86-NEXT:    sarl $3, %ecx
+; X86-NEXT:    movl %ecx, (%eax)
+; X86-NEXT:    movl %ecx, %eax
 ; X86-NEXT:    sarl $6, %eax
 ; X86-NEXT:    retl
 ;
 ; X64-LABEL: freeze_ashr_exact_extra_use:
 ; X64:       # %bb.0:
+; X64-NEXT:    sarl $3, %edi
+; X64-NEXT:    movl %edi, (%rsi)
 ; X64-NEXT:    movl %edi, %eax
-; X64-NEXT:    sarl $3, %eax
-; X64-NEXT:    movl %eax, (%rsi)
 ; X64-NEXT:    sarl $6, %eax
 ; X64-NEXT:    retq
   %x = ashr exact i32 %a0, 3
@@ -603,18 +604,19 @@ define i32 @freeze_lshr_exact(i32 %a0) nounwind {
 define i32 @freeze_lshr_exact_extra_use(i32 %a0, ptr %escape) nounwind {
 ; X86-LABEL: freeze_lshr_exact_extra_use:
 ; X86:       # %bb.0:
-; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
-; X86-NEXT:    shrl $3, %eax
-; X86-NEXT:    movl %eax, (%ecx)
+; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; X86-NEXT:    shrl $3, %ecx
+; X86-NEXT:    movl %ecx, (%eax)
+; X86-NEXT:    movl %ecx, %eax
 ; X86-NEXT:    shrl $5, %eax
 ; X86-NEXT:    retl
 ;
 ; X64-LABEL: freeze_lshr_exact_extra_use:
 ; X64:       # %bb.0:
+; X64-NEXT:    shrl $3, %edi
+; X64-NEXT:    movl %edi, (%rsi)
 ; X64-NEXT:    movl %edi, %eax
-; X64-NEXT:    shrl $3, %eax
-; X64-NEXT:    movl %eax, (%rsi)
 ; X64-NEXT:    shrl $5, %eax
 ; X64-NEXT:    retq
   %x = lshr exact i32 %a0, 3
@@ -814,11 +816,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 +844,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 +876,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 +908,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)
@@ -932,6 +924,7 @@ define i32 @freeze_usubo(i32 %a0, i32 %a1, i8 %a2, i8 %a3) nounwind {
   ret i32 %r
 }
 
+
 define i32 @freeze_scmp(i32 %a0) nounwind {
 ; X86-LABEL: freeze_scmp:
 ; X86:       # %bb.0:
@@ -1114,4 +1107,4 @@ define void @pr59676_nsw(ptr %dst, i32 %x) {
   %div = sdiv i32 %area, 42
   store i32 %div, ptr %dst, align 4
   ret void
-}
+}
\ No newline at end of file

>From 45315ce4ea3d702903f13004faf29db0bb860432 Mon Sep 17 00:00:00 2001
From: Temperz87 <= temperz871 at gmail.com>
Date: Mon, 18 Aug 2025 12:05:19 -0400
Subject: [PATCH 4/6] Readd newline at end of line

---
 llvm/test/CodeGen/X86/freeze-binary.ll | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llvm/test/CodeGen/X86/freeze-binary.ll b/llvm/test/CodeGen/X86/freeze-binary.ll
index af5b26f6e2dd9..b0a257d698770 100644
--- a/llvm/test/CodeGen/X86/freeze-binary.ll
+++ b/llvm/test/CodeGen/X86/freeze-binary.ll
@@ -1107,4 +1107,4 @@ define void @pr59676_nsw(ptr %dst, i32 %x) {
   %div = sdiv i32 %area, 42
   store i32 %div, ptr %dst, align 4
   ret void
-}
\ No newline at end of file
+}

>From f169dc45f966174d28045bc68e061e45faa1bcd7 Mon Sep 17 00:00:00 2001
From: Temperz87 <= temperz871 at gmail.com>
Date: Mon, 18 Aug 2025 12:06:32 -0400
Subject: [PATCH 5/6] [SelectionDAG] Move ISD::SCMP/UCMP location in
 canCreateUndefOrPoison

---
 llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index cbbf885115a59..e449c07bd8e3b 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -5709,6 +5709,8 @@ bool SelectionDAG::canCreateUndefOrPoison(SDValue Op, const APInt &DemandedElts,
   case ISD::UMULO:
   case ISD::UADDO_CARRY:
   case ISD::USUBO_CARRY:
+  case ISD::SCMP:
+  case ISD::UCMP:
     // No poison on result or overflow flags.
     return false;
 
@@ -5748,8 +5750,6 @@ bool SelectionDAG::canCreateUndefOrPoison(SDValue Op, const APInt &DemandedElts,
   case ISD::FMA:
   case ISD::FMAD:
   case ISD::FP_EXTEND:
-  case ISD::SCMP:
-  case ISD::UCMP:
     // No poison except from flags (which is handled above)
     return false;
 

>From fe1319b8390ede45545be7580b4cb0a1f15a39bd Mon Sep 17 00:00:00 2001
From: Temperz87 <= temperz871 at gmail.com>
Date: Mon, 18 Aug 2025 14:51:33 -0400
Subject: [PATCH 6/6] Move UCMP and SCMP next to UMIN and UMAX correctly

---
 llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index e449c07bd8e3b..3c3239310fcd1 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -5664,8 +5664,10 @@ bool SelectionDAG::canCreateUndefOrPoison(SDValue Op, const APInt &DemandedElts,
   case ISD::ABDS:
   case ISD::SMIN:
   case ISD::SMAX:
+  case ISD::SCMP:
   case ISD::UMIN:
   case ISD::UMAX:
+  case ISD::UCMP:
   case ISD::AND:
   case ISD::XOR:
   case ISD::ROTL:
@@ -5709,8 +5711,6 @@ bool SelectionDAG::canCreateUndefOrPoison(SDValue Op, const APInt &DemandedElts,
   case ISD::UMULO:
   case ISD::UADDO_CARRY:
   case ISD::USUBO_CARRY:
-  case ISD::SCMP:
-  case ISD::UCMP:
     // No poison on result or overflow flags.
     return false;
 



More information about the llvm-commits mailing list