[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
Peter Cooper
peter_cooper at apple.com
Wed Nov 16 09:30:44 PST 2011
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