[llvm-commits] [llvm] r122364 - in /llvm/trunk: lib/Target/X86/X86ISelLowering.cpp test/CodeGen/X86/conditional-indecrement.ll

Chris Lattner clattner at apple.com
Tue Dec 21 18:13:20 PST 2010


On Dec 21, 2010, at 1:41 PM, Benjamin Kramer wrote:

> Author: d0k
> Date: Tue Dec 21 15:41:44 2010
> New Revision: 122364
> 
> URL: http://llvm.org/viewvc/llvm-project?rev=122364&view=rev
> Log:
> Add some x86 specific dagcombines for conditional increments.
> 
> (add Y, (sete  X, 0)) -> cmp X, 1; adc  0, Y
> (add Y, (setne X, 0)) -> cmp X, 1; sbb -1, Y
> (sub (sete  X, 0), Y) -> cmp X, 1; sbb  0, Y
> (sub (setne X, 0), Y) -> cmp X, 1; adc -1, Y

Very nice.  Do we handle the cases when X and Y are the same value?  "X == 0 ? X+1 : X" simplifies to "X == 0 ? 1 : X".

-Chris

> 
> for
>  unsigned foo(unsigned a, unsigned b) {
>    if (a == 0) b++;
>    return b;
>  }
> we now get:
>  foo:
>    cmpl  $1, %edi
>    movl  %esi, %eax
>    adcl  $0, %eax
>    ret
> instead of:
>  foo:
>    testl %edi, %edi
>    sete  %al
>    movzbl  %al, %eax
>    addl  %esi, %eax
>    ret
> 
> Added:
>    llvm/trunk/test/CodeGen/X86/conditional-indecrement.ll
> Modified:
>    llvm/trunk/lib/Target/X86/X86ISelLowering.cpp
> 
> Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=122364&r1=122363&r2=122364&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original)
> +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Tue Dec 21 15:41:44 2010
> @@ -969,6 +969,8 @@
>   setTargetDAGCombine(ISD::SRL);
>   setTargetDAGCombine(ISD::OR);
>   setTargetDAGCombine(ISD::AND);
> +  setTargetDAGCombine(ISD::ADD);
> +  setTargetDAGCombine(ISD::SUB);
>   setTargetDAGCombine(ISD::STORE);
>   setTargetDAGCombine(ISD::ZERO_EXTEND);
>   if (Subtarget->is64Bit())
> @@ -11513,6 +11515,44 @@
>   return SDValue();
> }
> 
> +// fold (add Y, (sete  X, 0)) -> adc  0, Y
> +//      (add Y, (setne X, 0)) -> sbb -1, Y
> +//      (sub (sete  X, 0), Y) -> sbb  0, Y
> +//      (sub (setne X, 0), Y) -> adc -1, Y
> +static SDValue OptimizeConditonalInDecrement(SDNode *N, SelectionDAG &DAG) {
> +  DebugLoc DL = N->getDebugLoc();
> +  
> +  // Look through ZExts.
> +  SDValue Ext = N->getOperand(N->getOpcode() == ISD::SUB ? 1 : 0);
> +  if (Ext.getOpcode() != ISD::ZERO_EXTEND || !Ext.hasOneUse())
> +    return SDValue();
> +
> +  SDValue SetCC = Ext.getOperand(0);
> +  if (SetCC.getOpcode() != X86ISD::SETCC || !SetCC.hasOneUse())
> +    return SDValue();
> +
> +  X86::CondCode CC = (X86::CondCode)SetCC.getConstantOperandVal(0);
> +  if (CC != X86::COND_E && CC != X86::COND_NE)
> +    return SDValue();
> +
> +  SDValue Cmp = SetCC.getOperand(1);
> +  if (Cmp.getOpcode() != X86ISD::CMP || !Cmp.hasOneUse() ||
> +      !X86::isZeroNode(Cmp.getOperand(1)))
> +    return SDValue();
> +
> +  SDValue CmpOp0 = Cmp.getOperand(0);
> +  SDValue NewCmp = DAG.getNode(X86ISD::CMP, DL, MVT::i32, CmpOp0,
> +                               DAG.getConstant(1, CmpOp0.getValueType()));
> +
> +  SDValue OtherVal = N->getOperand(N->getOpcode() == ISD::SUB ? 0 : 1);
> +  if (CC == X86::COND_NE)
> +    return DAG.getNode(N->getOpcode() == ISD::SUB ? X86ISD::ADC : X86ISD::SBB,
> +                       DL, OtherVal.getValueType(), OtherVal,
> +                       DAG.getConstant(-1ULL, OtherVal.getValueType()), NewCmp);
> +  return DAG.getNode(N->getOpcode() == ISD::SUB ? X86ISD::SBB : X86ISD::ADC,
> +                     DL, OtherVal.getValueType(), OtherVal,
> +                     DAG.getConstant(0, OtherVal.getValueType()), NewCmp);
> +}
> 
> SDValue X86TargetLowering::PerformDAGCombine(SDNode *N,
>                                              DAGCombinerInfo &DCI) const {
> @@ -11523,6 +11563,8 @@
>     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:
> +  case ISD::SUB:            return OptimizeConditonalInDecrement(N, DAG);
>   case X86ISD::ADC:         return PerformADCCombine(N, DAG, DCI);
>   case ISD::MUL:            return PerformMulCombine(N, DAG, DCI);
>   case ISD::SHL:
> 
> Added: llvm/trunk/test/CodeGen/X86/conditional-indecrement.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/conditional-indecrement.ll?rev=122364&view=auto
> ==============================================================================
> --- llvm/trunk/test/CodeGen/X86/conditional-indecrement.ll (added)
> +++ llvm/trunk/test/CodeGen/X86/conditional-indecrement.ll Tue Dec 21 15:41:44 2010
> @@ -0,0 +1,89 @@
> +; RUN: llc -march=x86 < %s | FileCheck %s
> +
> +define i32 @test1(i32 %a, i32 %b) nounwind readnone {
> +  %not.cmp = icmp ne i32 %a, 0
> +  %inc = zext i1 %not.cmp to i32
> +  %retval.0 = add i32 %inc, %b
> +  ret i32 %retval.0
> +; CHECK: test1:
> +; CHECK: cmpl $1
> +; CHECK: sbbl $-1
> +; CHECK: ret
> +}
> +
> +define i32 @test2(i32 %a, i32 %b) nounwind readnone {
> +  %cmp = icmp eq i32 %a, 0
> +  %inc = zext i1 %cmp to i32
> +  %retval.0 = add i32 %inc, %b
> +  ret i32 %retval.0
> +; CHECK: test2:
> +; CHECK: cmpl $1
> +; CHECK: adcl $0
> +; CHECK: ret
> +}
> +
> +define i32 @test3(i32 %a, i32 %b) nounwind readnone {
> +  %cmp = icmp eq i32 %a, 0
> +  %inc = zext i1 %cmp to i32
> +  %retval.0 = add i32 %inc, %b
> +  ret i32 %retval.0
> +; CHECK: test3:
> +; CHECK: cmpl $1
> +; CHECK: adcl $0
> +; CHECK: ret
> +}
> +
> +define i32 @test4(i32 %a, i32 %b) nounwind readnone {
> +  %not.cmp = icmp ne i32 %a, 0
> +  %inc = zext i1 %not.cmp to i32
> +  %retval.0 = add i32 %inc, %b
> +  ret i32 %retval.0
> +; CHECK: test4:
> +; CHECK: cmpl $1
> +; CHECK: sbbl $-1
> +; CHECK: ret
> +}
> +
> +define i32 @test5(i32 %a, i32 %b) nounwind readnone {
> +  %not.cmp = icmp ne i32 %a, 0
> +  %inc = zext i1 %not.cmp to i32
> +  %retval.0 = sub i32 %b, %inc
> +  ret i32 %retval.0
> +; CHECK: test5:
> +; CHECK: cmpl $1
> +; CHECK: adcl $-1
> +; CHECK: ret
> +}
> +
> +define i32 @test6(i32 %a, i32 %b) nounwind readnone {
> +  %cmp = icmp eq i32 %a, 0
> +  %inc = zext i1 %cmp to i32
> +  %retval.0 = sub i32 %b, %inc
> +  ret i32 %retval.0
> +; CHECK: test6:
> +; CHECK: cmpl $1
> +; CHECK: sbbl $0
> +; CHECK: ret
> +}
> +
> +define i32 @test7(i32 %a, i32 %b) nounwind readnone {
> +  %cmp = icmp eq i32 %a, 0
> +  %inc = zext i1 %cmp to i32
> +  %retval.0 = sub i32 %b, %inc
> +  ret i32 %retval.0
> +; CHECK: test7:
> +; CHECK: cmpl $1
> +; CHECK: sbbl $0
> +; CHECK: ret
> +}
> +
> +define i32 @test8(i32 %a, i32 %b) nounwind readnone {
> +  %not.cmp = icmp ne i32 %a, 0
> +  %inc = zext i1 %not.cmp to i32
> +  %retval.0 = sub i32 %b, %inc
> +  ret i32 %retval.0
> +; CHECK: test8:
> +; CHECK: cmpl $1
> +; CHECK: adcl $-1
> +; 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