[ScheduleDAG] Support REQ_SEQUENCE unscheduling
authorFilipp Zhinkin <filipp.zhinkin@gmail.com>
Tue, 27 Dec 2022 15:08:54 +0000 (19:08 +0400)
committerFilipp Zhinkin <filipp.zhinkin@gmail.com>
Fri, 30 Dec 2022 11:17:11 +0000 (15:17 +0400)
REG_SEQUENCE node requires special treatment during the
unscheduling because the node is untyped and neither its
class, nor cost could be retrieved the same way as for
typed nodes.

Related issue: https://github.com/llvm/llvm-project/issues/58911

Reviewed By: efriedma

Differential Revision: https://reviews.llvm.org/D138837

llvm/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp
llvm/test/CodeGen/ARM/unschedule-reg-sequence.ll [new file with mode: 0644]

index 0be11b6..c573e3d 100644 (file)
@@ -302,6 +302,8 @@ private:
 
 }  // end anonymous namespace
 
+static constexpr unsigned RegSequenceCost = 1;
+
 /// GetCostForDef - Looks up the register class and cost for a given definition.
 /// Typically this just means looking up the representative register class,
 /// but for untyped values (MVT::Untyped) it means inspecting the node's
@@ -333,7 +335,7 @@ static void GetCostForDef(const ScheduleDAGSDNodes::RegDefIter &RegDefPos,
       unsigned DstRCIdx = cast<ConstantSDNode>(Node->getOperand(0))->getZExtValue();
       const TargetRegisterClass *RC = TRI->getRegClass(DstRCIdx);
       RegClass = RC->getID();
-      Cost = 1;
+      Cost = RegSequenceCost;
       return;
     }
 
@@ -2302,6 +2304,16 @@ void RegReductionPQBase::unscheduledNode(SUnit *SU) {
       RegPressure[RCId] += TLI->getRepRegClassCostFor(VT);
       continue;
     }
+    if (POpc == TargetOpcode::REG_SEQUENCE) {
+      unsigned DstRCIdx =
+          cast<ConstantSDNode>(PN->getOperand(0))->getZExtValue();
+      const TargetRegisterClass *RC = TRI->getRegClass(DstRCIdx);
+      unsigned RCId = RC->getID();
+      // REG_SEQUENCE is untyped, so getRepRegClassCostFor could not be used
+      // here. Instead use the same constant as in GetCostForDef.
+      RegPressure[RCId] += RegSequenceCost;
+      continue;
+    }
     unsigned NumDefs = TII->get(PN->getMachineOpcode()).getNumDefs();
     for (unsigned i = 0; i != NumDefs; ++i) {
       MVT VT = PN->getSimpleValueType(i);
diff --git a/llvm/test/CodeGen/ARM/unschedule-reg-sequence.ll b/llvm/test/CodeGen/ARM/unschedule-reg-sequence.ll
new file mode 100644 (file)
index 0000000..37ba34e
--- /dev/null
@@ -0,0 +1,21 @@
+; RUN: llc -verify-machineinstrs < %s
+; Regression test for https://github.com/llvm/llvm-project/issues/58911
+
+target datalayout = "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64"
+target triple = "armv7-none-unknown-eabi"
+
+@a = dso_local global i64 0, align 8
+@d = dso_local local_unnamed_addr global i32 0, align 4
+
+define dso_local void @f() nounwind {
+entry:
+  store volatile i64 0, ptr @a, align 8
+  %0 = load i32, ptr @d, align 4
+  %tobool.not = icmp eq i32 %0, 0
+  %conv = zext i32 %0 to i64
+  %sub = sub nsw i64 0, %conv
+  %cond = select i1 %tobool.not, i64 0, i64 %sub
+  store volatile i64 %cond, ptr @a, align 8
+  ret void
+}
+