Index: lib/Target/X86/X86ISelDAGToDAG.cpp =================================================================== --- lib/Target/X86/X86ISelDAGToDAG.cpp +++ lib/Target/X86/X86ISelDAGToDAG.cpp @@ -522,6 +522,7 @@ case X86ISD::XOR: case X86ISD::OR: case ISD::ADD: + case ISD::SUB: case ISD::ADDCARRY: case ISD::AND: case ISD::OR: @@ -569,6 +570,11 @@ return false; } + // Prefer NEG over folding the load. + if ((U->getOpcode() == ISD::SUB || U->getOpcode() == X86ISD::SUB) && + isNullConstant(U->getOperand(0))) + return false; + // Don't fold load if this matches the BTS/BTR/BTC patterns. // BTS: (or X, (shl 1, n)) // BTR: (and X, (rotl -2, n)) Index: test/CodeGen/X86/2008-09-11-CoalescerBug2.ll =================================================================== --- test/CodeGen/X86/2008-09-11-CoalescerBug2.ll +++ test/CodeGen/X86/2008-09-11-CoalescerBug2.ll @@ -14,8 +14,8 @@ ; SOURCE-SCHED: cmpl ; SOURCE-SCHED: setg ; SOURCE-SCHED: movb -; SOURCE-SCHED: xorl -; SOURCE-SCHED: subl +; SOURCE-SCHED: movl +; SOURCE-SCHED: negl ; SOURCE-SCHED: testb ; SOURCE-SCHED: jne %0 = load i32, i32* @g_5, align 4 ; [#uses=1] Index: test/CodeGen/X86/2010-08-04-MaskedSignedCompare.ll =================================================================== --- test/CodeGen/X86/2010-08-04-MaskedSignedCompare.ll +++ test/CodeGen/X86/2010-08-04-MaskedSignedCompare.ll @@ -9,8 +9,8 @@ define i32 @main() nounwind { ; CHECK-LABEL: main: ; CHECK: # %bb.0: # %entry -; CHECK-NEXT: xorl %eax, %eax -; CHECK-NEXT: cmpq {{.*}}(%rip), %rax +; CHECK-NEXT: movq {{.*}}(%rip), %rax +; CHECK-NEXT: negq %rax ; CHECK-NEXT: sbbl %eax, %eax ; CHECK-NEXT: andl $150, %eax ; CHECK-NEXT: testb %al, %al Index: test/CodeGen/X86/add.ll =================================================================== --- test/CodeGen/X86/add.ll +++ test/CodeGen/X86/add.ll @@ -386,8 +386,8 @@ define i32 @inc_not(i32 %a) { ; X32-LABEL: inc_not: ; X32: # %bb.0: -; X32-NEXT: xorl %eax, %eax -; X32-NEXT: subl {{[0-9]+}}(%esp), %eax +; X32-NEXT: movl {{[0-9]+}}(%esp), %eax +; X32-NEXT: negl %eax ; X32-NEXT: retl ; ; X64-LINUX-LABEL: inc_not: @@ -411,8 +411,8 @@ ; X32: # %bb.0: ; X32-NEXT: movl {{[0-9]+}}(%esp), %eax ; X32-NEXT: movl {{[0-9]+}}(%esp), %ecx -; X32-NEXT: xorl %edx, %edx -; X32-NEXT: subl {{[0-9]+}}(%esp), %edx +; X32-NEXT: movl {{[0-9]+}}(%esp), %edx +; X32-NEXT: negl %edx ; X32-NEXT: movl %edx, (%ecx) ; X32-NEXT: setae (%eax) ; X32-NEXT: retl Index: test/CodeGen/X86/imul.ll =================================================================== --- test/CodeGen/X86/imul.ll +++ test/CodeGen/X86/imul.ll @@ -274,8 +274,8 @@ ; ; X86-LABEL: mul4294967295_32: ; X86: # %bb.0: -; X86-NEXT: xorl %eax, %eax -; X86-NEXT: subl {{[0-9]+}}(%esp), %eax +; X86-NEXT: movl {{[0-9]+}}(%esp), %eax +; X86-NEXT: negl %eax ; X86-NEXT: retl %mul = mul i32 %A, 4294967295 ret i32 %mul @@ -290,9 +290,9 @@ ; ; X86-LABEL: mul18446744073709551615_64: ; X86: # %bb.0: +; X86-NEXT: movl {{[0-9]+}}(%esp), %eax ; X86-NEXT: xorl %edx, %edx -; X86-NEXT: xorl %eax, %eax -; X86-NEXT: subl {{[0-9]+}}(%esp), %eax +; X86-NEXT: negl %eax ; X86-NEXT: sbbl {{[0-9]+}}(%esp), %edx ; X86-NEXT: retl %mul = mul i64 %A, 18446744073709551615 Index: test/CodeGen/X86/merge-consecutive-stores.ll =================================================================== --- test/CodeGen/X86/merge-consecutive-stores.ll +++ test/CodeGen/X86/merge-consecutive-stores.ll @@ -10,10 +10,11 @@ ; CHECK-NEXT: movl {{[0-9]+}}(%esp), %eax ; CHECK-NEXT: movl $0, 28(%eax) ; CHECK-NEXT: movl $0, 24(%eax) -; CHECK-NEXT: xorl %ecx, %ecx -; CHECK-NEXT: cmpl 16(%eax), %ecx +; CHECK-NEXT: movl 16(%eax), %ecx ; CHECK-NEXT: movl $0, 16(%eax) -; CHECK-NEXT: sbbl 20(%eax), %ecx +; CHECK-NEXT: xorl %edx, %edx +; CHECK-NEXT: negl %ecx +; CHECK-NEXT: sbbl 20(%eax), %edx ; CHECK-NEXT: movl $0, 20(%eax) ; CHECK-NEXT: setl %al ; CHECK-NEXT: movzbl %al, %eax Index: test/CodeGen/X86/subcarry.ll =================================================================== --- test/CodeGen/X86/subcarry.ll +++ test/CodeGen/X86/subcarry.ll @@ -37,17 +37,17 @@ define %S @negate(%S* nocapture readonly %this) { ; CHECK-LABEL: negate: ; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movq (%rsi), %rax ; CHECK-NEXT: xorl %r8d, %r8d -; CHECK-NEXT: xorl %ecx, %ecx -; CHECK-NEXT: subq (%rsi), %rcx +; CHECK-NEXT: negq %rax ; CHECK-NEXT: movl $0, %edx ; CHECK-NEXT: sbbq 8(%rsi), %rdx -; CHECK-NEXT: movl $0, %eax -; CHECK-NEXT: sbbq 16(%rsi), %rax +; CHECK-NEXT: movl $0, %ecx +; CHECK-NEXT: sbbq 16(%rsi), %rcx ; CHECK-NEXT: sbbq 24(%rsi), %r8 -; CHECK-NEXT: movq %rcx, (%rdi) +; CHECK-NEXT: movq %rax, (%rdi) ; CHECK-NEXT: movq %rdx, 8(%rdi) -; CHECK-NEXT: movq %rax, 16(%rdi) +; CHECK-NEXT: movq %rcx, 16(%rdi) ; CHECK-NEXT: movq %r8, 24(%rdi) ; CHECK-NEXT: movq %rdi, %rax ; CHECK-NEXT: retq