From 3608a322eaebda378376d547e88adab4845ea158 Mon Sep 17 00:00:00 2001
From: clc5q <clc5q@git.zephyr-software.com>
Date: Tue, 11 Jun 2013 02:04:47 +0000
Subject: [PATCH] Extend recognition of sbb eax,eax ... add eax,small to allow
 intervening AND and OR opcodes.

---
 SMPBasicBlock.cpp | 18 +++++++++++++-----
 SMPInstr.h        |  2 ++
 2 files changed, 15 insertions(+), 5 deletions(-)

diff --git a/SMPBasicBlock.cpp b/SMPBasicBlock.cpp
index 582b9b94..be7bb059 100644
--- a/SMPBasicBlock.cpp
+++ b/SMPBasicBlock.cpp
@@ -4138,7 +4138,8 @@ bool SMPBasicBlock::IsStackOpNextUsedWithSignedness(op_t StackDefOp, ea_t DefAdd
 // Find inc/add that makes small negative back into positive. e.g.:
 //  sbb edx,edx  ; unsigned edx becomes 0 or -1; SMPInstr is suppressing underflow false positive.
 //  add edx,1    ; converts 0 or -1 to 1 or 0 (looks like unsigned overflow); catch this here.
-//  We also catch the case in which a "not edx" instruction is interposed between the sbb and the add.
+//  We also catch the case in which a "not edx" or "and edx,..." or "or edx,..." instruction 
+//  is interposed between the sbb and the add.
 void SMPBasicBlock::SuppressAnnotOnSignChangingAddition(op_t DefOp, int DefSSANum, size_t DefAddr) {
 	list<SMPInstr *>::iterator DefInstIter = this->GetInstIterFromAddr(DefAddr);
 	op_t SearchOp = DefOp;
@@ -4164,16 +4165,23 @@ void SMPBasicBlock::SuppressAnnotOnSignChangingAddition(op_t DefOp, int DefSSANu
 				}
 			}
 		}
-		else if (CurrInst->MDIsBitwiseNotOpcode()) {
+		else if (CurrInst->MDIsBitwiseNotOpcode() || CurrInst->MDIsBitwiseAndOpcode() || CurrInst->MDIsBitwiseOrOpcode()) {
 			UseIter = CurrInst->FindUse(SearchOp);
 			if (UseIter != CurrInst->GetLastUse()) {
-				// Bitwise not is performed on SearchOp.
+				// Bitwise operation is performed on SearchOp.
 				if (SearchSSANum == UseIter->GetSSANum()) {
 					// Reset the SearchSSANum that we expect to see in the small addition.
 					DefIter = CurrInst->GetFirstNonFlagsDef();
 					op_t NewDefOp = DefIter->GetOp();
-					assert(IsEqOp(DefOp, NewDefOp));
-					SearchSSANum = DefIter->GetSSANum();
+					if (IsEqOp(DefOp, NewDefOp)) {
+						SearchSSANum = DefIter->GetSSANum();
+					}
+					else {
+						// Must have an instruction such as "or dontcarereg,ourreg" which
+						//  does not re-DEF ourreg and thus the chain is no longer the pattern
+						//  we are looking for.
+						break;
+					}
 				}
 				else {
 					// We must have moved on past the original def-use chain.
diff --git a/SMPInstr.h b/SMPInstr.h
index 0463ef23..71a4782c 100644
--- a/SMPInstr.h
+++ b/SMPInstr.h
@@ -448,6 +448,8 @@ public:
 	bool MDIsCompareToPositiveConstant(op_t &NonConstOperand, uval_t &ConstValue) const;
 	bool MDIsSubtractionOfConstant(op_t &NonConstOperand, uval_t &ConstValue) const;
 	inline bool MDIsBitwiseNotOpcode(void) const { return (NN_not == SMPcmd.itype); };
+	inline bool MDIsBitwiseAndOpcode(void) const { return (NN_and == SMPcmd.itype); };
+	inline bool MDIsBitwiseOrOpcode(void) const { return (NN_or == SMPcmd.itype); };
 	inline bool MDIsSignBitFill(void) const { return ((NN_sar == SMPcmd.itype) && ((MD_NORMAL_MACHINE_BITWIDTH - 1) == MDGetShiftCount())); };
 	inline bool MDDoublesWidth(void) const { 
 		return ((NN_cbw == SMPcmd.itype) || (NN_cwde == SMPcmd.itype) || (NN_cdqe == SMPcmd.itype));
-- 
GitLab