1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc < %s -mtriple=x86_64-pc-linux -mattr=+bmi,+lzcnt | FileCheck %s 3 4; LZCNT and TZCNT will always produce the operand size when the input operand 5; is zero. This test is to verify that we efficiently select LZCNT/TZCNT 6; based on the fact that the 'icmp+select' sequence is always redundant 7; in every function defined below. 8 9 10define i16 @test1_ctlz(i16 %v) { 11; CHECK-LABEL: test1_ctlz: 12; CHECK: # %bb.0: 13; CHECK-NEXT: lzcntw %di, %ax 14; CHECK-NEXT: retq 15 %cnt = tail call i16 @llvm.ctlz.i16(i16 %v, i1 true) 16 %tobool = icmp eq i16 %v, 0 17 %cond = select i1 %tobool, i16 16, i16 %cnt 18 ret i16 %cond 19} 20 21 22define i32 @test2_ctlz(i32 %v) { 23; CHECK-LABEL: test2_ctlz: 24; CHECK: # %bb.0: 25; CHECK-NEXT: lzcntl %edi, %eax 26; CHECK-NEXT: retq 27 %cnt = tail call i32 @llvm.ctlz.i32(i32 %v, i1 true) 28 %tobool = icmp eq i32 %v, 0 29 %cond = select i1 %tobool, i32 32, i32 %cnt 30 ret i32 %cond 31} 32 33 34define i64 @test3_ctlz(i64 %v) { 35; CHECK-LABEL: test3_ctlz: 36; CHECK: # %bb.0: 37; CHECK-NEXT: lzcntq %rdi, %rax 38; CHECK-NEXT: retq 39 %cnt = tail call i64 @llvm.ctlz.i64(i64 %v, i1 true) 40 %tobool = icmp eq i64 %v, 0 41 %cond = select i1 %tobool, i64 64, i64 %cnt 42 ret i64 %cond 43} 44 45 46define i16 @test4_ctlz(i16 %v) { 47; CHECK-LABEL: test4_ctlz: 48; CHECK: # %bb.0: 49; CHECK-NEXT: lzcntw %di, %ax 50; CHECK-NEXT: retq 51 %cnt = tail call i16 @llvm.ctlz.i16(i16 %v, i1 true) 52 %tobool = icmp eq i16 0, %v 53 %cond = select i1 %tobool, i16 16, i16 %cnt 54 ret i16 %cond 55} 56 57 58define i32 @test5_ctlz(i32 %v) { 59; CHECK-LABEL: test5_ctlz: 60; CHECK: # %bb.0: 61; CHECK-NEXT: lzcntl %edi, %eax 62; CHECK-NEXT: retq 63 %cnt = tail call i32 @llvm.ctlz.i32(i32 %v, i1 true) 64 %tobool = icmp eq i32 0, %v 65 %cond = select i1 %tobool, i32 32, i32 %cnt 66 ret i32 %cond 67} 68 69 70define i64 @test6_ctlz(i64 %v) { 71; CHECK-LABEL: test6_ctlz: 72; CHECK: # %bb.0: 73; CHECK-NEXT: lzcntq %rdi, %rax 74; CHECK-NEXT: retq 75 %cnt = tail call i64 @llvm.ctlz.i64(i64 %v, i1 true) 76 %tobool = icmp eq i64 0, %v 77 %cond = select i1 %tobool, i64 64, i64 %cnt 78 ret i64 %cond 79} 80 81 82define i16 @test10_ctlz(i16* %ptr) { 83; CHECK-LABEL: test10_ctlz: 84; CHECK: # %bb.0: 85; CHECK-NEXT: lzcntw (%rdi), %ax 86; CHECK-NEXT: retq 87 %v = load i16, i16* %ptr 88 %cnt = tail call i16 @llvm.ctlz.i16(i16 %v, i1 true) 89 %tobool = icmp eq i16 %v, 0 90 %cond = select i1 %tobool, i16 16, i16 %cnt 91 ret i16 %cond 92} 93 94 95define i32 @test11_ctlz(i32* %ptr) { 96; CHECK-LABEL: test11_ctlz: 97; CHECK: # %bb.0: 98; CHECK-NEXT: lzcntl (%rdi), %eax 99; CHECK-NEXT: retq 100 %v = load i32, i32* %ptr 101 %cnt = tail call i32 @llvm.ctlz.i32(i32 %v, i1 true) 102 %tobool = icmp eq i32 %v, 0 103 %cond = select i1 %tobool, i32 32, i32 %cnt 104 ret i32 %cond 105} 106 107 108define i64 @test12_ctlz(i64* %ptr) { 109; CHECK-LABEL: test12_ctlz: 110; CHECK: # %bb.0: 111; CHECK-NEXT: lzcntq (%rdi), %rax 112; CHECK-NEXT: retq 113 %v = load i64, i64* %ptr 114 %cnt = tail call i64 @llvm.ctlz.i64(i64 %v, i1 true) 115 %tobool = icmp eq i64 %v, 0 116 %cond = select i1 %tobool, i64 64, i64 %cnt 117 ret i64 %cond 118} 119 120 121define i16 @test13_ctlz(i16* %ptr) { 122; CHECK-LABEL: test13_ctlz: 123; CHECK: # %bb.0: 124; CHECK-NEXT: lzcntw (%rdi), %ax 125; CHECK-NEXT: retq 126 %v = load i16, i16* %ptr 127 %cnt = tail call i16 @llvm.ctlz.i16(i16 %v, i1 true) 128 %tobool = icmp eq i16 0, %v 129 %cond = select i1 %tobool, i16 16, i16 %cnt 130 ret i16 %cond 131} 132 133 134define i32 @test14_ctlz(i32* %ptr) { 135; CHECK-LABEL: test14_ctlz: 136; CHECK: # %bb.0: 137; CHECK-NEXT: lzcntl (%rdi), %eax 138; CHECK-NEXT: retq 139 %v = load i32, i32* %ptr 140 %cnt = tail call i32 @llvm.ctlz.i32(i32 %v, i1 true) 141 %tobool = icmp eq i32 0, %v 142 %cond = select i1 %tobool, i32 32, i32 %cnt 143 ret i32 %cond 144} 145 146 147define i64 @test15_ctlz(i64* %ptr) { 148; CHECK-LABEL: test15_ctlz: 149; CHECK: # %bb.0: 150; CHECK-NEXT: lzcntq (%rdi), %rax 151; CHECK-NEXT: retq 152 %v = load i64, i64* %ptr 153 %cnt = tail call i64 @llvm.ctlz.i64(i64 %v, i1 true) 154 %tobool = icmp eq i64 0, %v 155 %cond = select i1 %tobool, i64 64, i64 %cnt 156 ret i64 %cond 157} 158 159 160define i16 @test1_cttz(i16 %v) { 161; CHECK-LABEL: test1_cttz: 162; CHECK: # %bb.0: 163; CHECK-NEXT: tzcntw %di, %ax 164; CHECK-NEXT: retq 165 %cnt = tail call i16 @llvm.cttz.i16(i16 %v, i1 true) 166 %tobool = icmp eq i16 %v, 0 167 %cond = select i1 %tobool, i16 16, i16 %cnt 168 ret i16 %cond 169} 170 171 172define i32 @test2_cttz(i32 %v) { 173; CHECK-LABEL: test2_cttz: 174; CHECK: # %bb.0: 175; CHECK-NEXT: tzcntl %edi, %eax 176; CHECK-NEXT: retq 177 %cnt = tail call i32 @llvm.cttz.i32(i32 %v, i1 true) 178 %tobool = icmp eq i32 %v, 0 179 %cond = select i1 %tobool, i32 32, i32 %cnt 180 ret i32 %cond 181} 182 183 184define i64 @test3_cttz(i64 %v) { 185; CHECK-LABEL: test3_cttz: 186; CHECK: # %bb.0: 187; CHECK-NEXT: tzcntq %rdi, %rax 188; CHECK-NEXT: retq 189 %cnt = tail call i64 @llvm.cttz.i64(i64 %v, i1 true) 190 %tobool = icmp eq i64 %v, 0 191 %cond = select i1 %tobool, i64 64, i64 %cnt 192 ret i64 %cond 193} 194 195 196define i16 @test4_cttz(i16 %v) { 197; CHECK-LABEL: test4_cttz: 198; CHECK: # %bb.0: 199; CHECK-NEXT: tzcntw %di, %ax 200; CHECK-NEXT: retq 201 %cnt = tail call i16 @llvm.cttz.i16(i16 %v, i1 true) 202 %tobool = icmp eq i16 0, %v 203 %cond = select i1 %tobool, i16 16, i16 %cnt 204 ret i16 %cond 205} 206 207 208define i32 @test5_cttz(i32 %v) { 209; CHECK-LABEL: test5_cttz: 210; CHECK: # %bb.0: 211; CHECK-NEXT: tzcntl %edi, %eax 212; CHECK-NEXT: retq 213 %cnt = tail call i32 @llvm.cttz.i32(i32 %v, i1 true) 214 %tobool = icmp eq i32 0, %v 215 %cond = select i1 %tobool, i32 32, i32 %cnt 216 ret i32 %cond 217} 218 219 220define i64 @test6_cttz(i64 %v) { 221; CHECK-LABEL: test6_cttz: 222; CHECK: # %bb.0: 223; CHECK-NEXT: tzcntq %rdi, %rax 224; CHECK-NEXT: retq 225 %cnt = tail call i64 @llvm.cttz.i64(i64 %v, i1 true) 226 %tobool = icmp eq i64 0, %v 227 %cond = select i1 %tobool, i64 64, i64 %cnt 228 ret i64 %cond 229} 230 231 232define i16 @test10_cttz(i16* %ptr) { 233; CHECK-LABEL: test10_cttz: 234; CHECK: # %bb.0: 235; CHECK-NEXT: tzcntw (%rdi), %ax 236; CHECK-NEXT: retq 237 %v = load i16, i16* %ptr 238 %cnt = tail call i16 @llvm.cttz.i16(i16 %v, i1 true) 239 %tobool = icmp eq i16 %v, 0 240 %cond = select i1 %tobool, i16 16, i16 %cnt 241 ret i16 %cond 242} 243 244 245define i32 @test11_cttz(i32* %ptr) { 246; CHECK-LABEL: test11_cttz: 247; CHECK: # %bb.0: 248; CHECK-NEXT: tzcntl (%rdi), %eax 249; CHECK-NEXT: retq 250 %v = load i32, i32* %ptr 251 %cnt = tail call i32 @llvm.cttz.i32(i32 %v, i1 true) 252 %tobool = icmp eq i32 %v, 0 253 %cond = select i1 %tobool, i32 32, i32 %cnt 254 ret i32 %cond 255} 256 257 258define i64 @test12_cttz(i64* %ptr) { 259; CHECK-LABEL: test12_cttz: 260; CHECK: # %bb.0: 261; CHECK-NEXT: tzcntq (%rdi), %rax 262; CHECK-NEXT: retq 263 %v = load i64, i64* %ptr 264 %cnt = tail call i64 @llvm.cttz.i64(i64 %v, i1 true) 265 %tobool = icmp eq i64 %v, 0 266 %cond = select i1 %tobool, i64 64, i64 %cnt 267 ret i64 %cond 268} 269 270 271define i16 @test13_cttz(i16* %ptr) { 272; CHECK-LABEL: test13_cttz: 273; CHECK: # %bb.0: 274; CHECK-NEXT: tzcntw (%rdi), %ax 275; CHECK-NEXT: retq 276 %v = load i16, i16* %ptr 277 %cnt = tail call i16 @llvm.cttz.i16(i16 %v, i1 true) 278 %tobool = icmp eq i16 0, %v 279 %cond = select i1 %tobool, i16 16, i16 %cnt 280 ret i16 %cond 281} 282 283 284define i32 @test14_cttz(i32* %ptr) { 285; CHECK-LABEL: test14_cttz: 286; CHECK: # %bb.0: 287; CHECK-NEXT: tzcntl (%rdi), %eax 288; CHECK-NEXT: retq 289 %v = load i32, i32* %ptr 290 %cnt = tail call i32 @llvm.cttz.i32(i32 %v, i1 true) 291 %tobool = icmp eq i32 0, %v 292 %cond = select i1 %tobool, i32 32, i32 %cnt 293 ret i32 %cond 294} 295 296 297define i64 @test15_cttz(i64* %ptr) { 298; CHECK-LABEL: test15_cttz: 299; CHECK: # %bb.0: 300; CHECK-NEXT: tzcntq (%rdi), %rax 301; CHECK-NEXT: retq 302 %v = load i64, i64* %ptr 303 %cnt = tail call i64 @llvm.cttz.i64(i64 %v, i1 true) 304 %tobool = icmp eq i64 0, %v 305 %cond = select i1 %tobool, i64 64, i64 %cnt 306 ret i64 %cond 307} 308 309 310define i16 @test4b_ctlz(i16 %v) { 311; CHECK-LABEL: test4b_ctlz: 312; CHECK: # %bb.0: 313; CHECK-NEXT: lzcntw %di, %ax 314; CHECK-NEXT: retq 315 %cnt = tail call i16 @llvm.ctlz.i16(i16 %v, i1 true) 316 %tobool = icmp ne i16 %v, 0 317 %cond = select i1 %tobool, i16 %cnt, i16 16 318 ret i16 %cond 319} 320 321 322define i32 @test5b_ctlz(i32 %v) { 323; CHECK-LABEL: test5b_ctlz: 324; CHECK: # %bb.0: 325; CHECK-NEXT: lzcntl %edi, %eax 326; CHECK-NEXT: retq 327 %cnt = tail call i32 @llvm.ctlz.i32(i32 %v, i1 true) 328 %tobool = icmp ne i32 %v, 0 329 %cond = select i1 %tobool, i32 %cnt, i32 32 330 ret i32 %cond 331} 332 333 334define i64 @test6b_ctlz(i64 %v) { 335; CHECK-LABEL: test6b_ctlz: 336; CHECK: # %bb.0: 337; CHECK-NEXT: lzcntq %rdi, %rax 338; CHECK-NEXT: retq 339 %cnt = tail call i64 @llvm.ctlz.i64(i64 %v, i1 true) 340 %tobool = icmp ne i64 %v, 0 341 %cond = select i1 %tobool, i64 %cnt, i64 64 342 ret i64 %cond 343} 344 345 346define i16 @test4b_cttz(i16 %v) { 347; CHECK-LABEL: test4b_cttz: 348; CHECK: # %bb.0: 349; CHECK-NEXT: tzcntw %di, %ax 350; CHECK-NEXT: retq 351 %cnt = tail call i16 @llvm.cttz.i16(i16 %v, i1 true) 352 %tobool = icmp ne i16 %v, 0 353 %cond = select i1 %tobool, i16 %cnt, i16 16 354 ret i16 %cond 355} 356 357 358define i32 @test5b_cttz(i32 %v) { 359; CHECK-LABEL: test5b_cttz: 360; CHECK: # %bb.0: 361; CHECK-NEXT: tzcntl %edi, %eax 362; CHECK-NEXT: retq 363 %cnt = tail call i32 @llvm.cttz.i32(i32 %v, i1 true) 364 %tobool = icmp ne i32 %v, 0 365 %cond = select i1 %tobool, i32 %cnt, i32 32 366 ret i32 %cond 367} 368 369 370define i64 @test6b_cttz(i64 %v) { 371; CHECK-LABEL: test6b_cttz: 372; CHECK: # %bb.0: 373; CHECK-NEXT: tzcntq %rdi, %rax 374; CHECK-NEXT: retq 375 %cnt = tail call i64 @llvm.cttz.i64(i64 %v, i1 true) 376 %tobool = icmp ne i64 %v, 0 377 %cond = select i1 %tobool, i64 %cnt, i64 64 378 ret i64 %cond 379} 380 381 382declare i64 @llvm.cttz.i64(i64, i1) 383declare i32 @llvm.cttz.i32(i32, i1) 384declare i16 @llvm.cttz.i16(i16, i1) 385declare i64 @llvm.ctlz.i64(i64, i1) 386declare i32 @llvm.ctlz.i32(i32, i1) 387declare i16 @llvm.ctlz.i16(i16, i1) 388 389