1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc < %s -mtriple=i686-unknown-unknown -mattr=+sse,+sse2,+slow-lea,+slow-3ops-lea | FileCheck %s --check-prefixes=ALL,X86,X86-SLOWLEA 3; RUN: llc < %s -mtriple=i686-unknown-unknown -mattr=+sse,+sse2,-slow-lea,-slow-3ops-lea | FileCheck %s --check-prefixes=ALL,X86,X86-FASTLEA 4; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+sse,+sse2,+slow-lea,+slow-3ops-lea | FileCheck %s --check-prefixes=ALL,X64 5; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+sse,+sse2,-slow-lea,-slow-3ops-lea | FileCheck %s --check-prefixes=ALL,X64 6 7; These two forms are equivalent: 8; sub %y, (xor %x, -1) 9; add (add %x, 1), %y 10; Some targets may prefer one to the other. 11 12define i8 @scalar_i8(i8 %x, i8 %y) nounwind { 13; X86-LABEL: scalar_i8: 14; X86: # %bb.0: 15; X86-NEXT: movb {{[0-9]+}}(%esp), %al 16; X86-NEXT: addb {{[0-9]+}}(%esp), %al 17; X86-NEXT: incb %al 18; X86-NEXT: retl 19; 20; X64-LABEL: scalar_i8: 21; X64: # %bb.0: 22; X64-NEXT: # kill: def $esi killed $esi def $rsi 23; X64-NEXT: # kill: def $edi killed $edi def $rdi 24; X64-NEXT: leal (%rsi,%rdi), %eax 25; X64-NEXT: incb %al 26; X64-NEXT: # kill: def $al killed $al killed $eax 27; X64-NEXT: retq 28 %t0 = xor i8 %x, -1 29 %t1 = sub i8 %y, %t0 30 ret i8 %t1 31} 32 33define i16 @scalar_i16(i16 %x, i16 %y) nounwind { 34; X86-LABEL: scalar_i16: 35; X86: # %bb.0: 36; X86-NEXT: movzwl {{[0-9]+}}(%esp), %eax 37; X86-NEXT: addw {{[0-9]+}}(%esp), %ax 38; X86-NEXT: incl %eax 39; X86-NEXT: # kill: def $ax killed $ax killed $eax 40; X86-NEXT: retl 41; 42; X64-LABEL: scalar_i16: 43; X64: # %bb.0: 44; X64-NEXT: # kill: def $esi killed $esi def $rsi 45; X64-NEXT: # kill: def $edi killed $edi def $rdi 46; X64-NEXT: leal 1(%rsi,%rdi), %eax 47; X64-NEXT: # kill: def $ax killed $ax killed $eax 48; X64-NEXT: retq 49 %t0 = xor i16 %x, -1 50 %t1 = sub i16 %y, %t0 51 ret i16 %t1 52} 53 54define i32 @scalar_i32(i32 %x, i32 %y) nounwind { 55; X86-SLOWLEA-LABEL: scalar_i32: 56; X86-SLOWLEA: # %bb.0: 57; X86-SLOWLEA-NEXT: movl {{[0-9]+}}(%esp), %eax 58; X86-SLOWLEA-NEXT: movl {{[0-9]+}}(%esp), %ecx 59; X86-SLOWLEA-NEXT: addl %ecx, %eax 60; X86-SLOWLEA-NEXT: addl $1, %eax 61; X86-SLOWLEA-NEXT: retl 62; 63; X86-FASTLEA-LABEL: scalar_i32: 64; X86-FASTLEA: # %bb.0: 65; X86-FASTLEA-NEXT: movl {{[0-9]+}}(%esp), %eax 66; X86-FASTLEA-NEXT: movl {{[0-9]+}}(%esp), %ecx 67; X86-FASTLEA-NEXT: leal 1(%ecx,%eax), %eax 68; X86-FASTLEA-NEXT: retl 69; 70; X64-LABEL: scalar_i32: 71; X64: # %bb.0: 72; X64-NEXT: # kill: def $esi killed $esi def $rsi 73; X64-NEXT: # kill: def $edi killed $edi def $rdi 74; X64-NEXT: leal 1(%rsi,%rdi), %eax 75; X64-NEXT: retq 76 %t0 = xor i32 %x, -1 77 %t1 = sub i32 %y, %t0 78 ret i32 %t1 79} 80 81define i64 @scalar_i64(i64 %x, i64 %y) nounwind { 82; X86-LABEL: scalar_i64: 83; X86: # %bb.0: 84; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 85; X86-NEXT: movl {{[0-9]+}}(%esp), %edx 86; X86-NEXT: addl {{[0-9]+}}(%esp), %eax 87; X86-NEXT: adcl {{[0-9]+}}(%esp), %edx 88; X86-NEXT: addl $1, %eax 89; X86-NEXT: adcl $0, %edx 90; X86-NEXT: retl 91; 92; X64-LABEL: scalar_i64: 93; X64: # %bb.0: 94; X64-NEXT: leaq 1(%rsi,%rdi), %rax 95; X64-NEXT: retq 96 %t0 = xor i64 %x, -1 97 %t1 = sub i64 %y, %t0 98 ret i64 %t1 99} 100 101define <16 x i8> @vector_i128_i8(<16 x i8> %x, <16 x i8> %y) nounwind { 102; ALL-LABEL: vector_i128_i8: 103; ALL: # %bb.0: 104; ALL-NEXT: paddb %xmm1, %xmm0 105; ALL-NEXT: pcmpeqd %xmm1, %xmm1 106; ALL-NEXT: psubb %xmm1, %xmm0 107; ALL-NEXT: ret{{[l|q]}} 108 %t0 = xor <16 x i8> %x, <i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1> 109 %t1 = sub <16 x i8> %y, %t0 110 ret <16 x i8> %t1 111} 112 113define <8 x i16> @vector_i128_i16(<8 x i16> %x, <8 x i16> %y) nounwind { 114; ALL-LABEL: vector_i128_i16: 115; ALL: # %bb.0: 116; ALL-NEXT: paddw %xmm1, %xmm0 117; ALL-NEXT: pcmpeqd %xmm1, %xmm1 118; ALL-NEXT: psubw %xmm1, %xmm0 119; ALL-NEXT: ret{{[l|q]}} 120 %t0 = xor <8 x i16> %x, <i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1> 121 %t1 = sub <8 x i16> %y, %t0 122 ret <8 x i16> %t1 123} 124 125define <4 x i32> @vector_i128_i32(<4 x i32> %x, <4 x i32> %y) nounwind { 126; ALL-LABEL: vector_i128_i32: 127; ALL: # %bb.0: 128; ALL-NEXT: paddd %xmm1, %xmm0 129; ALL-NEXT: pcmpeqd %xmm1, %xmm1 130; ALL-NEXT: psubd %xmm1, %xmm0 131; ALL-NEXT: ret{{[l|q]}} 132 %t0 = xor <4 x i32> %x, <i32 -1, i32 -1, i32 -1, i32 -1> 133 %t1 = sub <4 x i32> %y, %t0 134 ret <4 x i32> %t1 135} 136 137define <2 x i64> @vector_i128_i64(<2 x i64> %x, <2 x i64> %y) nounwind { 138; ALL-LABEL: vector_i128_i64: 139; ALL: # %bb.0: 140; ALL-NEXT: paddq %xmm1, %xmm0 141; ALL-NEXT: pcmpeqd %xmm1, %xmm1 142; ALL-NEXT: psubq %xmm1, %xmm0 143; ALL-NEXT: ret{{[l|q]}} 144 %t0 = xor <2 x i64> %x, <i64 -1, i64 -1> 145 %t1 = sub <2 x i64> %y, %t0 146 ret <2 x i64> %t1 147} 148