509 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+sse4.1 | FileCheck %s --check-prefixes=SSE,SSE413; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+sse4.2 | FileCheck %s --check-prefixes=SSE,SSE424; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx | FileCheck %s --check-prefixes=AVX5; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx2 | FileCheck %s --check-prefixes=AVX6 7;8; testz(~X,Y) -> testc(X,Y)9;10 11define i32 @ptestz_128_invert0(<2 x i64> %c, <2 x i64> %d, i32 %a, i32 %b) {12; SSE-LABEL: ptestz_128_invert0:13; SSE: # %bb.0:14; SSE-NEXT: movl %edi, %eax15; SSE-NEXT: ptest %xmm1, %xmm016; SSE-NEXT: cmovael %esi, %eax17; SSE-NEXT: retq18;19; AVX-LABEL: ptestz_128_invert0:20; AVX: # %bb.0:21; AVX-NEXT: movl %edi, %eax22; AVX-NEXT: vptest %xmm1, %xmm023; AVX-NEXT: cmovael %esi, %eax24; AVX-NEXT: retq25 %t1 = xor <2 x i64> %c, <i64 -1, i64 -1>26 %t2 = call i32 @llvm.x86.sse41.ptestz(<2 x i64> %t1, <2 x i64> %d)27 %t3 = icmp ne i32 %t2, 028 %t4 = select i1 %t3, i32 %a, i32 %b29 ret i32 %t430}31 32;33; testz(X,~Y) -> testc(Y,X)34;35 36define i32 @ptestz_128_invert1(<2 x i64> %c, <2 x i64> %d, i32 %a, i32 %b) {37; SSE-LABEL: ptestz_128_invert1:38; SSE: # %bb.0:39; SSE-NEXT: movl %edi, %eax40; SSE-NEXT: ptest %xmm0, %xmm141; SSE-NEXT: cmovael %esi, %eax42; SSE-NEXT: retq43;44; AVX-LABEL: ptestz_128_invert1:45; AVX: # %bb.0:46; AVX-NEXT: movl %edi, %eax47; AVX-NEXT: vptest %xmm0, %xmm148; AVX-NEXT: cmovael %esi, %eax49; AVX-NEXT: retq50 %t1 = xor <2 x i64> %d, <i64 -1, i64 -1>51 %t2 = call i32 @llvm.x86.sse41.ptestz(<2 x i64> %c, <2 x i64> %t1)52 %t3 = icmp ne i32 %t2, 053 %t4 = select i1 %t3, i32 %a, i32 %b54 ret i32 %t455}56 57;58; testc(~X,Y) -> testz(X,Y)59;60 61define i32 @ptestc_128_invert0(<2 x i64> %c, <2 x i64> %d, i32 %a, i32 %b) {62; SSE-LABEL: ptestc_128_invert0:63; SSE: # %bb.0:64; SSE-NEXT: movl %edi, %eax65; SSE-NEXT: ptest %xmm1, %xmm066; SSE-NEXT: cmovnel %esi, %eax67; SSE-NEXT: retq68;69; AVX-LABEL: ptestc_128_invert0:70; AVX: # %bb.0:71; AVX-NEXT: movl %edi, %eax72; AVX-NEXT: vptest %xmm1, %xmm073; AVX-NEXT: cmovnel %esi, %eax74; AVX-NEXT: retq75 %t1 = xor <2 x i64> %c, <i64 -1, i64 -1>76 %t2 = call i32 @llvm.x86.sse41.ptestc(<2 x i64> %t1, <2 x i64> %d)77 %t3 = icmp ne i32 %t2, 078 %t4 = select i1 %t3, i32 %a, i32 %b79 ret i32 %t480}81 82;83; testnzc(~X,Y) -> testnzc(X,Y)84;85 86define i32 @ptestnzc_128_invert0(<2 x i64> %c, <2 x i64> %d, i32 %a, i32 %b) {87; SSE-LABEL: ptestnzc_128_invert0:88; SSE: # %bb.0:89; SSE-NEXT: movl %edi, %eax90; SSE-NEXT: ptest %xmm1, %xmm091; SSE-NEXT: cmovnel %esi, %eax92; SSE-NEXT: retq93;94; AVX-LABEL: ptestnzc_128_invert0:95; AVX: # %bb.0:96; AVX-NEXT: movl %edi, %eax97; AVX-NEXT: vptest %xmm1, %xmm098; AVX-NEXT: cmovnel %esi, %eax99; AVX-NEXT: retq100 %t1 = xor <2 x i64> %c, <i64 -1, i64 -1>101 %t2 = call i32 @llvm.x86.sse41.ptestc(<2 x i64> %t1, <2 x i64> %d)102 %t3 = icmp ne i32 %t2, 0103 %t4 = select i1 %t3, i32 %a, i32 %b104 ret i32 %t4105}106 107;108; testc(X,~X) -> testc(X,-1)109;110 111define i32 @ptestc_128_not(<2 x i64> %c, <2 x i64> %d, i32 %a, i32 %b) {112; SSE-LABEL: ptestc_128_not:113; SSE: # %bb.0:114; SSE-NEXT: movl %edi, %eax115; SSE-NEXT: pcmpeqd %xmm1, %xmm1116; SSE-NEXT: ptest %xmm1, %xmm0117; SSE-NEXT: cmovael %esi, %eax118; SSE-NEXT: retq119;120; AVX-LABEL: ptestc_128_not:121; AVX: # %bb.0:122; AVX-NEXT: movl %edi, %eax123; AVX-NEXT: vpcmpeqd %xmm1, %xmm1, %xmm1124; AVX-NEXT: vptest %xmm1, %xmm0125; AVX-NEXT: cmovael %esi, %eax126; AVX-NEXT: retq127 %t1 = xor <2 x i64> %c, <i64 -1, i64 -1>128 %t2 = call i32 @llvm.x86.sse41.ptestc(<2 x i64> %c, <2 x i64> %t1)129 %t3 = icmp ne i32 %t2, 0130 %t4 = select i1 %t3, i32 %a, i32 %b131 ret i32 %t4132}133 134;135; testz(AND(X,Y),AND(X,Y)) -> testz(X,Y)136;137 138define i32 @ptestz_128_and(<2 x i64> %c, <2 x i64> %d, i32 %a, i32 %b) {139; SSE-LABEL: ptestz_128_and:140; SSE: # %bb.0:141; SSE-NEXT: movl %edi, %eax142; SSE-NEXT: ptest %xmm1, %xmm0143; SSE-NEXT: cmovnel %esi, %eax144; SSE-NEXT: retq145;146; AVX-LABEL: ptestz_128_and:147; AVX: # %bb.0:148; AVX-NEXT: movl %edi, %eax149; AVX-NEXT: vptest %xmm1, %xmm0150; AVX-NEXT: cmovnel %esi, %eax151; AVX-NEXT: retq152 %t1 = and <2 x i64> %c, %d153 %t2 = call i32 @llvm.x86.sse41.ptestz(<2 x i64> %t1, <2 x i64> %t1)154 %t3 = icmp ne i32 %t2, 0155 %t4 = select i1 %t3, i32 %a, i32 %b156 ret i32 %t4157}158 159;160; testz(AND(~X,Y),AND(~X,Y)) -> testc(X,Y)161;162 163define i32 @ptestz_128_andc(<2 x i64> %c, <2 x i64> %d, i32 %a, i32 %b) {164; SSE-LABEL: ptestz_128_andc:165; SSE: # %bb.0:166; SSE-NEXT: movl %edi, %eax167; SSE-NEXT: ptest %xmm1, %xmm0168; SSE-NEXT: cmovael %esi, %eax169; SSE-NEXT: retq170;171; AVX-LABEL: ptestz_128_andc:172; AVX: # %bb.0:173; AVX-NEXT: movl %edi, %eax174; AVX-NEXT: vptest %xmm1, %xmm0175; AVX-NEXT: cmovael %esi, %eax176; AVX-NEXT: retq177 %t1 = xor <2 x i64> %c, <i64 -1, i64 -1>178 %t2 = and <2 x i64> %t1, %d179 %t3 = call i32 @llvm.x86.sse41.ptestz(<2 x i64> %t2, <2 x i64> %t2)180 %t4 = icmp ne i32 %t3, 0181 %t5 = select i1 %t4, i32 %a, i32 %b182 ret i32 %t5183}184 185;186; testz(-1,X) -> testz(X,X)187;188 189define i32 @ptestz_128_allones0(<2 x i64> %c, i32 %a, i32 %b) {190; SSE-LABEL: ptestz_128_allones0:191; SSE: # %bb.0:192; SSE-NEXT: movl %edi, %eax193; SSE-NEXT: ptest %xmm0, %xmm0194; SSE-NEXT: cmovnel %esi, %eax195; SSE-NEXT: retq196;197; AVX-LABEL: ptestz_128_allones0:198; AVX: # %bb.0:199; AVX-NEXT: movl %edi, %eax200; AVX-NEXT: vptest %xmm0, %xmm0201; AVX-NEXT: cmovnel %esi, %eax202; AVX-NEXT: retq203 %t1 = call i32 @llvm.x86.sse41.ptestz(<2 x i64> <i64 -1, i64 -1>, <2 x i64> %c)204 %t2 = icmp ne i32 %t1, 0205 %t3 = select i1 %t2, i32 %a, i32 %b206 ret i32 %t3207}208 209;210; testz(X,-1) -> testz(X,X)211;212 213define i32 @ptestz_128_allones1(<2 x i64> %c, i32 %a, i32 %b) {214; SSE-LABEL: ptestz_128_allones1:215; SSE: # %bb.0:216; SSE-NEXT: movl %edi, %eax217; SSE-NEXT: ptest %xmm0, %xmm0218; SSE-NEXT: cmovnel %esi, %eax219; SSE-NEXT: retq220;221; AVX-LABEL: ptestz_128_allones1:222; AVX: # %bb.0:223; AVX-NEXT: movl %edi, %eax224; AVX-NEXT: vptest %xmm0, %xmm0225; AVX-NEXT: cmovnel %esi, %eax226; AVX-NEXT: retq227 %t1 = call i32 @llvm.x86.sse41.ptestz(<2 x i64> %c, <2 x i64> <i64 -1, i64 -1>)228 %t2 = icmp ne i32 %t1, 0229 %t3 = select i1 %t2, i32 %a, i32 %b230 ret i32 %t3231}232 233define zeroext i1 @PR38522(ptr %x, ptr %y) {234; SSE-LABEL: PR38522:235; SSE: # %bb.0: # %start236; SSE-NEXT: movdqa (%rdi), %xmm0237; SSE-NEXT: pcmpgtb (%rsi), %xmm0238; SSE-NEXT: ptest %xmm0, %xmm0239; SSE-NEXT: sete %al240; SSE-NEXT: retq241;242; AVX-LABEL: PR38522:243; AVX: # %bb.0: # %start244; AVX-NEXT: vmovdqa (%rdi), %xmm0245; AVX-NEXT: vpcmpgtb (%rsi), %xmm0, %xmm0246; AVX-NEXT: vptest %xmm0, %xmm0247; AVX-NEXT: sete %al248; AVX-NEXT: retq249start:250 %0 = load <16 x i8>, ptr %x, align 16251 %1 = load <16 x i8>, ptr %y, align 16252 %2 = icmp sle <16 x i8> %0, %1253 %3 = sext <16 x i1> %2 to <16 x i8>254 %4 = bitcast <16 x i8> %3 to <2 x i64>255 %5 = tail call i32 @llvm.x86.sse41.ptestc(<2 x i64> %4, <2 x i64> <i64 -1, i64 -1>)256 %6 = icmp eq i32 %5, 1257 ret i1 %6258}259 260;261; testz(ashr(X,bw-1),-1) -> testpd/testps/movmskpd/movmskps/pmovmskb(X)262;263 264define i32 @ptestz_v2i64_signbits(<2 x i64> %c, i32 %a, i32 %b) {265; SSE41-LABEL: ptestz_v2i64_signbits:266; SSE41: # %bb.0:267; SSE41-NEXT: movl %edi, %eax268; SSE41-NEXT: pshufd {{.*#+}} xmm0 = xmm0[1,1,3,3]269; SSE41-NEXT: movmskps %xmm0, %ecx270; SSE41-NEXT: testl %ecx, %ecx271; SSE41-NEXT: cmovnel %esi, %eax272; SSE41-NEXT: retq273;274; SSE42-LABEL: ptestz_v2i64_signbits:275; SSE42: # %bb.0:276; SSE42-NEXT: movl %edi, %eax277; SSE42-NEXT: movmskpd %xmm0, %ecx278; SSE42-NEXT: testl %ecx, %ecx279; SSE42-NEXT: cmovnel %esi, %eax280; SSE42-NEXT: retq281;282; AVX-LABEL: ptestz_v2i64_signbits:283; AVX: # %bb.0:284; AVX-NEXT: movl %edi, %eax285; AVX-NEXT: vtestpd %xmm0, %xmm0286; AVX-NEXT: cmovnel %esi, %eax287; AVX-NEXT: retq288 %t1 = ashr <2 x i64> %c, <i64 63, i64 63>289 %t2 = call i32 @llvm.x86.sse41.ptestz(<2 x i64> %t1, <2 x i64> <i64 -1, i64 -1>)290 %t3 = icmp ne i32 %t2, 0291 %t4 = select i1 %t3, i32 %a, i32 %b292 ret i32 %t4293}294 295define i32 @ptestz_v4i32_signbits(<4 x i32> %c, i32 %a, i32 %b) {296; SSE-LABEL: ptestz_v4i32_signbits:297; SSE: # %bb.0:298; SSE-NEXT: movl %edi, %eax299; SSE-NEXT: movmskps %xmm0, %ecx300; SSE-NEXT: testl %ecx, %ecx301; SSE-NEXT: cmovnel %esi, %eax302; SSE-NEXT: retq303;304; AVX-LABEL: ptestz_v4i32_signbits:305; AVX: # %bb.0:306; AVX-NEXT: movl %edi, %eax307; AVX-NEXT: vtestps %xmm0, %xmm0308; AVX-NEXT: cmovnel %esi, %eax309; AVX-NEXT: retq310 %t1 = ashr <4 x i32> %c, <i32 31, i32 31, i32 31, i32 31>311 %t2 = bitcast <4 x i32> %t1 to <2 x i64>312 %t3 = call i32 @llvm.x86.sse41.ptestz(<2 x i64> %t2, <2 x i64> <i64 -1, i64 -1>)313 %t4 = icmp ne i32 %t3, 0314 %t5 = select i1 %t4, i32 %a, i32 %b315 ret i32 %t5316}317 318define i32 @ptestz_v8i16_signbits(<8 x i16> %c, i32 %a, i32 %b) {319; SSE-LABEL: ptestz_v8i16_signbits:320; SSE: # %bb.0:321; SSE-NEXT: movl %edi, %eax322; SSE-NEXT: pmovmskb %xmm0, %ecx323; SSE-NEXT: testl $43690, %ecx # imm = 0xAAAA324; SSE-NEXT: cmovnel %esi, %eax325; SSE-NEXT: retq326;327; AVX-LABEL: ptestz_v8i16_signbits:328; AVX: # %bb.0:329; AVX-NEXT: movl %edi, %eax330; AVX-NEXT: vpmovmskb %xmm0, %ecx331; AVX-NEXT: testl $43690, %ecx # imm = 0xAAAA332; AVX-NEXT: cmovnel %esi, %eax333; AVX-NEXT: retq334 %t1 = ashr <8 x i16> %c, <i16 15, i16 15, i16 15, i16 15, i16 15, i16 15, i16 15, i16 15>335 %t2 = bitcast <8 x i16> %t1 to <2 x i64>336 %t3 = call i32 @llvm.x86.sse41.ptestz(<2 x i64> %t2, <2 x i64> <i64 -1, i64 -1>)337 %t4 = icmp ne i32 %t3, 0338 %t5 = select i1 %t4, i32 %a, i32 %b339 ret i32 %t5340}341 342;343; testz(or(extract_lo(X),extract_hi(X),or(extract_lo(Y),extract_hi(Y)) -> testz(X,Y)344;345 346define i32 @ptestz_v2i64_concat(<4 x i64> %c, <4 x i64> %d, i32 %a, i32 %b) {347; SSE-LABEL: ptestz_v2i64_concat:348; SSE: # %bb.0:349; SSE-NEXT: movl %edi, %eax350; SSE-NEXT: por %xmm1, %xmm0351; SSE-NEXT: por %xmm3, %xmm2352; SSE-NEXT: ptest %xmm2, %xmm0353; SSE-NEXT: cmovnel %esi, %eax354; SSE-NEXT: retq355;356; AVX-LABEL: ptestz_v2i64_concat:357; AVX: # %bb.0:358; AVX-NEXT: movl %edi, %eax359; AVX-NEXT: vptest %ymm1, %ymm0360; AVX-NEXT: cmovnel %esi, %eax361; AVX-NEXT: vzeroupper362; AVX-NEXT: retq363 %t1 = shufflevector <4 x i64> %c, <4 x i64> undef, <2 x i32> <i32 0, i32 1>364 %t2 = shufflevector <4 x i64> %c, <4 x i64> undef, <2 x i32> <i32 2, i32 3>365 %t3 = shufflevector <4 x i64> %d, <4 x i64> undef, <2 x i32> <i32 0, i32 1>366 %t4 = shufflevector <4 x i64> %d, <4 x i64> undef, <2 x i32> <i32 2, i32 3>367 %t5 = or <2 x i64> %t1, %t2368 %t6 = or <2 x i64> %t4, %t3369 %t7 = call i32 @llvm.x86.sse41.ptestz(<2 x i64> %t5, <2 x i64> %t6)370 %t8 = icmp ne i32 %t7, 0371 %t9 = select i1 %t8, i32 %a, i32 %b372 ret i32 %t9373}374 375; PR123456 - all_of(x == 0)376define i1 @ptestc_v4i32_eq0(<4 x i32> %a0) {377; SSE-LABEL: ptestc_v4i32_eq0:378; SSE: # %bb.0:379; SSE-NEXT: ptest %xmm0, %xmm0380; SSE-NEXT: sete %al381; SSE-NEXT: retq382;383; AVX-LABEL: ptestc_v4i32_eq0:384; AVX: # %bb.0:385; AVX-NEXT: vptest %xmm0, %xmm0386; AVX-NEXT: sete %al387; AVX-NEXT: retq388 %icmp = icmp eq <4 x i32> %a0, zeroinitializer389 %sext = sext <4 x i1> %icmp to <4 x i32>390 %bc = bitcast <4 x i32> %sext to <2 x i64>391 %test = tail call noundef i32 @llvm.x86.sse41.ptestc(<2 x i64> %bc, <2 x i64> splat (i64 -1))392 %res = icmp ne i32 %test, 0393 ret i1 %res394}395 396; PR123456 - all_of((a & b) == 0)397define i1 @ptestc_v4i32_and_eq0(<4 x i32> %a0, <4 x i32> %a1) {398; SSE-LABEL: ptestc_v4i32_and_eq0:399; SSE: # %bb.0:400; SSE-NEXT: ptest %xmm0, %xmm1401; SSE-NEXT: sete %al402; SSE-NEXT: retq403;404; AVX-LABEL: ptestc_v4i32_and_eq0:405; AVX: # %bb.0:406; AVX-NEXT: vptest %xmm0, %xmm1407; AVX-NEXT: sete %al408; AVX-NEXT: retq409 %and = and <4 x i32> %a1, %a0410 %icmp = icmp eq <4 x i32> %and, zeroinitializer411 %sext = sext <4 x i1> %icmp to <4 x i32>412 %bc = bitcast <4 x i32> %sext to <2 x i64>413 %test = tail call noundef i32 @llvm.x86.sse41.ptestc(<2 x i64> %bc, <2 x i64> splat (i64 -1))414 %res = icmp ne i32 %test, 0415 ret i1 %res416}417 418; PR123456 - !all_of((a & ~b) == 0)419define i1 @ptestc_v4i32_andnot_eq0(<4 x i32> %a0, <4 x i32> %a1) {420; SSE-LABEL: ptestc_v4i32_andnot_eq0:421; SSE: # %bb.0:422; SSE-NEXT: ptest %xmm0, %xmm1423; SSE-NEXT: setae %al424; SSE-NEXT: retq425;426; AVX-LABEL: ptestc_v4i32_andnot_eq0:427; AVX: # %bb.0:428; AVX-NEXT: vptest %xmm0, %xmm1429; AVX-NEXT: setae %al430; AVX-NEXT: retq431 %not = xor <4 x i32> %a1, splat (i32 -1)432 %and = and <4 x i32> %a0, %not433 %icmp = icmp eq <4 x i32> %and, zeroinitializer434 %sext = sext <4 x i1> %icmp to <4 x i32>435 %bc = bitcast <4 x i32> %sext to <2 x i64>436 %test = tail call noundef i32 @llvm.x86.sse41.ptestc(<2 x i64> %bc, <2 x i64> splat (i64 -1))437 %res = icmp eq i32 %test, 0438 ret i1 %res439}440 441; FIXME: Foldable to ptest(xor(%0,%1),xor(%0,%1))442define i1 @PR38788(<4 x i32> %0, <4 x i32> %1) {443; SSE-LABEL: PR38788:444; SSE: # %bb.0:445; SSE-NEXT: pcmpeqd %xmm1, %xmm0446; SSE-NEXT: pcmpeqd %xmm1, %xmm1447; SSE-NEXT: ptest %xmm1, %xmm0448; SSE-NEXT: setb %al449; SSE-NEXT: retq450;451; AVX-LABEL: PR38788:452; AVX: # %bb.0:453; AVX-NEXT: vpcmpeqd %xmm1, %xmm0, %xmm0454; AVX-NEXT: vpcmpeqd %xmm1, %xmm1, %xmm1455; AVX-NEXT: vptest %xmm1, %xmm0456; AVX-NEXT: setb %al457; AVX-NEXT: retq458 %3 = icmp eq <4 x i32> %0, %1459 %4 = sext <4 x i1> %3 to <4 x i32>460 %5 = bitcast <4 x i32> %4 to <2 x i64>461 %6 = tail call i32 @llvm.x86.sse41.ptestc(<2 x i64> %5, <2 x i64> <i64 -1, i64 -1>)462 %7 = icmp eq i32 %6, 1463 ret i1 %7464}465 466define i32 @PR88958_1(ptr %0, <2 x i64> %1) {467; SSE-LABEL: PR88958_1:468; SSE: # %bb.0:469; SSE-NEXT: xorl %eax, %eax470; SSE-NEXT: ptest (%rdi), %xmm0471; SSE-NEXT: sete %al472; SSE-NEXT: retq473;474; AVX-LABEL: PR88958_1:475; AVX: # %bb.0:476; AVX-NEXT: xorl %eax, %eax477; AVX-NEXT: vptest (%rdi), %xmm0478; AVX-NEXT: sete %al479; AVX-NEXT: retq480 %3 = load <2 x i64>, ptr %0481 %4 = tail call i32 @llvm.x86.sse41.ptestz(<2 x i64> %3, <2 x i64> %1)482 ret i32 %4483}484 485define i32 @PR88958_2(ptr %0, <2 x i64> %1) {486; SSE-LABEL: PR88958_2:487; SSE: # %bb.0:488; SSE-NEXT: movdqa (%rdi), %xmm1489; SSE-NEXT: xorl %eax, %eax490; SSE-NEXT: ptest %xmm0, %xmm1491; SSE-NEXT: setb %al492; SSE-NEXT: retq493;494; AVX-LABEL: PR88958_2:495; AVX: # %bb.0:496; AVX-NEXT: vmovdqa (%rdi), %xmm1497; AVX-NEXT: xorl %eax, %eax498; AVX-NEXT: vptest %xmm0, %xmm1499; AVX-NEXT: setb %al500; AVX-NEXT: retq501 %3 = load <2 x i64>, ptr %0502 %4 = tail call i32 @llvm.x86.sse41.ptestc(<2 x i64> %3, <2 x i64> %1)503 ret i32 %4504}505 506declare i32 @llvm.x86.sse41.ptestz(<2 x i64>, <2 x i64>) nounwind readnone507declare i32 @llvm.x86.sse41.ptestc(<2 x i64>, <2 x i64>) nounwind readnone508declare i32 @llvm.x86.sse41.ptestnzc(<2 x i64>, <2 x i64>) nounwind readnone509