From f50125ecaab0cc379892280de33f0a2d387f7f5b Mon Sep 17 00:00:00 2001 From: Benjamin Kramer Date: Wed, 22 Dec 2010 23:17:45 +0000 Subject: [PATCH] DAGCombine add (sext i1), X into sub X, (zext i1) if sext from i1 is illegal. The latter usually compiles into smaller code. example code: unsigned foo(unsigned x, unsigned y) { if (x != 0) y--; return y; } before: _foo: ## @foo cmpl $1, 4(%esp) ## encoding: [0x83,0x7c,0x24,0x04,0x01] sbbl %eax, %eax ## encoding: [0x19,0xc0] notl %eax ## encoding: [0xf7,0xd0] addl 8(%esp), %eax ## encoding: [0x03,0x44,0x24,0x08] ret ## encoding: [0xc3] after: _foo: ## @foo cmpl $1, 4(%esp) ## encoding: [0x83,0x7c,0x24,0x04,0x01] movl 8(%esp), %eax ## encoding: [0x8b,0x44,0x24,0x08] adcl $-1, %eax ## encoding: [0x83,0xd0,0xff] ret ## encoding: [0xc3] git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@122455 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 9 +++++++++ test/CodeGen/X86/add.ll | 12 ++++++++++++ 2 files changed, 21 insertions(+) diff --git a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index e4f30270538..7de66f6e90d 100644 --- a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -1443,6 +1443,15 @@ SDValue DAGCombiner::visitADD(SDNode *N) { } } + // add (sext i1), X -> sub X, (zext i1) + if (N0.getOpcode() == ISD::SIGN_EXTEND && + N0.getOperand(0).getValueType() == MVT::i1 && + !TLI.isOperationLegal(ISD::SIGN_EXTEND, MVT::i1)) { + DebugLoc DL = N->getDebugLoc(); + SDValue ZExt = DAG.getNode(ISD::ZERO_EXTEND, DL, VT, N0.getOperand(0)); + return DAG.getNode(ISD::SUB, DL, VT, N1, ZExt); + } + return SDValue(); } diff --git a/test/CodeGen/X86/add.ll b/test/CodeGen/X86/add.ll index d6e99ee1a7e..3ec5358affb 100644 --- a/test/CodeGen/X86/add.ll +++ b/test/CodeGen/X86/add.ll @@ -120,3 +120,15 @@ entry: ; X64: addq ; X64-NEXT: sbbq ; X64-NEXT: testb + +define i32 @test9(i32 %x, i32 %y) nounwind readnone { + %cmp = icmp eq i32 %x, 10 + %sub = sext i1 %cmp to i32 + %cond = add i32 %sub, %y + ret i32 %cond +; X64: test9: +; X64: cmpl $10 +; X64: sete +; X64: subl +; X64: ret +}