aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBill Wendling <isanbard@gmail.com>2010-06-24 22:00:37 +0000
committerBill Wendling <isanbard@gmail.com>2010-06-24 22:00:37 +0000
commit1bd8afcfb510c8b0826bc152ae72b67b4dbbcf1b (patch)
treeb7fb6e919146b382ece88e0cd3a6a3034f439df1
parent3d5b9833b5e2cfc178a3d778f59c49b007e061c6 (diff)
downloadexternal_llvm-1bd8afcfb510c8b0826bc152ae72b67b4dbbcf1b.zip
external_llvm-1bd8afcfb510c8b0826bc152ae72b67b4dbbcf1b.tar.gz
external_llvm-1bd8afcfb510c8b0826bc152ae72b67b4dbbcf1b.tar.bz2
It's possible that a flag is added to the SDNode that points back to the
original SDNode. This is badness. Also, this function allows one SDNode to point multiple flags to another SDNode. Badness as well. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@106793 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp30
-rw-r--r--test/CodeGen/ARM/flag-crash.ll27
2 files changed, 46 insertions, 11 deletions
diff --git a/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp b/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp
index 07277b3..c54f360 100644
--- a/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp
+++ b/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp
@@ -110,18 +110,25 @@ static void CheckForPhysRegDependency(SDNode *Def, SDNode *User, unsigned Op,
static void AddFlags(SDNode *N, SDValue Flag, bool AddFlag,
SelectionDAG *DAG) {
SmallVector<EVT, 4> VTs;
+ SDNode *FlagDestNode = Flag.getNode();
- for (unsigned i = 0, e = N->getNumValues(); i != e; ++i)
- VTs.push_back(N->getValueType(i));
+ // Don't add a flag from a node to itself.
+ if (FlagDestNode == N) return;
+
+ // Don't add a flag to something which already has a flag.
+ if (N->getValueType(N->getNumValues() - 1) == MVT::Flag) return;
+
+ for (unsigned I = 0, E = N->getNumValues(); I != E; ++I)
+ VTs.push_back(N->getValueType(I));
if (AddFlag)
VTs.push_back(MVT::Flag);
SmallVector<SDValue, 4> Ops;
- for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i)
- Ops.push_back(N->getOperand(i));
+ for (unsigned I = 0, E = N->getNumOperands(); I != E; ++I)
+ Ops.push_back(N->getOperand(I));
- if (Flag.getNode())
+ if (FlagDestNode)
Ops.push_back(Flag);
SDVTList VTList = DAG->getVTList(&VTs[0], VTs.size());
@@ -213,16 +220,17 @@ void ScheduleDAGSDNodes::ClusterNeighboringLoads(SDNode *Node) {
// Cluster loads by adding MVT::Flag outputs and inputs. This also
// ensure they are scheduled in order of increasing addresses.
SDNode *Lead = Loads[0];
- AddFlags(Lead, SDValue(0,0), true, DAG);
+ AddFlags(Lead, SDValue(0, 0), true, DAG);
+
+ SDValue InFlag = SDValue(Lead, Lead->getNumValues() - 1);
+ for (unsigned I = 1, E = Loads.size(); I != E; ++I) {
+ bool OutFlag = I < E - 1;
+ SDNode *Load = Loads[I];
- SDValue InFlag = SDValue(Lead, Lead->getNumValues()-1);
- for (unsigned i = 1, e = Loads.size(); i != e; ++i) {
- bool OutFlag = i < e-1;
- SDNode *Load = Loads[i];
AddFlags(Load, InFlag, OutFlag, DAG);
if (OutFlag)
- InFlag = SDValue(Load, Load->getNumValues()-1);
+ InFlag = SDValue(Load, Load->getNumValues() - 1);
++LoadsClustered;
}
diff --git a/test/CodeGen/ARM/flag-crash.ll b/test/CodeGen/ARM/flag-crash.ll
new file mode 100644
index 0000000..9c61944
--- /dev/null
+++ b/test/CodeGen/ARM/flag-crash.ll
@@ -0,0 +1,27 @@
+; RUN: llc < %s -O3 -mtriple=thumbv7-apple-darwin10 -mcpu=cortex-a8 -relocation-model=pic
+; PR7484
+
+%struct.gs_matrix = type { float, i32, float, i32, float, i32, float, i32, float, i32, float, i32 }
+
+define fastcc void @func(%struct.gs_matrix* nocapture %pm1) nounwind {
+entry:
+ %0 = getelementptr inbounds %struct.gs_matrix* %pm1, i32 0, i32 6
+ %1 = load float* %0, align 4
+ %2 = getelementptr inbounds %struct.gs_matrix* %pm1, i32 0, i32 8
+ %3 = load float* %2, align 4
+ %4 = getelementptr inbounds %struct.gs_matrix* %pm1, i32 0, i32 2
+ %5 = bitcast float* %4 to i32*
+ %6 = load i32* %5, align 4
+ %7 = or i32 0, %6
+ %.mask = and i32 %7, 2147483647
+ %8 = icmp eq i32 %.mask, 0
+ br i1 %8, label %bb, label %bb11
+
+bb:
+ ret void
+
+bb11:
+ %9 = fmul float %1, undef
+ %10 = fmul float %3, undef
+ ret void
+}