diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index f4caaf426de6a..77870f29759aa 100644 --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -9702,7 +9702,7 @@ SDValue DAGCombiner::visitXOR(SDNode *N) { } // fold (not (add X, -1)) -> (neg X) - if (isAllOnesConstant(N1) && N0.getOpcode() == ISD::ADD && + if (N0.getOpcode() == ISD::ADD && N0.hasOneUse() && isAllOnesConstant(N1) && isAllOnesOrAllOnesSplat(N0.getOperand(1))) { return DAG.getNegative(N0.getOperand(0), DL, VT); } diff --git a/llvm/test/CodeGen/AArch64/align-down.ll b/llvm/test/CodeGen/AArch64/align-down.ll index 4b1cdfd2770f6..96e2a5d7d33f7 100644 --- a/llvm/test/CodeGen/AArch64/align-down.ll +++ b/llvm/test/CodeGen/AArch64/align-down.ll @@ -54,10 +54,9 @@ define i32 @t2_commutative(i32 %ptr, i32 %alignment) nounwind { define i32 @t3_extrause0(i32 %ptr, i32 %alignment, ptr %mask_storage) nounwind { ; CHECK-LABEL: t3_extrause0: ; CHECK: // %bb.0: -; CHECK-NEXT: neg w8, w1 -; CHECK-NEXT: sub w9, w1, #1 -; CHECK-NEXT: and w0, w0, w8 -; CHECK-NEXT: str w9, [x2] +; CHECK-NEXT: sub w8, w1, #1 +; CHECK-NEXT: bic w0, w0, w8 +; CHECK-NEXT: str w8, [x2] ; CHECK-NEXT: ret %mask = add i32 %alignment, -1 store i32 %mask, ptr %mask_storage diff --git a/llvm/test/CodeGen/X86/align-down.ll b/llvm/test/CodeGen/X86/align-down.ll index 3c64e108e06dd..c359c04f527a3 100644 --- a/llvm/test/CodeGen/X86/align-down.ll +++ b/llvm/test/CodeGen/X86/align-down.ll @@ -82,25 +82,40 @@ define i32 @t2_commutative(i32 %ptr, i32 %alignment) nounwind { ; Extra use tests define i32 @t3_extrause0(i32 %ptr, i32 %alignment, ptr %mask_storage) nounwind { -; X86-LABEL: t3_extrause0: -; X86: # %bb.0: -; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx -; X86-NEXT: movl {{[0-9]+}}(%esp), %eax -; X86-NEXT: leal -1(%eax), %edx -; X86-NEXT: movl %edx, (%ecx) -; X86-NEXT: negl %eax -; X86-NEXT: andl {{[0-9]+}}(%esp), %eax -; X86-NEXT: retl +; NOBMI-X86-LABEL: t3_extrause0: +; NOBMI-X86: # %bb.0: +; NOBMI-X86-NEXT: movl {{[0-9]+}}(%esp), %ecx +; NOBMI-X86-NEXT: movl {{[0-9]+}}(%esp), %eax +; NOBMI-X86-NEXT: decl %eax +; NOBMI-X86-NEXT: movl %eax, (%ecx) +; NOBMI-X86-NEXT: notl %eax +; NOBMI-X86-NEXT: andl {{[0-9]+}}(%esp), %eax +; NOBMI-X86-NEXT: retl ; -; X64-LABEL: t3_extrause0: -; X64: # %bb.0: -; X64-NEXT: movl %esi, %eax -; X64-NEXT: leal -1(%rax), %ecx -; X64-NEXT: movl %ecx, (%rdx) -; X64-NEXT: negl %eax -; X64-NEXT: andl %edi, %eax -; X64-NEXT: # kill: def $eax killed $eax killed $rax -; X64-NEXT: retq +; BMI-X86-LABEL: t3_extrause0: +; BMI-X86: # %bb.0: +; BMI-X86-NEXT: movl {{[0-9]+}}(%esp), %eax +; BMI-X86-NEXT: movl {{[0-9]+}}(%esp), %ecx +; BMI-X86-NEXT: decl %ecx +; BMI-X86-NEXT: movl %ecx, (%eax) +; BMI-X86-NEXT: andnl {{[0-9]+}}(%esp), %ecx, %eax +; BMI-X86-NEXT: retl +; +; NOBMI-X64-LABEL: t3_extrause0: +; NOBMI-X64: # %bb.0: +; NOBMI-X64-NEXT: # kill: def $esi killed $esi def $rsi +; NOBMI-X64-NEXT: leal -1(%rsi), %eax +; NOBMI-X64-NEXT: movl %eax, (%rdx) +; NOBMI-X64-NEXT: notl %eax +; NOBMI-X64-NEXT: andl %edi, %eax +; NOBMI-X64-NEXT: retq +; +; BMI-X64-LABEL: t3_extrause0: +; BMI-X64: # %bb.0: +; BMI-X64-NEXT: decl %esi +; BMI-X64-NEXT: movl %esi, (%rdx) +; BMI-X64-NEXT: andnl %edi, %esi, %eax +; BMI-X64-NEXT: retq %mask = add i32 %alignment, -1 store i32 %mask, ptr %mask_storage %bias = and i32 %ptr, %mask diff --git a/llvm/test/CodeGen/X86/not-of-dec.ll b/llvm/test/CodeGen/X86/not-of-dec.ll index 9790649503123..29461619ac805 100644 --- a/llvm/test/CodeGen/X86/not-of-dec.ll +++ b/llvm/test/CodeGen/X86/not-of-dec.ll @@ -57,18 +57,17 @@ define i32 @t2_extrause(i32 %alignment, ptr %mask_storage) nounwind { ; X86: # %bb.0: ; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax -; X86-NEXT: leal -1(%eax), %edx -; X86-NEXT: movl %edx, (%ecx) -; X86-NEXT: negl %eax +; X86-NEXT: decl %eax +; X86-NEXT: movl %eax, (%ecx) +; X86-NEXT: notl %eax ; X86-NEXT: retl ; ; X64-LABEL: t2_extrause: ; X64: # %bb.0: -; X64-NEXT: movl %edi, %eax -; X64-NEXT: leal -1(%rax), %ecx -; X64-NEXT: movl %ecx, (%rsi) -; X64-NEXT: negl %eax -; X64-NEXT: # kill: def $eax killed $eax killed $rax +; X64-NEXT: # kill: def $edi killed $edi def $rdi +; X64-NEXT: leal -1(%rdi), %eax +; X64-NEXT: movl %eax, (%rsi) +; X64-NEXT: notl %eax ; X64-NEXT: retq %mask = add i32 %alignment, -1 store i32 %mask, ptr %mask_storage