In case a casual visitor should come along and wonder if there is an XSLT 1.0 solution for this problem, I offer the following. Note that I am not trying to diminish from Sean and Martin's correct answers; I am merely offering some flavor.
When this XSLT 1.0 solution:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output omit-xml-declaration="no" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key
name="kFollowing"
match="hi"
use="concat(@rend, '+', generate-id(following-sibling::text()[1]))" />
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/*">
<p>
<xsl:apply-templates
select="
hi[generate-id() =
generate-id(
key('kFollowing',
concat(@rend, '+', generate-id(following-sibling::text()[1])))[1])]" />
</p>
</xsl:template>
<xsl:template match="hi">
<xsl:copy>
<xsl:apply-templates
select="@*|key('kFollowing',
concat(@rend, '+', generate-id(following-sibling::text()[1])))/text()" />
</xsl:copy>
<xsl:apply-templates select="following-sibling::text()[1]" />
</xsl:template>
</xsl:stylesheet>
...is applied to the OP's original XML:
<p>
<hi rend="bold">aa</hi>
<hi rend="bold">bb</hi>
<hi rend="bold">cc</hi>
Perhaps some text.
<hi rend="italic">dd</hi>
<hi rend="italic">ee</hi>
Some more text.
<hi rend="italic">ff</hi>
<hi rend="italic">gg</hi>
Foo.
</p>
...the desired result is produced:
<p>
<hi rend="bold">aabbcc</hi>
Perhaps some text.
<hi rend="italic">ddee</hi>
Perhaps some text.
<hi rend="italic">ffgg</hi>
Foo.
</p>