1*9880d681SAndroid Build Coastguard Worker; RUN: llc < %s -mtriple=x86_64-unknown-unknown | FileCheck %s 2*9880d681SAndroid Build Coastguard Worker 3*9880d681SAndroid Build Coastguard Workerdeclare i8 @llvm.cttz.i8(i8, i1) 4*9880d681SAndroid Build Coastguard Workerdeclare i16 @llvm.cttz.i16(i16, i1) 5*9880d681SAndroid Build Coastguard Workerdeclare i32 @llvm.cttz.i32(i32, i1) 6*9880d681SAndroid Build Coastguard Workerdeclare i64 @llvm.cttz.i64(i64, i1) 7*9880d681SAndroid Build Coastguard Workerdeclare i8 @llvm.ctlz.i8(i8, i1) 8*9880d681SAndroid Build Coastguard Workerdeclare i16 @llvm.ctlz.i16(i16, i1) 9*9880d681SAndroid Build Coastguard Workerdeclare i32 @llvm.ctlz.i32(i32, i1) 10*9880d681SAndroid Build Coastguard Workerdeclare i64 @llvm.ctlz.i64(i64, i1) 11*9880d681SAndroid Build Coastguard Worker 12*9880d681SAndroid Build Coastguard Workerdefine i8 @cttz_i8(i8 %x) { 13*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: cttz_i8: 14*9880d681SAndroid Build Coastguard Worker; CHECK: # BB#0: 15*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: movzbl %dil, %eax 16*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bsfl %eax, %eax 17*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: # kill 18*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: retq 19*9880d681SAndroid Build Coastguard Worker %tmp = call i8 @llvm.cttz.i8( i8 %x, i1 true ) 20*9880d681SAndroid Build Coastguard Worker ret i8 %tmp 21*9880d681SAndroid Build Coastguard Worker} 22*9880d681SAndroid Build Coastguard Worker 23*9880d681SAndroid Build Coastguard Workerdefine i16 @cttz_i16(i16 %x) { 24*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: cttz_i16: 25*9880d681SAndroid Build Coastguard Worker; CHECK: # BB#0: 26*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bsfw %di, %ax 27*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: retq 28*9880d681SAndroid Build Coastguard Worker %tmp = call i16 @llvm.cttz.i16( i16 %x, i1 true ) 29*9880d681SAndroid Build Coastguard Worker ret i16 %tmp 30*9880d681SAndroid Build Coastguard Worker} 31*9880d681SAndroid Build Coastguard Worker 32*9880d681SAndroid Build Coastguard Workerdefine i32 @cttz_i32(i32 %x) { 33*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: cttz_i32: 34*9880d681SAndroid Build Coastguard Worker; CHECK: # BB#0: 35*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bsfl %edi, %eax 36*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: retq 37*9880d681SAndroid Build Coastguard Worker %tmp = call i32 @llvm.cttz.i32( i32 %x, i1 true ) 38*9880d681SAndroid Build Coastguard Worker ret i32 %tmp 39*9880d681SAndroid Build Coastguard Worker} 40*9880d681SAndroid Build Coastguard Worker 41*9880d681SAndroid Build Coastguard Workerdefine i64 @cttz_i64(i64 %x) { 42*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: cttz_i64: 43*9880d681SAndroid Build Coastguard Worker; CHECK: # BB#0: 44*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bsfq %rdi, %rax 45*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: retq 46*9880d681SAndroid Build Coastguard Worker %tmp = call i64 @llvm.cttz.i64( i64 %x, i1 true ) 47*9880d681SAndroid Build Coastguard Worker ret i64 %tmp 48*9880d681SAndroid Build Coastguard Worker} 49*9880d681SAndroid Build Coastguard Worker 50*9880d681SAndroid Build Coastguard Workerdefine i8 @ctlz_i8(i8 %x) { 51*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: ctlz_i8: 52*9880d681SAndroid Build Coastguard Worker; CHECK: # BB#0: 53*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: movzbl %dil, %eax 54*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bsrl %eax, %eax 55*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: xorl $7, %eax 56*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: # kill 57*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: retq 58*9880d681SAndroid Build Coastguard Worker %tmp2 = call i8 @llvm.ctlz.i8( i8 %x, i1 true ) 59*9880d681SAndroid Build Coastguard Worker ret i8 %tmp2 60*9880d681SAndroid Build Coastguard Worker} 61*9880d681SAndroid Build Coastguard Worker 62*9880d681SAndroid Build Coastguard Workerdefine i16 @ctlz_i16(i16 %x) { 63*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: ctlz_i16: 64*9880d681SAndroid Build Coastguard Worker; CHECK: # BB#0: 65*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bsrw %di, %ax 66*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: xorl $15, %eax 67*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: # kill 68*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: retq 69*9880d681SAndroid Build Coastguard Worker %tmp2 = call i16 @llvm.ctlz.i16( i16 %x, i1 true ) 70*9880d681SAndroid Build Coastguard Worker ret i16 %tmp2 71*9880d681SAndroid Build Coastguard Worker} 72*9880d681SAndroid Build Coastguard Worker 73*9880d681SAndroid Build Coastguard Workerdefine i32 @ctlz_i32(i32 %x) { 74*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: ctlz_i32: 75*9880d681SAndroid Build Coastguard Worker; CHECK: # BB#0: 76*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bsrl %edi, %eax 77*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: xorl $31, %eax 78*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: retq 79*9880d681SAndroid Build Coastguard Worker %tmp = call i32 @llvm.ctlz.i32( i32 %x, i1 true ) 80*9880d681SAndroid Build Coastguard Worker ret i32 %tmp 81*9880d681SAndroid Build Coastguard Worker} 82*9880d681SAndroid Build Coastguard Worker 83*9880d681SAndroid Build Coastguard Workerdefine i64 @ctlz_i64(i64 %x) { 84*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: ctlz_i64: 85*9880d681SAndroid Build Coastguard Worker; CHECK: # BB#0: 86*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bsrq %rdi, %rax 87*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: xorq $63, %rax 88*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: retq 89*9880d681SAndroid Build Coastguard Worker %tmp = call i64 @llvm.ctlz.i64( i64 %x, i1 true ) 90*9880d681SAndroid Build Coastguard Worker ret i64 %tmp 91*9880d681SAndroid Build Coastguard Worker} 92*9880d681SAndroid Build Coastguard Worker 93*9880d681SAndroid Build Coastguard Workerdefine i8 @ctlz_i8_zero_test(i8 %n) { 94*9880d681SAndroid Build Coastguard Worker; Generate a test and branch to handle zero inputs because bsr/bsf are very slow. 95*9880d681SAndroid Build Coastguard Worker 96*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: ctlz_i8_zero_test: 97*9880d681SAndroid Build Coastguard Worker; CHECK: # BB#0: 98*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: movb $8, %al 99*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: testb %dil, %dil 100*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: je .LBB8_2 101*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: # BB#1: # %cond.false 102*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: movzbl %dil, %eax 103*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bsrl %eax, %eax 104*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: xorl $7, %eax 105*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: .LBB8_2: # %cond.end 106*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: # kill 107*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: retq 108*9880d681SAndroid Build Coastguard Worker %tmp1 = call i8 @llvm.ctlz.i8(i8 %n, i1 false) 109*9880d681SAndroid Build Coastguard Worker ret i8 %tmp1 110*9880d681SAndroid Build Coastguard Worker} 111*9880d681SAndroid Build Coastguard Worker 112*9880d681SAndroid Build Coastguard Workerdefine i16 @ctlz_i16_zero_test(i16 %n) { 113*9880d681SAndroid Build Coastguard Worker; Generate a test and branch to handle zero inputs because bsr/bsf are very slow. 114*9880d681SAndroid Build Coastguard Worker 115*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: ctlz_i16_zero_test: 116*9880d681SAndroid Build Coastguard Worker; CHECK: # BB#0: 117*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: movw $16, %ax 118*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: testw %di, %di 119*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: je .LBB9_2 120*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: # BB#1: # %cond.false 121*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bsrw %di, %ax 122*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: xorl $15, %eax 123*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: .LBB9_2: # %cond.end 124*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: # kill 125*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: retq 126*9880d681SAndroid Build Coastguard Worker %tmp1 = call i16 @llvm.ctlz.i16(i16 %n, i1 false) 127*9880d681SAndroid Build Coastguard Worker ret i16 %tmp1 128*9880d681SAndroid Build Coastguard Worker} 129*9880d681SAndroid Build Coastguard Worker 130*9880d681SAndroid Build Coastguard Workerdefine i32 @ctlz_i32_zero_test(i32 %n) { 131*9880d681SAndroid Build Coastguard Worker; Generate a test and branch to handle zero inputs because bsr/bsf are very slow. 132*9880d681SAndroid Build Coastguard Worker 133*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: ctlz_i32_zero_test: 134*9880d681SAndroid Build Coastguard Worker; CHECK: # BB#0: 135*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: movl $32, %eax 136*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: testl %edi, %edi 137*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: je .LBB10_2 138*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: # BB#1: # %cond.false 139*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bsrl %edi, %eax 140*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: xorl $31, %eax 141*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: .LBB10_2: # %cond.end 142*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: retq 143*9880d681SAndroid Build Coastguard Worker %tmp1 = call i32 @llvm.ctlz.i32(i32 %n, i1 false) 144*9880d681SAndroid Build Coastguard Worker ret i32 %tmp1 145*9880d681SAndroid Build Coastguard Worker} 146*9880d681SAndroid Build Coastguard Worker 147*9880d681SAndroid Build Coastguard Workerdefine i64 @ctlz_i64_zero_test(i64 %n) { 148*9880d681SAndroid Build Coastguard Worker; Generate a test and branch to handle zero inputs because bsr/bsf are very slow. 149*9880d681SAndroid Build Coastguard Worker 150*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: ctlz_i64_zero_test: 151*9880d681SAndroid Build Coastguard Worker; CHECK: # BB#0: 152*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: movl $64, %eax 153*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: testq %rdi, %rdi 154*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: je .LBB11_2 155*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: # BB#1: # %cond.false 156*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bsrq %rdi, %rax 157*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: xorq $63, %rax 158*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: .LBB11_2: # %cond.end 159*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: retq 160*9880d681SAndroid Build Coastguard Worker %tmp1 = call i64 @llvm.ctlz.i64(i64 %n, i1 false) 161*9880d681SAndroid Build Coastguard Worker ret i64 %tmp1 162*9880d681SAndroid Build Coastguard Worker} 163*9880d681SAndroid Build Coastguard Worker 164*9880d681SAndroid Build Coastguard Workerdefine i8 @cttz_i8_zero_test(i8 %n) { 165*9880d681SAndroid Build Coastguard Worker; Generate a test and branch to handle zero inputs because bsr/bsf are very slow. 166*9880d681SAndroid Build Coastguard Worker 167*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: cttz_i8_zero_test: 168*9880d681SAndroid Build Coastguard Worker; CHECK: # BB#0: 169*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: movb $8, %al 170*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: testb %dil, %dil 171*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: je .LBB12_2 172*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: # BB#1: # %cond.false 173*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: movzbl %dil, %eax 174*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bsfl %eax, %eax 175*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: .LBB12_2: # %cond.end 176*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: # kill 177*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: retq 178*9880d681SAndroid Build Coastguard Worker %tmp1 = call i8 @llvm.cttz.i8(i8 %n, i1 false) 179*9880d681SAndroid Build Coastguard Worker ret i8 %tmp1 180*9880d681SAndroid Build Coastguard Worker} 181*9880d681SAndroid Build Coastguard Worker 182*9880d681SAndroid Build Coastguard Workerdefine i16 @cttz_i16_zero_test(i16 %n) { 183*9880d681SAndroid Build Coastguard Worker; Generate a test and branch to handle zero inputs because bsr/bsf are very slow. 184*9880d681SAndroid Build Coastguard Worker 185*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: cttz_i16_zero_test: 186*9880d681SAndroid Build Coastguard Worker; CHECK: # BB#0: 187*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: movw $16, %ax 188*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: testw %di, %di 189*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: je .LBB13_2 190*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: # BB#1: # %cond.false 191*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bsfw %di, %ax 192*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: .LBB13_2: # %cond.end 193*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: retq 194*9880d681SAndroid Build Coastguard Worker %tmp1 = call i16 @llvm.cttz.i16(i16 %n, i1 false) 195*9880d681SAndroid Build Coastguard Worker ret i16 %tmp1 196*9880d681SAndroid Build Coastguard Worker} 197*9880d681SAndroid Build Coastguard Worker 198*9880d681SAndroid Build Coastguard Workerdefine i32 @cttz_i32_zero_test(i32 %n) { 199*9880d681SAndroid Build Coastguard Worker; Generate a test and branch to handle zero inputs because bsr/bsf are very slow. 200*9880d681SAndroid Build Coastguard Worker 201*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: cttz_i32_zero_test: 202*9880d681SAndroid Build Coastguard Worker; CHECK: # BB#0: 203*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: movl $32, %eax 204*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: testl %edi, %edi 205*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: je .LBB14_2 206*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: # BB#1: # %cond.false 207*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bsfl %edi, %eax 208*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: .LBB14_2: # %cond.end 209*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: retq 210*9880d681SAndroid Build Coastguard Worker %tmp1 = call i32 @llvm.cttz.i32(i32 %n, i1 false) 211*9880d681SAndroid Build Coastguard Worker ret i32 %tmp1 212*9880d681SAndroid Build Coastguard Worker} 213*9880d681SAndroid Build Coastguard Worker 214*9880d681SAndroid Build Coastguard Workerdefine i64 @cttz_i64_zero_test(i64 %n) { 215*9880d681SAndroid Build Coastguard Worker; Generate a test and branch to handle zero inputs because bsr/bsf are very slow. 216*9880d681SAndroid Build Coastguard Worker 217*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: cttz_i64_zero_test: 218*9880d681SAndroid Build Coastguard Worker; CHECK: # BB#0: 219*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: movl $64, %eax 220*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: testq %rdi, %rdi 221*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: je .LBB15_2 222*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: # BB#1: # %cond.false 223*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bsfq %rdi, %rax 224*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: .LBB15_2: # %cond.end 225*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: retq 226*9880d681SAndroid Build Coastguard Worker %tmp1 = call i64 @llvm.cttz.i64(i64 %n, i1 false) 227*9880d681SAndroid Build Coastguard Worker ret i64 %tmp1 228*9880d681SAndroid Build Coastguard Worker} 229*9880d681SAndroid Build Coastguard Worker 230*9880d681SAndroid Build Coastguard Workerdefine i32 @ctlz_i32_fold_cmov(i32 %n) { 231*9880d681SAndroid Build Coastguard Worker; Don't generate the cmovne when the source is known non-zero (and bsr would 232*9880d681SAndroid Build Coastguard Worker; not set ZF). 233*9880d681SAndroid Build Coastguard Worker; rdar://9490949 234*9880d681SAndroid Build Coastguard Worker; FIXME: The compare and branch are produced late in IR (by CodeGenPrepare), and 235*9880d681SAndroid Build Coastguard Worker; codegen doesn't know how to delete the movl and je. 236*9880d681SAndroid Build Coastguard Worker 237*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: ctlz_i32_fold_cmov: 238*9880d681SAndroid Build Coastguard Worker; CHECK: # BB#0: 239*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: orl $1, %edi 240*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: movl $32, %eax 241*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: je .LBB16_2 242*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: # BB#1: # %cond.false 243*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bsrl %edi, %eax 244*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: xorl $31, %eax 245*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: .LBB16_2: # %cond.end 246*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: retq 247*9880d681SAndroid Build Coastguard Worker %or = or i32 %n, 1 248*9880d681SAndroid Build Coastguard Worker %tmp1 = call i32 @llvm.ctlz.i32(i32 %or, i1 false) 249*9880d681SAndroid Build Coastguard Worker ret i32 %tmp1 250*9880d681SAndroid Build Coastguard Worker} 251*9880d681SAndroid Build Coastguard Worker 252*9880d681SAndroid Build Coastguard Workerdefine i32 @ctlz_bsr(i32 %n) { 253*9880d681SAndroid Build Coastguard Worker; Don't generate any xors when a 'ctlz' intrinsic is actually used to compute 254*9880d681SAndroid Build Coastguard Worker; the most significant bit, which is what 'bsr' does natively. 255*9880d681SAndroid Build Coastguard Worker 256*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: ctlz_bsr: 257*9880d681SAndroid Build Coastguard Worker; CHECK: # BB#0: 258*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bsrl %edi, %eax 259*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: retq 260*9880d681SAndroid Build Coastguard Worker %ctlz = call i32 @llvm.ctlz.i32(i32 %n, i1 true) 261*9880d681SAndroid Build Coastguard Worker %bsr = xor i32 %ctlz, 31 262*9880d681SAndroid Build Coastguard Worker ret i32 %bsr 263*9880d681SAndroid Build Coastguard Worker} 264*9880d681SAndroid Build Coastguard Worker 265*9880d681SAndroid Build Coastguard Workerdefine i32 @ctlz_bsr_zero_test(i32 %n) { 266*9880d681SAndroid Build Coastguard Worker; Generate a test and branch to handle zero inputs because bsr/bsf are very slow. 267*9880d681SAndroid Build Coastguard Worker; FIXME: The compare and branch are produced late in IR (by CodeGenPrepare), and 268*9880d681SAndroid Build Coastguard Worker; codegen doesn't know how to combine the $32 and $31 into $63. 269*9880d681SAndroid Build Coastguard Worker 270*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: ctlz_bsr_zero_test: 271*9880d681SAndroid Build Coastguard Worker; CHECK: # BB#0: 272*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: movl $32, %eax 273*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: testl %edi, %edi 274*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: je .LBB18_2 275*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: # BB#1: # %cond.false 276*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bsrl %edi, %eax 277*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: xorl $31, %eax 278*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: .LBB18_2: # %cond.end 279*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: xorl $31, %eax 280*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: retq 281*9880d681SAndroid Build Coastguard Worker %ctlz = call i32 @llvm.ctlz.i32(i32 %n, i1 false) 282*9880d681SAndroid Build Coastguard Worker %bsr = xor i32 %ctlz, 31 283*9880d681SAndroid Build Coastguard Worker ret i32 %bsr 284*9880d681SAndroid Build Coastguard Worker} 285