1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc < %s -mtriple=i686-unknown-unknown | FileCheck %s --check-prefixes=X86,X86-NOCMOV 3; RUN: llc < %s -mtriple=i686-unknown-unknown -mattr=+cmov | FileCheck %s --check-prefixes=X86,X86-CMOV 4; RUN: llc < %s -mtriple=x86_64-unknown-unknown | FileCheck %s --check-prefix=X64 5; RUN: llc < %s -mtriple=i686-unknown-unknown -mattr=+bmi,+lzcnt | FileCheck %s --check-prefix=X86-CLZ 6; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+bmi,+lzcnt | FileCheck %s --check-prefix=X64-CLZ 7; RUN: llc < %s -mtriple=i686-unknown-unknown -mattr=+bmi,+lzcnt,+fast-lzcnt | FileCheck %s --check-prefix=X86-CLZ 8; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+bmi,+lzcnt,+fast-lzcnt | FileCheck %s --check-prefix=X64-CLZ 9 10declare i8 @llvm.ctlz.i8(i8, i1) 11declare i16 @llvm.ctlz.i16(i16, i1) 12declare i32 @llvm.ctlz.i32(i32, i1) 13declare i64 @llvm.ctlz.i64(i64, i1) 14 15define i8 @ctlo_i8(i8 %x) { 16; X86-NOCMOV-LABEL: ctlo_i8: 17; X86-NOCMOV: # %bb.0: 18; X86-NOCMOV-NEXT: movzbl {{[0-9]+}}(%esp), %eax 19; X86-NOCMOV-NEXT: xorb $-1, %al 20; X86-NOCMOV-NEXT: je .LBB0_1 21; X86-NOCMOV-NEXT: # %bb.2: # %cond.false 22; X86-NOCMOV-NEXT: movzbl %al, %eax 23; X86-NOCMOV-NEXT: bsrl %eax, %eax 24; X86-NOCMOV-NEXT: xorl $7, %eax 25; X86-NOCMOV-NEXT: # kill: def $al killed $al killed $eax 26; X86-NOCMOV-NEXT: retl 27; X86-NOCMOV-NEXT: .LBB0_1: 28; X86-NOCMOV-NEXT: movb $8, %al 29; X86-NOCMOV-NEXT: # kill: def $al killed $al killed $eax 30; X86-NOCMOV-NEXT: retl 31; 32; X86-CMOV-LABEL: ctlo_i8: 33; X86-CMOV: # %bb.0: 34; X86-CMOV-NEXT: movzbl {{[0-9]+}}(%esp), %eax 35; X86-CMOV-NEXT: notb %al 36; X86-CMOV-NEXT: movzbl %al, %eax 37; X86-CMOV-NEXT: bsrl %eax, %ecx 38; X86-CMOV-NEXT: movl $15, %eax 39; X86-CMOV-NEXT: cmovnel %ecx, %eax 40; X86-CMOV-NEXT: xorl $7, %eax 41; X86-CMOV-NEXT: # kill: def $al killed $al killed $eax 42; X86-CMOV-NEXT: retl 43; 44; X64-LABEL: ctlo_i8: 45; X64: # %bb.0: 46; X64-NEXT: notb %dil 47; X64-NEXT: movzbl %dil, %ecx 48; X64-NEXT: movl $15, %eax 49; X64-NEXT: bsrl %ecx, %eax 50; X64-NEXT: xorl $7, %eax 51; X64-NEXT: # kill: def $al killed $al killed $eax 52; X64-NEXT: retq 53; 54; X86-CLZ-LABEL: ctlo_i8: 55; X86-CLZ: # %bb.0: 56; X86-CLZ-NEXT: movl {{[0-9]+}}(%esp), %eax 57; X86-CLZ-NEXT: shll $24, %eax 58; X86-CLZ-NEXT: notl %eax 59; X86-CLZ-NEXT: lzcntl %eax, %eax 60; X86-CLZ-NEXT: # kill: def $al killed $al killed $eax 61; X86-CLZ-NEXT: retl 62; 63; X64-CLZ-LABEL: ctlo_i8: 64; X64-CLZ: # %bb.0: 65; X64-CLZ-NEXT: shll $24, %edi 66; X64-CLZ-NEXT: notl %edi 67; X64-CLZ-NEXT: lzcntl %edi, %eax 68; X64-CLZ-NEXT: # kill: def $al killed $al killed $eax 69; X64-CLZ-NEXT: retq 70 %tmp1 = xor i8 %x, -1 71 %tmp2 = call i8 @llvm.ctlz.i8( i8 %tmp1, i1 false ) 72 ret i8 %tmp2 73} 74 75define i8 @ctlo_i8_undef(i8 %x) { 76; X86-LABEL: ctlo_i8_undef: 77; X86: # %bb.0: 78; X86-NEXT: movzbl {{[0-9]+}}(%esp), %eax 79; X86-NEXT: notb %al 80; X86-NEXT: movzbl %al, %eax 81; X86-NEXT: bsrl %eax, %eax 82; X86-NEXT: xorl $7, %eax 83; X86-NEXT: # kill: def $al killed $al killed $eax 84; X86-NEXT: retl 85; 86; X64-LABEL: ctlo_i8_undef: 87; X64: # %bb.0: 88; X64-NEXT: notb %dil 89; X64-NEXT: movzbl %dil, %eax 90; X64-NEXT: bsrl %eax, %eax 91; X64-NEXT: xorl $7, %eax 92; X64-NEXT: # kill: def $al killed $al killed $eax 93; X64-NEXT: retq 94; 95; X86-CLZ-LABEL: ctlo_i8_undef: 96; X86-CLZ: # %bb.0: 97; X86-CLZ-NEXT: movzbl {{[0-9]+}}(%esp), %eax 98; X86-CLZ-NEXT: notb %al 99; X86-CLZ-NEXT: movzbl %al, %eax 100; X86-CLZ-NEXT: shll $24, %eax 101; X86-CLZ-NEXT: lzcntl %eax, %eax 102; X86-CLZ-NEXT: # kill: def $al killed $al killed $eax 103; X86-CLZ-NEXT: retl 104; 105; X64-CLZ-LABEL: ctlo_i8_undef: 106; X64-CLZ: # %bb.0: 107; X64-CLZ-NEXT: notb %dil 108; X64-CLZ-NEXT: movzbl %dil, %eax 109; X64-CLZ-NEXT: shll $24, %eax 110; X64-CLZ-NEXT: lzcntl %eax, %eax 111; X64-CLZ-NEXT: # kill: def $al killed $al killed $eax 112; X64-CLZ-NEXT: retq 113 %tmp1 = xor i8 %x, -1 114 %tmp2 = call i8 @llvm.ctlz.i8( i8 %tmp1, i1 true ) 115 ret i8 %tmp2 116} 117 118define i16 @ctlo_i16(i16 %x) { 119; X86-NOCMOV-LABEL: ctlo_i16: 120; X86-NOCMOV: # %bb.0: 121; X86-NOCMOV-NEXT: movzwl {{[0-9]+}}(%esp), %eax 122; X86-NOCMOV-NEXT: xorw $-1, %ax 123; X86-NOCMOV-NEXT: je .LBB2_1 124; X86-NOCMOV-NEXT: # %bb.2: # %cond.false 125; X86-NOCMOV-NEXT: bsrw %ax, %ax 126; X86-NOCMOV-NEXT: xorl $15, %eax 127; X86-NOCMOV-NEXT: # kill: def $ax killed $ax killed $eax 128; X86-NOCMOV-NEXT: retl 129; X86-NOCMOV-NEXT: .LBB2_1: 130; X86-NOCMOV-NEXT: movw $16, %ax 131; X86-NOCMOV-NEXT: # kill: def $ax killed $ax killed $eax 132; X86-NOCMOV-NEXT: retl 133; 134; X86-CMOV-LABEL: ctlo_i16: 135; X86-CMOV: # %bb.0: 136; X86-CMOV-NEXT: movl {{[0-9]+}}(%esp), %eax 137; X86-CMOV-NEXT: notl %eax 138; X86-CMOV-NEXT: bsrw %ax, %cx 139; X86-CMOV-NEXT: movw $31, %ax 140; X86-CMOV-NEXT: cmovnew %cx, %ax 141; X86-CMOV-NEXT: xorl $15, %eax 142; X86-CMOV-NEXT: # kill: def $ax killed $ax killed $eax 143; X86-CMOV-NEXT: retl 144; 145; X64-LABEL: ctlo_i16: 146; X64: # %bb.0: 147; X64-NEXT: notl %edi 148; X64-NEXT: movw $31, %ax 149; X64-NEXT: bsrw %di, %ax 150; X64-NEXT: xorl $15, %eax 151; X64-NEXT: # kill: def $ax killed $ax killed $eax 152; X64-NEXT: retq 153; 154; X86-CLZ-LABEL: ctlo_i16: 155; X86-CLZ: # %bb.0: 156; X86-CLZ-NEXT: movl {{[0-9]+}}(%esp), %eax 157; X86-CLZ-NEXT: notl %eax 158; X86-CLZ-NEXT: lzcntw %ax, %ax 159; X86-CLZ-NEXT: retl 160; 161; X64-CLZ-LABEL: ctlo_i16: 162; X64-CLZ: # %bb.0: 163; X64-CLZ-NEXT: notl %edi 164; X64-CLZ-NEXT: lzcntw %di, %ax 165; X64-CLZ-NEXT: retq 166 %tmp1 = xor i16 %x, -1 167 %tmp2 = call i16 @llvm.ctlz.i16( i16 %tmp1, i1 false ) 168 ret i16 %tmp2 169} 170 171define i16 @ctlo_i16_undef(i16 %x) { 172; X86-LABEL: ctlo_i16_undef: 173; X86: # %bb.0: 174; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 175; X86-NEXT: notl %eax 176; X86-NEXT: bsrw %ax, %ax 177; X86-NEXT: xorl $15, %eax 178; X86-NEXT: # kill: def $ax killed $ax killed $eax 179; X86-NEXT: retl 180; 181; X64-LABEL: ctlo_i16_undef: 182; X64: # %bb.0: 183; X64-NEXT: notl %edi 184; X64-NEXT: bsrw %di, %ax 185; X64-NEXT: xorl $15, %eax 186; X64-NEXT: # kill: def $ax killed $ax killed $eax 187; X64-NEXT: retq 188; 189; X86-CLZ-LABEL: ctlo_i16_undef: 190; X86-CLZ: # %bb.0: 191; X86-CLZ-NEXT: movl {{[0-9]+}}(%esp), %eax 192; X86-CLZ-NEXT: notl %eax 193; X86-CLZ-NEXT: lzcntw %ax, %ax 194; X86-CLZ-NEXT: retl 195; 196; X64-CLZ-LABEL: ctlo_i16_undef: 197; X64-CLZ: # %bb.0: 198; X64-CLZ-NEXT: notl %edi 199; X64-CLZ-NEXT: lzcntw %di, %ax 200; X64-CLZ-NEXT: retq 201 %tmp1 = xor i16 %x, -1 202 %tmp2 = call i16 @llvm.ctlz.i16( i16 %tmp1, i1 true ) 203 ret i16 %tmp2 204} 205 206define i32 @ctlo_i32(i32 %x) { 207; X86-NOCMOV-LABEL: ctlo_i32: 208; X86-NOCMOV: # %bb.0: 209; X86-NOCMOV-NEXT: movl {{[0-9]+}}(%esp), %eax 210; X86-NOCMOV-NEXT: xorl $-1, %eax 211; X86-NOCMOV-NEXT: je .LBB4_1 212; X86-NOCMOV-NEXT: # %bb.2: # %cond.false 213; X86-NOCMOV-NEXT: bsrl %eax, %eax 214; X86-NOCMOV-NEXT: xorl $31, %eax 215; X86-NOCMOV-NEXT: retl 216; X86-NOCMOV-NEXT: .LBB4_1: 217; X86-NOCMOV-NEXT: movl $32, %eax 218; X86-NOCMOV-NEXT: retl 219; 220; X86-CMOV-LABEL: ctlo_i32: 221; X86-CMOV: # %bb.0: 222; X86-CMOV-NEXT: movl {{[0-9]+}}(%esp), %eax 223; X86-CMOV-NEXT: notl %eax 224; X86-CMOV-NEXT: bsrl %eax, %ecx 225; X86-CMOV-NEXT: movl $63, %eax 226; X86-CMOV-NEXT: cmovnel %ecx, %eax 227; X86-CMOV-NEXT: xorl $31, %eax 228; X86-CMOV-NEXT: retl 229; 230; X64-LABEL: ctlo_i32: 231; X64: # %bb.0: 232; X64-NEXT: notl %edi 233; X64-NEXT: movl $63, %eax 234; X64-NEXT: bsrl %edi, %eax 235; X64-NEXT: xorl $31, %eax 236; X64-NEXT: retq 237; 238; X86-CLZ-LABEL: ctlo_i32: 239; X86-CLZ: # %bb.0: 240; X86-CLZ-NEXT: movl {{[0-9]+}}(%esp), %eax 241; X86-CLZ-NEXT: notl %eax 242; X86-CLZ-NEXT: lzcntl %eax, %eax 243; X86-CLZ-NEXT: retl 244; 245; X64-CLZ-LABEL: ctlo_i32: 246; X64-CLZ: # %bb.0: 247; X64-CLZ-NEXT: notl %edi 248; X64-CLZ-NEXT: lzcntl %edi, %eax 249; X64-CLZ-NEXT: retq 250 %tmp1 = xor i32 %x, -1 251 %tmp2 = call i32 @llvm.ctlz.i32( i32 %tmp1, i1 false ) 252 ret i32 %tmp2 253} 254 255define i32 @ctlo_i32_undef(i32 %x) { 256; X86-LABEL: ctlo_i32_undef: 257; X86: # %bb.0: 258; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 259; X86-NEXT: notl %eax 260; X86-NEXT: bsrl %eax, %eax 261; X86-NEXT: xorl $31, %eax 262; X86-NEXT: retl 263; 264; X64-LABEL: ctlo_i32_undef: 265; X64: # %bb.0: 266; X64-NEXT: notl %edi 267; X64-NEXT: bsrl %edi, %eax 268; X64-NEXT: xorl $31, %eax 269; X64-NEXT: retq 270; 271; X86-CLZ-LABEL: ctlo_i32_undef: 272; X86-CLZ: # %bb.0: 273; X86-CLZ-NEXT: movl {{[0-9]+}}(%esp), %eax 274; X86-CLZ-NEXT: notl %eax 275; X86-CLZ-NEXT: lzcntl %eax, %eax 276; X86-CLZ-NEXT: retl 277; 278; X64-CLZ-LABEL: ctlo_i32_undef: 279; X64-CLZ: # %bb.0: 280; X64-CLZ-NEXT: notl %edi 281; X64-CLZ-NEXT: lzcntl %edi, %eax 282; X64-CLZ-NEXT: retq 283 %tmp1 = xor i32 %x, -1 284 %tmp2 = call i32 @llvm.ctlz.i32( i32 %tmp1, i1 true ) 285 ret i32 %tmp2 286} 287 288define i64 @ctlo_i64(i64 %x) { 289; X86-NOCMOV-LABEL: ctlo_i64: 290; X86-NOCMOV: # %bb.0: 291; X86-NOCMOV-NEXT: movl {{[0-9]+}}(%esp), %eax 292; X86-NOCMOV-NEXT: movl {{[0-9]+}}(%esp), %ecx 293; X86-NOCMOV-NEXT: notl %ecx 294; X86-NOCMOV-NEXT: notl %eax 295; X86-NOCMOV-NEXT: bsrl %eax, %edx 296; X86-NOCMOV-NEXT: movl $63, %eax 297; X86-NOCMOV-NEXT: je .LBB6_2 298; X86-NOCMOV-NEXT: # %bb.1: 299; X86-NOCMOV-NEXT: movl %edx, %eax 300; X86-NOCMOV-NEXT: .LBB6_2: 301; X86-NOCMOV-NEXT: testl %ecx, %ecx 302; X86-NOCMOV-NEXT: jne .LBB6_3 303; X86-NOCMOV-NEXT: # %bb.4: 304; X86-NOCMOV-NEXT: xorl $31, %eax 305; X86-NOCMOV-NEXT: addl $32, %eax 306; X86-NOCMOV-NEXT: xorl %edx, %edx 307; X86-NOCMOV-NEXT: retl 308; X86-NOCMOV-NEXT: .LBB6_3: 309; X86-NOCMOV-NEXT: bsrl %ecx, %eax 310; X86-NOCMOV-NEXT: xorl $31, %eax 311; X86-NOCMOV-NEXT: xorl %edx, %edx 312; X86-NOCMOV-NEXT: retl 313; 314; X86-CMOV-LABEL: ctlo_i64: 315; X86-CMOV: # %bb.0: 316; X86-CMOV-NEXT: movl {{[0-9]+}}(%esp), %eax 317; X86-CMOV-NEXT: movl {{[0-9]+}}(%esp), %ecx 318; X86-CMOV-NEXT: notl %ecx 319; X86-CMOV-NEXT: notl %eax 320; X86-CMOV-NEXT: bsrl %eax, %eax 321; X86-CMOV-NEXT: movl $63, %edx 322; X86-CMOV-NEXT: cmovnel %eax, %edx 323; X86-CMOV-NEXT: xorl $31, %edx 324; X86-CMOV-NEXT: addl $32, %edx 325; X86-CMOV-NEXT: bsrl %ecx, %eax 326; X86-CMOV-NEXT: xorl $31, %eax 327; X86-CMOV-NEXT: testl %ecx, %ecx 328; X86-CMOV-NEXT: cmovel %edx, %eax 329; X86-CMOV-NEXT: xorl %edx, %edx 330; X86-CMOV-NEXT: retl 331; 332; X64-LABEL: ctlo_i64: 333; X64: # %bb.0: 334; X64-NEXT: notq %rdi 335; X64-NEXT: movl $127, %eax 336; X64-NEXT: bsrq %rdi, %rax 337; X64-NEXT: xorq $63, %rax 338; X64-NEXT: retq 339; 340; X86-CLZ-LABEL: ctlo_i64: 341; X86-CLZ: # %bb.0: 342; X86-CLZ-NEXT: movl {{[0-9]+}}(%esp), %eax 343; X86-CLZ-NEXT: notl %eax 344; X86-CLZ-NEXT: testl %eax, %eax 345; X86-CLZ-NEXT: jne .LBB6_1 346; X86-CLZ-NEXT: # %bb.2: 347; X86-CLZ-NEXT: movl {{[0-9]+}}(%esp), %eax 348; X86-CLZ-NEXT: notl %eax 349; X86-CLZ-NEXT: lzcntl %eax, %eax 350; X86-CLZ-NEXT: addl $32, %eax 351; X86-CLZ-NEXT: xorl %edx, %edx 352; X86-CLZ-NEXT: retl 353; X86-CLZ-NEXT: .LBB6_1: 354; X86-CLZ-NEXT: lzcntl %eax, %eax 355; X86-CLZ-NEXT: xorl %edx, %edx 356; X86-CLZ-NEXT: retl 357; 358; X64-CLZ-LABEL: ctlo_i64: 359; X64-CLZ: # %bb.0: 360; X64-CLZ-NEXT: notq %rdi 361; X64-CLZ-NEXT: lzcntq %rdi, %rax 362; X64-CLZ-NEXT: retq 363 %tmp1 = xor i64 %x, -1 364 %tmp2 = call i64 @llvm.ctlz.i64( i64 %tmp1, i1 false ) 365 ret i64 %tmp2 366} 367 368define i64 @ctlo_i64_undef(i64 %x) { 369; X86-NOCMOV-LABEL: ctlo_i64_undef: 370; X86-NOCMOV: # %bb.0: 371; X86-NOCMOV-NEXT: movl {{[0-9]+}}(%esp), %eax 372; X86-NOCMOV-NEXT: notl %eax 373; X86-NOCMOV-NEXT: testl %eax, %eax 374; X86-NOCMOV-NEXT: jne .LBB7_1 375; X86-NOCMOV-NEXT: # %bb.2: 376; X86-NOCMOV-NEXT: movl {{[0-9]+}}(%esp), %eax 377; X86-NOCMOV-NEXT: notl %eax 378; X86-NOCMOV-NEXT: bsrl %eax, %eax 379; X86-NOCMOV-NEXT: xorl $31, %eax 380; X86-NOCMOV-NEXT: orl $32, %eax 381; X86-NOCMOV-NEXT: xorl %edx, %edx 382; X86-NOCMOV-NEXT: retl 383; X86-NOCMOV-NEXT: .LBB7_1: 384; X86-NOCMOV-NEXT: bsrl %eax, %eax 385; X86-NOCMOV-NEXT: xorl $31, %eax 386; X86-NOCMOV-NEXT: xorl %edx, %edx 387; X86-NOCMOV-NEXT: retl 388; 389; X86-CMOV-LABEL: ctlo_i64_undef: 390; X86-CMOV: # %bb.0: 391; X86-CMOV-NEXT: movl {{[0-9]+}}(%esp), %eax 392; X86-CMOV-NEXT: movl {{[0-9]+}}(%esp), %ecx 393; X86-CMOV-NEXT: notl %eax 394; X86-CMOV-NEXT: notl %ecx 395; X86-CMOV-NEXT: bsrl %ecx, %edx 396; X86-CMOV-NEXT: xorl $31, %edx 397; X86-CMOV-NEXT: bsrl %eax, %eax 398; X86-CMOV-NEXT: xorl $31, %eax 399; X86-CMOV-NEXT: orl $32, %eax 400; X86-CMOV-NEXT: testl %ecx, %ecx 401; X86-CMOV-NEXT: cmovnel %edx, %eax 402; X86-CMOV-NEXT: xorl %edx, %edx 403; X86-CMOV-NEXT: retl 404; 405; X64-LABEL: ctlo_i64_undef: 406; X64: # %bb.0: 407; X64-NEXT: notq %rdi 408; X64-NEXT: bsrq %rdi, %rax 409; X64-NEXT: xorq $63, %rax 410; X64-NEXT: retq 411; 412; X86-CLZ-LABEL: ctlo_i64_undef: 413; X86-CLZ: # %bb.0: 414; X86-CLZ-NEXT: movl {{[0-9]+}}(%esp), %eax 415; X86-CLZ-NEXT: notl %eax 416; X86-CLZ-NEXT: testl %eax, %eax 417; X86-CLZ-NEXT: jne .LBB7_1 418; X86-CLZ-NEXT: # %bb.2: 419; X86-CLZ-NEXT: movl {{[0-9]+}}(%esp), %eax 420; X86-CLZ-NEXT: notl %eax 421; X86-CLZ-NEXT: lzcntl %eax, %eax 422; X86-CLZ-NEXT: addl $32, %eax 423; X86-CLZ-NEXT: xorl %edx, %edx 424; X86-CLZ-NEXT: retl 425; X86-CLZ-NEXT: .LBB7_1: 426; X86-CLZ-NEXT: lzcntl %eax, %eax 427; X86-CLZ-NEXT: xorl %edx, %edx 428; X86-CLZ-NEXT: retl 429; 430; X64-CLZ-LABEL: ctlo_i64_undef: 431; X64-CLZ: # %bb.0: 432; X64-CLZ-NEXT: notq %rdi 433; X64-CLZ-NEXT: lzcntq %rdi, %rax 434; X64-CLZ-NEXT: retq 435 %tmp1 = xor i64 %x, -1 436 %tmp2 = call i64 @llvm.ctlz.i64( i64 %tmp1, i1 true ) 437 ret i64 %tmp2 438} 439