Skip to content

[SelectionDAG] Propagate poison in getNode with two operands if the input is poison. #135387

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Apr 17, 2025

Conversation

diggerlin
Copy link
Contributor

@diggerlin diggerlin commented Apr 11, 2025

Propagation to poison in function SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT,SDValue N1, SDValue N2, const SDNodeFlags Flags) if one of the input is poison.

The patch also revert the test cases
llvm/test/CodeGen/X86/pr119158.ll
llvm/test/CodeGen/X86/half.ll

which are mentioned in #125883 (comment)

@llvmbot llvmbot added backend:X86 llvm:SelectionDAG SelectionDAGISel as well labels Apr 11, 2025
@llvmbot
Copy link
Member

llvmbot commented Apr 11, 2025

@llvm/pr-subscribers-backend-x86

Author: zhijian lin (diggerlin)

Changes

Propagation to poison in function SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT,SDValue N1, SDValue N2, const SDNodeFlags Flags) if N2 is poison.

The patch also revert the test cases which mentions in
llvm/test/CodeGen/X86/pr119158.ll


Full diff: https://github.com/llvm/llvm-project/pull/135387.diff

4 Files Affected:

  • (modified) llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp (+16-3)
  • (modified) llvm/test/CodeGen/X86/half.ll (+12-12)
  • (modified) llvm/test/CodeGen/X86/poison-ops.ll (-12)
  • (modified) llvm/test/CodeGen/X86/pr119158.ll (+3-4)
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index d6dcb3f15ae7c..4ad5efdcc0555 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -7586,6 +7586,14 @@ SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT,
     }
   }
 
+  /*
+  if (N2.getOpcode() == ISD::POISON) {
+    switch (Opcode) {
+    case ISD::ADD:
+      return getPOISON(VT);
+    }
+  }*/
+
   // Fold a bunch of operators when the RHS is undef.
   if (N2.isUndef()) {
     switch (Opcode) {
@@ -7601,16 +7609,21 @@ 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
+      return N2.getOpcode() == ISD::POISON
+                 ? getPOISON(VT)
+                 : getUNDEF(VT); // fold op(arg1, undef) -> undef
     case ISD::MUL:
     case ISD::AND:
     case ISD::SSUBSAT:
     case ISD::USUBSAT:
-      return getConstant(0, DL, VT);  // fold op(arg1, undef) -> 0
+      return N2.getOpcode() == ISD::POISON
+                 ? getPOISON(VT)
+                 : getConstant(0, DL, VT); // fold op(arg1, undef) -> 0
     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)

@llvmbot
Copy link
Member

llvmbot commented Apr 11, 2025

@llvm/pr-subscribers-llvm-selectiondag

Author: zhijian lin (diggerlin)

Changes

Propagation to poison in function SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &amp;DL, EVT VT,SDValue N1, SDValue N2, const SDNodeFlags Flags) if N2 is poison.

The patch also revert the test cases which mentions in
llvm/test/CodeGen/X86/pr119158.ll


Full diff: https://github.com/llvm/llvm-project/pull/135387.diff

4 Files Affected:

  • (modified) llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp (+16-3)
  • (modified) llvm/test/CodeGen/X86/half.ll (+12-12)
  • (modified) llvm/test/CodeGen/X86/poison-ops.ll (-12)
  • (modified) llvm/test/CodeGen/X86/pr119158.ll (+3-4)
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index d6dcb3f15ae7c..4ad5efdcc0555 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -7586,6 +7586,14 @@ SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT,
     }
   }
 
+  /*
+  if (N2.getOpcode() == ISD::POISON) {
+    switch (Opcode) {
+    case ISD::ADD:
+      return getPOISON(VT);
+    }
+  }*/
+
   // Fold a bunch of operators when the RHS is undef.
   if (N2.isUndef()) {
     switch (Opcode) {
@@ -7601,16 +7609,21 @@ 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
+      return N2.getOpcode() == ISD::POISON
+                 ? getPOISON(VT)
+                 : getUNDEF(VT); // fold op(arg1, undef) -> undef
     case ISD::MUL:
     case ISD::AND:
     case ISD::SSUBSAT:
     case ISD::USUBSAT:
-      return getConstant(0, DL, VT);  // fold op(arg1, undef) -> 0
+      return N2.getOpcode() == ISD::POISON
+                 ? getPOISON(VT)
+                 : getConstant(0, DL, VT); // fold op(arg1, undef) -> 0
     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)

@diggerlin diggerlin changed the title [SelectionDAG] Propagation of poison to poison in two input operands getNode() if the second input operand is poison. [SelectionDAG] Propagation to poison in getNode()which has two input operands if the second input operand is poison. Apr 11, 2025
@diggerlin diggerlin changed the title [SelectionDAG] Propagation to poison in getNode()which has two input operands if the second input operand is poison. [SelectionDAG] Propagation to poison in getNode function which has two input operands if the second input operand is poison. Apr 11, 2025
@diggerlin diggerlin changed the title [SelectionDAG] Propagation to poison in getNode function which has two input operands if the second input operand is poison. [SelectionDAG] Propagate poison in getNode with two operands if the second is poison. Apr 11, 2025
Comment on lines 7589 to 7595
/*
if (N2.getOpcode() == ISD::POISON) {
switch (Opcode) {
case ISD::ADD:
return getPOISON(VT);
}
}*/
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Commented out code

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)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can return N2 instead of returning doing a new getPOISON

Copy link
Contributor Author

@diggerlin diggerlin Apr 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do not think we can guarantee N2.getValueType() is same as VT. using N2 instead of N2 is a risk,

@diggerlin diggerlin requested a review from arsenm April 14, 2025 14:20
@diggerlin diggerlin changed the title [SelectionDAG] Propagate poison in getNode with two operands if the second is poison. [SelectionDAG] Propagate poison in getNode with two operands if the input is poison. Apr 16, 2025
Copy link
Collaborator

@topperc topperc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Copy link
Contributor

@amy-kwan amy-kwan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think overall LGTM, but a question regarding the description:

Propagation to poison in function SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT,SDValue N1, SDValue N2, const SDNodeFlags Flags) if N2 is poison.

It doesn't need to be N2, right? Just as long as one of them is poison?

@@ -7573,15 +7573,18 @@ SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT,
} else {
switch (Opcode) {
case ISD::SUB:
return getUNDEF(VT); // fold op(undef, arg2) -> undef
// fold op(undef, arg2) -> undef, fold op(poison, arg2) ->poison.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment nit.

Suggested change
// fold op(undef, arg2) -> undef, fold op(poison, arg2) ->poison.
// fold op(undef, arg2) -> undef, fold op(poison, arg2) -> poison.

case ISD::OR:
case ISD::SADDSAT:
case ISD::UADDSAT:
return getAllOnesConstant(DL, VT);
return N2.getOpcode() == ISD::POISON ? getPOISON(VT)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: maybe we can add a similar comment, like the other cases?

diggerlin and others added 2 commits April 16, 2025 15:14
Co-authored-by: Amy Kwan <amy.kwan1@ibm.com>
Co-authored-by: Amy Kwan <amy.kwan1@ibm.com>
@diggerlin
Copy link
Contributor Author

I think overall LGTM, but a question regarding the description:

Propagation to poison in function SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT,SDValue N1, SDValue N2, const SDNodeFlags Flags) if N2 is poison.

It doesn't need to be N2, right? Just as long as one of them is poison?

changed , thanks

@diggerlin diggerlin requested a review from amy-kwan April 16, 2025 19:22
Copy link
Contributor

@amy-kwan amy-kwan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks Digger!

@diggerlin diggerlin merged commit 3dfdb4d into llvm:main Apr 17, 2025
11 checks passed
IanWood1 pushed a commit to IanWood1/llvm-project that referenced this pull request May 6, 2025
…nput is poison. (llvm#135387)

Propagation to poison in function `SDValue
SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT,SDValue
N1, SDValue N2, const SDNodeFlags Flags) ` if one of the input is
poison.
 
 The patch also revert the test cases
 llvm/test/CodeGen/X86/pr119158.ll
 llvm/test/CodeGen/X86/half.ll
 
which are mentioned in
llvm#125883 (comment)

---------

Co-authored-by: Amy Kwan <amy.kwan1@ibm.com>
IanWood1 pushed a commit to IanWood1/llvm-project that referenced this pull request May 6, 2025
…nput is poison. (llvm#135387)

Propagation to poison in function `SDValue
SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT,SDValue
N1, SDValue N2, const SDNodeFlags Flags) ` if one of the input is
poison.
 
 The patch also revert the test cases
 llvm/test/CodeGen/X86/pr119158.ll
 llvm/test/CodeGen/X86/half.ll
 
which are mentioned in
llvm#125883 (comment)

---------

Co-authored-by: Amy Kwan <amy.kwan1@ibm.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backend:X86 llvm:SelectionDAG SelectionDAGISel as well
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants