[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
Wed Nov 16 12:48:56 PST 2011


Thanks. I think you can use getOpcodeAfterMemoryUnfold() to test if the instruction is folding both a load and a store.

Evan

On Nov 16, 2011, at 9:30 AM, Peter Cooper wrote:

> Hi Evan
> 
> Thanks for the comments.  I'll add the changes you requested.
> 
> Pete
> 
> On Nov 15, 2011, at 9:42 PM, Evan Cheng wrote:
> 
>> 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