diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index 0ea0c0df7f372..a21b9acad7da2 100644 --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -2831,9 +2831,9 @@ SDValue DAGCombiner::visitADDLike(SDNode *N) { // (x - y) + -1 -> add (xor y, -1), x if (N0.getOpcode() == ISD::SUB && N0.hasOneUse() && - isAllOnesOrAllOnesSplat(N1)) { - SDValue Xor = DAG.getNode(ISD::XOR, DL, VT, N0.getOperand(1), N1); - return DAG.getNode(ISD::ADD, DL, VT, Xor, N0.getOperand(0)); + isAllOnesOrAllOnesSplat(N1, /*AllowUndefs=*/true)) { + SDValue Not = DAG.getNOT(DL, N0.getOperand(1), VT); + return DAG.getNode(ISD::ADD, DL, VT, Not, N0.getOperand(0)); } if (SDValue Combined = visitADDLikeCommutative(N0, N1, N)) diff --git a/llvm/test/CodeGen/AArch64/xor.ll b/llvm/test/CodeGen/AArch64/xor.ll index 1379bcb78e24b..08557c8cd9c4a 100644 --- a/llvm/test/CodeGen/AArch64/xor.ll +++ b/llvm/test/CodeGen/AArch64/xor.ll @@ -61,9 +61,8 @@ define <4 x i32> @vec_add_of_not_decrement(<4 x i32> %x, <4 x i32> %y) { define <4 x i32> @vec_add_of_not_with_undef(<4 x i32> %x, <4 x i32> %y) { ; CHECK-LABEL: vec_add_of_not_with_undef: ; CHECK: // %bb.0: -; CHECK-NEXT: movi v2.2d, #0xffffffffffffffff -; CHECK-NEXT: sub v0.4s, v0.4s, v1.4s -; CHECK-NEXT: add v0.4s, v0.4s, v2.4s +; CHECK-NEXT: mvn v1.16b, v1.16b +; CHECK-NEXT: add v0.4s, v1.4s, v0.4s ; CHECK-NEXT: ret %t0 = sub <4 x i32> %x, %y %r = add <4 x i32> %t0, diff --git a/llvm/test/CodeGen/X86/xor.ll b/llvm/test/CodeGen/X86/xor.ll index 62b39786787a3..7f4006792ef1a 100644 --- a/llvm/test/CodeGen/X86/xor.ll +++ b/llvm/test/CodeGen/X86/xor.ll @@ -627,24 +627,23 @@ define <4 x i32> @vec_add_of_not_decrement(<4 x i32> %x, <4 x i32> %y) { define <4 x i32> @vec_add_of_not_with_undef(<4 x i32> %x, <4 x i32> %y) { ; X86-LABEL: vec_add_of_not_with_undef: ; X86: # %bb.0: -; X86-NEXT: psubd %xmm1, %xmm0 -; X86-NEXT: pcmpeqd %xmm1, %xmm1 -; X86-NEXT: paddd %xmm1, %xmm0 +; X86-NEXT: pcmpeqd %xmm2, %xmm2 +; X86-NEXT: pxor %xmm1, %xmm2 +; X86-NEXT: paddd %xmm2, %xmm0 ; X86-NEXT: retl ; ; X64-LIN-LABEL: vec_add_of_not_with_undef: ; X64-LIN: # %bb.0: -; X64-LIN-NEXT: psubd %xmm1, %xmm0 -; X64-LIN-NEXT: pcmpeqd %xmm1, %xmm1 -; X64-LIN-NEXT: paddd %xmm1, %xmm0 +; X64-LIN-NEXT: pcmpeqd %xmm2, %xmm2 +; X64-LIN-NEXT: pxor %xmm1, %xmm2 +; X64-LIN-NEXT: paddd %xmm2, %xmm0 ; X64-LIN-NEXT: retq ; ; X64-WIN-LABEL: vec_add_of_not_with_undef: ; X64-WIN: # %bb.0: -; X64-WIN-NEXT: movdqa (%rcx), %xmm1 -; X64-WIN-NEXT: psubd (%rdx), %xmm1 ; X64-WIN-NEXT: pcmpeqd %xmm0, %xmm0 -; X64-WIN-NEXT: paddd %xmm1, %xmm0 +; X64-WIN-NEXT: pxor (%rdx), %xmm0 +; X64-WIN-NEXT: paddd (%rcx), %xmm0 ; X64-WIN-NEXT: retq %t0 = sub <4 x i32> %x, %y %r = add <4 x i32> %t0,