[llvm-commits] [llvm] r123621 - in /llvm/trunk: lib/CodeGen/SelectionDAG/TargetLowering.cpp test/CodeGen/X86/ctpop-combine.ll
Nick Lewycky
nicholas at mxc.ca
Mon Jan 17 11:34:55 PST 2011
Benjamin Kramer wrote:
> Author: d0k
> Date: Mon Jan 17 06:04:57 2011
> New Revision: 123621
>
> URL: http://llvm.org/viewvc/llvm-project?rev=123621&view=rev
> Log:
> Add a DAGCombine to turn (ctpop x) u< 2 into (x& x-1) == 0.
This should be an instcombine instead unless there's a reason not to?
Nick
> This shaves off 4 popcounts from the hacked 186.crafty source.
>
> This is enabled even when a native popcount instruction is available. The
> combined code is one operation longer but it should be faster nevertheless.
>
> Added:
> llvm/trunk/test/CodeGen/X86/ctpop-combine.ll
> Modified:
> llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp
>
> Modified: llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp?rev=123621&r1=123620&r2=123621&view=diff
> ==============================================================================
> --- llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp (original)
> +++ llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp Mon Jan 17 06:04:57 2011
> @@ -1870,6 +1870,30 @@
> }
> }
>
> + SDValue CTPOP = N0;
> + // Look through truncs that don't change the value of a ctpop.
> + if (N0.hasOneUse()&& N0.getOpcode() == ISD::TRUNCATE)
> + CTPOP = N0.getOperand(0);
> +
> + if (CTPOP.hasOneUse()&& CTPOP.getOpcode() == ISD::CTPOP&&
> + (N0 == CTPOP || N0.getValueType().getSizeInBits()>=
> + Log2_32_Ceil(CTPOP.getValueType().getSizeInBits()))) {
> + EVT CTVT = CTPOP.getValueType();
> + SDValue CTOp = CTPOP.getOperand(0);
> +
> + // (ctpop x) u< 2 -> (x& x-1) == 0
> + // (ctpop x) u> 1 -> (x& x-1) != 0
> + if ((Cond == ISD::SETULT&& C1 == 2) || (Cond == ISD::SETUGT&& C1 == 1)){
> + SDValue Sub = DAG.getNode(ISD::SUB, dl, CTVT, CTOp,
> + DAG.getConstant(1, CTVT));
> + SDValue And = DAG.getNode(ISD::AND, dl, CTVT, CTOp, Sub);
> + ISD::CondCode CC = Cond == ISD::SETULT ? ISD::SETEQ : ISD::SETNE;
> + return DAG.getSetCC(dl, VT, And, DAG.getConstant(0, CTVT), CC);
> + }
> +
> + // TODO: (ctpop x) == 1 -> x&& (x& x-1) == 0 iff ctpop is illegal.
> + }
> +
> // If the LHS is '(and load, const)', the RHS is 0,
> // the test is for equality or unsigned, and all 1 bits of the const are
> // in the same partial word, see if we can shorten the load.
>
> Added: llvm/trunk/test/CodeGen/X86/ctpop-combine.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/ctpop-combine.ll?rev=123621&view=auto
> ==============================================================================
> --- llvm/trunk/test/CodeGen/X86/ctpop-combine.ll (added)
> +++ llvm/trunk/test/CodeGen/X86/ctpop-combine.ll Mon Jan 17 06:04:57 2011
> @@ -0,0 +1,31 @@
> +; RUN: llc -march=x86-64< %s | FileCheck %s
> +
> +declare i64 @llvm.ctpop.i64(i64) nounwind readnone
> +
> +define i32 @test1(i64 %x) nounwind readnone {
> + %count = tail call i64 @llvm.ctpop.i64(i64 %x)
> + %cast = trunc i64 %count to i32
> + %cmp = icmp ugt i32 %cast, 1
> + %conv = zext i1 %cmp to i32
> + ret i32 %conv
> +; CHECK: test1:
> +; CHECK: leaq -1(%rdi)
> +; CHECK-NEXT: testq
> +; CHECK-NEXT: setne
> +; CHECK: ret
> +}
> +
> +
> +define i32 @test2(i64 %x) nounwind readnone {
> + %count = tail call i64 @llvm.ctpop.i64(i64 %x)
> + %cast = trunc i64 %count to i32
> + %cmp = icmp ult i32 %cast, 2
> + %conv = zext i1 %cmp to i32
> + ret i32 %conv
> +; CHECK: test2:
> +; CHECK: leaq -1(%rdi)
> +; CHECK-NEXT: testq
> +; CHECK-NEXT: sete
> +; CHECK: ret
> +}
> +
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>
More information about the llvm-commits
mailing list