1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+sse2 | FileCheck %s --check-prefix=SSE --check-prefix=SSE2 3; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+sse4.2 | FileCheck %s --check-prefix=SSE --check-prefix=SSE42 4; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx | FileCheck %s --check-prefix=AVX --check-prefix=AVX1 5; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx2 | FileCheck %s --check-prefix=AVX --check-prefix=AVX2 6 7; Lower common integer comparisons such as 'isPositive' efficiently: 8; https://llvm.org/bugs/show_bug.cgi?id=26701 9 10define <16 x i8> @test_pcmpgtb(<16 x i8> %x) { 11; SSE-LABEL: test_pcmpgtb: 12; SSE: # BB#0: 13; SSE-NEXT: pcmpeqd %xmm1, %xmm1 14; SSE-NEXT: pcmpgtb %xmm1, %xmm0 15; SSE-NEXT: retq 16; 17; AVX-LABEL: test_pcmpgtb: 18; AVX: # BB#0: 19; AVX-NEXT: vpcmpeqd %xmm1, %xmm1, %xmm1 20; AVX-NEXT: vpcmpgtb %xmm1, %xmm0, %xmm0 21; AVX-NEXT: retq 22 %sign = ashr <16 x i8> %x, <i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7> 23 %not = xor <16 x i8> %sign, <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> 24 ret <16 x i8> %not 25} 26 27define <8 x i16> @test_pcmpgtw(<8 x i16> %x) { 28; SSE-LABEL: test_pcmpgtw: 29; SSE: # BB#0: 30; SSE-NEXT: pcmpeqd %xmm1, %xmm1 31; SSE-NEXT: pcmpgtw %xmm1, %xmm0 32; SSE-NEXT: retq 33; 34; AVX-LABEL: test_pcmpgtw: 35; AVX: # BB#0: 36; AVX-NEXT: vpcmpeqd %xmm1, %xmm1, %xmm1 37; AVX-NEXT: vpcmpgtw %xmm1, %xmm0, %xmm0 38; AVX-NEXT: retq 39 %sign = ashr <8 x i16> %x, <i16 15, i16 15, i16 15, i16 15, i16 15, i16 15, i16 15, i16 15> 40 %not = xor <8 x i16> %sign, <i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1> 41 ret <8 x i16> %not 42} 43 44define <4 x i32> @test_pcmpgtd(<4 x i32> %x) { 45; SSE-LABEL: test_pcmpgtd: 46; SSE: # BB#0: 47; SSE-NEXT: pcmpeqd %xmm1, %xmm1 48; SSE-NEXT: pcmpgtd %xmm1, %xmm0 49; SSE-NEXT: retq 50; 51; AVX-LABEL: test_pcmpgtd: 52; AVX: # BB#0: 53; AVX-NEXT: vpcmpeqd %xmm1, %xmm1, %xmm1 54; AVX-NEXT: vpcmpgtd %xmm1, %xmm0, %xmm0 55; AVX-NEXT: retq 56 %sign = ashr <4 x i32> %x, <i32 31, i32 31, i32 31, i32 31> 57 %not = xor <4 x i32> %sign, <i32 -1, i32 -1, i32 -1, i32 -1> 58 ret <4 x i32> %not 59} 60 61define <2 x i64> @test_pcmpgtq(<2 x i64> %x) { 62; SSE2-LABEL: test_pcmpgtq: 63; SSE2: # BB#0: 64; SSE2-NEXT: psrad $31, %xmm0 65; SSE2-NEXT: pshufd {{.*#+}} xmm1 = xmm0[1,1,3,3] 66; SSE2-NEXT: pcmpeqd %xmm0, %xmm0 67; SSE2-NEXT: pxor %xmm1, %xmm0 68; SSE2-NEXT: retq 69; 70; SSE42-LABEL: test_pcmpgtq: 71; SSE42: # BB#0: 72; SSE42-NEXT: pcmpeqd %xmm1, %xmm1 73; SSE42-NEXT: pcmpgtq %xmm1, %xmm0 74; SSE42-NEXT: retq 75; 76; AVX-LABEL: test_pcmpgtq: 77; AVX: # BB#0: 78; AVX-NEXT: vpcmpeqd %xmm1, %xmm1, %xmm1 79; AVX-NEXT: vpcmpgtq %xmm1, %xmm0, %xmm0 80; AVX-NEXT: retq 81 %sign = ashr <2 x i64> %x, <i64 63, i64 63> 82 %not = xor <2 x i64> %sign, <i64 -1, i64 -1> 83 ret <2 x i64> %not 84} 85 86define <1 x i128> @test_strange_type(<1 x i128> %x) { 87; SSE2-LABEL: test_strange_type: 88; SSE2: # BB#0: 89; SSE2-NEXT: sarq $63, %rsi 90; SSE2-NEXT: notq %rsi 91; SSE2-NEXT: movd %rsi, %xmm0 92; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm0[0,1,0,1] 93; SSE2-NEXT: movd %xmm0, %rax 94; SSE2-NEXT: movq %rsi, %rdx 95; SSE2-NEXT: retq 96; 97; SSE42-LABEL: test_strange_type: 98; SSE42: # BB#0: 99; SSE42-NEXT: sarq $63, %rsi 100; SSE42-NEXT: notq %rsi 101; SSE42-NEXT: movd %rsi, %xmm0 102; SSE42-NEXT: pshufd {{.*#+}} xmm0 = xmm0[0,1,0,1] 103; SSE42-NEXT: movd %xmm0, %rax 104; SSE42-NEXT: pextrq $1, %xmm0, %rdx 105; SSE42-NEXT: retq 106; 107; AVX1-LABEL: test_strange_type: 108; AVX1: # BB#0: 109; AVX1-NEXT: sarq $63, %rsi 110; AVX1-NEXT: notq %rsi 111; AVX1-NEXT: vmovq %rsi, %xmm0 112; AVX1-NEXT: vpshufd {{.*#+}} xmm0 = xmm0[0,1,0,1] 113; AVX1-NEXT: vmovq %xmm0, %rax 114; AVX1-NEXT: vpextrq $1, %xmm0, %rdx 115; AVX1-NEXT: retq 116; 117; AVX2-LABEL: test_strange_type: 118; AVX2: # BB#0: 119; AVX2-NEXT: sarq $63, %rsi 120; AVX2-NEXT: notq %rsi 121; AVX2-NEXT: vmovq %rsi, %xmm0 122; AVX2-NEXT: vpbroadcastq %xmm0, %xmm0 123; AVX2-NEXT: vmovq %xmm0, %rax 124; AVX2-NEXT: vpextrq $1, %xmm0, %rdx 125; AVX2-NEXT: retq 126 %sign = ashr <1 x i128> %x, <i128 127> 127 %not = xor <1 x i128> %sign, <i128 -1> 128 ret <1 x i128> %not 129} 130 131define <32 x i8> @test_pcmpgtb_256(<32 x i8> %x) { 132; SSE-LABEL: test_pcmpgtb_256: 133; SSE: # BB#0: 134; SSE-NEXT: pcmpeqd %xmm2, %xmm2 135; SSE-NEXT: pcmpgtb %xmm2, %xmm0 136; SSE-NEXT: pcmpgtb %xmm2, %xmm1 137; SSE-NEXT: retq 138; 139; AVX1-LABEL: test_pcmpgtb_256: 140; AVX1: # BB#0: 141; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm1 142; AVX1-NEXT: vpxor %xmm2, %xmm2, %xmm2 143; AVX1-NEXT: vpcmpgtb %xmm1, %xmm2, %xmm1 144; AVX1-NEXT: vpcmpgtb %xmm0, %xmm2, %xmm0 145; AVX1-NEXT: vinsertf128 $1, %xmm1, %ymm0, %ymm0 146; AVX1-NEXT: vpcmpeqd %xmm1, %xmm1, %xmm1 147; AVX1-NEXT: vinsertf128 $1, %xmm1, %ymm1, %ymm1 148; AVX1-NEXT: vxorps %ymm1, %ymm0, %ymm0 149; AVX1-NEXT: retq 150; 151; AVX2-LABEL: test_pcmpgtb_256: 152; AVX2: # BB#0: 153; AVX2-NEXT: vpcmpeqd %ymm1, %ymm1, %ymm1 154; AVX2-NEXT: vpcmpgtb %ymm1, %ymm0, %ymm0 155; AVX2-NEXT: retq 156 %sign = ashr <32 x i8> %x, <i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7> 157 %not = xor <32 x i8> %sign, <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, 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> 158 ret <32 x i8> %not 159} 160 161define <16 x i16> @test_pcmpgtw_256(<16 x i16> %x) { 162; SSE-LABEL: test_pcmpgtw_256: 163; SSE: # BB#0: 164; SSE-NEXT: pcmpeqd %xmm2, %xmm2 165; SSE-NEXT: pcmpgtw %xmm2, %xmm0 166; SSE-NEXT: pcmpgtw %xmm2, %xmm1 167; SSE-NEXT: retq 168; 169; AVX1-LABEL: test_pcmpgtw_256: 170; AVX1: # BB#0: 171; AVX1-NEXT: vpsraw $15, %xmm0, %xmm1 172; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm0 173; AVX1-NEXT: vpsraw $15, %xmm0, %xmm0 174; AVX1-NEXT: vinsertf128 $1, %xmm0, %ymm1, %ymm0 175; AVX1-NEXT: vpcmpeqd %xmm1, %xmm1, %xmm1 176; AVX1-NEXT: vinsertf128 $1, %xmm1, %ymm1, %ymm1 177; AVX1-NEXT: vxorps %ymm1, %ymm0, %ymm0 178; AVX1-NEXT: retq 179; 180; AVX2-LABEL: test_pcmpgtw_256: 181; AVX2: # BB#0: 182; AVX2-NEXT: vpcmpeqd %ymm1, %ymm1, %ymm1 183; AVX2-NEXT: vpcmpgtw %ymm1, %ymm0, %ymm0 184; AVX2-NEXT: retq 185 %sign = ashr <16 x i16> %x, <i16 15, i16 15, i16 15, i16 15, i16 15, i16 15, i16 15, i16 15, i16 15, i16 15, i16 15, i16 15, i16 15, i16 15, i16 15, i16 15> 186 %not = xor <16 x i16> %sign, <i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1> 187 ret <16 x i16> %not 188} 189 190define <8 x i32> @test_pcmpgtd_256(<8 x i32> %x) { 191; SSE-LABEL: test_pcmpgtd_256: 192; SSE: # BB#0: 193; SSE-NEXT: pcmpeqd %xmm2, %xmm2 194; SSE-NEXT: pcmpgtd %xmm2, %xmm0 195; SSE-NEXT: pcmpgtd %xmm2, %xmm1 196; SSE-NEXT: retq 197; 198; AVX1-LABEL: test_pcmpgtd_256: 199; AVX1: # BB#0: 200; AVX1-NEXT: vpsrad $31, %xmm0, %xmm1 201; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm0 202; AVX1-NEXT: vpsrad $31, %xmm0, %xmm0 203; AVX1-NEXT: vinsertf128 $1, %xmm0, %ymm1, %ymm0 204; AVX1-NEXT: vpcmpeqd %xmm1, %xmm1, %xmm1 205; AVX1-NEXT: vinsertf128 $1, %xmm1, %ymm1, %ymm1 206; AVX1-NEXT: vxorps %ymm1, %ymm0, %ymm0 207; AVX1-NEXT: retq 208; 209; AVX2-LABEL: test_pcmpgtd_256: 210; AVX2: # BB#0: 211; AVX2-NEXT: vpcmpeqd %ymm1, %ymm1, %ymm1 212; AVX2-NEXT: vpcmpgtd %ymm1, %ymm0, %ymm0 213; AVX2-NEXT: retq 214 %sign = ashr <8 x i32> %x, <i32 31, i32 31, i32 31, i32 31, i32 31, i32 31, i32 31, i32 31> 215 %not = xor <8 x i32> %sign, <i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1> 216 ret <8 x i32> %not 217} 218 219define <4 x i64> @test_pcmpgtq_256(<4 x i64> %x) { 220; SSE2-LABEL: test_pcmpgtq_256: 221; SSE2: # BB#0: 222; SSE2-NEXT: psrad $31, %xmm1 223; SSE2-NEXT: pshufd {{.*#+}} xmm1 = xmm1[1,1,3,3] 224; SSE2-NEXT: psrad $31, %xmm0 225; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm0[1,1,3,3] 226; SSE2-NEXT: pcmpeqd %xmm2, %xmm2 227; SSE2-NEXT: pxor %xmm2, %xmm0 228; SSE2-NEXT: pxor %xmm2, %xmm1 229; SSE2-NEXT: retq 230; 231; SSE42-LABEL: test_pcmpgtq_256: 232; SSE42: # BB#0: 233; SSE42-NEXT: pcmpeqd %xmm2, %xmm2 234; SSE42-NEXT: pcmpgtq %xmm2, %xmm0 235; SSE42-NEXT: pcmpgtq %xmm2, %xmm1 236; SSE42-NEXT: retq 237; 238; AVX1-LABEL: test_pcmpgtq_256: 239; AVX1: # BB#0: 240; AVX1-NEXT: vpsrad $31, %xmm0, %xmm1 241; AVX1-NEXT: vpshufd {{.*#+}} xmm1 = xmm1[1,1,3,3] 242; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm0 243; AVX1-NEXT: vpsrad $31, %xmm0, %xmm0 244; AVX1-NEXT: vpshufd {{.*#+}} xmm0 = xmm0[1,1,3,3] 245; AVX1-NEXT: vinsertf128 $1, %xmm0, %ymm1, %ymm0 246; AVX1-NEXT: vpcmpeqd %xmm1, %xmm1, %xmm1 247; AVX1-NEXT: vinsertf128 $1, %xmm1, %ymm1, %ymm1 248; AVX1-NEXT: vxorps %ymm1, %ymm0, %ymm0 249; AVX1-NEXT: retq 250; 251; AVX2-LABEL: test_pcmpgtq_256: 252; AVX2: # BB#0: 253; AVX2-NEXT: vpcmpeqd %ymm1, %ymm1, %ymm1 254; AVX2-NEXT: vpcmpgtq %ymm1, %ymm0, %ymm0 255; AVX2-NEXT: retq 256 %sign = ashr <4 x i64> %x, <i64 63, i64 63, i64 63, i64 63> 257 %not = xor <4 x i64> %sign, <i64 -1, i64 -1, i64 -1, i64 -1> 258 ret <4 x i64> %not 259} 260 261