383 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc < %s -fast-isel -mtriple=i686-unknown-unknown -mattr=+bmi | FileCheck %s --check-prefix=X863; RUN: llc < %s -fast-isel -mtriple=x86_64-unknown-unknown -mattr=+bmi | FileCheck %s --check-prefix=X644; RUN: llc < %s -fast-isel -mtriple=x86_64-unknown-unknown -mattr=+bmi,+egpr --show-mc-encoding | FileCheck %s --check-prefix=EGPR5; NOTE: This should use IR equivalent to what is generated by clang/test/CodeGen/bmi-builtins.c6 7;8; AMD Intrinsics9;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), %eax15; X86-NEXT: orl $65536, %eax # imm = 0x1000016; X86-NEXT: tzcntl %eax, %eax17; X86-NEXT: # kill: def $ax killed $ax killed $eax18; X86-NEXT: retl19;20; X64-LABEL: test__tzcnt_u16:21; X64: # %bb.0:22; X64-NEXT: orl $65536, %edi # imm = 0x1000023; X64-NEXT: tzcntl %edi, %eax24; X64-NEXT: # kill: def $ax killed $ax killed $eax25; X64-NEXT: retq26;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 = 0x1000031; EGPR-NEXT: tzcntl %edi, %eax # encoding: [0xf3,0x0f,0xbc,0xc7]32; EGPR-NEXT: # kill: def $ax killed $ax killed $eax33; EGPR-NEXT: retq # encoding: [0xc3]34 %zext = zext i16 %a0 to i3235 %cmp = icmp ne i32 %zext, 036 %cttz = call i16 @llvm.cttz.i16(i16 %a0, i1 false)37 ret i16 %cttz38}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), %eax44; X86-NEXT: xorl $-1, %eax45; X86-NEXT: andl {{[0-9]+}}(%esp), %eax46; X86-NEXT: retl47;48; X64-LABEL: test__andn_u32:49; X64: # %bb.0:50; X64-NEXT: movl %edi, %eax51; X64-NEXT: xorl $-1, %eax52; X64-NEXT: andl %esi, %eax53; X64-NEXT: retq54;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, -162 %res = and i32 %xor, %a163 ret i32 %res64}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), %eax70; X86-NEXT: bextrl %eax, {{[0-9]+}}(%esp), %eax71; X86-NEXT: retl72;73; X64-LABEL: test__bextr_u32:74; X64: # %bb.0:75; X64-NEXT: bextrl %esi, %edi, %eax76; X64-NEXT: retq77;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 %res84}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), %ecx90; X86-NEXT: xorl %eax, %eax91; X86-NEXT: subl %ecx, %eax92; X86-NEXT: andl %ecx, %eax93; X86-NEXT: retl94;95; X64-LABEL: test__blsi_u32:96; X64: # %bb.0:97; X64-NEXT: xorl %eax, %eax98; X64-NEXT: subl %edi, %eax99; X64-NEXT: andl %edi, %eax100; X64-NEXT: retq101;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, %a0109 %res = and i32 %a0, %neg110 ret i32 %res111}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), %ecx117; X86-NEXT: leal -1(%ecx), %eax118; X86-NEXT: xorl %ecx, %eax119; X86-NEXT: retl120;121; X64-LABEL: test__blsmsk_u32:122; X64: # %bb.0:123; X64-NEXT: # kill: def $edi killed $edi def $rdi124; X64-NEXT: leal -1(%rdi), %eax125; X64-NEXT: xorl %edi, %eax126; X64-NEXT: retq127;128; EGPR-LABEL: test__blsmsk_u32:129; EGPR: # %bb.0:130; EGPR-NEXT: # kill: def $edi killed $edi def $rdi131; 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, 1135 %res = xor i32 %a0, %dec136 ret i32 %res137}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), %ecx143; X86-NEXT: leal -1(%ecx), %eax144; X86-NEXT: andl %ecx, %eax145; X86-NEXT: retl146;147; X64-LABEL: test__blsr_u32:148; X64: # %bb.0:149; X64-NEXT: # kill: def $edi killed $edi def $rdi150; X64-NEXT: leal -1(%rdi), %eax151; X64-NEXT: andl %edi, %eax152; X64-NEXT: retq153;154; EGPR-LABEL: test__blsr_u32:155; EGPR: # %bb.0:156; EGPR-NEXT: # kill: def $edi killed $edi def $rdi157; 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, 1161 %res = and i32 %a0, %dec162 ret i32 %res163}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), %eax169; X86-NEXT: retl170;171; X64-LABEL: test__tzcnt_u32:172; X64: # %bb.0:173; X64-NEXT: tzcntl %edi, %eax174; X64-NEXT: retq175;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, 0181 %cttz = call i32 @llvm.cttz.i32(i32 %a0, i1 false)182 ret i32 %cttz183}184 185;186; Intel intrinsics187;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), %eax193; X86-NEXT: orl $65536, %eax # imm = 0x10000194; X86-NEXT: tzcntl %eax, %eax195; X86-NEXT: # kill: def $ax killed $ax killed $eax196; X86-NEXT: retl197;198; X64-LABEL: test_tzcnt_u16:199; X64: # %bb.0:200; X64-NEXT: orl $65536, %edi # imm = 0x10000201; X64-NEXT: tzcntl %edi, %eax202; X64-NEXT: # kill: def $ax killed $ax killed $eax203; X64-NEXT: retq204;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 = 0x10000209; EGPR-NEXT: tzcntl %edi, %eax # encoding: [0xf3,0x0f,0xbc,0xc7]210; EGPR-NEXT: # kill: def $ax killed $ax killed $eax211; EGPR-NEXT: retq # encoding: [0xc3]212 %zext = zext i16 %a0 to i32213 %cmp = icmp ne i32 %zext, 0214 %cttz = call i16 @llvm.cttz.i16(i16 %a0, i1 false)215 ret i16 %cttz216}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), %eax222; X86-NEXT: xorl $-1, %eax223; X86-NEXT: andl {{[0-9]+}}(%esp), %eax224; X86-NEXT: retl225;226; X64-LABEL: test_andn_u32:227; X64: # %bb.0:228; X64-NEXT: movl %edi, %eax229; X64-NEXT: xorl $-1, %eax230; X64-NEXT: andl %esi, %eax231; X64-NEXT: retq232;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, -1240 %res = and i32 %xor, %a1241 ret i32 %res242}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), %eax248; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx249; X86-NEXT: andl $255, %ecx250; X86-NEXT: andl $255, %eax251; X86-NEXT: shll $8, %eax252; X86-NEXT: orl %ecx, %eax253; X86-NEXT: bextrl %eax, {{[0-9]+}}(%esp), %eax254; X86-NEXT: retl255;256; X64-LABEL: test_bextr_u32:257; X64: # %bb.0:258; X64-NEXT: andl $255, %esi259; X64-NEXT: andl $255, %edx260; X64-NEXT: shll $8, %edx261; X64-NEXT: orl %esi, %edx262; X64-NEXT: bextrl %edx, %edi, %eax263; X64-NEXT: retq264;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, 255274 %and2 = and i32 %a2, 255275 %shl = shl i32 %and2, 8276 %or = or i32 %and1, %shl277 %res = call i32 @llvm.x86.bmi.bextr.32(i32 %a0, i32 %or)278 ret i32 %res279}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), %ecx285; X86-NEXT: xorl %eax, %eax286; X86-NEXT: subl %ecx, %eax287; X86-NEXT: andl %ecx, %eax288; X86-NEXT: retl289;290; X64-LABEL: test_blsi_u32:291; X64: # %bb.0:292; X64-NEXT: xorl %eax, %eax293; X64-NEXT: subl %edi, %eax294; X64-NEXT: andl %edi, %eax295; X64-NEXT: retq296;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, %a0304 %res = and i32 %a0, %neg305 ret i32 %res306}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), %ecx312; X86-NEXT: leal -1(%ecx), %eax313; X86-NEXT: xorl %ecx, %eax314; X86-NEXT: retl315;316; X64-LABEL: test_blsmsk_u32:317; X64: # %bb.0:318; X64-NEXT: # kill: def $edi killed $edi def $rdi319; X64-NEXT: leal -1(%rdi), %eax320; X64-NEXT: xorl %edi, %eax321; X64-NEXT: retq322;323; EGPR-LABEL: test_blsmsk_u32:324; EGPR: # %bb.0:325; EGPR-NEXT: # kill: def $edi killed $edi def $rdi326; 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, 1330 %res = xor i32 %a0, %dec331 ret i32 %res332}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), %ecx338; X86-NEXT: leal -1(%ecx), %eax339; X86-NEXT: andl %ecx, %eax340; X86-NEXT: retl341;342; X64-LABEL: test_blsr_u32:343; X64: # %bb.0:344; X64-NEXT: # kill: def $edi killed $edi def $rdi345; X64-NEXT: leal -1(%rdi), %eax346; X64-NEXT: andl %edi, %eax347; X64-NEXT: retq348;349; EGPR-LABEL: test_blsr_u32:350; EGPR: # %bb.0:351; EGPR-NEXT: # kill: def $edi killed $edi def $rdi352; 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, 1356 %res = and i32 %a0, %dec357 ret i32 %res358}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), %eax364; X86-NEXT: retl365;366; X64-LABEL: test_tzcnt_u32:367; X64: # %bb.0:368; X64-NEXT: tzcntl %edi, %eax369; X64-NEXT: retq370;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, 0376 %cttz = call i32 @llvm.cttz.i32(i32 %a0, i1 false)377 ret i32 %cttz378}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