diff --git a/SMPBasicBlock.cpp b/SMPBasicBlock.cpp
index 6673d378e1a7115f20335a16245026d92d234ca6..1048a26210cbbff531910d90f013e0fce6617656 100644
--- a/SMPBasicBlock.cpp
+++ b/SMPBasicBlock.cpp
@@ -733,7 +733,7 @@ void SMPBasicBlock::SSALocalRenumber(void) {
 // For the newly defined type DefType for DefOp at instruction DefAddr, propagate the
 //  type to all USEs in the local SSA chain for the DEF. If any USE types change,
 // return true.
-bool SMPBasicBlock::PropagateLocalDefType(op_t DefOp, SMPOperandType DefType, ea_t DefAddr) {
+bool SMPBasicBlock::PropagateLocalDefType(op_t DefOp, SMPOperandType DefType, ea_t DefAddr, int SSANum) {
 	bool changed = false;
 	bool DebugFlag = false;
 #if SMP_DEBUG_OPTIMIZATIONS
@@ -758,30 +758,6 @@ bool SMPBasicBlock::PropagateLocalDefType(op_t DefOp, SMPOperandType DefType, ea
 		// DefOp is in the LocalNames, as expected
 		unsigned int RegIndex = ExtractGlobalIndex(*NameIter);
 		list<list<SMPInstr>::iterator>::iterator InstIter;
-		// Find the instruction at DefAddr
-		for (InstIter = this->Instrs.begin(); InstIter != this->Instrs.end(); ++InstIter) {
-			if (DefAddr > (*InstIter)->GetAddr()) {
-				;
-			}
-			else if (DefAddr == (*InstIter)->GetAddr()) {
-				break;
-			}
-			else {
-				msg("ERROR: DefAddr %x not found in PropagateLocalDefType for DefOp: ", DefAddr);
-				PrintOperand(DefOp);
-				msg("\n");
-				return false;
-			}
-		} // end for all instructions
-		set<DefOrUse, LessDefUse>::iterator CurrDef;
-		CurrDef = (*InstIter)->FindDef(DefOp);
-		if (CurrDef == (*InstIter)->GetLastDef()) {
-			msg("ERROR: DEF at %x not found in DEF list by PropagateLocalDefType for DefOp: ", DefAddr);
-			PrintOperand(DefOp);
-			msg("\n");
-			return false;
-		}
-		int SSANum = CurrDef->GetSSANum();
 		assert(0 <= SSANum);
 		assert(SSANum < (int) this->LocalDUChains.ChainsByName.at(RegIndex).DUChains.size());
 		ea_t StartAddr = this->LocalDUChains.ChainsByName.at(RegIndex).DUChains.at(SSANum).GetDef();
@@ -1074,10 +1050,6 @@ bool SMPBasicBlock::InferLocalDefType(op_t DefOp, unsigned int LocIndex, ea_t De
 		// See if we have a consistent type.
 		// If we see any definite POINTER uses, we must set the DEF
 		//  to type POINTER or a refinement of it.
-#if 1
-		if (!FoundNumeric || FoundUninit || FoundPointer || FoundUnknown)
-			return false;
-#endif
 		if (FoundPointer)
 			UseType = PtrType;
 		else if (FoundNumeric && !FoundUninit && !FoundUnknown)
@@ -1091,7 +1063,7 @@ bool SMPBasicBlock::InferLocalDefType(op_t DefOp, unsigned int LocIndex, ea_t De
 		if (FoundPointer && FoundUninit) {
 			// We will propagate PtrType to the UNINIT elements of
 			//  the DEF-USE chain.
-			changed |= this->PropagateLocalDefType(DefOp, PtrType, DefAddr);
+			changed |= this->PropagateLocalDefType(DefOp, PtrType, DefAddr, CurrDef->GetSSANum());
 		}
 	}
 
@@ -1131,29 +1103,28 @@ set<SMPPhiFunction, LessPhi>::iterator SMPBasicBlock::InferPhiDefType(set<SMPPhi
 	changed = false;
 	set<SMPPhiFunction, LessPhi>::iterator UsePhi;
 	set<SMPPhiFunction, LessPhi>::iterator ReturnPhi;
-	SMPOperandType UseType;
-	op_t DefOp = DefPhi->GetAnyOp();
-	int SSANum = DefPhi->GetDefSSANum();
+	SMPOperandType MeetType;
 
 	assert(UNINIT == DefPhi->GetDefType());
 	for (size_t index = 0; index < DefPhi->GetPhiListSize(); ++index) {
-		if (0 == index) {
-			UseType = DefPhi->GetUseType(index);
-			if (UNINIT == UseType)
-				return DefPhi; // not all USEs have type yet
-		}
-		else {
-			if (IsNotEqType(UseType, DefPhi->GetUseType(index)))
-				return DefPhi;  // inconsistent types
-		}
+		if (IsEqType(UNINIT, DefPhi->GetUseType(index)))
+			return DefPhi; // not all USEs have type yet
 	}
-	// Must have seen consistent types if we reach this point.
-	ReturnPhi = this->SetPhiDefType(DefOp, UseType);
+	// Must have seen all non-UNINIT types if we reach this point.
+	MeetType = DefPhi->ConditionalMeetType();
+	if (IsNotEqType(UNKNOWN, MeetType)) {
+		// Don't infer UNKNOWN until conditional type propagation stage.
+		return DefPhi;
+	}
+	op_t DefOp = DefPhi->GetAnyOp();
+	ReturnPhi = this->SetPhiDefType(DefOp, MeetType);
 	changed = true;
 	// Propagate down to USEs of this DEF.
-	if (!MDIsIndirectMemoryOpnd(DefOp, this->MyFunc->UsesFramePointer()))
+	if (!MDIsIndirectMemoryOpnd(DefOp, this->MyFunc->UsesFramePointer())) {
+		int SSANum = DefPhi->GetDefSSANum();
 		this->MyFunc->ResetProcessedBlocks();
-		changed |= this->PropagateGlobalDefType(DefOp, UseType, SSANum);
+		changed |= this->PropagateGlobalDefType(DefOp, MeetType, SSANum);
+	}
 	return ReturnPhi;
 } // end of SMPBasicBlock::InferPhiDefType()
 
diff --git a/SMPBasicBlock.h b/SMPBasicBlock.h
index b711e15c63127cfd0989e4ed8824a1e44ee1ba37..4da02782220c8f47dee826d8a4924435335d2e11 100644
--- a/SMPBasicBlock.h
+++ b/SMPBasicBlock.h
@@ -116,7 +116,7 @@ public:
 #endif
 	bool IsRegDead(ea_t InstAddr, unsigned int RegIndex) const; // Is local reg dead at InstAddr?
 	void MarkDeadRegs(void); // Find dead registers for each mmStrata-instrumented instruction
-	bool PropagateLocalDefType(op_t DefOp, SMPOperandType DefType, ea_t DefAddr); // to all uses
+	bool PropagateLocalDefType(op_t DefOp, SMPOperandType DefType, ea_t DefAddr, int SSANum); // to all uses
 	bool InferLocalDefType(op_t DefOp, unsigned int LocIndex, ea_t DefAddr); // Can DEF type be inferred from all USEs?
 	bool PropagateGlobalDefType(op_t DefOp, SMPOperandType DefType, int SSANum); // to all uses
 	bool InferAllPhiDefTypes(void); // infer, propagate to all uses