[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