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, 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, 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, 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, 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 i64 @bextr64b_load(i64* %x) { 149 %1 = load i64, i64* %x, align 8 150 %2 = lshr i64 %1, 4 151 %3 = and i64 %2, 4095 152 ret i64 %3 153; CHECK-LABEL: bextr64b_load: 154; CHECK: bextrq {{.*}}, ({{.*}}), {{.*}} 155} 156 157define i32 @non_bextr32(i32 %x) { 158entry: 159 %shr = lshr i32 %x, 2 160 %and = and i32 %shr, 111 161 ret i32 %and 162; CHECK-LABEL: non_bextr32: 163; CHECK: shrl $2 164; CHECK: andl $111 165} 166 167define i64 @non_bextr64(i64 %x) { 168entry: 169 %shr = lshr i64 %x, 2 170 %and = and i64 %shr, 8589934590 171 ret i64 %and 172; CHECK-LABEL: non_bextr64: 173; CHECK: shrq $2 174; CHECK: movabsq $8589934590 175; CHECK: andq 176} 177 178define i32 @bzhi32(i32 %x, i32 %y) nounwind readnone { 179 %tmp = tail call i32 @llvm.x86.bmi.bzhi.32(i32 %x, i32 %y) 180 ret i32 %tmp 181; CHECK-LABEL: bzhi32: 182; CHECK: bzhil 183} 184 185define i32 @bzhi32_load(i32* %x, i32 %y) nounwind readnone { 186 %x1 = load i32, i32* %x 187 %tmp = tail call i32 @llvm.x86.bmi.bzhi.32(i32 %x1, i32 %y) 188 ret i32 %tmp 189; CHECK-LABEL: bzhi32_load: 190; CHECK: bzhil {{.*}}, ({{.*}}), {{.*}} 191} 192 193declare i32 @llvm.x86.bmi.bzhi.32(i32, i32) nounwind readnone 194 195define i64 @bzhi64(i64 %x, i64 %y) nounwind readnone { 196 %tmp = tail call i64 @llvm.x86.bmi.bzhi.64(i64 %x, i64 %y) 197 ret i64 %tmp 198; CHECK-LABEL: bzhi64: 199; CHECK: bzhiq 200} 201 202declare i64 @llvm.x86.bmi.bzhi.64(i64, i64) nounwind readnone 203 204define i32 @bzhi32b(i32 %x, i8 zeroext %index) #0 { 205entry: 206 %conv = zext i8 %index to i32 207 %shl = shl i32 1, %conv 208 %sub = add nsw i32 %shl, -1 209 %and = and i32 %sub, %x 210 ret i32 %and 211; CHECK-LABEL: bzhi32b: 212; CHECK: bzhil 213} 214 215define i32 @bzhi32b_load(i32* %w, i8 zeroext %index) #0 { 216entry: 217 %x = load i32, i32* %w 218 %conv = zext i8 %index to i32 219 %shl = shl i32 1, %conv 220 %sub = add nsw i32 %shl, -1 221 %and = and i32 %sub, %x 222 ret i32 %and 223; CHECK-LABEL: bzhi32b_load: 224; CHECK: bzhil {{.*}}, ({{.*}}), {{.*}} 225} 226 227define i32 @bzhi32c(i32 %x, i8 zeroext %index) #0 { 228entry: 229 %conv = zext i8 %index to i32 230 %shl = shl i32 1, %conv 231 %sub = add nsw i32 %shl, -1 232 %and = and i32 %x, %sub 233 ret i32 %and 234; CHECK-LABEL: bzhi32c: 235; CHECK: bzhil 236} 237 238define i64 @bzhi64b(i64 %x, i8 zeroext %index) #0 { 239entry: 240 %conv = zext i8 %index to i64 241 %shl = shl i64 1, %conv 242 %sub = add nsw i64 %shl, -1 243 %and = and i64 %x, %sub 244 ret i64 %and 245; CHECK-LABEL: bzhi64b: 246; CHECK: bzhiq 247} 248 249define i64 @bzhi64_constant_mask(i64 %x) #0 { 250entry: 251 %and = and i64 %x, 4611686018427387903 252 ret i64 %and 253; CHECK-LABEL: bzhi64_constant_mask: 254; CHECK: movb $62, %al 255; CHECK: bzhiq %rax, %r[[ARG1:di|cx]], %rax 256} 257 258define i64 @bzhi64_small_constant_mask(i64 %x) #0 { 259entry: 260 %and = and i64 %x, 2147483647 261 ret i64 %and 262; CHECK-LABEL: bzhi64_small_constant_mask: 263; CHECK: andl $2147483647, %e[[ARG1]] 264} 265 266define i32 @blsi32(i32 %x) nounwind readnone { 267 %tmp = sub i32 0, %x 268 %tmp2 = and i32 %x, %tmp 269 ret i32 %tmp2 270; CHECK-LABEL: blsi32: 271; CHECK: blsil 272} 273 274define i32 @blsi32_load(i32* %x) nounwind readnone { 275 %x1 = load i32, i32* %x 276 %tmp = sub i32 0, %x1 277 %tmp2 = and i32 %x1, %tmp 278 ret i32 %tmp2 279; CHECK-LABEL: blsi32_load: 280; CHECK: blsil ({{.*}}) 281} 282 283define i64 @blsi64(i64 %x) nounwind readnone { 284 %tmp = sub i64 0, %x 285 %tmp2 = and i64 %tmp, %x 286 ret i64 %tmp2 287; CHECK-LABEL: blsi64: 288; CHECK: blsiq 289} 290 291define i32 @blsmsk32(i32 %x) nounwind readnone { 292 %tmp = sub i32 %x, 1 293 %tmp2 = xor i32 %x, %tmp 294 ret i32 %tmp2 295; CHECK-LABEL: blsmsk32: 296; CHECK: blsmskl 297} 298 299define i32 @blsmsk32_load(i32* %x) nounwind readnone { 300 %x1 = load i32, i32* %x 301 %tmp = sub i32 %x1, 1 302 %tmp2 = xor i32 %x1, %tmp 303 ret i32 %tmp2 304; CHECK-LABEL: blsmsk32_load: 305; CHECK: blsmskl ({{.*}}) 306} 307 308define i64 @blsmsk64(i64 %x) nounwind readnone { 309 %tmp = sub i64 %x, 1 310 %tmp2 = xor i64 %tmp, %x 311 ret i64 %tmp2 312; CHECK-LABEL: blsmsk64: 313; CHECK: blsmskq 314} 315 316define i32 @blsr32(i32 %x) nounwind readnone { 317 %tmp = sub i32 %x, 1 318 %tmp2 = and i32 %x, %tmp 319 ret i32 %tmp2 320; CHECK-LABEL: blsr32: 321; CHECK: blsrl 322} 323 324define i32 @blsr32_load(i32* %x) nounwind readnone { 325 %x1 = load i32, i32* %x 326 %tmp = sub i32 %x1, 1 327 %tmp2 = and i32 %x1, %tmp 328 ret i32 %tmp2 329; CHECK-LABEL: blsr32_load: 330; CHECK: blsrl ({{.*}}) 331} 332 333define i64 @blsr64(i64 %x) nounwind readnone { 334 %tmp = sub i64 %x, 1 335 %tmp2 = and i64 %tmp, %x 336 ret i64 %tmp2 337; CHECK-LABEL: blsr64: 338; CHECK: blsrq 339} 340 341define i32 @pdep32(i32 %x, i32 %y) nounwind readnone { 342 %tmp = tail call i32 @llvm.x86.bmi.pdep.32(i32 %x, i32 %y) 343 ret i32 %tmp 344; CHECK-LABEL: pdep32: 345; CHECK: pdepl 346} 347 348define i32 @pdep32_load(i32 %x, i32* %y) nounwind readnone { 349 %y1 = load i32, i32* %y 350 %tmp = tail call i32 @llvm.x86.bmi.pdep.32(i32 %x, i32 %y1) 351 ret i32 %tmp 352; CHECK-LABEL: pdep32_load: 353; CHECK: pdepl ({{.*}}) 354} 355 356declare i32 @llvm.x86.bmi.pdep.32(i32, i32) nounwind readnone 357 358define i64 @pdep64(i64 %x, i64 %y) nounwind readnone { 359 %tmp = tail call i64 @llvm.x86.bmi.pdep.64(i64 %x, i64 %y) 360 ret i64 %tmp 361; CHECK-LABEL: pdep64: 362; CHECK: pdepq 363} 364 365declare i64 @llvm.x86.bmi.pdep.64(i64, i64) nounwind readnone 366 367define i32 @pext32(i32 %x, i32 %y) nounwind readnone { 368 %tmp = tail call i32 @llvm.x86.bmi.pext.32(i32 %x, i32 %y) 369 ret i32 %tmp 370; CHECK-LABEL: pext32: 371; CHECK: pextl 372} 373 374define i32 @pext32_load(i32 %x, i32* %y) nounwind readnone { 375 %y1 = load i32, i32* %y 376 %tmp = tail call i32 @llvm.x86.bmi.pext.32(i32 %x, i32 %y1) 377 ret i32 %tmp 378; CHECK-LABEL: pext32_load: 379; CHECK: pextl ({{.*}}) 380} 381 382declare i32 @llvm.x86.bmi.pext.32(i32, i32) nounwind readnone 383 384define i64 @pext64(i64 %x, i64 %y) nounwind readnone { 385 %tmp = tail call i64 @llvm.x86.bmi.pext.64(i64 %x, i64 %y) 386 ret i64 %tmp 387; CHECK-LABEL: pext64: 388; CHECK: pextq 389} 390 391declare i64 @llvm.x86.bmi.pext.64(i64, i64) nounwind readnone 392 393