[llvm] [SelectionDAG] Propagate poison in getNode with two operands if the second is poison. (PR #135387)

zhijian lin via llvm-commits llvm-commits at lists.llvm.org
Mon Apr 14 07:19:59 PDT 2025


https://github.com/diggerlin updated https://github.com/llvm/llvm-project/pull/135387

>From 273f4de4ae38e57ed34ad50db1a6504a794c7238 Mon Sep 17 00:00:00 2001
From: zhijian <zhijian at ca.ibm.com>
Date: Fri, 11 Apr 2025 15:15:16 +0000
Subject: [PATCH 1/2] return POISON value in the getNode() in input is poison

---
 .../lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 13 +++++++---
 llvm/test/CodeGen/X86/half.ll                 | 24 +++++++++----------
 llvm/test/CodeGen/X86/poison-ops.ll           | 12 ----------
 llvm/test/CodeGen/X86/pr119158.ll             |  7 +++---
 4 files changed, 25 insertions(+), 31 deletions(-)

diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index d6dcb3f15ae7c..7563d86d65c7e 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -7601,16 +7601,23 @@ SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT,
     case ISD::SDIV:
     case ISD::UREM:
     case ISD::SREM:
-      return getUNDEF(VT);       // fold op(arg1, undef) -> undef
+      // fold op(arg1, undef) -> undef, // fold op(arg1, poison) -> poison.
+      return N2.getOpcode() == ISD::POISON
+                 ? getPOISON(VT)
+                 : getUNDEF(VT);
     case ISD::MUL:
     case ISD::AND:
     case ISD::SSUBSAT:
     case ISD::USUBSAT:
-      return getConstant(0, DL, VT);  // fold op(arg1, undef) -> 0
+       // fold op(arg1, undef) -> 0, fold op(arg1, poison) -> poison.
+      return N2.getOpcode() == ISD::POISON
+                 ? getPOISON(VT)
+                 : getConstant(0, DL, VT);
     case ISD::OR:
     case ISD::SADDSAT:
     case ISD::UADDSAT:
-      return getAllOnesConstant(DL, VT);
+      return N2.getOpcode() == ISD::POISON ? getPOISON(VT)
+                                           : getAllOnesConstant(DL, VT);
     }
   }
 
diff --git a/llvm/test/CodeGen/X86/half.ll b/llvm/test/CodeGen/X86/half.ll
index a64238170cef9..1b98886ba24e7 100644
--- a/llvm/test/CodeGen/X86/half.ll
+++ b/llvm/test/CodeGen/X86/half.ll
@@ -1991,8 +1991,8 @@ define void @pr63114() {
 ; CHECK-LIBCALL-LABEL: pr63114:
 ; CHECK-LIBCALL:       # %bb.0:
 ; CHECK-LIBCALL-NEXT:    movdqu (%rax), %xmm4
-; CHECK-LIBCALL-NEXT:    pshufhw {{.*#+}} xmm0 = xmm4[0,1,2,3,4,5,7,7]
-; CHECK-LIBCALL-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[0,2,2,3]
+; CHECK-LIBCALL-NEXT:    pshuflw {{.*#+}} xmm0 = xmm4[0,1,3,3,4,5,6,7]
+; CHECK-LIBCALL-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[0,0,2,1]
 ; CHECK-LIBCALL-NEXT:    movdqa {{.*#+}} xmm1 = [65535,65535,65535,0,65535,65535,65535,65535]
 ; CHECK-LIBCALL-NEXT:    pand %xmm1, %xmm0
 ; CHECK-LIBCALL-NEXT:    movq {{.*#+}} xmm2 = [0,0,0,15360,0,0,0,0]
@@ -2001,8 +2001,8 @@ define void @pr63114() {
 ; CHECK-LIBCALL-NEXT:    pand %xmm3, %xmm0
 ; CHECK-LIBCALL-NEXT:    movdqa {{.*#+}} xmm5 = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,60]
 ; CHECK-LIBCALL-NEXT:    por %xmm5, %xmm0
-; CHECK-LIBCALL-NEXT:    pshuflw {{.*#+}} xmm6 = xmm4[0,1,3,3,4,5,6,7]
-; CHECK-LIBCALL-NEXT:    pshufd {{.*#+}} xmm6 = xmm6[0,0,2,1]
+; CHECK-LIBCALL-NEXT:    pshufhw {{.*#+}} xmm6 = xmm4[0,1,2,3,4,5,7,7]
+; CHECK-LIBCALL-NEXT:    pshufd {{.*#+}} xmm6 = xmm6[0,2,2,3]
 ; CHECK-LIBCALL-NEXT:    pand %xmm1, %xmm6
 ; CHECK-LIBCALL-NEXT:    por %xmm2, %xmm6
 ; CHECK-LIBCALL-NEXT:    pand %xmm3, %xmm6
@@ -2020,8 +2020,8 @@ define void @pr63114() {
 ; CHECK-LIBCALL-NEXT:    por %xmm5, %xmm7
 ; CHECK-LIBCALL-NEXT:    movdqu %xmm7, 0
 ; CHECK-LIBCALL-NEXT:    movdqu %xmm4, 32
-; CHECK-LIBCALL-NEXT:    movdqu %xmm6, 16
-; CHECK-LIBCALL-NEXT:    movdqu %xmm0, 48
+; CHECK-LIBCALL-NEXT:    movdqu %xmm6, 48
+; CHECK-LIBCALL-NEXT:    movdqu %xmm0, 16
 ; CHECK-LIBCALL-NEXT:    retq
 ;
 ; BWON-F16C-LABEL: pr63114:
@@ -2056,8 +2056,8 @@ define void @pr63114() {
 ; CHECK-I686-LABEL: pr63114:
 ; CHECK-I686:       # %bb.0:
 ; CHECK-I686-NEXT:    movdqu (%eax), %xmm6
-; CHECK-I686-NEXT:    pshufhw {{.*#+}} xmm0 = xmm6[0,1,2,3,4,5,7,7]
-; CHECK-I686-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[0,2,2,3]
+; CHECK-I686-NEXT:    pshuflw {{.*#+}} xmm0 = xmm6[0,1,3,3,4,5,6,7]
+; CHECK-I686-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[0,0,2,1]
 ; CHECK-I686-NEXT:    movdqa {{.*#+}} xmm1 = [65535,65535,65535,0,65535,65535,65535,65535]
 ; CHECK-I686-NEXT:    pand %xmm1, %xmm0
 ; CHECK-I686-NEXT:    movq {{.*#+}} xmm2 = [0,0,0,15360,0,0,0,0]
@@ -2066,8 +2066,8 @@ define void @pr63114() {
 ; CHECK-I686-NEXT:    pand %xmm3, %xmm0
 ; CHECK-I686-NEXT:    movdqa {{.*#+}} xmm4 = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,60]
 ; CHECK-I686-NEXT:    por %xmm4, %xmm0
-; CHECK-I686-NEXT:    pshuflw {{.*#+}} xmm5 = xmm6[0,1,3,3,4,5,6,7]
-; CHECK-I686-NEXT:    pshufd {{.*#+}} xmm5 = xmm5[0,0,2,1]
+; CHECK-I686-NEXT:    pshufhw {{.*#+}} xmm5 = xmm6[0,1,2,3,4,5,7,7]
+; CHECK-I686-NEXT:    pshufd {{.*#+}} xmm5 = xmm5[0,2,2,3]
 ; CHECK-I686-NEXT:    pand %xmm1, %xmm5
 ; CHECK-I686-NEXT:    por %xmm2, %xmm5
 ; CHECK-I686-NEXT:    pand %xmm3, %xmm5
@@ -2085,8 +2085,8 @@ define void @pr63114() {
 ; CHECK-I686-NEXT:    por %xmm4, %xmm7
 ; CHECK-I686-NEXT:    movdqu %xmm7, 0
 ; CHECK-I686-NEXT:    movdqu %xmm6, 32
-; CHECK-I686-NEXT:    movdqu %xmm5, 16
-; CHECK-I686-NEXT:    movdqu %xmm0, 48
+; CHECK-I686-NEXT:    movdqu %xmm5, 48
+; CHECK-I686-NEXT:    movdqu %xmm0, 16
 ; CHECK-I686-NEXT:    retl
   %1 = load <24 x half>, ptr poison, align 2
   %2 = shufflevector <24 x half> %1, <24 x half> poison, <8 x i32> <i32 2, i32 5, i32 8, i32 11, i32 14, i32 17, i32 20, i32 23>
diff --git a/llvm/test/CodeGen/X86/poison-ops.ll b/llvm/test/CodeGen/X86/poison-ops.ll
index 3cd2ceb125ce8..88aeb641b1cd1 100644
--- a/llvm/test/CodeGen/X86/poison-ops.ll
+++ b/llvm/test/CodeGen/X86/poison-ops.ll
@@ -68,7 +68,6 @@ define <4 x i32> @sub_poison_lhs_vec(<4 x i32> %x) {
 define i32 @mul_poison_rhs(i32 %x) {
 ; CHECK-LABEL: mul_poison_rhs:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    xorl %eax, %eax
 ; CHECK-NEXT:    retq
   %r = mul i32 %x, poison
   ret i32 %r
@@ -77,7 +76,6 @@ define i32 @mul_poison_rhs(i32 %x) {
 define <4 x i32> @mul_poison_rhs_vec(<4 x i32> %x) {
 ; CHECK-LABEL: mul_poison_rhs_vec:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    xorps %xmm0, %xmm0
 ; CHECK-NEXT:    retq
   %r = mul <4 x i32> %x, poison
   ret <4 x i32> %r
@@ -86,7 +84,6 @@ define <4 x i32> @mul_poison_rhs_vec(<4 x i32> %x) {
 define i32 @mul_poison_lhs(i32 %x) {
 ; CHECK-LABEL: mul_poison_lhs:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    xorl %eax, %eax
 ; CHECK-NEXT:    retq
   %r = mul i32 poison, %x
   ret i32 %r
@@ -95,7 +92,6 @@ define i32 @mul_poison_lhs(i32 %x) {
 define <4 x i32> @mul_poison_lhs_vec(<4 x i32> %x) {
 ; CHECK-LABEL: mul_poison_lhs_vec:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    xorps %xmm0, %xmm0
 ; CHECK-NEXT:    retq
   %r = mul <4 x i32> poison, %x
   ret <4 x i32> %r
@@ -342,7 +338,6 @@ define <4 x i32> @shl_poison_lhs_vec(<4 x i32> %x) {
 define i32 @and_poison_rhs(i32 %x) {
 ; CHECK-LABEL: and_poison_rhs:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    xorl %eax, %eax
 ; CHECK-NEXT:    retq
   %r = and i32 %x, poison
   ret i32 %r
@@ -351,7 +346,6 @@ define i32 @and_poison_rhs(i32 %x) {
 define <4 x i32> @and_poison_rhs_vec(<4 x i32> %x) {
 ; CHECK-LABEL: and_poison_rhs_vec:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    xorps %xmm0, %xmm0
 ; CHECK-NEXT:    retq
   %r = and <4 x i32> %x, poison
   ret <4 x i32> %r
@@ -360,7 +354,6 @@ define <4 x i32> @and_poison_rhs_vec(<4 x i32> %x) {
 define i32 @and_poison_lhs(i32 %x) {
 ; CHECK-LABEL: and_poison_lhs:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    xorl %eax, %eax
 ; CHECK-NEXT:    retq
   %r = and i32 poison, %x
   ret i32 %r
@@ -369,7 +362,6 @@ define i32 @and_poison_lhs(i32 %x) {
 define <4 x i32> @and_poison_lhs_vec(<4 x i32> %x) {
 ; CHECK-LABEL: and_poison_lhs_vec:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    xorps %xmm0, %xmm0
 ; CHECK-NEXT:    retq
   %r = and <4 x i32> poison, %x
   ret <4 x i32> %r
@@ -378,7 +370,6 @@ define <4 x i32> @and_poison_lhs_vec(<4 x i32> %x) {
 define i32 @or_poison_rhs(i32 %x) {
 ; CHECK-LABEL: or_poison_rhs:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    movl $-1, %eax
 ; CHECK-NEXT:    retq
   %r = or i32 %x, poison
   ret i32 %r
@@ -387,7 +378,6 @@ define i32 @or_poison_rhs(i32 %x) {
 define <4 x i32> @or_poison_rhs_vec(<4 x i32> %x) {
 ; CHECK-LABEL: or_poison_rhs_vec:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    pcmpeqd %xmm0, %xmm0
 ; CHECK-NEXT:    retq
   %r = or <4 x i32> %x, poison
   ret <4 x i32> %r
@@ -396,7 +386,6 @@ define <4 x i32> @or_poison_rhs_vec(<4 x i32> %x) {
 define i32 @or_poison_lhs(i32 %x) {
 ; CHECK-LABEL: or_poison_lhs:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    movl $-1, %eax
 ; CHECK-NEXT:    retq
   %r = or i32 poison, %x
   ret i32 %r
@@ -405,7 +394,6 @@ define i32 @or_poison_lhs(i32 %x) {
 define <4 x i32> @or_poison_lhs_vec(<4 x i32> %x) {
 ; CHECK-LABEL: or_poison_lhs_vec:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    pcmpeqd %xmm0, %xmm0
 ; CHECK-NEXT:    retq
   %r = or <4 x i32> poison, %x
   ret <4 x i32> %r
diff --git a/llvm/test/CodeGen/X86/pr119158.ll b/llvm/test/CodeGen/X86/pr119158.ll
index 4a1da30ca6c25..ca31df802c913 100644
--- a/llvm/test/CodeGen/X86/pr119158.ll
+++ b/llvm/test/CodeGen/X86/pr119158.ll
@@ -5,10 +5,9 @@ define dso_local void @foo() #1 {
 ; CHECK-LABEL: foo:
 ; CHECK:       # %bb.0: # %newFuncRoot
 ; CHECK-NEXT:    vpmovzxbd {{.*#+}} ymm0 = mem[0],zero,zero,zero,mem[1],zero,zero,zero,mem[2],zero,zero,zero,mem[3],zero,zero,zero,mem[4],zero,zero,zero,mem[5],zero,zero,zero,mem[6],zero,zero,zero,mem[7],zero,zero,zero
-; CHECK-NEXT:    vpbroadcastd {{.*#+}} ymm1 = [18,0,18,0,18,0,18,0,18,0,18,0,18,0,18,0]
-; CHECK-NEXT:    vpmaddwd        %ymm1, %ymm0, %ymm0
-; CHECK-NEXT:    vpaddd {{\.?LCPI[0-9]+_[0-9]+}}(%rip){1to8}, %ymm0, %ymm0
-; CHECK-NEXT:    vpsrld $7, %ymm0, %ymm0
+; CHECK-NEXT:    vpbroadcastd {{.*#+}} ymm1 = [64,64,64,64,64,64,64,64]
+; CHECK-NEXT:    vpdpwssd {{\.?LCPI[0-9]+_[0-9]+}}(%rip){1to8}, %ymm0, %ymm1
+; CHECK-NEXT:    vpsrld $7, %ymm1, %ymm0
 ; CHECK-NEXT:    vpackusdw %ymm0, %ymm0, %ymm0
 ; CHECK-NEXT:    vpermq {{.*#+}} ymm0 = ymm0[0,2,1,3]
 ; CHECK-NEXT:    vmovdqu %ymm0, (%rax)

>From bea1bbdcccb00ef99238bc27717baadda3a21ef0 Mon Sep 17 00:00:00 2001
From: zhijian <zhijian at ca.ibm.com>
Date: Mon, 14 Apr 2025 14:20:19 +0000
Subject: [PATCH 2/2] address comment

---
 llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 11 +++--------
 1 file changed, 3 insertions(+), 8 deletions(-)

diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index 7563d86d65c7e..baa1de8449dd1 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -7602,22 +7602,17 @@ SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT,
     case ISD::UREM:
     case ISD::SREM:
       // fold op(arg1, undef) -> undef, // fold op(arg1, poison) -> poison.
-      return N2.getOpcode() == ISD::POISON
-                 ? getPOISON(VT)
-                 : getUNDEF(VT);
+      return N2;
     case ISD::MUL:
     case ISD::AND:
     case ISD::SSUBSAT:
     case ISD::USUBSAT:
        // fold op(arg1, undef) -> 0, fold op(arg1, poison) -> poison.
-      return N2.getOpcode() == ISD::POISON
-                 ? getPOISON(VT)
-                 : getConstant(0, DL, VT);
+      return N2.getOpcode() == ISD::POISON ? N2 : getConstant(0, DL, VT);
     case ISD::OR:
     case ISD::SADDSAT:
     case ISD::UADDSAT:
-      return N2.getOpcode() == ISD::POISON ? getPOISON(VT)
-                                           : getAllOnesConstant(DL, VT);
+      return N2.getOpcode() == ISD::POISON ? N2 : getAllOnesConstant(DL, VT);
     }
   }
 



More information about the llvm-commits mailing list