<html>
<head>
<base href="http://llvm.org/bugs/" />
</head>
<body><table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Bug ID</th>
<td><a class="bz_bug_link
bz_status_NEW "
title="NEW --- - Constant merging may illegally downgrade global alignment"
href="http://llvm.org/bugs/show_bug.cgi?id=17815">17815</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>Constant merging may illegally downgrade global alignment
</td>
</tr>
<tr>
<th>Product</th>
<td>libraries
</td>
</tr>
<tr>
<th>Version</th>
<td>3.2
</td>
</tr>
<tr>
<th>Hardware</th>
<td>PC
</td>
</tr>
<tr>
<th>OS</th>
<td>Linux
</td>
</tr>
<tr>
<th>Status</th>
<td>NEW
</td>
</tr>
<tr>
<th>Severity</th>
<td>normal
</td>
</tr>
<tr>
<th>Priority</th>
<td>P
</td>
</tr>
<tr>
<th>Component</th>
<td>Interprocedural Optimizations
</td>
</tr>
<tr>
<th>Assignee</th>
<td>unassignedbugs@nondot.org
</td>
</tr>
<tr>
<th>Reporter</th>
<td>chris@smowton.net
</td>
</tr>
<tr>
<th>CC</th>
<td>llvmbugs@cs.uiuc.edu
</td>
</tr>
<tr>
<th>Classification</th>
<td>Unclassified
</td>
</tr></table>
<p>
<div>
<pre>Created <span class=""><a href="attachment.cgi?id=11488" name="attach_11488" title="Patch to fix constmerge">attachment 11488</a> <a href="attachment.cgi?id=11488&action=edit" title="Patch to fix constmerge">[details]</a></span>
Patch to fix constmerge
The global constant merger and the instruction combining pass make
contradictory assumptions about the meaning of globals with zero (unspecified)
alignment.
Instcombine tries to upgrade the alignment on llvm.memcpy intrinsics. When
memcpy operates on a global without a defined alignment, using a stack like:
InstCombiner::SimplifyMemTransfer
llvm::getKnownAlignment
llvm::getOrEnforceKnownAlignment
llvm::ComputeMaskedBits
This latter uses TD->getPreferredAlignment if DataLayout is available; on
x86-64 this is 16 byte alignment.
By contrast, ConstMerge contains the line:
Replacements[i].second->setAlignment(std::max(
Replacements[i].first->getAlignment(),
Replacements[i].second->getAlignment()));
This assumes that zero alignment is exactly that -- no alignment at all.
ConstMerge also contains an unused, broken function ConstantMerge::getAlignment
that looks like it was trying to implement similar logic to ComputeMaskedBits.
My patch fixes it and uses it (I think it is ok that it remains simpler than
ComputeMaskedBits, which must deal with declarations, weak definitions and
other cases that cannot happen during constant merging).
I attach a test case in.ll which uses an unaligned memcpy against a global with
no declared alignment, but a duplicate constant exists with 8-byte alignment.
instcombine.ll illustrates the results of opt -instcombine: note the memcpy is
upgraded to assume 16-byte alignment, since the unaligned global will be
written with such (we think).
However, constmerge.ll shows what happens after a further opt -constmerge: the
two constants have merged, keeping the 8-byte alignment. Thus we have a
16-aligned memcpy against 8-aligned memory. If this particular test is compiled
we get away with it; however, inserting an extra rodata constant before .cst2
will cause synthesis of a misaligned x86 vector operation and consequent
segfault in the compiled program.
I will mention this report to llvm-commits per Chris Lattner's comment in <a class="bz_bug_link
bz_status_NEW "
title="NEW --- - ExpandInlineAsm is brittle, and uses obsolete register dirflag"
href="show_bug.cgi?id=17757">bug
17757</a>.</pre>
</div>
</p>
<hr>
<span>You are receiving this mail because:</span>
<ul>
<li>You are on the CC list for the bug.</li>
</ul>
</body>
</html>