llvm.org GIT mirror llvm / dd0fb01
Track IR ordering of SelectionDAG nodes 3/4. Remove the old IR ordering mechanism and switch to new one. Fix unit test failures. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@182704 91177308-0d34-0410-b5e6-96231b3b80d8 Andrew Trick 6 years ago
17 changed file(s) with 31 addition(s) and 190 deletion(s). Raw diff Collapse all Expand all
3232 class MachineConstantPoolValue;
3333 class MachineFunction;
3434 class MDNode;
35 class SDNodeOrdering;
3635 class SDDbgValue;
3736 class TargetLowering;
3837 class TargetSelectionDAGInfo;
164163 /// Allocator - Pool allocation for misc. objects that are created once per
165164 /// SelectionDAG.
166165 BumpPtrAllocator Allocator;
167
168 /// SDNodeOrdering - The ordering of the SDNodes. It roughly corresponds to
169 /// the ordering of the original LLVM instructions.
170 SDNodeOrdering *Ordering;
171166
172167 /// DbgInfo - Tracks dbg_value information through SDISel.
173168 SDDbgInfo *DbgInfo;
949944 }
950945 }
951946
952 /// AssignOrdering - Assign an order to the SDNode.
953 void AssignOrdering(const SDNode *SD, unsigned Order);
954
955 /// GetOrdering - Get the order for the SDNode.
956 unsigned GetOrdering(const SDNode *SD) const;
957
958947 /// AddDbgValue - Add a dbg_value SDNode. If SD is non-null that means the
959948 /// value is produced by SD.
960949 void AddDbgValue(SDDbgValue *DB, SDNode *SD, bool isParameter);
734734 SDValue &OpEntry = PromotedIntegers[Op];
735735 assert(OpEntry.getNode() == 0 && "Node is already promoted!");
736736 OpEntry = Result;
737
738 // Propagate node ordering
739 DAG.AssignOrdering(Result.getNode(), DAG.GetOrdering(Op.getNode()));
740737 }
741738
742739 void DAGTypeLegalizer::SetSoftenedFloat(SDValue Op, SDValue Result) {
748745 SDValue &OpEntry = SoftenedFloats[Op];
749746 assert(OpEntry.getNode() == 0 && "Node is already converted to integer!");
750747 OpEntry = Result;
751
752 // Propagate node ordering
753 DAG.AssignOrdering(Result.getNode(), DAG.GetOrdering(Op.getNode()));
754748 }
755749
756750 void DAGTypeLegalizer::SetScalarizedVector(SDValue Op, SDValue Result) {
765759 SDValue &OpEntry = ScalarizedVectors[Op];
766760 assert(OpEntry.getNode() == 0 && "Node is already scalarized!");
767761 OpEntry = Result;
768
769 // Propagate node ordering
770 DAG.AssignOrdering(Result.getNode(), DAG.GetOrdering(Op.getNode()));
771762 }
772763
773764 void DAGTypeLegalizer::GetExpandedInteger(SDValue Op, SDValue &Lo,
795786 assert(Entry.first.getNode() == 0 && "Node already expanded");
796787 Entry.first = Lo;
797788 Entry.second = Hi;
798
799 // Propagate ordering
800 DAG.AssignOrdering(Lo.getNode(), DAG.GetOrdering(Op.getNode()));
801 DAG.AssignOrdering(Hi.getNode(), DAG.GetOrdering(Op.getNode()));
802789 }
803790
804791 void DAGTypeLegalizer::GetExpandedFloat(SDValue Op, SDValue &Lo,
826813 assert(Entry.first.getNode() == 0 && "Node already expanded");
827814 Entry.first = Lo;
828815 Entry.second = Hi;
829
830 // Propagate ordering
831 DAG.AssignOrdering(Lo.getNode(), DAG.GetOrdering(Op.getNode()));
832 DAG.AssignOrdering(Hi.getNode(), DAG.GetOrdering(Op.getNode()));
833816 }
834817
835818 void DAGTypeLegalizer::GetSplitVector(SDValue Op, SDValue &Lo,
859842 assert(Entry.first.getNode() == 0 && "Node already split");
860843 Entry.first = Lo;
861844 Entry.second = Hi;
862
863 // Propagate ordering
864 DAG.AssignOrdering(Lo.getNode(), DAG.GetOrdering(Op.getNode()));
865 DAG.AssignOrdering(Hi.getNode(), DAG.GetOrdering(Op.getNode()));
866845 }
867846
868847 void DAGTypeLegalizer::SetWidenedVector(SDValue Op, SDValue Result) {
874853 SDValue &OpEntry = WidenedVectors[Op];
875854 assert(OpEntry.getNode() == 0 && "Node already widened!");
876855 OpEntry = Result;
877
878 // Propagate node ordering
879 DAG.AssignOrdering(Result.getNode(), DAG.GetOrdering(Op.getNode()));
880856 }
881857
882858
944920 "Custom lowering returned the wrong number of results!");
945921 for (unsigned i = 0, e = Results.size(); i != e; ++i) {
946922 ReplaceValueWith(SDValue(N, i), Results[i]);
947 // Propagate node ordering
948 DAG.AssignOrdering(Results[i].getNode(), DAG.GetOrdering(N));
949923 }
950924 return true;
951925 }
+0
-56
lib/CodeGen/SelectionDAG/SDNodeOrdering.h less more
None //===-- llvm/CodeGen/SDNodeOrdering.h - SDNode Ordering ---------*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file declares the SDNodeOrdering class.
10 //
11 //===----------------------------------------------------------------------===//
12
13 #ifndef LLVM_CODEGEN_SDNODEORDERING_H
14 #define LLVM_CODEGEN_SDNODEORDERING_H
15
16 #include "llvm/ADT/DenseMap.h"
17
18 namespace llvm {
19
20 class SDNode;
21
22 /// SDNodeOrdering - Maps a unique (monotonically increasing) value to each
23 /// SDNode that roughly corresponds to the ordering of the original LLVM
24 /// instruction. This is used for turning off scheduling, because we'll forgo
25 /// the normal scheduling algorithms and output the instructions according to
26 /// this ordering.
27 class SDNodeOrdering {
28 DenseMap OrderMap;
29
30 void operator=(const SDNodeOrdering&) LLVM_DELETED_FUNCTION;
31 SDNodeOrdering(const SDNodeOrdering&) LLVM_DELETED_FUNCTION;
32 public:
33 SDNodeOrdering() {}
34
35 void add(const SDNode *Node, unsigned NewOrder) {
36 unsigned &OldOrder = OrderMap[Node];
37 if (OldOrder == 0 || (OldOrder > 0 && NewOrder < OldOrder))
38 OldOrder = NewOrder;
39 }
40 void remove(const SDNode *Node) {
41 DenseMap::iterator Itr = OrderMap.find(Node);
42 if (Itr != OrderMap.end())
43 OrderMap.erase(Itr);
44 }
45 void clear() {
46 OrderMap.clear();
47 }
48 unsigned getOrder(const SDNode *Node) {
49 return OrderMap[Node];
50 }
51 };
52
53 } // end llvm namespace
54
55 #endif
16911691 unsigned getNodeOrdering(const SUnit *SU) const {
16921692 if (!SU->getNode()) return 0;
16931693
1694 return scheduleDAG->DAG->GetOrdering(SU->getNode());
1694 return SU->getNode()->getIROrder();
16951695 }
16961696
16971697 bool empty() const { return Queue.empty(); }
735735 DenseMap &VRBaseMap,
736736 SmallVector, 32> &Orders,
737737 SmallSet &Seen) {
738 unsigned Order = DAG->GetOrdering(N);
738 unsigned Order = N->getIROrder();
739739 if (!Order || !Seen.insert(Order)) {
740740 // Process any valid SDDbgValues even if node does not have any order
741741 // assigned.
1212
1313 #include "llvm/CodeGen/SelectionDAG.h"
1414 #include "SDNodeDbgValue.h"
15 #include "SDNodeOrdering.h"
1615 #include "llvm/ADT/SetVector.h"
1716 #include "llvm/ADT/SmallPtrSet.h"
1817 #include "llvm/ADT/SmallSet.h"
635634
636635 NodeAllocator.Deallocate(AllNodes.remove(N));
637636
638 // Remove the ordering of this node.
639 Ordering->remove(N);
640
641637 // If any of the SDDbgValue nodes refer to this SDNode, invalidate them.
642638 ArrayRef DbgVals = DbgInfo->getSDDbgValues(N);
643639 for (unsigned i = 0, e = DbgVals.size(); i != e; ++i)
875871 : TM(tm), TLI(*tm.getTargetLowering()), TSI(*tm.getSelectionDAGInfo()),
876872 TTI(0), OptLevel(OL), EntryNode(ISD::EntryToken, 0, DebugLoc(),
877873 getVTList(MVT::Other)),
878 Root(getEntryNode()), Ordering(0), UpdateListeners(0) {
874 Root(getEntryNode()), UpdateListeners(0) {
879875 AllNodes.push_back(&EntryNode);
880 Ordering = new SDNodeOrdering();
881876 DbgInfo = new SDDbgInfo();
882877 }
883878
890885 SelectionDAG::~SelectionDAG() {
891886 assert(!UpdateListeners && "Dangling registered DAGUpdateListeners");
892887 allnodes_clear();
893 delete Ordering;
894888 delete DbgInfo;
895889 }
896890
917911 EntryNode.UseList = 0;
918912 AllNodes.push_back(&EntryNode);
919913 Root = getEntryNode();
920 Ordering->clear();
921914 DbgInfo->clear();
922915 }
923916
34693462
34703463 /// getMemBasePlusOffset - Returns base and offset node for the
34713464 ///
3472 static SDValue getMemBasePlusOffset(SDValue Base, unsigned Offset,
3465 static SDValue getMemBasePlusOffset(SDValue Base, unsigned Offset, SDLoc dl,
34733466 SelectionDAG &DAG) {
34743467 EVT VT = Base.getValueType();
3475 return DAG.getNode(ISD::ADD, SDLoc(Base),
3468 return DAG.getNode(ISD::ADD, dl,
34763469 VT, Base, DAG.getConstant(Offset, VT));
34773470 }
34783471
36863679 Value = getMemsetStringVal(VT, dl, DAG, TLI, Str.substr(SrcOff));
36873680 if (Value.getNode())
36883681 Store = DAG.getStore(Chain, dl, Value,
3689 getMemBasePlusOffset(Dst, DstOff, DAG),
3682 getMemBasePlusOffset(Dst, DstOff, dl, DAG),
36903683 DstPtrInfo.getWithOffset(DstOff), isVol,
36913684 false, Align);
36923685 }
37003693 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
37013694 assert(NVT.bitsGE(VT));
37023695 Value = DAG.getExtLoad(ISD::EXTLOAD, dl, NVT, Chain,
3703 getMemBasePlusOffset(Src, SrcOff, DAG),
3696 getMemBasePlusOffset(Src, SrcOff, dl, DAG),
37043697 SrcPtrInfo.getWithOffset(SrcOff), VT, isVol, false,
37053698 MinAlign(SrcAlign, SrcOff));
37063699 Store = DAG.getTruncStore(Chain, dl, Value,
3707 getMemBasePlusOffset(Dst, DstOff, DAG),
3700 getMemBasePlusOffset(Dst, DstOff, dl, DAG),
37083701 DstPtrInfo.getWithOffset(DstOff), VT, isVol,
37093702 false, Align);
37103703 }
37733766 SDValue Value, Store;
37743767
37753768 Value = DAG.getLoad(VT, dl, Chain,
3776 getMemBasePlusOffset(Src, SrcOff, DAG),
3769 getMemBasePlusOffset(Src, SrcOff, dl, DAG),
37773770 SrcPtrInfo.getWithOffset(SrcOff), isVol,
37783771 false, false, SrcAlign);
37793772 LoadValues.push_back(Value);
37893782 SDValue Value, Store;
37903783
37913784 Store = DAG.getStore(Chain, dl, LoadValues[i],
3792 getMemBasePlusOffset(Dst, DstOff, DAG),
3785 getMemBasePlusOffset(Dst, DstOff, dl, DAG),
37933786 DstPtrInfo.getWithOffset(DstOff), isVol, false, Align);
37943787 OutChains.push_back(Store);
37953788 DstOff += VTSize;
38713864 }
38723865 assert(Value.getValueType() == VT && "Value with wrong type.");
38733866 SDValue Store = DAG.getStore(Chain, dl, Value,
3874 getMemBasePlusOffset(Dst, DstOff, DAG),
3867 getMemBasePlusOffset(Dst, DstOff, dl, DAG),
38753868 DstPtrInfo.getWithOffset(DstOff),
38763869 isVol, false, Align);
38773870 OutChains.push_back(Store);
58645857 return DAGSize;
58655858 }
58665859
5867 /// AssignOrdering - Assign an order to the SDNode.
5868 void SelectionDAG::AssignOrdering(const SDNode *SD, unsigned Order) {
5869 assert(SD && "Trying to assign an order to a null node!");
5870 Ordering->add(SD, Order);
5871 }
5872
5873 /// GetOrdering - Get the order for the SDNode.
5874 unsigned SelectionDAG::GetOrdering(const SDNode *SD) const {
5875 assert(SD && "Trying to get the order of a null node!");
5876 return Ordering->getOrder(SD);
5877 }
5878
58795860 /// AddDbgValue - Add a dbg_value SDNode. If SD is non-null that means the
58805861 /// value is produced by SD.
58815862 void SelectionDAG::AddDbgValue(SDDbgValue *DB, SDNode *SD, bool isParameter) {
937937 return Root;
938938 }
939939
940 void SelectionDAGBuilder::AssignOrderingToNode(const SDNode *Node) {
941 if (DAG.GetOrdering(Node) != 0) return; // Already has ordering.
942 DAG.AssignOrdering(Node, SDNodeOrder);
943
944 for (unsigned I = 0, E = Node->getNumOperands(); I != E; ++I)
945 AssignOrderingToNode(Node->getOperand(I).getNode());
946 }
947
948940 void SelectionDAGBuilder::visit(const Instruction &I) {
949941 // Set up outgoing PHI node register values before emitting the terminator.
950942 if (isa(&I))
951943 HandlePHINodesInSuccessorBlocks(I.getParent());
944
945 ++SDNodeOrder;
952946
953947 CurInst = &I;
954948
973967 #define HANDLE_INST(NUM, OPCODE, CLASS) \
974968 case Instruction::OPCODE: visit##OPCODE((const CLASS&)I); break;
975969 #include "llvm/IR/Instruction.def"
976 }
977
978 // Assign the ordering to the freshly created DAG nodes.
979 if (NodeMap.count(&I)) {
980 ++SDNodeOrder;
981 AssignOrderingToNode(getValue(&I).getNode());
982970 }
983971 }
984972
33963384
33973385 SDValue StoreNode = DAG.getNode(ISD::TokenFactor, getCurSDLoc(),
33983386 MVT::Other, &Chains[0], ChainI);
3399 ++SDNodeOrder;
3400 AssignOrderingToNode(StoreNode.getNode());
34013387 DAG.setRoot(StoreNode);
34023388 }
34033389
36513637 }
36523638
36533639 setValue(&I, Result);
3654 } else {
3655 // Assign order to result here. If the intrinsic does not produce a result,
3656 // it won't be mapped to a SDNode and visit() will not assign it an order
3657 // number.
3658 ++SDNodeOrder;
3659 AssignOrderingToNode(Result.getNode());
36603640 }
36613641 }
36623642
45244504 return 0;
45254505 }
45264506
4527 // Build an entry in DbgOrdering. Debug info input nodes get an SDNodeOrder
4528 // but do not always have a corresponding SDNode built. The SDNodeOrder
4529 // absolute, but not relative, values are different depending on whether
4530 // debug info exists.
4531 ++SDNodeOrder;
4532
45334507 // Check if address has undef value.
45344508 if (isa(Address) ||
45354509 (Address->use_empty() && !isa(Address))) {
46094583 if (!V)
46104584 return 0;
46114585
4612 // Build an entry in DbgOrdering. Debug info input nodes get an SDNodeOrder
4613 // but do not always have a corresponding SDNode built. The SDNodeOrder
4614 // absolute, but not relative, values are different depending on whether
4615 // debug info exists.
4616 ++SDNodeOrder;
46174586 SDDbgValue *SDV;
46184587 if (isa(V) || isa(V) || isa(V)) {
46194588 SDV = DAG.getDbgValue(Variable, V, Offset, dl, SDNodeOrder);
53465315 &Values[0], Values.size()));
53475316 }
53485317
5349 // Assign order to nodes here. If the call does not produce a result, it won't
5350 // be mapped to a SDNode and visit() will not assign it an order number.
53515318 if (!Result.second.getNode()) {
53525319 // As a special case, a null chain means that a tail call has been emitted and
53535320 // the DAG root is already updated.
53545321 HasTailCall = true;
5355 ++SDNodeOrder;
5356 AssignOrderingToNode(DAG.getRoot().getNode());
53575322 } else {
53585323 DAG.setRoot(Result.second);
5359 ++SDNodeOrder;
5360 AssignOrderingToNode(Result.second.getNode());
53615324 }
53625325
53635326 if (LandingPad) {
376376
377377 void CopyValueToVirtualRegister(const Value *V, unsigned Reg);
378378
379 /// AssignOrderingToNode - Assign an ordering to the node. The order is gotten
380 /// from how the code appeared in the source. The ordering is used by the
381 /// scheduler to effectively turn off scheduling.
382 void AssignOrderingToNode(const SDNode *Node);
383
384379 void visit(const Instruction &I);
385380
386381 void visit(unsigned Opcode, const User &I);
623623
624624 DEBUG(dbgs() << "Optimized type-legalized selection DAG: BB#" << BlockNumber
625625 << " '" << BlockName << "'\n"; CurDAG->dump());
626
626627 }
627628
628629 {
789790 continue;
790791 // Replace node.
791792 if (ResNode) {
792 // Propagate ordering
793 CurDAG->AssignOrdering(ResNode, CurDAG->GetOrdering(Node));
794
795793 ReplaceUses(Node, ResNode);
796794 }
797795
11441144 false,
11451145 TD->getABITypeAlignment(ObjectVT.getTypeForEVT(F->getContext())));
11461146 if (p.getNode())
1147 DAG.AssignOrdering(p.getNode(), idx + 1);
1147 p.getNode()->setIROrder(idx + 1);
11481148 InVals.push_back(p);
11491149 } else {
11501150 // If no ABI, just move the param symbol
11511151 SDValue Arg = getParamSymbol(DAG, idx, ObjectVT);
11521152 SDValue p = DAG.getNode(NVPTXISD::MoveParam, dl, ObjectVT, Arg);
11531153 if (p.getNode())
1154 DAG.AssignOrdering(p.getNode(), idx + 1);
1154 p.getNode()->setIROrder(idx + 1);
11551155 InVals.push_back(p);
11561156 }
11571157 continue;
11681168 SDValue Arg = getParamSymbol(DAG, idx, getPointerTy());
11691169 SDValue p = DAG.getNode(NVPTXISD::MoveParam, dl, ObjectVT, Arg);
11701170 if (p.getNode())
1171 DAG.AssignOrdering(p.getNode(), idx + 1);
1171 p.getNode()->setIROrder(idx + 1);
11721172 if (isKernel)
11731173 InVals.push_back(p);
11741174 else {
23342334 DEBUG(dbgs() << "=> "; ResHi.getNode()->dump(CurDAG); dbgs() << '\n');
23352335 }
23362336
2337 // Propagate ordering to the last node, for now.
2338 CurDAG->AssignOrdering(InFlag.getNode(), CurDAG->GetOrdering(Node));
2339
23402337 return NULL;
23412338 }
23422339
22 define float @test_sincos_f32(float %f) {
33 %sin = call float @sinf(float %f) readnone
44 %cos = call float @cosf(float %f) readnone
5 ; CHECK: bl sinf
56 ; CHECK: bl cosf
6 ; CHECK: bl sinf
77 %val = fadd float %sin, %cos
88 ret float %val
99 }
1212 %sin = call double @sin(double %f) readnone
1313 %cos = call double @cos(double %f) readnone
1414 %val = fadd double %sin, %cos
15 ; CHECK: bl sin
1516 ; CHECK: bl cos
16 ; CHECK: bl sin
1717 ret double %val
1818 }
1919
2121 %sin = call fp128 @sinl(fp128 %f) readnone
2222 %cos = call fp128 @cosl(fp128 %f) readnone
2323 %val = fadd fp128 %sin, %cos
24 ; CHECK: bl sinl
2425 ; CHECK: bl cosl
25 ; CHECK: bl sinl
2626 ret fp128 %val
2727 }
2828
4141 ; If-convert the return
4242 ; CHECK: it ne
4343 ; Fold the CSR+return into a pop
44 ; CHECK: popne {r4, r5, r7, pc}
44 ; CHECK: pop {r4, r5, r6, r7, pc}
4545 sw.bb18:
4646 %call20 = tail call i32 @bar(i32 %in2) nounwind
4747 switch i32 %call20, label %sw.default56 [
1414 ; THUMB-ELF: LoadGV
1515 ; THUMB-ELF: ldr.n r[[reg0:[0-9]+]],
1616 ; THUMB-ELF: ldr.n r[[reg1:[0-9]+]],
17 ; THUMB-ELF: ldr r[[reg0]], [r[[reg1]], r[[reg0]]]
17 ; THUMB-ELF: ldr r[[reg0]], [r[[reg0]], r[[reg1]]]
1818 ; ARM: LoadGV
1919 ; ARM: ldr [[reg1:r[0-9]+]],
2020 ; ARM: add [[reg1]], pc, [[reg1]]
2525 ; ARMv7-ELF: LoadGV
2626 ; ARMv7-ELF: ldr r[[reg2:[0-9]+]],
2727 ; ARMv7-ELF: ldr r[[reg3:[0-9]+]],
28 ; ARMv7-ELF: ldr r[[reg2]], [r[[reg3]], r[[reg2]]]
28 ; ARMv7-ELF: ldr r[[reg2]], [r[[reg2]], r[[reg3]]]
2929 %tmp = load i32* @g
3030 ret i32 %tmp
3131 }
4242 ; THUMB-ELF: LoadIndirectSymbol
4343 ; THUMB-ELF: ldr.n r[[reg3:[0-9]+]],
4444 ; THUMB-ELF: ldr.n r[[reg4:[0-9]+]],
45 ; THUMB-ELF: ldr r[[reg3]], [r[[reg4]], r[[reg3]]]
45 ; THUMB-ELF: ldr r[[reg3]], [r[[reg3]], r[[reg4]]]
4646 ; ARM: LoadIndirectSymbol
4747 ; ARM: ldr [[reg4:r[0-9]+]],
4848 ; ARM: ldr [[reg4]], [pc, [[reg4]]]
5454 ; ARMv7-ELF: LoadIndirectSymbol
5555 ; ARMv7-ELF: ldr r[[reg5:[0-9]+]],
5656 ; ARMv7-ELF: ldr r[[reg6:[0-9]+]],
57 ; ARMv7-ELF: ldr r[[reg5]], [r[[reg6]], r[[reg5]]]
57 ; ARMv7-ELF: ldr r[[reg5]], [r[[reg5]], r[[reg6]]]
5858 %tmp = load i32* @i
5959 ret i32 %tmp
6060 }
1818 ; OSX_SINCOS: addss %xmm0, %xmm1
1919
2020 ; OSX_NOOPT: test1
21 ; OSX_NOOPT: callq _sinf
2122 ; OSX_NOOPT: callq _cosf
22 ; OSX_NOOPT: callq _sinf
2323 %call = tail call float @sinf(float %x) nounwind readnone
2424 %call1 = tail call float @cosf(float %x) nounwind readnone
2525 %add = fadd float %call, %call1
3838 ; OSX_SINCOS: addsd %xmm1, %xmm0
3939
4040 ; OSX_NOOPT: test2
41 ; OSX_NOOPT: callq _sin
4142 ; OSX_NOOPT: callq _cos
42 ; OSX_NOOPT: callq _sin
4343 %call = tail call double @sin(double %x) nounwind readnone
4444 %call1 = tail call double @cos(double %x) nounwind readnone
4545 %add = fadd double %call, %call1
114114
115115 ; Load the address of the result and put it onto stack
116116 ; (through %ecx in the -O0 build).
117 ; WIN32: leal {{[0-9]+}}(%esp), %eax
118 ; WIN32: movl %eax, (%e{{[sc][px]}})
117 ; WIN32: leal {{[0-9]+}}(%esp), %e{{[a-d]}}x
118 ; WIN32: movl %e{{[a-d]}}x, (%e{{([a-d]x)|(sp)}})
119119
120120 ; The this pointer goes to ECX.
121121 ; WIN32-NEXT: leal {{[0-9]+}}(%esp), %ecx
1010
1111 ; Check that LSR did something close to the behavior at the time of the bug.
1212 ; CHECK: @sqlite3DropTriggerPtr
13 ; CHECK: incq %rax
13 ; CHECK: incq %r{{[a-d]}}x
1414 ; CHECK: jne
15 ; CHECK: decq %rax
15 ; CHECK: decq %r{{[a-d]}}x
1616 ; CHECK: ret
1717 define i64 @sqlite3DropTriggerPtr() nounwind {
1818 bb: