1; RUN: llc < %s -march=x86-64 -mattr=+bmi,+bmi2 | FileCheck %s 2 3declare i8 @llvm.cttz.i8(i8, i1) nounwind readnone 4declare i16 @llvm.cttz.i16(i16, i1) nounwind readnone 5declare i32 @llvm.cttz.i32(i32, i1) nounwind readnone 6declare i64 @llvm.cttz.i64(i64, i1) nounwind readnone 7 8define i8 @t1(i8 %x) nounwind { 9 %tmp = tail call i8 @llvm.cttz.i8( i8 %x, i1 false ) 10 ret i8 %tmp 11; CHECK-LABEL: t1: 12; CHECK: tzcntl 13} 14 15define i16 @t2(i16 %x) nounwind { 16 %tmp = tail call i16 @llvm.cttz.i16( i16 %x, i1 false ) 17 ret i16 %tmp 18; CHECK-LABEL: t2: 19; CHECK: tzcntw 20} 21 22define i32 @t3(i32 %x) nounwind { 23 %tmp = tail call i32 @llvm.cttz.i32( i32 %x, i1 false ) 24 ret i32 %tmp 25; CHECK-LABEL: t3: 26; CHECK: tzcntl 27} 28 29define i32 @tzcnt32_load(i32* %x) nounwind { 30 %x1 = load i32* %x 31 %tmp = tail call i32 @llvm.cttz.i32(i32 %x1, i1 false ) 32 ret i32 %tmp 33; CHECK-LABEL: tzcnt32_load: 34; CHECK: tzcntl ({{.*}}) 35} 36 37define i64 @t4(i64 %x) nounwind { 38 %tmp = tail call i64 @llvm.cttz.i64( i64 %x, i1 false ) 39 ret i64 %tmp 40; CHECK-LABEL: t4: 41; CHECK: tzcntq 42} 43 44define i8 @t5(i8 %x) nounwind { 45 %tmp = tail call i8 @llvm.cttz.i8( i8 %x, i1 true ) 46 ret i8 %tmp 47; CHECK-LABEL: t5: 48; CHECK: tzcntl 49} 50 51define i16 @t6(i16 %x) nounwind { 52 %tmp = tail call i16 @llvm.cttz.i16( i16 %x, i1 true ) 53 ret i16 %tmp 54; CHECK-LABEL: t6: 55; CHECK: tzcntw 56} 57 58define i32 @t7(i32 %x) nounwind { 59 %tmp = tail call i32 @llvm.cttz.i32( i32 %x, i1 true ) 60 ret i32 %tmp 61; CHECK-LABEL: t7: 62; CHECK: tzcntl 63} 64 65define i64 @t8(i64 %x) nounwind { 66 %tmp = tail call i64 @llvm.cttz.i64( i64 %x, i1 true ) 67 ret i64 %tmp 68; CHECK-LABEL: t8: 69; CHECK: tzcntq 70} 71 72define i32 @andn32(i32 %x, i32 %y) nounwind readnone { 73 %tmp1 = xor i32 %x, -1 74 %tmp2 = and i32 %y, %tmp1 75 ret i32 %tmp2 76; CHECK-LABEL: andn32: 77; CHECK: andnl 78} 79 80define i32 @andn32_load(i32 %x, i32* %y) nounwind readnone { 81 %y1 = load i32* %y 82 %tmp1 = xor i32 %x, -1 83 %tmp2 = and i32 %y1, %tmp1 84 ret i32 %tmp2 85; CHECK-LABEL: andn32_load: 86; CHECK: andnl ({{.*}}) 87} 88 89define i64 @andn64(i64 %x, i64 %y) nounwind readnone { 90 %tmp1 = xor i64 %x, -1 91 %tmp2 = and i64 %tmp1, %y 92 ret i64 %tmp2 93; CHECK-LABEL: andn64: 94; CHECK: andnq 95} 96 97define i32 @bextr32(i32 %x, i32 %y) nounwind readnone { 98 %tmp = tail call i32 @llvm.x86.bmi.bextr.32(i32 %x, i32 %y) 99 ret i32 %tmp 100; CHECK-LABEL: bextr32: 101; CHECK: bextrl 102} 103 104define i32 @bextr32_load(i32* %x, i32 %y) nounwind readnone { 105 %x1 = load i32* %x 106 %tmp = tail call i32 @llvm.x86.bmi.bextr.32(i32 %x1, i32 %y) 107 ret i32 %tmp 108; CHECK-LABEL: bextr32_load: 109; CHECK: bextrl {{.*}}, ({{.*}}), {{.*}} 110} 111 112declare i32 @llvm.x86.bmi.bextr.32(i32, i32) nounwind readnone 113 114define i32 @bextr32b(i32 %x) nounwind uwtable readnone ssp { 115 %1 = lshr i32 %x, 4 116 %2 = and i32 %1, 4095 117 ret i32 %2 118; CHECK-LABEL: bextr32b: 119; CHECK: bextrl 120} 121 122define i32 @bextr32b_load(i32* %x) nounwind uwtable readnone ssp { 123 %1 = load i32* %x 124 %2 = lshr i32 %1, 4 125 %3 = and i32 %2, 4095 126 ret i32 %3 127; CHECK-LABEL: bextr32b_load: 128; CHECK: bextrl {{.*}}, ({{.*}}), {{.*}} 129} 130 131define i64 @bextr64(i64 %x, i64 %y) nounwind readnone { 132 %tmp = tail call i64 @llvm.x86.bmi.bextr.64(i64 %x, i64 %y) 133 ret i64 %tmp 134; CHECK-LABEL: bextr64: 135; CHECK: bextrq 136} 137 138declare i64 @llvm.x86.bmi.bextr.64(i64, i64) nounwind readnone 139 140define i64 @bextr64b(i64 %x) nounwind uwtable readnone ssp { 141 %1 = lshr i64 %x, 4 142 %2 = and i64 %1, 4095 143 ret i64 %2 144; CHECK-LABEL: bextr64b: 145; CHECK: bextrq 146} 147 148define i32 @bzhi32(i32 %x, i32 %y) nounwind readnone { 149 %tmp = tail call i32 @llvm.x86.bmi.bzhi.32(i32 %x, i32 %y) 150 ret i32 %tmp 151; CHECK-LABEL: bzhi32: 152; CHECK: bzhil 153} 154 155define i32 @bzhi32_load(i32* %x, i32 %y) nounwind readnone { 156 %x1 = load i32* %x 157 %tmp = tail call i32 @llvm.x86.bmi.bzhi.32(i32 %x1, i32 %y) 158 ret i32 %tmp 159; CHECK-LABEL: bzhi32_load: 160; CHECK: bzhil {{.*}}, ({{.*}}), {{.*}} 161} 162 163declare i32 @llvm.x86.bmi.bzhi.32(i32, i32) nounwind readnone 164 165define i64 @bzhi64(i64 %x, i64 %y) nounwind readnone { 166 %tmp = tail call i64 @llvm.x86.bmi.bzhi.64(i64 %x, i64 %y) 167 ret i64 %tmp 168; CHECK-LABEL: bzhi64: 169; CHECK: bzhiq 170} 171 172declare i64 @llvm.x86.bmi.bzhi.64(i64, i64) nounwind readnone 173 174define i32 @bzhi32b(i32 %x, i8 zeroext %index) #0 { 175entry: 176 %conv = zext i8 %index to i32 177 %shl = shl i32 1, %conv 178 %sub = add nsw i32 %shl, -1 179 %and = and i32 %sub, %x 180 ret i32 %and 181; CHECK-LABEL: bzhi32b: 182; CHECK: bzhil 183} 184 185define i32 @bzhi32b_load(i32* %w, i8 zeroext %index) #0 { 186entry: 187 %x = load i32* %w 188 %conv = zext i8 %index to i32 189 %shl = shl i32 1, %conv 190 %sub = add nsw i32 %shl, -1 191 %and = and i32 %sub, %x 192 ret i32 %and 193; CHECK-LABEL: bzhi32b_load: 194; CHECK: bzhil {{.*}}, ({{.*}}), {{.*}} 195} 196 197define i32 @bzhi32c(i32 %x, i8 zeroext %index) #0 { 198entry: 199 %conv = zext i8 %index to i32 200 %shl = shl i32 1, %conv 201 %sub = add nsw i32 %shl, -1 202 %and = and i32 %x, %sub 203 ret i32 %and 204; CHECK-LABEL: bzhi32c: 205; CHECK: bzhil 206} 207 208define i64 @bzhi64b(i64 %x, i8 zeroext %index) #0 { 209entry: 210 %conv = zext i8 %index to i64 211 %shl = shl i64 1, %conv 212 %sub = add nsw i64 %shl, -1 213 %and = and i64 %x, %sub 214 ret i64 %and 215; CHECK-LABEL: bzhi64b: 216; CHECK: bzhiq 217} 218 219define i64 @bzhi64_constant_mask(i64 %x) #0 { 220entry: 221 %and = and i64 %x, 4611686018427387903 222 ret i64 %and 223; CHECK-LABEL: bzhi64_constant_mask: 224; CHECK: movb $62, %al 225; CHECK: bzhiq %rax, %r[[ARG1:di|cx]], %rax 226} 227 228define i64 @bzhi64_small_constant_mask(i64 %x) #0 { 229entry: 230 %and = and i64 %x, 2147483647 231 ret i64 %and 232; CHECK-LABEL: bzhi64_small_constant_mask: 233; CHECK: andq $2147483647, %r[[ARG1]] 234} 235 236define i32 @blsi32(i32 %x) nounwind readnone { 237 %tmp = sub i32 0, %x 238 %tmp2 = and i32 %x, %tmp 239 ret i32 %tmp2 240; CHECK-LABEL: blsi32: 241; CHECK: blsil 242} 243 244define i32 @blsi32_load(i32* %x) nounwind readnone { 245 %x1 = load i32* %x 246 %tmp = sub i32 0, %x1 247 %tmp2 = and i32 %x1, %tmp 248 ret i32 %tmp2 249; CHECK-LABEL: blsi32_load: 250; CHECK: blsil ({{.*}}) 251} 252 253define i64 @blsi64(i64 %x) nounwind readnone { 254 %tmp = sub i64 0, %x 255 %tmp2 = and i64 %tmp, %x 256 ret i64 %tmp2 257; CHECK-LABEL: blsi64: 258; CHECK: blsiq 259} 260 261define i32 @blsmsk32(i32 %x) nounwind readnone { 262 %tmp = sub i32 %x, 1 263 %tmp2 = xor i32 %x, %tmp 264 ret i32 %tmp2 265; CHECK-LABEL: blsmsk32: 266; CHECK: blsmskl 267} 268 269define i32 @blsmsk32_load(i32* %x) nounwind readnone { 270 %x1 = load i32* %x 271 %tmp = sub i32 %x1, 1 272 %tmp2 = xor i32 %x1, %tmp 273 ret i32 %tmp2 274; CHECK-LABEL: blsmsk32_load: 275; CHECK: blsmskl ({{.*}}) 276} 277 278define i64 @blsmsk64(i64 %x) nounwind readnone { 279 %tmp = sub i64 %x, 1 280 %tmp2 = xor i64 %tmp, %x 281 ret i64 %tmp2 282; CHECK-LABEL: blsmsk64: 283; CHECK: blsmskq 284} 285 286define i32 @blsr32(i32 %x) nounwind readnone { 287 %tmp = sub i32 %x, 1 288 %tmp2 = and i32 %x, %tmp 289 ret i32 %tmp2 290; CHECK-LABEL: blsr32: 291; CHECK: blsrl 292} 293 294define i32 @blsr32_load(i32* %x) nounwind readnone { 295 %x1 = load i32* %x 296 %tmp = sub i32 %x1, 1 297 %tmp2 = and i32 %x1, %tmp 298 ret i32 %tmp2 299; CHECK-LABEL: blsr32_load: 300; CHECK: blsrl ({{.*}}) 301} 302 303define i64 @blsr64(i64 %x) nounwind readnone { 304 %tmp = sub i64 %x, 1 305 %tmp2 = and i64 %tmp, %x 306 ret i64 %tmp2 307; CHECK-LABEL: blsr64: 308; CHECK: blsrq 309} 310 311define i32 @pdep32(i32 %x, i32 %y) nounwind readnone { 312 %tmp = tail call i32 @llvm.x86.bmi.pdep.32(i32 %x, i32 %y) 313 ret i32 %tmp 314; CHECK-LABEL: pdep32: 315; CHECK: pdepl 316} 317 318define i32 @pdep32_load(i32 %x, i32* %y) nounwind readnone { 319 %y1 = load i32* %y 320 %tmp = tail call i32 @llvm.x86.bmi.pdep.32(i32 %x, i32 %y1) 321 ret i32 %tmp 322; CHECK-LABEL: pdep32_load: 323; CHECK: pdepl ({{.*}}) 324} 325 326declare i32 @llvm.x86.bmi.pdep.32(i32, i32) nounwind readnone 327 328define i64 @pdep64(i64 %x, i64 %y) nounwind readnone { 329 %tmp = tail call i64 @llvm.x86.bmi.pdep.64(i64 %x, i64 %y) 330 ret i64 %tmp 331; CHECK-LABEL: pdep64: 332; CHECK: pdepq 333} 334 335declare i64 @llvm.x86.bmi.pdep.64(i64, i64) nounwind readnone 336 337define i32 @pext32(i32 %x, i32 %y) nounwind readnone { 338 %tmp = tail call i32 @llvm.x86.bmi.pext.32(i32 %x, i32 %y) 339 ret i32 %tmp 340; CHECK-LABEL: pext32: 341; CHECK: pextl 342} 343 344define i32 @pext32_load(i32 %x, i32* %y) nounwind readnone { 345 %y1 = load i32* %y 346 %tmp = tail call i32 @llvm.x86.bmi.pext.32(i32 %x, i32 %y1) 347 ret i32 %tmp 348; CHECK-LABEL: pext32_load: 349; CHECK: pextl ({{.*}}) 350} 351 352declare i32 @llvm.x86.bmi.pext.32(i32, i32) nounwind readnone 353 354define i64 @pext64(i64 %x, i64 %y) nounwind readnone { 355 %tmp = tail call i64 @llvm.x86.bmi.pext.64(i64 %x, i64 %y) 356 ret i64 %tmp 357; CHECK-LABEL: pext64: 358; CHECK: pextq 359} 360 361declare i64 @llvm.x86.bmi.pext.64(i64, i64) nounwind readnone 362 363