[llvm-commits] [llvm] r144705 - in /llvm/trunk: lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp lib/Target/X86/X86ISelDAGToDAG.cpp lib/Target/X86/X86ISelLowering.cpp test/CodeGen/X86/dec-eflags-lower.ll

Evan Cheng evan.cheng at apple.com
Tue Nov 15 21:42:30 PST 2011


Hi Pete,

Comments below.

On Nov 15, 2011, at 1:57 PM, Pete Cooper wrote:

> Author: pete
> Date: Tue Nov 15 15:57:53 2011
> New Revision: 144705
> 
> URL: http://llvm.org/viewvc/llvm-project?rev=144705&view=rev
> Log:
> Added custom lowering for load->dec->store sequence in x86 when the EFLAGS registers is used
> by later instructions.
> 
> Only done for DEC64m right now.
> 
> Fixes <rdar://problem/6172640>
> 
> Added:
>    llvm/trunk/test/CodeGen/X86/dec-eflags-lower.ll
> Modified:
>    llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp
>    llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp
>    llvm/trunk/lib/Target/X86/X86ISelLowering.cpp
> 
> Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp?rev=144705&r1=144704&r2=144705&view=diff
> ==============================================================================
> --- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp (original)
> +++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp Tue Nov 15 15:57:53 2011
> @@ -948,6 +948,11 @@
>     if (!TII->unfoldMemoryOperand(*DAG, N, NewNodes))
>       return NULL;
> 
> +    // unfolding an x86 DEC64m operation results in store, dec, load which
> +    // can't be handled here so quit
> +    if (NewNodes.size() == 3)
> +      return NULL;

I don't think this is the right way. Can't you detect it's folding both a load and a store before doing a bunch of work?


> +
>     DEBUG(dbgs() << "Unfolding SU #" << SU->NodeNum << "\n");
>     assert(NewNodes.size() == 2 && "Expected a load folding node!");
> 
> 
> Modified: llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp?rev=144705&r1=144704&r2=144705&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp (original)
> +++ llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp Tue Nov 15 15:57:53 2011
> @@ -2216,6 +2216,63 @@
>     }
>     break;
>   }
> +  case ISD::STORE: {

Please add comments to show why we need c++ code to isel this. Preferably with a example of what the isel pattern *should* look like when we get around to adding the tablegen syntax.

Thanks,

Evan

> +    StoreSDNode *StoreNode = cast<StoreSDNode>(Node);
> +    SDValue Chain = StoreNode->getOperand(0);
> +    SDValue StoredVal = StoreNode->getOperand(1);
> +    SDValue Address = StoreNode->getOperand(2);
> +    SDValue Undef = StoreNode->getOperand(3);
> +
> +    if (StoreNode->getMemOperand()->getSize() != 8 ||
> +        Undef->getOpcode() != ISD::UNDEF ||
> +        Chain->getOpcode() != ISD::LOAD ||
> +        StoredVal->getOpcode() != X86ISD::DEC ||
> +        StoredVal.getResNo() != 0 ||
> +        StoredVal->getOperand(0).getNode() != Chain.getNode())
> +      break;
> +
> +    //OPC_CheckPredicate, 1, // Predicate_nontemporalstore
> +    if (StoreNode->isNonTemporal())
> +      break;
> +
> +    LoadSDNode *LoadNode = cast<LoadSDNode>(Chain.getNode());
> +    if (LoadNode->getOperand(1) != Address ||
> +        LoadNode->getOperand(2) != Undef)
> +      break;
> +
> +    if (!ISD::isNormalLoad(LoadNode))
> +      break;
> +
> +    if (!ISD::isNormalStore(StoreNode))
> +      break;
> +
> +    // check load chain has only one use (from the store)
> +    if (!Chain.hasOneUse())
> +      break;
> +
> +    // Merge the input chains if they are not intra-pattern references.
> +    SDValue InputChain = LoadNode->getOperand(0);
> +
> +    SDValue Base, Scale, Index, Disp, Segment;
> +    if (!SelectAddr(LoadNode, LoadNode->getBasePtr(),
> +                    Base, Scale, Index, Disp, Segment))
> +      break;
> +
> +    MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(2);
> +    MemOp[0] = StoreNode->getMemOperand();
> +    MemOp[1] = LoadNode->getMemOperand();
> +    const SDValue Ops[] = { Base, Scale, Index, Disp, Segment, InputChain };
> +    MachineSDNode *Result = CurDAG->getMachineNode(X86::DEC64m,
> +                                                   Node->getDebugLoc(),
> +                                                   MVT::i32, MVT::Other, Ops,
> +                                                   array_lengthof(Ops));
> +    Result->setMemRefs(MemOp, MemOp + 2);
> +
> +    ReplaceUses(SDValue(StoreNode, 0), SDValue(Result, 1));
> +    ReplaceUses(SDValue(StoredVal.getNode(), 1), SDValue(Result, 0));
> +
> +    return Result;
> +  }
>   }
> 
>   SDNode *ResNode = SelectCode(Node);
> 
> Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=144705&r1=144704&r2=144705&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original)
> +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Tue Nov 15 15:57:53 2011
> @@ -8263,8 +8263,10 @@
>     // climbing the DAG back to the root, and it doesn't seem to be worth the
>     // effort.
>     for (SDNode::use_iterator UI = Op.getNode()->use_begin(),
> -           UE = Op.getNode()->use_end(); UI != UE; ++UI)
> -      if (UI->getOpcode() != ISD::CopyToReg && UI->getOpcode() != ISD::SETCC)
> +         UE = Op.getNode()->use_end(); UI != UE; ++UI)
> +      if (UI->getOpcode() != ISD::CopyToReg &&
> +          UI->getOpcode() != ISD::SETCC &&
> +          UI->getOpcode() != ISD::STORE)
>         goto default_case;
> 
>     if (ConstantSDNode *C =
> 
> Added: llvm/trunk/test/CodeGen/X86/dec-eflags-lower.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/dec-eflags-lower.ll?rev=144705&view=auto
> ==============================================================================
> --- llvm/trunk/test/CodeGen/X86/dec-eflags-lower.ll (added)
> +++ llvm/trunk/test/CodeGen/X86/dec-eflags-lower.ll Tue Nov 15 15:57:53 2011
> @@ -0,0 +1,29 @@
> +; RUN: llc < %s -march=x86-64 | FileCheck %s
> +
> +%struct.obj = type { i64 }
> +
> +define void @_Z7releaseP3obj(%struct.obj* nocapture %o) nounwind uwtable ssp {
> +entry:
> +; CHECK: decq	(%rdi)
> +; CHECK-NEXT: je
> +  %refcnt = getelementptr inbounds %struct.obj* %o, i64 0, i32 0
> +  %0 = load i64* %refcnt, align 8, !tbaa !0
> +  %dec = add i64 %0, -1
> +  store i64 %dec, i64* %refcnt, align 8, !tbaa !0
> +  %tobool = icmp eq i64 %dec, 0
> +  br i1 %tobool, label %if.end, label %return
> +
> +if.end:                                           ; preds = %entry
> +  %1 = bitcast %struct.obj* %o to i8*
> +  tail call void @free(i8* %1)
> +  br label %return
> +
> +return:                                           ; preds = %entry, %if.end
> +  ret void
> +}
> +
> +declare void @free(i8* nocapture) nounwind
> +
> +!0 = metadata !{metadata !"long", metadata !1}
> +!1 = metadata !{metadata !"omnipotent char", metadata !2}
> +!2 = metadata !{metadata !"Simple C/C++ TBAA", null}
> 
> 
> _______________________________________________
> 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