Index: src/GenPoly/Lvalue.cc
===================================================================
--- src/GenPoly/Lvalue.cc	(revision c8ad5d9ee9d1ad9027a536667adcb82740622d91)
+++ src/GenPoly/Lvalue.cc	(revision da7fe3906c96450ab7bb9652fd41097ef1096f9e)
@@ -17,4 +17,5 @@
 #include <string>                        // for string
 
+#include "Common/Debug.h"
 #include "Common/PassVisitor.h"
 #include "GenPoly.h"                     // for isPolyType
@@ -128,11 +129,19 @@
 		PassVisitor<AddrRef> addrRef;
 		PassVisitor<FixIntrinsicResult> intrinsicResults;
+		Debug::codeGen( translationUnit, "begin" );
 		mutateAll( translationUnit, intrinsicResults );
+		Debug::codeGen( translationUnit, "intrinsicResults" );
 		mutateAll( translationUnit, addrRef );
+		Debug::codeGen( translationUnit, "addrRef" );
 		mutateAll( translationUnit, refCvt );
+		Debug::codeGen( translationUnit, "refCvt" );
 		mutateAll( translationUnit, fixer );
+		Debug::codeGen( translationUnit, "fixer" );
 		mutateAll( translationUnit, collapser );
+		Debug::codeGen( translationUnit, "collapser" );
 		mutateAll( translationUnit, genLval );
+		Debug::codeGen( translationUnit, "genLval" );
 		mutateAll( translationUnit, elim );  // last because other passes need reference types to work
+		Debug::codeGen( translationUnit, "elim" );
 
 		// from this point forward, no other pass should create reference types.
@@ -211,5 +220,7 @@
 						)
 						// TODO: it's likely that the second condition should be ... && ! isIntrinsicReference( arg ), but this requires investigation.
+
 						if ( function->get_linkage() != LinkageSpec::Intrinsic && isIntrinsicReference( arg ) ) {
+							// needed for definition of prelude functions, etc.
 							// if argument is dereference or array subscript, the result isn't REALLY a reference, but non-intrinsic functions expect a reference: take address
 
@@ -225,4 +236,5 @@
 							)
 							arg = new AddressExpr( arg );
+						// } else if ( function->get_linkage() == LinkageSpec::Intrinsic && InitTweak::getPointerBase( arg->result ) ) {
 						} else if ( function->get_linkage() == LinkageSpec::Intrinsic && arg->result->referenceDepth() != 0 ) {
 							// argument is a 'real' reference, but function expects a C lvalue: add a dereference to the reference-typed argument
@@ -234,7 +246,7 @@
 							PointerType * ptrType = new PointerType( Type::Qualifiers(), baseType->clone() );
 							delete arg->result;
-							arg->set_result( ptrType );
+							arg->result = ptrType;
 							arg = mkDeref( arg );
-							assertf( arg->result->referenceDepth() == 0, "Reference types should have been eliminated from intrinsic function calls, but weren't: %s", toCString( arg->result ) );
+							// assertf( arg->result->referenceDepth() == 0, "Reference types should have been eliminated from intrinsic function calls, but weren't: %s", toCString( arg->result ) );
 						}
 					}
@@ -413,4 +425,5 @@
 				for ( int i = 0; i < diff; ++i ) {
 					ret = mkDeref( ret );
+					// xxx - try removing one reference here? actually, looks like mkDeref already does this, so more closely look at the types generated.
 				}
 				if ( ! ResolvExpr::typesCompatibleIgnoreQualifiers( destType->stripReferences(), srcType->stripReferences(), SymTab::Indexer() ) ) {
Index: src/InitTweak/InitTweak.cc
===================================================================
--- src/InitTweak/InitTweak.cc	(revision c8ad5d9ee9d1ad9027a536667adcb82740622d91)
+++ src/InitTweak/InitTweak.cc	(revision da7fe3906c96450ab7bb9652fd41097ef1096f9e)
@@ -520,4 +520,8 @@
 
 	ApplicationExpr * createBitwiseAssignment( Expression * dst, Expression * src ) {
+		std::cerr << "=== createBitwiseAssignment ===" << std::endl;
+		std::cerr << "== dst: " << dst << std::endl;
+		std::cerr << "== src: " << src << std::endl;
+
 		static FunctionDecl * assign = nullptr;
 		if ( ! assign ) {
@@ -528,11 +532,19 @@
 		}
 		if ( dynamic_cast< ReferenceType * >( dst->result ) ) {
-			dst = new AddressExpr( dst );
+			for (int depth = dst->result->referenceDepth(); depth > 0; depth--) {
+				dst = new AddressExpr( dst );
+			}
 		} else {
 			dst = new CastExpr( dst, new ReferenceType( noQualifiers, dst->result->clone() ) );
 		}
 		if ( dynamic_cast< ReferenceType * >( src->result ) ) {
-			src = new CastExpr( src, new ReferenceType( noQualifiers, src->result->stripReferences()->clone() ) );
-		}
+			for (int depth = src->result->referenceDepth(); depth > 0; depth--) {
+				src = new AddressExpr( src );
+			}
+			// src = new CastExpr( src, new ReferenceType( noQualifiers, src->result->stripReferences()->clone() ) );
+		}
+		std::cerr << "============= endl : " << std::endl;
+		std::cerr << "-- dst: " << dst << std::endl;
+		std::cerr << "-- src: " << src << std::endl;
 		return new ApplicationExpr( VariableExpr::functionPointer( assign ), { dst, src } );
 	}
Index: src/ResolvExpr/CommonType.cc
===================================================================
--- src/ResolvExpr/CommonType.cc	(revision c8ad5d9ee9d1ad9027a536667adcb82740622d91)
+++ src/ResolvExpr/CommonType.cc	(revision da7fe3906c96450ab7bb9652fd41097ef1096f9e)
@@ -101,5 +101,5 @@
 			int diff = depth1-depth2;
 			// TODO: should it be possible for commonType to generate complicated conversions? I would argue no, only conversions that involve types of the same reference level or a difference of 1 should be allowed.
-			if ( diff > 1 || diff < -1 ) return nullptr;
+			// if ( diff > 1 || diff < -1 ) return nullptr;
 
 			// special case where one type has a reference depth of 1 larger than the other
