1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc < %s -fast-isel -mtriple=i686-unknown-unknown -mattr=+bmi | FileCheck %s --check-prefix=X86 3; RUN: llc < %s -fast-isel -mtriple=x86_64-unknown-unknown -mattr=+bmi | FileCheck %s --check-prefix=X64 4; RUN: llc < %s -fast-isel -mtriple=x86_64-unknown-unknown -mattr=+bmi,+egpr --show-mc-encoding | FileCheck %s --check-prefix=EGPR 5; NOTE: This should use IR equivalent to what is generated by clang/test/CodeGen/bmi-builtins.c 6 7; 8; AMD Intrinsics 9; 10 11define i16 @test__tzcnt_u16(i16 %a0) { 12; X86-LABEL: test__tzcnt_u16: 13; X86: # %bb.0: 14; X86-NEXT: movzwl {{[0-9]+}}(%esp), %eax 15; X86-NEXT: orl $65536, %eax # imm = 0x10000 16; X86-NEXT: tzcntl %eax, %eax 17; X86-NEXT: # kill: def $ax killed $ax killed $eax 18; X86-NEXT: retl 19; 20; X64-LABEL: test__tzcnt_u16: 21; X64: # %bb.0: 22; X64-NEXT: orl $65536, %edi # imm = 0x10000 23; X64-NEXT: tzcntl %edi, %eax 24; X64-NEXT: # kill: def $ax killed $ax killed $eax 25; X64-NEXT: retq 26; 27; EGPR-LABEL: test__tzcnt_u16: 28; EGPR: # %bb.0: 29; EGPR-NEXT: orl $65536, %edi # encoding: [0x81,0xcf,0x00,0x00,0x01,0x00] 30; EGPR-NEXT: # imm = 0x10000 31; EGPR-NEXT: tzcntl %edi, %eax # encoding: [0xf3,0x0f,0xbc,0xc7] 32; EGPR-NEXT: # kill: def $ax killed $ax killed $eax 33; EGPR-NEXT: retq # encoding: [0xc3] 34 %zext = zext i16 %a0 to i32 35 %cmp = icmp ne i32 %zext, 0 36 %cttz = call i16 @llvm.cttz.i16(i16 %a0, i1 false) 37 ret i16 %cttz 38} 39 40define i32 @test__andn_u32(i32 %a0, i32 %a1) { 41; X86-LABEL: test__andn_u32: 42; X86: # %bb.0: 43; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 44; X86-NEXT: xorl $-1, %eax 45; X86-NEXT: andl {{[0-9]+}}(%esp), %eax 46; X86-NEXT: retl 47; 48; X64-LABEL: test__andn_u32: 49; X64: # %bb.0: 50; X64-NEXT: movl %edi, %eax 51; X64-NEXT: xorl $-1, %eax 52; X64-NEXT: andl %esi, %eax 53; X64-NEXT: retq 54; 55; EGPR-LABEL: test__andn_u32: 56; EGPR: # %bb.0: 57; EGPR-NEXT: movl %edi, %eax # encoding: [0x89,0xf8] 58; EGPR-NEXT: xorl $-1, %eax # encoding: [0x83,0xf0,0xff] 59; EGPR-NEXT: andl %esi, %eax # encoding: [0x21,0xf0] 60; EGPR-NEXT: retq # encoding: [0xc3] 61 %xor = xor i32 %a0, -1 62 %res = and i32 %xor, %a1 63 ret i32 %res 64} 65 66define i32 @test__bextr_u32(i32 %a0, i32 %a1) { 67; X86-LABEL: test__bextr_u32: 68; X86: # %bb.0: 69; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 70; X86-NEXT: bextrl %eax, {{[0-9]+}}(%esp), %eax 71; X86-NEXT: retl 72; 73; X64-LABEL: test__bextr_u32: 74; X64: # %bb.0: 75; X64-NEXT: bextrl %esi, %edi, %eax 76; X64-NEXT: retq 77; 78; EGPR-LABEL: test__bextr_u32: 79; EGPR: # %bb.0: 80; EGPR-NEXT: bextrl %esi, %edi, %eax # EVEX TO VEX Compression encoding: [0xc4,0xe2,0x48,0xf7,0xc7] 81; EGPR-NEXT: retq # encoding: [0xc3] 82 %res = call i32 @llvm.x86.bmi.bextr.32(i32 %a0, i32 %a1) 83 ret i32 %res 84} 85 86define i32 @test__blsi_u32(i32 %a0) { 87; X86-LABEL: test__blsi_u32: 88; X86: # %bb.0: 89; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 90; X86-NEXT: xorl %eax, %eax 91; X86-NEXT: subl %ecx, %eax 92; X86-NEXT: andl %ecx, %eax 93; X86-NEXT: retl 94; 95; X64-LABEL: test__blsi_u32: 96; X64: # %bb.0: 97; X64-NEXT: xorl %eax, %eax 98; X64-NEXT: subl %edi, %eax 99; X64-NEXT: andl %edi, %eax 100; X64-NEXT: retq 101; 102; EGPR-LABEL: test__blsi_u32: 103; EGPR: # %bb.0: 104; EGPR-NEXT: xorl %eax, %eax # encoding: [0x31,0xc0] 105; EGPR-NEXT: subl %edi, %eax # encoding: [0x29,0xf8] 106; EGPR-NEXT: andl %edi, %eax # encoding: [0x21,0xf8] 107; EGPR-NEXT: retq # encoding: [0xc3] 108 %neg = sub i32 0, %a0 109 %res = and i32 %a0, %neg 110 ret i32 %res 111} 112 113define i32 @test__blsmsk_u32(i32 %a0) { 114; X86-LABEL: test__blsmsk_u32: 115; X86: # %bb.0: 116; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 117; X86-NEXT: leal -1(%ecx), %eax 118; X86-NEXT: xorl %ecx, %eax 119; X86-NEXT: retl 120; 121; X64-LABEL: test__blsmsk_u32: 122; X64: # %bb.0: 123; X64-NEXT: # kill: def $edi killed $edi def $rdi 124; X64-NEXT: leal -1(%rdi), %eax 125; X64-NEXT: xorl %edi, %eax 126; X64-NEXT: retq 127; 128; EGPR-LABEL: test__blsmsk_u32: 129; EGPR: # %bb.0: 130; EGPR-NEXT: # kill: def $edi killed $edi def $rdi 131; EGPR-NEXT: leal -1(%rdi), %eax # encoding: [0x8d,0x47,0xff] 132; EGPR-NEXT: xorl %edi, %eax # encoding: [0x31,0xf8] 133; EGPR-NEXT: retq # encoding: [0xc3] 134 %dec = sub i32 %a0, 1 135 %res = xor i32 %a0, %dec 136 ret i32 %res 137} 138 139define i32 @test__blsr_u32(i32 %a0) { 140; X86-LABEL: test__blsr_u32: 141; X86: # %bb.0: 142; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 143; X86-NEXT: leal -1(%ecx), %eax 144; X86-NEXT: andl %ecx, %eax 145; X86-NEXT: retl 146; 147; X64-LABEL: test__blsr_u32: 148; X64: # %bb.0: 149; X64-NEXT: # kill: def $edi killed $edi def $rdi 150; X64-NEXT: leal -1(%rdi), %eax 151; X64-NEXT: andl %edi, %eax 152; X64-NEXT: retq 153; 154; EGPR-LABEL: test__blsr_u32: 155; EGPR: # %bb.0: 156; EGPR-NEXT: # kill: def $edi killed $edi def $rdi 157; EGPR-NEXT: leal -1(%rdi), %eax # encoding: [0x8d,0x47,0xff] 158; EGPR-NEXT: andl %edi, %eax # encoding: [0x21,0xf8] 159; EGPR-NEXT: retq # encoding: [0xc3] 160 %dec = sub i32 %a0, 1 161 %res = and i32 %a0, %dec 162 ret i32 %res 163} 164 165define i32 @test__tzcnt_u32(i32 %a0) { 166; X86-LABEL: test__tzcnt_u32: 167; X86: # %bb.0: 168; X86-NEXT: tzcntl {{[0-9]+}}(%esp), %eax 169; X86-NEXT: retl 170; 171; X64-LABEL: test__tzcnt_u32: 172; X64: # %bb.0: 173; X64-NEXT: tzcntl %edi, %eax 174; X64-NEXT: retq 175; 176; EGPR-LABEL: test__tzcnt_u32: 177; EGPR: # %bb.0: 178; EGPR-NEXT: tzcntl %edi, %eax # encoding: [0xf3,0x0f,0xbc,0xc7] 179; EGPR-NEXT: retq # encoding: [0xc3] 180 %cmp = icmp ne i32 %a0, 0 181 %cttz = call i32 @llvm.cttz.i32(i32 %a0, i1 false) 182 ret i32 %cttz 183} 184 185; 186; Intel intrinsics 187; 188 189define i16 @test_tzcnt_u16(i16 %a0) { 190; X86-LABEL: test_tzcnt_u16: 191; X86: # %bb.0: 192; X86-NEXT: movzwl {{[0-9]+}}(%esp), %eax 193; X86-NEXT: orl $65536, %eax # imm = 0x10000 194; X86-NEXT: tzcntl %eax, %eax 195; X86-NEXT: # kill: def $ax killed $ax killed $eax 196; X86-NEXT: retl 197; 198; X64-LABEL: test_tzcnt_u16: 199; X64: # %bb.0: 200; X64-NEXT: orl $65536, %edi # imm = 0x10000 201; X64-NEXT: tzcntl %edi, %eax 202; X64-NEXT: # kill: def $ax killed $ax killed $eax 203; X64-NEXT: retq 204; 205; EGPR-LABEL: test_tzcnt_u16: 206; EGPR: # %bb.0: 207; EGPR-NEXT: orl $65536, %edi # encoding: [0x81,0xcf,0x00,0x00,0x01,0x00] 208; EGPR-NEXT: # imm = 0x10000 209; EGPR-NEXT: tzcntl %edi, %eax # encoding: [0xf3,0x0f,0xbc,0xc7] 210; EGPR-NEXT: # kill: def $ax killed $ax killed $eax 211; EGPR-NEXT: retq # encoding: [0xc3] 212 %zext = zext i16 %a0 to i32 213 %cmp = icmp ne i32 %zext, 0 214 %cttz = call i16 @llvm.cttz.i16(i16 %a0, i1 false) 215 ret i16 %cttz 216} 217 218define i32 @test_andn_u32(i32 %a0, i32 %a1) { 219; X86-LABEL: test_andn_u32: 220; X86: # %bb.0: 221; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 222; X86-NEXT: xorl $-1, %eax 223; X86-NEXT: andl {{[0-9]+}}(%esp), %eax 224; X86-NEXT: retl 225; 226; X64-LABEL: test_andn_u32: 227; X64: # %bb.0: 228; X64-NEXT: movl %edi, %eax 229; X64-NEXT: xorl $-1, %eax 230; X64-NEXT: andl %esi, %eax 231; X64-NEXT: retq 232; 233; EGPR-LABEL: test_andn_u32: 234; EGPR: # %bb.0: 235; EGPR-NEXT: movl %edi, %eax # encoding: [0x89,0xf8] 236; EGPR-NEXT: xorl $-1, %eax # encoding: [0x83,0xf0,0xff] 237; EGPR-NEXT: andl %esi, %eax # encoding: [0x21,0xf0] 238; EGPR-NEXT: retq # encoding: [0xc3] 239 %xor = xor i32 %a0, -1 240 %res = and i32 %xor, %a1 241 ret i32 %res 242} 243 244define i32 @test_bextr_u32(i32 %a0, i32 %a1, i32 %a2) { 245; X86-LABEL: test_bextr_u32: 246; X86: # %bb.0: 247; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 248; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 249; X86-NEXT: andl $255, %ecx 250; X86-NEXT: andl $255, %eax 251; X86-NEXT: shll $8, %eax 252; X86-NEXT: orl %ecx, %eax 253; X86-NEXT: bextrl %eax, {{[0-9]+}}(%esp), %eax 254; X86-NEXT: retl 255; 256; X64-LABEL: test_bextr_u32: 257; X64: # %bb.0: 258; X64-NEXT: andl $255, %esi 259; X64-NEXT: andl $255, %edx 260; X64-NEXT: shll $8, %edx 261; X64-NEXT: orl %esi, %edx 262; X64-NEXT: bextrl %edx, %edi, %eax 263; X64-NEXT: retq 264; 265; EGPR-LABEL: test_bextr_u32: 266; EGPR: # %bb.0: 267; EGPR-NEXT: andl $255, %esi # encoding: [0x81,0xe6,0xff,0x00,0x00,0x00] 268; EGPR-NEXT: andl $255, %edx # encoding: [0x81,0xe2,0xff,0x00,0x00,0x00] 269; EGPR-NEXT: shll $8, %edx # encoding: [0xc1,0xe2,0x08] 270; EGPR-NEXT: orl %esi, %edx # encoding: [0x09,0xf2] 271; EGPR-NEXT: bextrl %edx, %edi, %eax # EVEX TO VEX Compression encoding: [0xc4,0xe2,0x68,0xf7,0xc7] 272; EGPR-NEXT: retq # encoding: [0xc3] 273 %and1 = and i32 %a1, 255 274 %and2 = and i32 %a2, 255 275 %shl = shl i32 %and2, 8 276 %or = or i32 %and1, %shl 277 %res = call i32 @llvm.x86.bmi.bextr.32(i32 %a0, i32 %or) 278 ret i32 %res 279} 280 281define i32 @test_blsi_u32(i32 %a0) { 282; X86-LABEL: test_blsi_u32: 283; X86: # %bb.0: 284; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 285; X86-NEXT: xorl %eax, %eax 286; X86-NEXT: subl %ecx, %eax 287; X86-NEXT: andl %ecx, %eax 288; X86-NEXT: retl 289; 290; X64-LABEL: test_blsi_u32: 291; X64: # %bb.0: 292; X64-NEXT: xorl %eax, %eax 293; X64-NEXT: subl %edi, %eax 294; X64-NEXT: andl %edi, %eax 295; X64-NEXT: retq 296; 297; EGPR-LABEL: test_blsi_u32: 298; EGPR: # %bb.0: 299; EGPR-NEXT: xorl %eax, %eax # encoding: [0x31,0xc0] 300; EGPR-NEXT: subl %edi, %eax # encoding: [0x29,0xf8] 301; EGPR-NEXT: andl %edi, %eax # encoding: [0x21,0xf8] 302; EGPR-NEXT: retq # encoding: [0xc3] 303 %neg = sub i32 0, %a0 304 %res = and i32 %a0, %neg 305 ret i32 %res 306} 307 308define i32 @test_blsmsk_u32(i32 %a0) { 309; X86-LABEL: test_blsmsk_u32: 310; X86: # %bb.0: 311; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 312; X86-NEXT: leal -1(%ecx), %eax 313; X86-NEXT: xorl %ecx, %eax 314; X86-NEXT: retl 315; 316; X64-LABEL: test_blsmsk_u32: 317; X64: # %bb.0: 318; X64-NEXT: # kill: def $edi killed $edi def $rdi 319; X64-NEXT: leal -1(%rdi), %eax 320; X64-NEXT: xorl %edi, %eax 321; X64-NEXT: retq 322; 323; EGPR-LABEL: test_blsmsk_u32: 324; EGPR: # %bb.0: 325; EGPR-NEXT: # kill: def $edi killed $edi def $rdi 326; EGPR-NEXT: leal -1(%rdi), %eax # encoding: [0x8d,0x47,0xff] 327; EGPR-NEXT: xorl %edi, %eax # encoding: [0x31,0xf8] 328; EGPR-NEXT: retq # encoding: [0xc3] 329 %dec = sub i32 %a0, 1 330 %res = xor i32 %a0, %dec 331 ret i32 %res 332} 333 334define i32 @test_blsr_u32(i32 %a0) { 335; X86-LABEL: test_blsr_u32: 336; X86: # %bb.0: 337; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 338; X86-NEXT: leal -1(%ecx), %eax 339; X86-NEXT: andl %ecx, %eax 340; X86-NEXT: retl 341; 342; X64-LABEL: test_blsr_u32: 343; X64: # %bb.0: 344; X64-NEXT: # kill: def $edi killed $edi def $rdi 345; X64-NEXT: leal -1(%rdi), %eax 346; X64-NEXT: andl %edi, %eax 347; X64-NEXT: retq 348; 349; EGPR-LABEL: test_blsr_u32: 350; EGPR: # %bb.0: 351; EGPR-NEXT: # kill: def $edi killed $edi def $rdi 352; EGPR-NEXT: leal -1(%rdi), %eax # encoding: [0x8d,0x47,0xff] 353; EGPR-NEXT: andl %edi, %eax # encoding: [0x21,0xf8] 354; EGPR-NEXT: retq # encoding: [0xc3] 355 %dec = sub i32 %a0, 1 356 %res = and i32 %a0, %dec 357 ret i32 %res 358} 359 360define i32 @test_tzcnt_u32(i32 %a0) { 361; X86-LABEL: test_tzcnt_u32: 362; X86: # %bb.0: 363; X86-NEXT: tzcntl {{[0-9]+}}(%esp), %eax 364; X86-NEXT: retl 365; 366; X64-LABEL: test_tzcnt_u32: 367; X64: # %bb.0: 368; X64-NEXT: tzcntl %edi, %eax 369; X64-NEXT: retq 370; 371; EGPR-LABEL: test_tzcnt_u32: 372; EGPR: # %bb.0: 373; EGPR-NEXT: tzcntl %edi, %eax # encoding: [0xf3,0x0f,0xbc,0xc7] 374; EGPR-NEXT: retq # encoding: [0xc3] 375 %cmp = icmp ne i32 %a0, 0 376 %cttz = call i32 @llvm.cttz.i32(i32 %a0, i1 false) 377 ret i32 %cttz 378} 379 380declare i16 @llvm.cttz.i16(i16, i1) 381declare i32 @llvm.cttz.i32(i32, i1) 382declare i32 @llvm.x86.bmi.bextr.32(i32, i32) 383