Index: src/GenPoly/Lvalue.cpp
===================================================================
--- src/GenPoly/Lvalue.cpp	(revision ecf38123a0e4f99e0d73b57ef72d89c766288f78)
+++ src/GenPoly/Lvalue.cpp	(revision bdf4065045c0651b196411ff05d1d2c353dbfa1d)
@@ -365,8 +365,8 @@
 			ret = new ast::AddressExpr( ret->location, ret );
 		}
+		// Must keep cast if types are different.
 		if ( !ResolvExpr::typesCompatible(
 				srcType,
 				strict_dynamic_cast<ast::ReferenceType const *>( dstType )->base ) ) {
-			// Must keep cast if cast-to type is different from the actual type.
 			return ast::mutate_field( expr, &ast::CastExpr::arg, ret );
 		}
@@ -503,4 +503,20 @@
 }
 
+/// Recursively move an address expression underneath casts. Casts are not
+/// lvalue expressions in C but are sometimes considered as such in Cforall,
+/// (passes like InstantiateGeneric can add them.) - &(int) => (int*)&
+ast::Expr const * moveAddressUnderCast( ast::AddressExpr const * expr ) {
+	if ( !dynamic_cast<ast::CastExpr const *>( expr->arg.get() ) ) {
+		return expr;
+	}
+	auto mutExpr = ast::mutate( expr );
+	auto mutCast = strict_dynamic_cast<ast::CastExpr *>(
+			ast::mutate( mutExpr->arg.release() ) );
+	mutExpr->arg = mutCast->arg;
+	mutCast->arg = moveAddressUnderCast( mutExpr );
+	mutCast->result = new ast::PointerType( mutCast->result );
+	return mutCast;
+}
+
 ast::Expr const * CollapseAddressDeref::postvisit(
 		ast::AddressExpr const * expr ) {
@@ -514,17 +530,6 @@
 			return ret;
 		}
-	} else if ( auto cast = dynamic_cast<ast::CastExpr const *>( arg ) ) {
-		// Need to move cast to pointer type out a level since address of
-		// pointer is not valid C code (can be introduced in prior passes,
-		// e.g., InstantiateGeneric)
-		if ( ast::getPointerBase( cast->result ) ) {
-			auto mutExpr = ast::mutate( expr );
-			auto mutCast = strict_dynamic_cast<ast::CastExpr *>(
-					ast::mutate( mutExpr->arg.release() ) );
-			mutExpr->arg = mutCast->arg;
-			mutCast->arg = mutExpr;
-			mutCast->result = new ast::PointerType( mutCast->result );
-			return mutCast;
-		}
+	} else {
+		return moveAddressUnderCast( expr );
 	}
 	return expr;
