From 1982ef20c44d85386a239a1b24eb2bb72cea29ec Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Wed, 11 Apr 2007 05:11:38 +0000 Subject: [PATCH] Codegen integer abs more efficiently using the trick from the PPC CWG. This improves codegen on many architectures. Tests committed as CodeGen/*/iabs.ll X86 Old: X86 New: _test: _test: movl 4(%esp), %ecx movl 4(%esp), %eax movl %ecx, %eax movl %eax, %ecx negl %eax sarl $31, %ecx testl %ecx, %ecx addl %ecx, %eax cmovns %ecx, %eax xorl %ecx, %eax ret ret PPC Old: PPC New: _test: _test: cmpwi cr0, r3, -1 srawi r2, r3, 31 neg r2, r3 add r3, r3, r2 bgt cr0, LBB1_2 ; xor r3, r3, r2 LBB1_1: ; blr mr r3, r2 LBB1_2: ; blr ARM Old: ARM New: _test: _test: rsb r3, r0, #0 add r3, r0, r0, asr #31 cmp r0, #0 eor r0, r3, r0, asr #31 movge r3, r0 bx lr mov r0, r3 bx lr Thumb Old: Thumb New: _test: _test: neg r2, r0 asr r2, r0, #31 cmp r0, #0 add r0, r0, r2 bge LBB1_2 eor r0, r2 LBB1_1: @ bx lr cpy r0, r2 LBB1_2: @ bx lr Sparc Old: Sparc New: test: test: save -96, %o6, %o6 save -96, %o6, %o6 sethi 0, %l0 sra %i0, 31, %l0 sub %l0, %i0, %l0 add %i0, %l0, %l1 subcc %i0, -1, %l1 xor %l1, %l0, %i0 bg .BB1_2 restore %g0, %g0, %g0 nop retl .BB1_1: nop or %g0, %l0, %i0 .BB1_2: restore %g0, %g0, %g0 retl nop It also helps alpha/ia64 :) git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@35881 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index ed026084aae..9ce6a8fa9b9 100644 --- a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -4159,13 +4159,27 @@ SDOperand DAGCombiner::SimplifySelectCC(SDOperand N0, SDOperand N1, // Check to see if this is an integer abs. select_cc setl[te] X, 0, -X, X -> // Y = sra (X, size(X)-1); xor (add (X, Y), Y) if (N1C && N1C->isNullValue() && (CC == ISD::SETLT || CC == ISD::SETLE) && - N0 == N3 && N2.getOpcode() == ISD::SUB && N0 == N2.getOperand(1)) { - if (ConstantSDNode *SubC = dyn_cast(N2.getOperand(0))) { + N0 == N3 && N2.getOpcode() == ISD::SUB && N0 == N2.getOperand(1) && + N2.getOperand(0) == N1 && MVT::isInteger(N0.getValueType())) { + MVT::ValueType XType = N0.getValueType(); + SDOperand Shift = DAG.getNode(ISD::SRA, XType, N0, + DAG.getConstant(MVT::getSizeInBits(XType)-1, + TLI.getShiftAmountTy())); + SDOperand Add = DAG.getNode(ISD::ADD, XType, N0, Shift); + AddToWorkList(Shift.Val); + AddToWorkList(Add.Val); + return DAG.getNode(ISD::XOR, XType, Add, Shift); + } + // Check to see if this is an integer abs. select_cc setgt X, -1, X, -X -> + // Y = sra (X, size(X)-1); xor (add (X, Y), Y) + if (N1C && N1C->isAllOnesValue() && CC == ISD::SETGT && + N0 == N2 && N3.getOpcode() == ISD::SUB && N0 == N3.getOperand(1)) { + if (ConstantSDNode *SubC = dyn_cast(N3.getOperand(0))) { MVT::ValueType XType = N0.getValueType(); if (SubC->isNullValue() && MVT::isInteger(XType)) { SDOperand Shift = DAG.getNode(ISD::SRA, XType, N0, DAG.getConstant(MVT::getSizeInBits(XType)-1, - TLI.getShiftAmountTy())); + TLI.getShiftAmountTy())); SDOperand Add = DAG.getNode(ISD::ADD, XType, N0, Shift); AddToWorkList(Shift.Val); AddToWorkList(Add.Val); @@ -4173,7 +4187,7 @@ SDOperand DAGCombiner::SimplifySelectCC(SDOperand N0, SDOperand N1, } } } - + return SDOperand(); }