[llvm-commits] [llvm] r71446 - in /llvm/trunk: lib/Target/X86/X86ISelDAGToDAG.cpp lib/Target/X86/X86InstrInfo.td test/CodeGen/X86/lea-neg.ll

Bill Wendling isanbard at gmail.com
Mon May 11 11:31:19 PDT 2009


Dan,

This is failing at least in release mode:

Running /Volumes/Sandbox/Buildbot/llvm/full-llvm/build/llvm.src/test/CodeGen/X86/dg.exp
...
FAIL: /Volumes/Sandbox/Buildbot/llvm/full-llvm/build/llvm.src/test/CodeGen/X86/lea-neg.ll
Failed with exit(1) at line 3
while running: not /usr/bin/grep sub lea-neg.ll.tmp
	.subsections_via_symbols
child process exited abnormally

-bw

On Mon, May 11, 2009 at 11:02 AM, Dan Gohman <gohman at apple.com> wrote:
> Author: djg
> Date: Mon May 11 13:02:53 2009
> New Revision: 71446
>
> URL: http://llvm.org/viewvc/llvm-project?rev=71446&view=rev
> Log:
> Convert a subtract into a negate and an add when it helps x86
> address folding.
>
> Added:
>    llvm/trunk/test/CodeGen/X86/lea-neg.ll
> Modified:
>    llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp
>    llvm/trunk/lib/Target/X86/X86InstrInfo.td
>
> Modified: llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp?rev=71446&r1=71445&r2=71446&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp (original)
> +++ llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp Mon May 11 13:02:53 2009
> @@ -868,6 +868,76 @@
>     }
>     break;
>
> +  case ISD::SUB: {
> +    // Given A-B, if A can be completely folded into the address and
> +    // the index field with the index field unused, use -B as the index.
> +    // This is a win if a has multiple parts that can be folded into
> +    // the address. Also, this saves a mov if the base register has
> +    // other uses, since it avoids a two-address sub instruction, however
> +    // it costs an additional mov if the index register has other uses.
> +
> +    // Test if the LHS of the sub can be folded.
> +    X86ISelAddressMode Backup = AM;
> +    if (MatchAddress(N.getNode()->getOperand(0), AM, Depth+1)) {
> +      AM = Backup;
> +      break;
> +    }
> +    // Test if the index field is free for use.
> +    if (AM.IndexReg.getNode() || AM.isRIPRel) {
> +      AM = Backup;
> +      break;
> +    }
> +    int Cost = 0;
> +    SDValue RHS = N.getNode()->getOperand(1);
> +    // If the RHS involves a register with multiple uses, this
> +    // transformation incurs an extra mov, due to the neg instruction
> +    // clobbering its operand.
> +    if (!RHS.getNode()->hasOneUse() ||
> +        RHS.getNode()->getOpcode() == ISD::CopyFromReg ||
> +        RHS.getNode()->getOpcode() == ISD::TRUNCATE ||
> +        RHS.getNode()->getOpcode() == ISD::ANY_EXTEND ||
> +        (RHS.getNode()->getOpcode() == ISD::ZERO_EXTEND &&
> +         RHS.getNode()->getOperand(0).getValueType() == MVT::i32))
> +      ++Cost;
> +    // If the base is a register with multiple uses, this
> +    // transformation may save a mov.
> +    if ((AM.BaseType == X86ISelAddressMode::RegBase &&
> +         AM.Base.Reg.getNode() &&
> +         !AM.Base.Reg.getNode()->hasOneUse()) ||
> +        AM.BaseType == X86ISelAddressMode::FrameIndexBase)
> +      --Cost;
> +    // If the folded LHS was interesting, this transformation saves
> +    // address arithmetic.
> +    if ((AM.hasSymbolicDisplacement() && !Backup.hasSymbolicDisplacement()) +
> +        ((AM.Disp != 0) && (Backup.Disp == 0)) +
> +        (AM.Segment.getNode() && !Backup.Segment.getNode()) >= 2)
> +      --Cost;
> +    // If it doesn't look like it may be an overall win, don't do it.
> +    if (Cost >= 0) {
> +      AM = Backup;
> +      break;
> +    }
> +
> +    // Ok, the transformation is legal and appears profitable. Go for it.
> +    SDValue Zero = CurDAG->getConstant(0, N.getValueType());
> +    SDValue Neg = CurDAG->getNode(ISD::SUB, dl, N.getValueType(), Zero, RHS);
> +    AM.IndexReg = Neg;
> +    AM.Scale = 1;
> +
> +    // Insert the new nodes into the topological ordering.
> +    if (Zero.getNode()->getNodeId() == -1 ||
> +        Zero.getNode()->getNodeId() > N.getNode()->getNodeId()) {
> +      CurDAG->RepositionNode(N.getNode(), Zero.getNode());
> +      Zero.getNode()->setNodeId(N.getNode()->getNodeId());
> +    }
> +    if (Neg.getNode()->getNodeId() == -1 ||
> +        Neg.getNode()->getNodeId() > N.getNode()->getNodeId()) {
> +      CurDAG->RepositionNode(N.getNode(), Neg.getNode());
> +      Neg.getNode()->setNodeId(N.getNode()->getNodeId());
> +    }
> +    return false;
> +  }
> +
>   case ISD::ADD: {
>     X86ISelAddressMode Backup = AM;
>     if (!MatchAddress(N.getNode()->getOperand(0), AM, Depth+1) &&
>
> Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.td
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.td?rev=71446&r1=71445&r2=71446&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/Target/X86/X86InstrInfo.td (original)
> +++ llvm/trunk/lib/Target/X86/X86InstrInfo.td Mon May 11 13:02:53 2009
> @@ -217,7 +217,7 @@
>  // Define X86 specific addressing mode.
>  def addr      : ComplexPattern<iPTR, 5, "SelectAddr", [], []>;
>  def lea32addr : ComplexPattern<i32, 4, "SelectLEAAddr",
> -                               [add, mul, shl, or, frameindex], []>;
> +                               [add, sub, mul, shl, or, frameindex], []>;
>
>  //===----------------------------------------------------------------------===//
>  // X86 Instruction Predicate Definitions.
>
> Added: llvm/trunk/test/CodeGen/X86/lea-neg.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/lea-neg.ll?rev=71446&view=auto
>
> ==============================================================================
> --- llvm/trunk/test/CodeGen/X86/lea-neg.ll (added)
> +++ llvm/trunk/test/CodeGen/X86/lea-neg.ll Mon May 11 13:02:53 2009
> @@ -0,0 +1,25 @@
> +; RUN: llvm-as < %s | llc -march=x86-64 > %t
> +; RUN: grep negl %t | count 1
> +; RUN: not grep sub %t
> +; RUN: grep mov %t | count 1
> +; RUN: grep {leal      -4(} %t | count 1
> +
> +; ISel the add of -4 with a neg and use an lea for the rest of the
> +; arithemtic.
> +
> +define i32 @test(i32 %x_offs) nounwind readnone {
> +entry:
> +       %t0 = icmp sgt i32 %x_offs, 4           ; <i1> [#uses=1]
> +       br i1 %t0, label %bb.nph, label %bb2
> +
> +bb.nph:                ; preds = %entry
> +       %tmp = add i32 %x_offs, -5              ; <i32> [#uses=1]
> +       %tmp6 = lshr i32 %tmp, 2                ; <i32> [#uses=1]
> +       %tmp7 = mul i32 %tmp6, -4               ; <i32> [#uses=1]
> +       %tmp8 = add i32 %tmp7, %x_offs          ; <i32> [#uses=1]
> +       %tmp9 = add i32 %tmp8, -4               ; <i32> [#uses=1]
> +       ret i32 %tmp9
> +
> +bb2:           ; preds = %entry
> +       ret i32 %x_offs
> +}
>
>
> _______________________________________________
> 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