diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index d6dcb3f15ae7c..e95e7fe251463 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -7573,7 +7573,8 @@ 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. + return N1.getOpcode() == ISD::POISON ? getPOISON(VT) : getUNDEF(VT); case ISD::SIGN_EXTEND_INREG: case ISD::UDIV: case ISD::SDIV: @@ -7581,7 +7582,9 @@ SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT, case ISD::SREM: case ISD::SSUBSAT: case ISD::USUBSAT: - return getConstant(0, DL, VT); // fold op(undef, arg2) -> 0 + // fold op(undef, arg2) -> 0, fold op(poison, arg2) -> poison. + return N1.getOpcode() == ISD::POISON ? getPOISON(VT) + : getConstant(0, DL, VT); } } } @@ -7601,16 +7604,22 @@ 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); + // fold op(arg1, undef) -> an all-ones constant, fold op(arg1, poison) -> + // poison. + 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> diff --git a/llvm/test/CodeGen/X86/poison-ops.ll b/llvm/test/CodeGen/X86/poison-ops.ll index 3cd2ceb125ce8..636a42fd06e26 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 @@ -120,7 +116,6 @@ define <4 x i32> @sdiv_poison_rhs_vec(<4 x i32> %x) { define i32 @sdiv_poison_lhs(i32 %x) { ; CHECK-LABEL: sdiv_poison_lhs: ; CHECK: # %bb.0: -; CHECK-NEXT: xorl %eax, %eax ; CHECK-NEXT: retq %r = sdiv i32 poison, %x ret i32 %r @@ -129,7 +124,6 @@ define i32 @sdiv_poison_lhs(i32 %x) { define <4 x i32> @sdiv_poison_lhs_vec(<4 x i32> %x) { ; CHECK-LABEL: sdiv_poison_lhs_vec: ; CHECK: # %bb.0: -; CHECK-NEXT: xorps %xmm0, %xmm0 ; CHECK-NEXT: retq %r = sdiv <4 x i32> poison, %x ret <4 x i32> %r @@ -154,7 +148,6 @@ define <4 x i32> @udiv_poison_rhs_vec(<4 x i32> %x) { define i32 @udiv_poison_lhs(i32 %x) { ; CHECK-LABEL: udiv_poison_lhs: ; CHECK: # %bb.0: -; CHECK-NEXT: xorl %eax, %eax ; CHECK-NEXT: retq %r = udiv i32 poison, %x ret i32 %r @@ -163,7 +156,6 @@ define i32 @udiv_poison_lhs(i32 %x) { define <4 x i32> @udiv_poison_lhs_vec(<4 x i32> %x) { ; CHECK-LABEL: udiv_poison_lhs_vec: ; CHECK: # %bb.0: -; CHECK-NEXT: xorps %xmm0, %xmm0 ; CHECK-NEXT: retq %r = udiv <4 x i32> poison, %x ret <4 x i32> %r @@ -188,7 +180,6 @@ define <4 x i32> @srem_poison_rhs_vec(<4 x i32> %x) { define i32 @srem_poison_lhs(i32 %x) { ; CHECK-LABEL: srem_poison_lhs: ; CHECK: # %bb.0: -; CHECK-NEXT: xorl %eax, %eax ; CHECK-NEXT: retq %r = srem i32 poison, %x ret i32 %r @@ -197,7 +188,6 @@ define i32 @srem_poison_lhs(i32 %x) { define <4 x i32> @srem_poison_lhs_vec(<4 x i32> %x) { ; CHECK-LABEL: srem_poison_lhs_vec: ; CHECK: # %bb.0: -; CHECK-NEXT: xorps %xmm0, %xmm0 ; CHECK-NEXT: retq %r = srem <4 x i32> poison, %x ret <4 x i32> %r @@ -222,7 +212,6 @@ define <4 x i32> @urem_poison_rhs_vec(<4 x i32> %x) { define i32 @urem_poison_lhs(i32 %x) { ; CHECK-LABEL: urem_poison_lhs: ; CHECK: # %bb.0: -; CHECK-NEXT: xorl %eax, %eax ; CHECK-NEXT: retq %r = urem i32 poison, %x ret i32 %r @@ -231,7 +220,6 @@ define i32 @urem_poison_lhs(i32 %x) { define <4 x i32> @urem_poison_lhs_vec(<4 x i32> %x) { ; CHECK-LABEL: urem_poison_lhs_vec: ; CHECK: # %bb.0: -; CHECK-NEXT: xorps %xmm0, %xmm0 ; CHECK-NEXT: retq %r = urem <4 x i32> poison, %x ret <4 x i32> %r @@ -342,7 +330,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 +338,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 +346,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 +354,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 +362,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 +370,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 +378,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 +386,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)