From 8781645fc2a9ea104265768ed310b1db61291df4 Mon Sep 17 00:00:00 2001
From: Clark Coleman <clc@zephyr-software.com>
Date: Tue, 6 Oct 2020 09:28:00 -0400
Subject: [PATCH] SPAR: Fix boundary case in detecting unstructured
 conditionals.

---
 src/base/SMPFunction.cpp | 18 +++++++++++++-----
 1 file changed, 13 insertions(+), 5 deletions(-)

diff --git a/src/base/SMPFunction.cpp b/src/base/SMPFunction.cpp
index cf8599f5..09c74e9c 100644
--- a/src/base/SMPFunction.cpp
+++ b/src/base/SMPFunction.cpp
@@ -11831,8 +11831,8 @@ int SMPFunction::FindConditionalFollowNode(int HeadBlockNum) {
 	if (0 <= FollowBlockNum) {
 		if (this->FindUnstructuredIfThenElse(HeadBlockNum, FollowBlockNum)) {
 			FollowBlockNum = SMP_BLOCKNUM_UNINIT; // error signal
-			return FollowBlockNum;
 		}
+		return FollowBlockNum;
 	}
 
 #if 0
@@ -12076,6 +12076,12 @@ int SMPFunction::FindConditionalFollowNode(int HeadBlockNum) {
 		}
 	}
 
+	if (0 <= FollowBlockNum) {
+		if (this->FindUnstructuredIfThenElse(HeadBlockNum, FollowBlockNum)) {
+			FollowBlockNum = SMP_BLOCKNUM_UNINIT; // error signal
+		}
+	}
+
 	return FollowBlockNum;
 } // end of SMPFunction::FindConditionalFollowNode()
 
@@ -12234,6 +12240,7 @@ bool SMPFunction::FindUnstructuredIfThenElse(const int HeadBlockNum, const int F
 	// Follow no back edges, start at ThenBlock, stop at FollowBlockNum, record blocks seen.
 	list<int> WorkList;
 	int ThenBlockNum = ThenBlock->GetNumber();
+	ThenBlocksSeen.SetBit((size_t)ThenBlockNum);
 	WorkList.push_back(ThenBlockNum);
 	while (!WorkList.empty()) { // RPO ordering, no back edges, ensures termination
 		int CurrBlockNum = WorkList.front();
@@ -12253,6 +12260,7 @@ bool SMPFunction::FindUnstructuredIfThenElse(const int HeadBlockNum, const int F
 	} // end while WorkList is not empty
 
 	WorkList.push_back(ElseBlockNum);
+	ElseBlocksSeen.SetBit((size_t)ElseBlockNum);
 	while (!WorkList.empty()) { // RPO ordering, no back edges, ensures termination
 		int CurrBlockNum = WorkList.front();
 		WorkList.pop_front();
@@ -23003,8 +23011,10 @@ void SMPFunction::EmitSPARKAdaForConditional(int HeaderBlockNum, int FollowBlock
 			int LoopNum = this->GetLoopNumFromHeaderBlockNum(CurrBlockNum);
 			assert(0 <= LoopNum);
 			this->EmitSPARKAdaLoopCall(LoopAddr, (size_t) LoopNum, SPARKBodyFile);
-			// Put the if-then header and follow block numbers onto the work list
-			pair<int, int> BlockItem(CurrBlockNum, FollowBlockNum);
+			// Put the loop header and loop follow block numbers onto the work list
+			int LoopFollowBlockNum = this->LoopFollowNodes[(size_t)LoopNum];
+			assert(0 < LoopFollowBlockNum);
+			pair<int, int> BlockItem(CurrBlockNum, LoopFollowBlockNum);
 			pair<int, pair<int, int> > WorkListItem(LoopNum, BlockItem);
 			this->SPARKLoopWorkList.push_back(WorkListItem);
 			this->CleanUpSPARKLoopWorkList();
@@ -23014,8 +23024,6 @@ void SMPFunction::EmitSPARKAdaForConditional(int HeaderBlockNum, int FollowBlock
 			//  contained within the conditional. We need to NOT recurse into the loop follow block
 			//  in the case where the conditional is entirely contained within a loop; in that case,
 			//  wait until we return to EmitSPARKAdaForLoop() to go into the loop follow node.
-			int LoopFollowBlockNum = this->LoopFollowNodes[LoopNum];
-			assert(0 < LoopFollowBlockNum);
 			SMPBasicBlock *LoopFollowBlock = this->GetBlockByNum((size_t) LoopFollowBlockNum);
 			if (!LoopFollowBlock->IsProcessed() && this->DoesBlockDominateBlock(HeaderBlockNum, LoopFollowBlockNum)) {
 				this->EmitSPARKAdaForBlock(LoopFollowBlockNum, FollowBlockNum, SPARKBodyFile, false, false);
-- 
GitLab