[llvm-commits] [llvm] r114460 - in /llvm/trunk: lib/Target/X86/X86ISelLowering.cpp test/CodeGen/X86/add-of-carry.ll
Chris Lattner
clattner at apple.com
Tue Sep 21 11:51:38 PDT 2010
On Sep 21, 2010, at 11:41 AM, Owen Anderson wrote:
> Author: resistor
> Date: Tue Sep 21 13:41:19 2010
> New Revision: 114460
>
> URL: http://llvm.org/viewvc/llvm-project?rev=114460&view=rev
> Log:
> When adding the carry bit to another value on X86, exploit the fact that the carry-materialization
> (sbbl x, x) sets the registers to 0 or ~0. Combined with two's complement arithmetic, we can fold
> the intermediate AND and the ADD into a single SUB.
>
> This fixes <rdar://problem/8449754>.
Cool, thanks Owen. Instead of checking for sbbl specifically, can this just use "is num sign bits == register width"? That would allow the xform to go into target independent code.
-Chris
> +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Tue Sep 21 13:41:19 2010
> @@ -1021,6 +1021,7 @@
> setTargetDAGCombine(ISD::OR);
> setTargetDAGCombine(ISD::STORE);
> setTargetDAGCombine(ISD::ZERO_EXTEND);
> + setTargetDAGCombine(ISD::ADD);
> if (Subtarget->is64Bit())
> setTargetDAGCombine(ISD::MUL);
>
> @@ -10452,6 +10453,27 @@
> return SDValue();
> }
>
> +/// PerformAddCombine - Optimize ADD when combined with X86 opcodes.
> +static SDValue PerformAddCombine(SDNode *N, SelectionDAG &DAG,
> + TargetLowering::DAGCombinerInfo &DCI) {
> + if (DCI.isBeforeLegalize() || DCI.isCalledByLegalizer())
> + return SDValue();
> +
> + EVT VT = N->getValueType(0);
> + SDValue Op1 = N->getOperand(1);
> + if (Op1->getOpcode() == ISD::AND) {
> + SDValue AndOp0 = Op1->getOperand(0);
> + ConstantSDNode *AndOp1 = dyn_cast<ConstantSDNode>(Op1->getOperand(1));
> + // (add z, (and (sbbl x, x), 1)) -> (sub z, (sbbl x, x))
> + if (AndOp0->getOpcode() == X86ISD::SETCC_CARRY &&
> + AndOp1 && AndOp1->getZExtValue() == 1) {
> + DebugLoc DL = N->getDebugLoc();
> + return DAG.getNode(ISD::SUB, DL, VT, N->getOperand(0), AndOp0);
> + }
> + }
> +
> + return SDValue();
> +}
>
> /// PerformMulCombine - Optimize a single multiply with constant into two
> /// in order to implement it with two cheaper instructions, e.g.
> @@ -10938,6 +10960,7 @@
> return PerformEXTRACT_VECTOR_ELTCombine(N, DAG, *this);
> case ISD::SELECT: return PerformSELECTCombine(N, DAG, Subtarget);
> case X86ISD::CMOV: return PerformCMOVCombine(N, DAG, DCI);
> + case ISD::ADD: return PerformAddCombine(N, DAG, DCI);
> case ISD::MUL: return PerformMulCombine(N, DAG, DCI);
> case ISD::SHL:
> case ISD::SRA:
>
> Added: llvm/trunk/test/CodeGen/X86/add-of-carry.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/add-of-carry.ll?rev=114460&view=auto
> ==============================================================================
> --- llvm/trunk/test/CodeGen/X86/add-of-carry.ll (added)
> +++ llvm/trunk/test/CodeGen/X86/add-of-carry.ll Tue Sep 21 13:41:19 2010
> @@ -0,0 +1,14 @@
> +; RUN: llc < %s -march=x86 | FileCheck %s
> +; <rdar://problem/8449754>
> +
> +define i32 @add32carry(i32 %sum, i32 %x) nounwind readnone ssp {
> +entry:
> +; CHECK: sbbl %ecx, %ecx
> +; CHECK-NOT: addl
> +; CHECK: subl %ecx, %eax
> + %add4 = add i32 %x, %sum
> + %cmp = icmp ult i32 %add4, %x
> + %inc = zext i1 %cmp to i32
> + %z.0 = add i32 %add4, %inc
> + ret i32 %z.0
> +}
>
>
> _______________________________________________
> 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