372 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; Test patterns which generates lzcnt instructions.3; Eg: zext(or(setcc(cmp), setcc(cmp))) -> shr(or(lzcnt, lzcnt))4; RUN: llc < %s -mtriple=x86_64-pc-linux -mcpu=btver2 | FileCheck --check-prefix=ALL --check-prefix=FASTLZCNT %s5; RUN: llc < %s -mtriple=x86_64-pc-linux -mcpu=btver2 -mattr=-fast-lzcnt | FileCheck --check-prefix=ALL --check-prefix=NOFASTLZCNT %s6; RUN: llc < %s -mtriple=x86_64-pc-linux -mcpu=znver1 | FileCheck --check-prefix=ALL --check-prefix=FASTLZCNT %s7; RUN: llc < %s -mtriple=x86_64-pc-linux -mcpu=znver1 -mattr=-fast-lzcnt | FileCheck --check-prefix=ALL --check-prefix=NOFASTLZCNT %s8; RUN: llc < %s -mtriple=x86_64-pc-linux -mcpu=znver2 | FileCheck --check-prefix=ALL --check-prefix=FASTLZCNT %s9; RUN: llc < %s -mtriple=x86_64-pc-linux -mcpu=znver2 -mattr=-fast-lzcnt | FileCheck --check-prefix=ALL --check-prefix=NOFASTLZCNT %s10 11; Test one 32-bit input, output is 32-bit, no transformations expected.12define i32 @test_zext_cmp0(i32 %a) {13; ALL-LABEL: test_zext_cmp0:14; ALL: # %bb.0: # %entry15; ALL-NEXT: xorl %eax, %eax16; ALL-NEXT: testl %edi, %edi17; ALL-NEXT: sete %al18; ALL-NEXT: retq19entry:20 %cmp = icmp eq i32 %a, 021 %conv = zext i1 %cmp to i3222 ret i32 %conv23}24 25; Test two 32-bit inputs, output is 32-bit.26define i32 @test_zext_cmp1(i32 %a, i32 %b) {27; FASTLZCNT-LABEL: test_zext_cmp1:28; FASTLZCNT: # %bb.0:29; FASTLZCNT-NEXT: lzcntl %edi, %ecx30; FASTLZCNT-NEXT: lzcntl %esi, %eax31; FASTLZCNT-NEXT: orl %ecx, %eax32; FASTLZCNT-NEXT: shrl $5, %eax33; FASTLZCNT-NEXT: retq34;35; NOFASTLZCNT-LABEL: test_zext_cmp1:36; NOFASTLZCNT: # %bb.0:37; NOFASTLZCNT-NEXT: testl %edi, %edi38; NOFASTLZCNT-NEXT: sete %al39; NOFASTLZCNT-NEXT: testl %esi, %esi40; NOFASTLZCNT-NEXT: sete %cl41; NOFASTLZCNT-NEXT: orb %al, %cl42; NOFASTLZCNT-NEXT: movzbl %cl, %eax43; NOFASTLZCNT-NEXT: retq44 %cmp = icmp eq i32 %a, 045 %cmp1 = icmp eq i32 %b, 046 %or = or i1 %cmp, %cmp147 %lor.ext = zext i1 %or to i3248 ret i32 %lor.ext49}50 51; Test two 64-bit inputs, output is 64-bit.52define i64 @test_zext_cmp2(i64 %a, i64 %b) {53; FASTLZCNT-LABEL: test_zext_cmp2:54; FASTLZCNT: # %bb.0:55; FASTLZCNT-NEXT: lzcntq %rdi, %rcx56; FASTLZCNT-NEXT: lzcntq %rsi, %rax57; FASTLZCNT-NEXT: orl %ecx, %eax58; FASTLZCNT-NEXT: shrl $6, %eax59; FASTLZCNT-NEXT: retq60;61; NOFASTLZCNT-LABEL: test_zext_cmp2:62; NOFASTLZCNT: # %bb.0:63; NOFASTLZCNT-NEXT: testq %rdi, %rdi64; NOFASTLZCNT-NEXT: sete %al65; NOFASTLZCNT-NEXT: testq %rsi, %rsi66; NOFASTLZCNT-NEXT: sete %cl67; NOFASTLZCNT-NEXT: orb %al, %cl68; NOFASTLZCNT-NEXT: movzbl %cl, %eax69; NOFASTLZCNT-NEXT: retq70 %cmp = icmp eq i64 %a, 071 %cmp1 = icmp eq i64 %b, 072 %or = or i1 %cmp, %cmp173 %lor.ext = zext i1 %or to i6474 ret i64 %lor.ext75}76 77; Test two 16-bit inputs, output is 16-bit.78; The transform is disabled for the 16-bit case, as we still have to clear the79; upper 16-bits, adding one more instruction.80define i16 @test_zext_cmp3(i16 %a, i16 %b) {81; ALL-LABEL: test_zext_cmp3:82; ALL: # %bb.0:83; ALL-NEXT: testw %di, %di84; ALL-NEXT: sete %al85; ALL-NEXT: testw %si, %si86; ALL-NEXT: sete %cl87; ALL-NEXT: orb %al, %cl88; ALL-NEXT: movzbl %cl, %eax89; ALL-NEXT: # kill: def $ax killed $ax killed $eax90; ALL-NEXT: retq91 %cmp = icmp eq i16 %a, 092 %cmp1 = icmp eq i16 %b, 093 %or = or i1 %cmp, %cmp194 %lor.ext = zext i1 %or to i1695 ret i16 %lor.ext96}97 98; Test two 32-bit inputs, output is 64-bit.99define i64 @test_zext_cmp4(i32 %a, i32 %b) {100; FASTLZCNT-LABEL: test_zext_cmp4:101; FASTLZCNT: # %bb.0: # %entry102; FASTLZCNT-NEXT: lzcntl %edi, %ecx103; FASTLZCNT-NEXT: lzcntl %esi, %eax104; FASTLZCNT-NEXT: orl %ecx, %eax105; FASTLZCNT-NEXT: shrl $5, %eax106; FASTLZCNT-NEXT: retq107;108; NOFASTLZCNT-LABEL: test_zext_cmp4:109; NOFASTLZCNT: # %bb.0: # %entry110; NOFASTLZCNT-NEXT: testl %edi, %edi111; NOFASTLZCNT-NEXT: sete %al112; NOFASTLZCNT-NEXT: testl %esi, %esi113; NOFASTLZCNT-NEXT: sete %cl114; NOFASTLZCNT-NEXT: orb %al, %cl115; NOFASTLZCNT-NEXT: movzbl %cl, %eax116; NOFASTLZCNT-NEXT: retq117entry:118 %cmp = icmp eq i32 %a, 0119 %cmp1 = icmp eq i32 %b, 0120 %0 = or i1 %cmp, %cmp1121 %conv = zext i1 %0 to i64122 ret i64 %conv123}124 125; Test two 64-bit inputs, output is 32-bit.126define i32 @test_zext_cmp5(i64 %a, i64 %b) {127; FASTLZCNT-LABEL: test_zext_cmp5:128; FASTLZCNT: # %bb.0: # %entry129; FASTLZCNT-NEXT: lzcntq %rdi, %rcx130; FASTLZCNT-NEXT: lzcntq %rsi, %rax131; FASTLZCNT-NEXT: orl %ecx, %eax132; FASTLZCNT-NEXT: shrl $6, %eax133; FASTLZCNT-NEXT: # kill: def $eax killed $eax killed $rax134; FASTLZCNT-NEXT: retq135;136; NOFASTLZCNT-LABEL: test_zext_cmp5:137; NOFASTLZCNT: # %bb.0: # %entry138; NOFASTLZCNT-NEXT: testq %rdi, %rdi139; NOFASTLZCNT-NEXT: sete %al140; NOFASTLZCNT-NEXT: testq %rsi, %rsi141; NOFASTLZCNT-NEXT: sete %cl142; NOFASTLZCNT-NEXT: orb %al, %cl143; NOFASTLZCNT-NEXT: movzbl %cl, %eax144; NOFASTLZCNT-NEXT: retq145entry:146 %cmp = icmp eq i64 %a, 0147 %cmp1 = icmp eq i64 %b, 0148 %0 = or i1 %cmp, %cmp1149 %lor.ext = zext i1 %0 to i32150 ret i32 %lor.ext151}152 153; Test three 32-bit inputs, output is 32-bit.154define i32 @test_zext_cmp6(i32 %a, i32 %b, i32 %c) {155; FASTLZCNT-LABEL: test_zext_cmp6:156; FASTLZCNT: # %bb.0: # %entry157; FASTLZCNT-NEXT: lzcntl %edi, %ecx158; FASTLZCNT-NEXT: lzcntl %edx, %eax159; FASTLZCNT-NEXT: lzcntl %esi, %esi160; FASTLZCNT-NEXT: orl %ecx, %eax161; FASTLZCNT-NEXT: orl %esi, %eax162; FASTLZCNT-NEXT: shrl $5, %eax163; FASTLZCNT-NEXT: retq164;165; NOFASTLZCNT-LABEL: test_zext_cmp6:166; NOFASTLZCNT: # %bb.0: # %entry167; NOFASTLZCNT-NEXT: testl %edi, %edi168; NOFASTLZCNT-NEXT: sete %al169; NOFASTLZCNT-NEXT: testl %esi, %esi170; NOFASTLZCNT-NEXT: sete %cl171; NOFASTLZCNT-NEXT: orb %al, %cl172; NOFASTLZCNT-NEXT: testl %edx, %edx173; NOFASTLZCNT-NEXT: sete %al174; NOFASTLZCNT-NEXT: orb %cl, %al175; NOFASTLZCNT-NEXT: movzbl %al, %eax176; NOFASTLZCNT-NEXT: retq177entry:178 %cmp = icmp eq i32 %a, 0179 %cmp1 = icmp eq i32 %b, 0180 %or.cond = or i1 %cmp, %cmp1181 %cmp2 = icmp eq i32 %c, 0182 %.cmp2 = or i1 %or.cond, %cmp2183 %lor.ext = zext i1 %.cmp2 to i32184 ret i32 %lor.ext185}186 187; Test three 32-bit inputs, output is 32-bit, but compared to test_zext_cmp6 test,188; %.cmp2 inputs' order is inverted.189define i32 @test_zext_cmp7(i32 %a, i32 %b, i32 %c) {190; FASTLZCNT-LABEL: test_zext_cmp7:191; FASTLZCNT: # %bb.0: # %entry192; FASTLZCNT-NEXT: lzcntl %edi, %ecx193; FASTLZCNT-NEXT: lzcntl %edx, %eax194; FASTLZCNT-NEXT: lzcntl %esi, %esi195; FASTLZCNT-NEXT: orl %ecx, %eax196; FASTLZCNT-NEXT: orl %esi, %eax197; FASTLZCNT-NEXT: shrl $5, %eax198; FASTLZCNT-NEXT: retq199;200; NOFASTLZCNT-LABEL: test_zext_cmp7:201; NOFASTLZCNT: # %bb.0: # %entry202; NOFASTLZCNT-NEXT: testl %edi, %edi203; NOFASTLZCNT-NEXT: sete %al204; NOFASTLZCNT-NEXT: testl %esi, %esi205; NOFASTLZCNT-NEXT: sete %cl206; NOFASTLZCNT-NEXT: orb %al, %cl207; NOFASTLZCNT-NEXT: testl %edx, %edx208; NOFASTLZCNT-NEXT: sete %al209; NOFASTLZCNT-NEXT: orb %cl, %al210; NOFASTLZCNT-NEXT: movzbl %al, %eax211; NOFASTLZCNT-NEXT: retq212entry:213 %cmp = icmp eq i32 %a, 0214 %cmp1 = icmp eq i32 %b, 0215 %or.cond = or i1 %cmp, %cmp1216 %cmp2 = icmp eq i32 %c, 0217 %.cmp2 = or i1 %cmp2, %or.cond218 %lor.ext = zext i1 %.cmp2 to i32219 ret i32 %lor.ext220}221 222; Test four 32-bit inputs, output is 32-bit.223define i32 @test_zext_cmp8(i32 %a, i32 %b, i32 %c, i32 %d) {224; FASTLZCNT-LABEL: test_zext_cmp8:225; FASTLZCNT: # %bb.0: # %entry226; FASTLZCNT-NEXT: lzcntl %edi, %eax227; FASTLZCNT-NEXT: lzcntl %esi, %esi228; FASTLZCNT-NEXT: lzcntl %edx, %edx229; FASTLZCNT-NEXT: orl %eax, %esi230; FASTLZCNT-NEXT: lzcntl %ecx, %eax231; FASTLZCNT-NEXT: orl %edx, %eax232; FASTLZCNT-NEXT: orl %esi, %eax233; FASTLZCNT-NEXT: shrl $5, %eax234; FASTLZCNT-NEXT: retq235;236; NOFASTLZCNT-LABEL: test_zext_cmp8:237; NOFASTLZCNT: # %bb.0: # %entry238; NOFASTLZCNT-NEXT: testl %edi, %edi239; NOFASTLZCNT-NEXT: sete %al240; NOFASTLZCNT-NEXT: testl %esi, %esi241; NOFASTLZCNT-NEXT: sete %sil242; NOFASTLZCNT-NEXT: orb %al, %sil243; NOFASTLZCNT-NEXT: testl %edx, %edx244; NOFASTLZCNT-NEXT: sete %al245; NOFASTLZCNT-NEXT: testl %ecx, %ecx246; NOFASTLZCNT-NEXT: sete %cl247; NOFASTLZCNT-NEXT: orb %al, %cl248; NOFASTLZCNT-NEXT: orb %sil, %cl249; NOFASTLZCNT-NEXT: movzbl %cl, %eax250; NOFASTLZCNT-NEXT: retq251entry:252 %cmp = icmp eq i32 %a, 0253 %cmp1 = icmp eq i32 %b, 0254 %or.cond = or i1 %cmp, %cmp1255 %cmp3 = icmp eq i32 %c, 0256 %or.cond5 = or i1 %or.cond, %cmp3257 %cmp4 = icmp eq i32 %d, 0258 %.cmp4 = or i1 %or.cond5, %cmp4259 %lor.ext = zext i1 %.cmp4 to i32260 ret i32 %lor.ext261}262 263; Test one 32-bit input, one 64-bit input, output is 32-bit.264define i32 @test_zext_cmp9(i32 %a, i64 %b) {265; FASTLZCNT-LABEL: test_zext_cmp9:266; FASTLZCNT: # %bb.0: # %entry267; FASTLZCNT-NEXT: lzcntq %rsi, %rax268; FASTLZCNT-NEXT: lzcntl %edi, %ecx269; FASTLZCNT-NEXT: shrl $5, %ecx270; FASTLZCNT-NEXT: shrl $6, %eax271; FASTLZCNT-NEXT: orl %ecx, %eax272; FASTLZCNT-NEXT: # kill: def $eax killed $eax killed $rax273; FASTLZCNT-NEXT: retq274;275; NOFASTLZCNT-LABEL: test_zext_cmp9:276; NOFASTLZCNT: # %bb.0: # %entry277; NOFASTLZCNT-NEXT: testl %edi, %edi278; NOFASTLZCNT-NEXT: sete %al279; NOFASTLZCNT-NEXT: testq %rsi, %rsi280; NOFASTLZCNT-NEXT: sete %cl281; NOFASTLZCNT-NEXT: orb %al, %cl282; NOFASTLZCNT-NEXT: movzbl %cl, %eax283; NOFASTLZCNT-NEXT: retq284entry:285 %cmp = icmp eq i32 %a, 0286 %cmp1 = icmp eq i64 %b, 0287 %0 = or i1 %cmp, %cmp1288 %lor.ext = zext i1 %0 to i32289 ret i32 %lor.ext290}291 292; Test 2 128-bit inputs, output is 32-bit, no transformations expected.293define i32 @test_zext_cmp10(i64 %a.coerce0, i64 %a.coerce1, i64 %b.coerce0, i64 %b.coerce1) {294; ALL-LABEL: test_zext_cmp10:295; ALL: # %bb.0: # %entry296; ALL-NEXT: orq %rsi, %rdi297; ALL-NEXT: sete %al298; ALL-NEXT: orq %rcx, %rdx299; ALL-NEXT: sete %cl300; ALL-NEXT: orb %al, %cl301; ALL-NEXT: movzbl %cl, %eax302; ALL-NEXT: retq303entry:304 %a.sroa.2.0.insert.ext = zext i64 %a.coerce1 to i128305 %a.sroa.2.0.insert.shift = shl nuw i128 %a.sroa.2.0.insert.ext, 64306 %a.sroa.0.0.insert.ext = zext i64 %a.coerce0 to i128307 %a.sroa.0.0.insert.insert = or i128 %a.sroa.2.0.insert.shift, %a.sroa.0.0.insert.ext308 %b.sroa.2.0.insert.ext = zext i64 %b.coerce1 to i128309 %b.sroa.2.0.insert.shift = shl nuw i128 %b.sroa.2.0.insert.ext, 64310 %b.sroa.0.0.insert.ext = zext i64 %b.coerce0 to i128311 %b.sroa.0.0.insert.insert = or i128 %b.sroa.2.0.insert.shift, %b.sroa.0.0.insert.ext312 %cmp = icmp eq i128 %a.sroa.0.0.insert.insert, 0313 %cmp3 = icmp eq i128 %b.sroa.0.0.insert.insert, 0314 %0 = or i1 %cmp, %cmp3315 %lor.ext = zext i1 %0 to i32316 ret i32 %lor.ext317}318 319; PR31902 Fix a crash in combineOrCmpEqZeroToCtlzSrl under fast math.320define i32 @test_zext_cmp11(double %a, double %b) "no-nans-fp-math"="true" {321;322; ALL-LABEL: test_zext_cmp11:323; ALL: # %bb.0: # %entry324; ALL-NEXT: vxorpd %xmm2, %xmm2, %xmm2325; ALL-NEXT: vcmpeqsd %xmm2, %xmm1, %xmm1326; ALL-NEXT: vcmpeqsd %xmm2, %xmm0, %xmm0327; ALL-NEXT: vorpd %xmm1, %xmm0, %xmm0328; ALL-NEXT: vmovd %xmm0, %eax329; ALL-NEXT: andl $1, %eax330; ALL-NEXT: retq331entry:332 %cmp = fcmp fast oeq double %a, 0.000000e+00333 %cmp1 = fcmp fast oeq double %b, 0.000000e+00334 %0 = or i1 %cmp, %cmp1335 %conv = zext i1 %0 to i32336 ret i32 %conv337}338 339; PR54694 Fix an infinite loop in DAG combiner.340define i32 @test_zext_cmp12(i32 %0, i32 %1) {341; FASTLZCNT-LABEL: test_zext_cmp12:342; FASTLZCNT: # %bb.0:343; FASTLZCNT-NEXT: andl $131072, %edi # imm = 0x20000344; FASTLZCNT-NEXT: andl $131072, %esi # imm = 0x20000345; FASTLZCNT-NEXT: lzcntl %edi, %eax346; FASTLZCNT-NEXT: lzcntl %esi, %ecx347; FASTLZCNT-NEXT: orl %eax, %ecx348; FASTLZCNT-NEXT: movl $2, %eax349; FASTLZCNT-NEXT: shrl $5, %ecx350; FASTLZCNT-NEXT: subl %ecx, %eax351; FASTLZCNT-NEXT: retq352;353; NOFASTLZCNT-LABEL: test_zext_cmp12:354; NOFASTLZCNT: # %bb.0:355; NOFASTLZCNT-NEXT: testl $131072, %edi # imm = 0x20000356; NOFASTLZCNT-NEXT: sete %al357; NOFASTLZCNT-NEXT: testl $131072, %esi # imm = 0x20000358; NOFASTLZCNT-NEXT: sete %cl359; NOFASTLZCNT-NEXT: orb %al, %cl360; NOFASTLZCNT-NEXT: movl $2, %eax361; NOFASTLZCNT-NEXT: movzbl %cl, %ecx362; NOFASTLZCNT-NEXT: subl %ecx, %eax363; NOFASTLZCNT-NEXT: retq364 %3 = and i32 %0, 131072365 %4 = icmp eq i32 %3, 0366 %5 = and i32 %1, 131072367 %6 = icmp eq i32 %5, 0368 %7 = select i1 %4, i1 true, i1 %6369 %8 = select i1 %7, i32 1, i32 2370 ret i32 %8371}372