401 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc < %s -mtriple=x86_64-pc-linux -mattr=+bmi,+lzcnt | FileCheck %s3 4; LZCNT and TZCNT will always produce the operand size when the input operand5; is zero. This test is to verify that we efficiently select LZCNT/TZCNT6; based on the fact that the 'icmp+select' sequence is always redundant7; in every function defined below.8 9 10define i16 @test1_ctlz(i16 %v) {11; CHECK-LABEL: test1_ctlz:12; CHECK: # %bb.0:13; CHECK-NEXT: lzcntw %di, %ax14; CHECK-NEXT: retq15 %cnt = tail call i16 @llvm.ctlz.i16(i16 %v, i1 true)16 %tobool = icmp eq i16 %v, 017 %cond = select i1 %tobool, i16 16, i16 %cnt18 ret i16 %cond19}20 21 22define i32 @test2_ctlz(i32 %v) {23; CHECK-LABEL: test2_ctlz:24; CHECK: # %bb.0:25; CHECK-NEXT: lzcntl %edi, %eax26; CHECK-NEXT: retq27 %cnt = tail call i32 @llvm.ctlz.i32(i32 %v, i1 true)28 %tobool = icmp eq i32 %v, 029 %cond = select i1 %tobool, i32 32, i32 %cnt30 ret i32 %cond31}32 33 34define i64 @test3_ctlz(i64 %v) {35; CHECK-LABEL: test3_ctlz:36; CHECK: # %bb.0:37; CHECK-NEXT: lzcntq %rdi, %rax38; CHECK-NEXT: retq39 %cnt = tail call i64 @llvm.ctlz.i64(i64 %v, i1 true)40 %tobool = icmp eq i64 %v, 041 %cond = select i1 %tobool, i64 64, i64 %cnt42 ret i64 %cond43}44 45 46define i16 @test4_ctlz(i16 %v) {47; CHECK-LABEL: test4_ctlz:48; CHECK: # %bb.0:49; CHECK-NEXT: lzcntw %di, %ax50; CHECK-NEXT: retq51 %cnt = tail call i16 @llvm.ctlz.i16(i16 %v, i1 true)52 %tobool = icmp eq i16 0, %v53 %cond = select i1 %tobool, i16 16, i16 %cnt54 ret i16 %cond55}56 57 58define i32 @test5_ctlz(i32 %v) {59; CHECK-LABEL: test5_ctlz:60; CHECK: # %bb.0:61; CHECK-NEXT: lzcntl %edi, %eax62; CHECK-NEXT: retq63 %cnt = tail call i32 @llvm.ctlz.i32(i32 %v, i1 true)64 %tobool = icmp eq i32 0, %v65 %cond = select i1 %tobool, i32 32, i32 %cnt66 ret i32 %cond67}68 69 70define i64 @test6_ctlz(i64 %v) {71; CHECK-LABEL: test6_ctlz:72; CHECK: # %bb.0:73; CHECK-NEXT: lzcntq %rdi, %rax74; CHECK-NEXT: retq75 %cnt = tail call i64 @llvm.ctlz.i64(i64 %v, i1 true)76 %tobool = icmp eq i64 0, %v77 %cond = select i1 %tobool, i64 64, i64 %cnt78 ret i64 %cond79}80 81 82define i16 @test10_ctlz(ptr %ptr) {83; CHECK-LABEL: test10_ctlz:84; CHECK: # %bb.0:85; CHECK-NEXT: lzcntw (%rdi), %ax86; CHECK-NEXT: retq87 %v = load i16, ptr %ptr88 %cnt = tail call i16 @llvm.ctlz.i16(i16 %v, i1 true)89 %tobool = icmp eq i16 %v, 090 %cond = select i1 %tobool, i16 16, i16 %cnt91 ret i16 %cond92}93 94 95define i32 @test11_ctlz(ptr %ptr) {96; CHECK-LABEL: test11_ctlz:97; CHECK: # %bb.0:98; CHECK-NEXT: lzcntl (%rdi), %eax99; CHECK-NEXT: retq100 %v = load i32, ptr %ptr101 %cnt = tail call i32 @llvm.ctlz.i32(i32 %v, i1 true)102 %tobool = icmp eq i32 %v, 0103 %cond = select i1 %tobool, i32 32, i32 %cnt104 ret i32 %cond105}106 107 108define i64 @test12_ctlz(ptr %ptr) {109; CHECK-LABEL: test12_ctlz:110; CHECK: # %bb.0:111; CHECK-NEXT: lzcntq (%rdi), %rax112; CHECK-NEXT: retq113 %v = load i64, ptr %ptr114 %cnt = tail call i64 @llvm.ctlz.i64(i64 %v, i1 true)115 %tobool = icmp eq i64 %v, 0116 %cond = select i1 %tobool, i64 64, i64 %cnt117 ret i64 %cond118}119 120 121define i16 @test13_ctlz(ptr %ptr) {122; CHECK-LABEL: test13_ctlz:123; CHECK: # %bb.0:124; CHECK-NEXT: lzcntw (%rdi), %ax125; CHECK-NEXT: retq126 %v = load i16, ptr %ptr127 %cnt = tail call i16 @llvm.ctlz.i16(i16 %v, i1 true)128 %tobool = icmp eq i16 0, %v129 %cond = select i1 %tobool, i16 16, i16 %cnt130 ret i16 %cond131}132 133 134define i32 @test14_ctlz(ptr %ptr) {135; CHECK-LABEL: test14_ctlz:136; CHECK: # %bb.0:137; CHECK-NEXT: lzcntl (%rdi), %eax138; CHECK-NEXT: retq139 %v = load i32, ptr %ptr140 %cnt = tail call i32 @llvm.ctlz.i32(i32 %v, i1 true)141 %tobool = icmp eq i32 0, %v142 %cond = select i1 %tobool, i32 32, i32 %cnt143 ret i32 %cond144}145 146 147define i64 @test15_ctlz(ptr %ptr) {148; CHECK-LABEL: test15_ctlz:149; CHECK: # %bb.0:150; CHECK-NEXT: lzcntq (%rdi), %rax151; CHECK-NEXT: retq152 %v = load i64, ptr %ptr153 %cnt = tail call i64 @llvm.ctlz.i64(i64 %v, i1 true)154 %tobool = icmp eq i64 0, %v155 %cond = select i1 %tobool, i64 64, i64 %cnt156 ret i64 %cond157}158 159 160define i16 @test1_cttz(i16 %v) {161; CHECK-LABEL: test1_cttz:162; CHECK: # %bb.0:163; CHECK-NEXT: orl $65536, %edi # imm = 0x10000164; CHECK-NEXT: tzcntl %edi, %eax165; CHECK-NEXT: # kill: def $ax killed $ax killed $eax166; CHECK-NEXT: retq167 %cnt = tail call i16 @llvm.cttz.i16(i16 %v, i1 true)168 %tobool = icmp eq i16 %v, 0169 %cond = select i1 %tobool, i16 16, i16 %cnt170 ret i16 %cond171}172 173 174define i32 @test2_cttz(i32 %v) {175; CHECK-LABEL: test2_cttz:176; CHECK: # %bb.0:177; CHECK-NEXT: tzcntl %edi, %eax178; CHECK-NEXT: retq179 %cnt = tail call i32 @llvm.cttz.i32(i32 %v, i1 true)180 %tobool = icmp eq i32 %v, 0181 %cond = select i1 %tobool, i32 32, i32 %cnt182 ret i32 %cond183}184 185 186define i64 @test3_cttz(i64 %v) {187; CHECK-LABEL: test3_cttz:188; CHECK: # %bb.0:189; CHECK-NEXT: tzcntq %rdi, %rax190; CHECK-NEXT: retq191 %cnt = tail call i64 @llvm.cttz.i64(i64 %v, i1 true)192 %tobool = icmp eq i64 %v, 0193 %cond = select i1 %tobool, i64 64, i64 %cnt194 ret i64 %cond195}196 197 198define i16 @test4_cttz(i16 %v) {199; CHECK-LABEL: test4_cttz:200; CHECK: # %bb.0:201; CHECK-NEXT: orl $65536, %edi # imm = 0x10000202; CHECK-NEXT: tzcntl %edi, %eax203; CHECK-NEXT: # kill: def $ax killed $ax killed $eax204; CHECK-NEXT: retq205 %cnt = tail call i16 @llvm.cttz.i16(i16 %v, i1 true)206 %tobool = icmp eq i16 0, %v207 %cond = select i1 %tobool, i16 16, i16 %cnt208 ret i16 %cond209}210 211 212define i32 @test5_cttz(i32 %v) {213; CHECK-LABEL: test5_cttz:214; CHECK: # %bb.0:215; CHECK-NEXT: tzcntl %edi, %eax216; CHECK-NEXT: retq217 %cnt = tail call i32 @llvm.cttz.i32(i32 %v, i1 true)218 %tobool = icmp eq i32 0, %v219 %cond = select i1 %tobool, i32 32, i32 %cnt220 ret i32 %cond221}222 223 224define i64 @test6_cttz(i64 %v) {225; CHECK-LABEL: test6_cttz:226; CHECK: # %bb.0:227; CHECK-NEXT: tzcntq %rdi, %rax228; CHECK-NEXT: retq229 %cnt = tail call i64 @llvm.cttz.i64(i64 %v, i1 true)230 %tobool = icmp eq i64 0, %v231 %cond = select i1 %tobool, i64 64, i64 %cnt232 ret i64 %cond233}234 235 236define i16 @test10_cttz(ptr %ptr) {237; CHECK-LABEL: test10_cttz:238; CHECK: # %bb.0:239; CHECK-NEXT: movzwl (%rdi), %eax240; CHECK-NEXT: orl $65536, %eax # imm = 0x10000241; CHECK-NEXT: tzcntl %eax, %eax242; CHECK-NEXT: # kill: def $ax killed $ax killed $eax243; CHECK-NEXT: retq244 %v = load i16, ptr %ptr245 %cnt = tail call i16 @llvm.cttz.i16(i16 %v, i1 true)246 %tobool = icmp eq i16 %v, 0247 %cond = select i1 %tobool, i16 16, i16 %cnt248 ret i16 %cond249}250 251 252define i32 @test11_cttz(ptr %ptr) {253; CHECK-LABEL: test11_cttz:254; CHECK: # %bb.0:255; CHECK-NEXT: tzcntl (%rdi), %eax256; CHECK-NEXT: retq257 %v = load i32, ptr %ptr258 %cnt = tail call i32 @llvm.cttz.i32(i32 %v, i1 true)259 %tobool = icmp eq i32 %v, 0260 %cond = select i1 %tobool, i32 32, i32 %cnt261 ret i32 %cond262}263 264 265define i64 @test12_cttz(ptr %ptr) {266; CHECK-LABEL: test12_cttz:267; CHECK: # %bb.0:268; CHECK-NEXT: tzcntq (%rdi), %rax269; CHECK-NEXT: retq270 %v = load i64, ptr %ptr271 %cnt = tail call i64 @llvm.cttz.i64(i64 %v, i1 true)272 %tobool = icmp eq i64 %v, 0273 %cond = select i1 %tobool, i64 64, i64 %cnt274 ret i64 %cond275}276 277 278define i16 @test13_cttz(ptr %ptr) {279; CHECK-LABEL: test13_cttz:280; CHECK: # %bb.0:281; CHECK-NEXT: movzwl (%rdi), %eax282; CHECK-NEXT: orl $65536, %eax # imm = 0x10000283; CHECK-NEXT: tzcntl %eax, %eax284; CHECK-NEXT: # kill: def $ax killed $ax killed $eax285; CHECK-NEXT: retq286 %v = load i16, ptr %ptr287 %cnt = tail call i16 @llvm.cttz.i16(i16 %v, i1 true)288 %tobool = icmp eq i16 0, %v289 %cond = select i1 %tobool, i16 16, i16 %cnt290 ret i16 %cond291}292 293 294define i32 @test14_cttz(ptr %ptr) {295; CHECK-LABEL: test14_cttz:296; CHECK: # %bb.0:297; CHECK-NEXT: tzcntl (%rdi), %eax298; CHECK-NEXT: retq299 %v = load i32, ptr %ptr300 %cnt = tail call i32 @llvm.cttz.i32(i32 %v, i1 true)301 %tobool = icmp eq i32 0, %v302 %cond = select i1 %tobool, i32 32, i32 %cnt303 ret i32 %cond304}305 306 307define i64 @test15_cttz(ptr %ptr) {308; CHECK-LABEL: test15_cttz:309; CHECK: # %bb.0:310; CHECK-NEXT: tzcntq (%rdi), %rax311; CHECK-NEXT: retq312 %v = load i64, ptr %ptr313 %cnt = tail call i64 @llvm.cttz.i64(i64 %v, i1 true)314 %tobool = icmp eq i64 0, %v315 %cond = select i1 %tobool, i64 64, i64 %cnt316 ret i64 %cond317}318 319 320define i16 @test4b_ctlz(i16 %v) {321; CHECK-LABEL: test4b_ctlz:322; CHECK: # %bb.0:323; CHECK-NEXT: lzcntw %di, %ax324; CHECK-NEXT: retq325 %cnt = tail call i16 @llvm.ctlz.i16(i16 %v, i1 true)326 %tobool = icmp ne i16 %v, 0327 %cond = select i1 %tobool, i16 %cnt, i16 16328 ret i16 %cond329}330 331 332define i32 @test5b_ctlz(i32 %v) {333; CHECK-LABEL: test5b_ctlz:334; CHECK: # %bb.0:335; CHECK-NEXT: lzcntl %edi, %eax336; CHECK-NEXT: retq337 %cnt = tail call i32 @llvm.ctlz.i32(i32 %v, i1 true)338 %tobool = icmp ne i32 %v, 0339 %cond = select i1 %tobool, i32 %cnt, i32 32340 ret i32 %cond341}342 343 344define i64 @test6b_ctlz(i64 %v) {345; CHECK-LABEL: test6b_ctlz:346; CHECK: # %bb.0:347; CHECK-NEXT: lzcntq %rdi, %rax348; CHECK-NEXT: retq349 %cnt = tail call i64 @llvm.ctlz.i64(i64 %v, i1 true)350 %tobool = icmp ne i64 %v, 0351 %cond = select i1 %tobool, i64 %cnt, i64 64352 ret i64 %cond353}354 355 356define i16 @test4b_cttz(i16 %v) {357; CHECK-LABEL: test4b_cttz:358; CHECK: # %bb.0:359; CHECK-NEXT: orl $65536, %edi # imm = 0x10000360; CHECK-NEXT: tzcntl %edi, %eax361; CHECK-NEXT: # kill: def $ax killed $ax killed $eax362; CHECK-NEXT: retq363 %cnt = tail call i16 @llvm.cttz.i16(i16 %v, i1 true)364 %tobool = icmp ne i16 %v, 0365 %cond = select i1 %tobool, i16 %cnt, i16 16366 ret i16 %cond367}368 369 370define i32 @test5b_cttz(i32 %v) {371; CHECK-LABEL: test5b_cttz:372; CHECK: # %bb.0:373; CHECK-NEXT: tzcntl %edi, %eax374; CHECK-NEXT: retq375 %cnt = tail call i32 @llvm.cttz.i32(i32 %v, i1 true)376 %tobool = icmp ne i32 %v, 0377 %cond = select i1 %tobool, i32 %cnt, i32 32378 ret i32 %cond379}380 381 382define i64 @test6b_cttz(i64 %v) {383; CHECK-LABEL: test6b_cttz:384; CHECK: # %bb.0:385; CHECK-NEXT: tzcntq %rdi, %rax386; CHECK-NEXT: retq387 %cnt = tail call i64 @llvm.cttz.i64(i64 %v, i1 true)388 %tobool = icmp ne i64 %v, 0389 %cond = select i1 %tobool, i64 %cnt, i64 64390 ret i64 %cond391}392 393 394declare i64 @llvm.cttz.i64(i64, i1)395declare i32 @llvm.cttz.i32(i32, i1)396declare i16 @llvm.cttz.i16(i16, i1)397declare i64 @llvm.ctlz.i64(i64, i1)398declare i32 @llvm.ctlz.i32(i32, i1)399declare i16 @llvm.ctlz.i16(i16, i1)400 401