llvm.org GIT mirror llvm / f10da4b
[TargetLowering] Simplify (ctpop x) == 1 Reviewers: craig.topper, spatel, RKSimon, bkramer Reviewed By: spatel Subscribers: javed.absar, lebedev.ri, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D63004 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@362912 91177308-0d34-0410-b5e6-96231b3b80d8 David Bolvansky 4 months ago
3 changed file(s) with 29 addition(s) and 53 deletion(s). Raw diff Collapse all Expand all
26902690 return DAG.getSetCC(dl, VT, And, DAG.getConstant(0, dl, CTVT), CC);
26912691 }
26922692
2693 // TODO: (ctpop x) == 1 -> x && (x & x-1) == 0 iff ctpop is illegal.
2693 // (ctpop x) == 1 -> x && (x & x-1) == 0 iff ctpop is illegal.
2694 if (Cond == ISD::SETEQ && C1 == 1 &&
2695 !isOperationLegalOrCustom(ISD::CTPOP, CTVT)) {
2696 SDValue Sub =
2697 DAG.getNode(ISD::SUB, dl, CTVT, CTOp, DAG.getConstant(1, dl, CTVT));
2698 SDValue And = DAG.getNode(ISD::AND, dl, CTVT, CTOp, Sub);
2699 SDValue LHS = DAG.getSetCC(dl, VT, CTOp, DAG.getConstant(0, dl, CTVT),
2700 ISD::SETUGT);
2701 SDValue RHS =
2702 DAG.getSetCC(dl, VT, And, DAG.getConstant(0, dl, CTVT), ISD::SETEQ);
2703 return DAG.getNode(ISD::AND, dl, VT, LHS, RHS);
2704 }
26942705 }
26952706
26962707 // (zext x) == C --> x == (trunc C)
325325 ;
326326 ; CHECK-ARM8A-NEON-LABEL: ctpop_eq_one:
327327 ; CHECK-ARM8A-NEON: @ %bb.0:
328 ; CHECK-ARM8A-NEON-NEXT: push {r11, lr}
329 ; CHECK-ARM8A-NEON-NEXT: movw r12, #21845
330 ; CHECK-ARM8A-NEON-NEXT: movw lr, #3855
331 ; CHECK-ARM8A-NEON-NEXT: movt r12, #21845
332 ; CHECK-ARM8A-NEON-NEXT: and r3, r12, r0, lsr #1
333 ; CHECK-ARM8A-NEON-NEXT: sub r0, r0, r3
334 ; CHECK-ARM8A-NEON-NEXT: movw r3, #13107
335 ; CHECK-ARM8A-NEON-NEXT: movt r3, #13107
336 ; CHECK-ARM8A-NEON-NEXT: and r2, r0, r3
337 ; CHECK-ARM8A-NEON-NEXT: and r0, r3, r0, lsr #2
338 ; CHECK-ARM8A-NEON-NEXT: movt lr, #3855
339 ; CHECK-ARM8A-NEON-NEXT: add r0, r2, r0
340 ; CHECK-ARM8A-NEON-NEXT: and r2, r12, r1, lsr #1
341 ; CHECK-ARM8A-NEON-NEXT: sub r1, r1, r2
342 ; CHECK-ARM8A-NEON-NEXT: and r2, r1, r3
343 ; CHECK-ARM8A-NEON-NEXT: add r0, r0, r0, lsr #4
344 ; CHECK-ARM8A-NEON-NEXT: and r1, r3, r1, lsr #2
345 ; CHECK-ARM8A-NEON-NEXT: and r0, r0, lr
346 ; CHECK-ARM8A-NEON-NEXT: add r1, r2, r1
347 ; CHECK-ARM8A-NEON-NEXT: movw r2, #257
348 ; CHECK-ARM8A-NEON-NEXT: movt r2, #257
349 ; CHECK-ARM8A-NEON-NEXT: add r1, r1, r1, lsr #4
350 ; CHECK-ARM8A-NEON-NEXT: mul r0, r0, r2
351 ; CHECK-ARM8A-NEON-NEXT: and r1, r1, lr
352 ; CHECK-ARM8A-NEON-NEXT: mul r1, r1, r2
353 ; CHECK-ARM8A-NEON-NEXT: lsr r0, r0, #24
354 ; CHECK-ARM8A-NEON-NEXT: add r0, r0, r1, lsr #24
355 ; CHECK-ARM8A-NEON-NEXT: eor r0, r0, #1
356 ; CHECK-ARM8A-NEON-NEXT: clz r0, r0
357 ; CHECK-ARM8A-NEON-NEXT: lsr r0, r0, #5
358 ; CHECK-ARM8A-NEON-NEXT: pop {r11, pc}
328 ; CHECK-ARM8A-NEON-NEXT: subs r2, r0, #1
329 ; CHECK-ARM8A-NEON-NEXT: sbc r3, r1, #0
330 ; CHECK-ARM8A-NEON-NEXT: and r2, r0, r2
331 ; CHECK-ARM8A-NEON-NEXT: and r3, r1, r3
332 ; CHECK-ARM8A-NEON-NEXT: orrs r0, r0, r1
333 ; CHECK-ARM8A-NEON-NEXT: orr r2, r2, r3
334 ; CHECK-ARM8A-NEON-NEXT: movwne r0, #1
335 ; CHECK-ARM8A-NEON-NEXT: clz r2, r2
336 ; CHECK-ARM8A-NEON-NEXT: lsr r2, r2, #5
337 ; CHECK-ARM8A-NEON-NEXT: and r0, r0, r2
338 ; CHECK-ARM8A-NEON-NEXT: bx lr
359339 %count = tail call i64 @llvm.ctpop.i64(i64 %x)
360340 %cmp = icmp eq i64 %count, 1
361341 %conv = zext i1 %cmp to i32
121121 ;
122122 ; NO-POPCOUNT-LABEL: ctpop_eq_one:
123123 ; NO-POPCOUNT: # %bb.0:
124 ; NO-POPCOUNT-NEXT: movq %rdi, %rax
125 ; NO-POPCOUNT-NEXT: shrq %rax
126 ; NO-POPCOUNT-NEXT: movabsq $6148914691236517205, %rcx # imm = 0x5555555555555555
127 ; NO-POPCOUNT-NEXT: andq %rax, %rcx
128 ; NO-POPCOUNT-NEXT: subq %rcx, %rdi
129 ; NO-POPCOUNT-NEXT: movabsq $3689348814741910323, %rax # imm = 0x3333333333333333
130 ; NO-POPCOUNT-NEXT: movq %rdi, %rcx
131 ; NO-POPCOUNT-NEXT: andq %rax, %rcx
132 ; NO-POPCOUNT-NEXT: shrq $2, %rdi
133 ; NO-POPCOUNT-NEXT: andq %rax, %rdi
134 ; NO-POPCOUNT-NEXT: addq %rcx, %rdi
135 ; NO-POPCOUNT-NEXT: movq %rdi, %rax
136 ; NO-POPCOUNT-NEXT: shrq $4, %rax
137 ; NO-POPCOUNT-NEXT: addq %rdi, %rax
138 ; NO-POPCOUNT-NEXT: movabsq $1085102592571150095, %rcx # imm = 0xF0F0F0F0F0F0F0F
139 ; NO-POPCOUNT-NEXT: andq %rax, %rcx
140 ; NO-POPCOUNT-NEXT: movabsq $72340172838076673, %rdx # imm = 0x101010101010101
141 ; NO-POPCOUNT-NEXT: imulq %rcx, %rdx
142 ; NO-POPCOUNT-NEXT: shrq $56, %rdx
143 ; NO-POPCOUNT-NEXT: xorl %eax, %eax
144 ; NO-POPCOUNT-NEXT: cmpq $1, %rdx
124 ; NO-POPCOUNT-NEXT: leaq -1(%rdi), %rax
125 ; NO-POPCOUNT-NEXT: testq %rax, %rdi
145126 ; NO-POPCOUNT-NEXT: sete %al
127 ; NO-POPCOUNT-NEXT: testq %rdi, %rdi
128 ; NO-POPCOUNT-NEXT: setne %cl
129 ; NO-POPCOUNT-NEXT: andb %al, %cl
130 ; NO-POPCOUNT-NEXT: movzbl %cl, %eax
146131 ; NO-POPCOUNT-NEXT: retq
147132 %count = tail call i64 @llvm.ctpop.i64(i64 %x)
148133 %cmp = icmp eq i64 %count, 1