1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc -fast-isel-sink-local-values < %s -fast-isel -mtriple=i686-unknown-unknown -mattr=+bmi | FileCheck %s --check-prefix=X86 3; RUN: llc -fast-isel-sink-local-values < %s -fast-isel -mtriple=x86_64-unknown-unknown -mattr=+bmi | FileCheck %s --check-prefix=X64 4 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: tzcntw {{[0-9]+}}(%esp), %ax 15; X86-NEXT: retl 16; 17; X64-LABEL: test__tzcnt_u16: 18; X64: # %bb.0: 19; X64-NEXT: tzcntw %di, %ax 20; X64-NEXT: retq 21 %zext = zext i16 %a0 to i32 22 %cmp = icmp ne i32 %zext, 0 23 %cttz = call i16 @llvm.cttz.i16(i16 %a0, i1 false) 24 ret i16 %cttz 25} 26 27define i32 @test__andn_u32(i32 %a0, i32 %a1) { 28; X86-LABEL: test__andn_u32: 29; X86: # %bb.0: 30; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 31; X86-NEXT: xorl $-1, %eax 32; X86-NEXT: andl {{[0-9]+}}(%esp), %eax 33; X86-NEXT: retl 34; 35; X64-LABEL: test__andn_u32: 36; X64: # %bb.0: 37; X64-NEXT: movl %edi, %eax 38; X64-NEXT: xorl $-1, %eax 39; X64-NEXT: andl %esi, %eax 40; X64-NEXT: retq 41 %xor = xor i32 %a0, -1 42 %res = and i32 %xor, %a1 43 ret i32 %res 44} 45 46define i32 @test__bextr_u32(i32 %a0, i32 %a1) { 47; X86-LABEL: test__bextr_u32: 48; X86: # %bb.0: 49; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 50; X86-NEXT: bextrl %eax, {{[0-9]+}}(%esp), %eax 51; X86-NEXT: retl 52; 53; X64-LABEL: test__bextr_u32: 54; X64: # %bb.0: 55; X64-NEXT: bextrl %esi, %edi, %eax 56; X64-NEXT: retq 57 %res = call i32 @llvm.x86.bmi.bextr.32(i32 %a0, i32 %a1) 58 ret i32 %res 59} 60 61define i32 @test__blsi_u32(i32 %a0) { 62; X86-LABEL: test__blsi_u32: 63; X86: # %bb.0: 64; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 65; X86-NEXT: xorl %eax, %eax 66; X86-NEXT: subl %ecx, %eax 67; X86-NEXT: andl %ecx, %eax 68; X86-NEXT: retl 69; 70; X64-LABEL: test__blsi_u32: 71; X64: # %bb.0: 72; X64-NEXT: xorl %eax, %eax 73; X64-NEXT: subl %edi, %eax 74; X64-NEXT: andl %edi, %eax 75; X64-NEXT: retq 76 %neg = sub i32 0, %a0 77 %res = and i32 %a0, %neg 78 ret i32 %res 79} 80 81define i32 @test__blsmsk_u32(i32 %a0) { 82; X86-LABEL: test__blsmsk_u32: 83; X86: # %bb.0: 84; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 85; X86-NEXT: leal -1(%ecx), %eax 86; X86-NEXT: xorl %ecx, %eax 87; X86-NEXT: retl 88; 89; X64-LABEL: test__blsmsk_u32: 90; X64: # %bb.0: 91; X64-NEXT: # kill: def $edi killed $edi def $rdi 92; X64-NEXT: leal -1(%rdi), %eax 93; X64-NEXT: xorl %edi, %eax 94; X64-NEXT: retq 95 %dec = sub i32 %a0, 1 96 %res = xor i32 %a0, %dec 97 ret i32 %res 98} 99 100define i32 @test__blsr_u32(i32 %a0) { 101; X86-LABEL: test__blsr_u32: 102; X86: # %bb.0: 103; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 104; X86-NEXT: leal -1(%ecx), %eax 105; X86-NEXT: andl %ecx, %eax 106; X86-NEXT: retl 107; 108; X64-LABEL: test__blsr_u32: 109; X64: # %bb.0: 110; X64-NEXT: # kill: def $edi killed $edi def $rdi 111; X64-NEXT: leal -1(%rdi), %eax 112; X64-NEXT: andl %edi, %eax 113; X64-NEXT: retq 114 %dec = sub i32 %a0, 1 115 %res = and i32 %a0, %dec 116 ret i32 %res 117} 118 119define i32 @test__tzcnt_u32(i32 %a0) { 120; X86-LABEL: test__tzcnt_u32: 121; X86: # %bb.0: 122; X86-NEXT: tzcntl {{[0-9]+}}(%esp), %eax 123; X86-NEXT: retl 124; 125; X64-LABEL: test__tzcnt_u32: 126; X64: # %bb.0: 127; X64-NEXT: tzcntl %edi, %eax 128; X64-NEXT: retq 129 %cmp = icmp ne i32 %a0, 0 130 %cttz = call i32 @llvm.cttz.i32(i32 %a0, i1 false) 131 ret i32 %cttz 132} 133 134; 135; Intel intrinsics 136; 137 138define i16 @test_tzcnt_u16(i16 %a0) { 139; X86-LABEL: test_tzcnt_u16: 140; X86: # %bb.0: 141; X86-NEXT: tzcntw {{[0-9]+}}(%esp), %ax 142; X86-NEXT: retl 143; 144; X64-LABEL: test_tzcnt_u16: 145; X64: # %bb.0: 146; X64-NEXT: tzcntw %di, %ax 147; X64-NEXT: retq 148 %zext = zext i16 %a0 to i32 149 %cmp = icmp ne i32 %zext, 0 150 %cttz = call i16 @llvm.cttz.i16(i16 %a0, i1 false) 151 ret i16 %cttz 152} 153 154define i32 @test_andn_u32(i32 %a0, i32 %a1) { 155; X86-LABEL: test_andn_u32: 156; X86: # %bb.0: 157; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 158; X86-NEXT: xorl $-1, %eax 159; X86-NEXT: andl {{[0-9]+}}(%esp), %eax 160; X86-NEXT: retl 161; 162; X64-LABEL: test_andn_u32: 163; X64: # %bb.0: 164; X64-NEXT: movl %edi, %eax 165; X64-NEXT: xorl $-1, %eax 166; X64-NEXT: andl %esi, %eax 167; X64-NEXT: retq 168 %xor = xor i32 %a0, -1 169 %res = and i32 %xor, %a1 170 ret i32 %res 171} 172 173define i32 @test_bextr_u32(i32 %a0, i32 %a1, i32 %a2) { 174; X86-LABEL: test_bextr_u32: 175; X86: # %bb.0: 176; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 177; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 178; X86-NEXT: andl $255, %ecx 179; X86-NEXT: andl $255, %eax 180; X86-NEXT: shll $8, %eax 181; X86-NEXT: orl %ecx, %eax 182; X86-NEXT: bextrl %eax, {{[0-9]+}}(%esp), %eax 183; X86-NEXT: retl 184; 185; X64-LABEL: test_bextr_u32: 186; X64: # %bb.0: 187; X64-NEXT: andl $255, %esi 188; X64-NEXT: andl $255, %edx 189; X64-NEXT: shll $8, %edx 190; X64-NEXT: orl %esi, %edx 191; X64-NEXT: bextrl %edx, %edi, %eax 192; X64-NEXT: retq 193 %and1 = and i32 %a1, 255 194 %and2 = and i32 %a2, 255 195 %shl = shl i32 %and2, 8 196 %or = or i32 %and1, %shl 197 %res = call i32 @llvm.x86.bmi.bextr.32(i32 %a0, i32 %or) 198 ret i32 %res 199} 200 201define i32 @test_blsi_u32(i32 %a0) { 202; X86-LABEL: test_blsi_u32: 203; X86: # %bb.0: 204; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 205; X86-NEXT: xorl %eax, %eax 206; X86-NEXT: subl %ecx, %eax 207; X86-NEXT: andl %ecx, %eax 208; X86-NEXT: retl 209; 210; X64-LABEL: test_blsi_u32: 211; X64: # %bb.0: 212; X64-NEXT: xorl %eax, %eax 213; X64-NEXT: subl %edi, %eax 214; X64-NEXT: andl %edi, %eax 215; X64-NEXT: retq 216 %neg = sub i32 0, %a0 217 %res = and i32 %a0, %neg 218 ret i32 %res 219} 220 221define i32 @test_blsmsk_u32(i32 %a0) { 222; X86-LABEL: test_blsmsk_u32: 223; X86: # %bb.0: 224; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 225; X86-NEXT: leal -1(%ecx), %eax 226; X86-NEXT: xorl %ecx, %eax 227; X86-NEXT: retl 228; 229; X64-LABEL: test_blsmsk_u32: 230; X64: # %bb.0: 231; X64-NEXT: # kill: def $edi killed $edi def $rdi 232; X64-NEXT: leal -1(%rdi), %eax 233; X64-NEXT: xorl %edi, %eax 234; X64-NEXT: retq 235 %dec = sub i32 %a0, 1 236 %res = xor i32 %a0, %dec 237 ret i32 %res 238} 239 240define i32 @test_blsr_u32(i32 %a0) { 241; X86-LABEL: test_blsr_u32: 242; X86: # %bb.0: 243; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 244; X86-NEXT: leal -1(%ecx), %eax 245; X86-NEXT: andl %ecx, %eax 246; X86-NEXT: retl 247; 248; X64-LABEL: test_blsr_u32: 249; X64: # %bb.0: 250; X64-NEXT: # kill: def $edi killed $edi def $rdi 251; X64-NEXT: leal -1(%rdi), %eax 252; X64-NEXT: andl %edi, %eax 253; X64-NEXT: retq 254 %dec = sub i32 %a0, 1 255 %res = and i32 %a0, %dec 256 ret i32 %res 257} 258 259define i32 @test_tzcnt_u32(i32 %a0) { 260; X86-LABEL: test_tzcnt_u32: 261; X86: # %bb.0: 262; X86-NEXT: tzcntl {{[0-9]+}}(%esp), %eax 263; X86-NEXT: retl 264; 265; X64-LABEL: test_tzcnt_u32: 266; X64: # %bb.0: 267; X64-NEXT: tzcntl %edi, %eax 268; X64-NEXT: retq 269 %cmp = icmp ne i32 %a0, 0 270 %cttz = call i32 @llvm.cttz.i32(i32 %a0, i1 false) 271 ret i32 %cttz 272} 273 274declare i16 @llvm.cttz.i16(i16, i1) 275declare i32 @llvm.cttz.i32(i32, i1) 276declare i32 @llvm.x86.bmi.bextr.32(i32, i32) 277