diff --git a/llvm/test/CodeGen/X86/add-and-not.ll b/llvm/test/CodeGen/X86/add-and-not.ll new file mode 100644 index 0000000000000..98f9f1ae4be79 --- /dev/null +++ b/llvm/test/CodeGen/X86/add-and-not.ll @@ -0,0 +1,122 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc < %s -mtriple=x86_64-linux | FileCheck %s + +declare void @use(i8) + +define i8 @add_and_xor(i8 %x, i8 %y) { +; CHECK-LABEL: add_and_xor: +; CHECK: # %bb.0: +; CHECK-NEXT: movl %edi, %eax +; CHECK-NEXT: notb %al +; CHECK-NEXT: andb %sil, %al +; CHECK-NEXT: addb %dil, %al +; CHECK-NEXT: retq + %xor = xor i8 %x, -1 + %and = and i8 %xor, %y + %add = add i8 %and, %x + ret i8 %add +} + +define i8 @add_and_xor_wrong_const(i8 %x, i8 %y) { +; CHECK-LABEL: add_and_xor_wrong_const: +; CHECK: # %bb.0: +; CHECK-NEXT: movl %edi, %eax +; CHECK-NEXT: xorb $-2, %al +; CHECK-NEXT: andb %sil, %al +; CHECK-NEXT: addb %dil, %al +; CHECK-NEXT: retq + %xor = xor i8 %x, -2 + %and = and i8 %xor, %y + %add = add i8 %and, %x + ret i8 %add +} + +define i8 @add_and_xor_wrong_op(i8 %x, i8 %y, i8 %z) { +; CHECK-LABEL: add_and_xor_wrong_op: +; CHECK: # %bb.0: +; CHECK-NEXT: # kill: def $edx killed $edx def $rdx +; CHECK-NEXT: # kill: def $edi killed $edi def $rdi +; CHECK-NEXT: notb %dl +; CHECK-NEXT: andb %sil, %dl +; CHECK-NEXT: leal (%rdx,%rdi), %eax +; CHECK-NEXT: # kill: def $al killed $al killed $eax +; CHECK-NEXT: retq + %xor = xor i8 %z, -1 + %and = and i8 %xor, %y + %add = add i8 %and, %x + ret i8 %add +} + +define i8 @add_and_xor_commuted1(i8 %x, i8 %y) { +; CHECK-LABEL: add_and_xor_commuted1: +; CHECK: # %bb.0: +; CHECK-NEXT: movl %edi, %eax +; CHECK-NEXT: notb %al +; CHECK-NEXT: andb %sil, %al +; CHECK-NEXT: addb %dil, %al +; CHECK-NEXT: retq + %xor = xor i8 %x, -1 + %and = and i8 %y, %xor + %add = add i8 %and, %x + ret i8 %add +} + +define i8 @add_and_xor_commuted2(i8 %x, i8 %y) { +; CHECK-LABEL: add_and_xor_commuted2: +; CHECK: # %bb.0: +; CHECK-NEXT: movl %edi, %eax +; CHECK-NEXT: notb %al +; CHECK-NEXT: andb %sil, %al +; CHECK-NEXT: addb %dil, %al +; CHECK-NEXT: retq + %xor = xor i8 %x, -1 + %and = and i8 %xor, %y + %add = add i8 %x, %and + ret i8 %add +} + +define i8 @add_and_xor_commuted3(i8 %x, i8 %y) { +; CHECK-LABEL: add_and_xor_commuted3: +; CHECK: # %bb.0: +; CHECK-NEXT: movl %edi, %eax +; CHECK-NEXT: notb %al +; CHECK-NEXT: andb %sil, %al +; CHECK-NEXT: addb %dil, %al +; CHECK-NEXT: retq + %xor = xor i8 %x, -1 + %and = and i8 %y, %xor + %add = add i8 %x, %and + ret i8 %add +} + +define i8 @add_and_xor_extra_use(i8 %x, i8 %y) nounwind { +; CHECK-LABEL: add_and_xor_extra_use: +; CHECK: # %bb.0: +; CHECK-NEXT: pushq %rbp +; CHECK-NEXT: pushq %r14 +; CHECK-NEXT: pushq %rbx +; CHECK-NEXT: movl %esi, %r14d +; CHECK-NEXT: movl %edi, %ebp +; CHECK-NEXT: movl %ebp, %eax +; CHECK-NEXT: notb %al +; CHECK-NEXT: movzbl %al, %ebx +; CHECK-NEXT: movl %ebx, %edi +; CHECK-NEXT: callq use@PLT +; CHECK-NEXT: andb %r14b, %bl +; CHECK-NEXT: movzbl %bl, %ebx +; CHECK-NEXT: movl %ebx, %edi +; CHECK-NEXT: callq use@PLT +; CHECK-NEXT: addb %bpl, %bl +; CHECK-NEXT: movl %ebx, %eax +; CHECK-NEXT: popq %rbx +; CHECK-NEXT: popq %r14 +; CHECK-NEXT: popq %rbp +; CHECK-NEXT: retq + %xor = xor i8 %x, -1 + call void @use(i8 %xor) + %and = and i8 %xor, %y + call void @use(i8 %and) + %add = add i8 %and, %x + ret i8 %add +} +