<html>
<head>
<base href="https://bugs.llvm.org/">
</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 - [MIPS] miscompilation of passing 32 bits from 64 bit struct from input register"
href="https://bugs.llvm.org/show_bug.cgi?id=51958">51958</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>[MIPS] miscompilation of passing 32 bits from 64 bit struct from input register
</td>
</tr>
<tr>
<th>Product</th>
<td>new-bugs
</td>
</tr>
<tr>
<th>Version</th>
<td>12.0
</td>
</tr>
<tr>
<th>Hardware</th>
<td>All
</td>
</tr>
<tr>
<th>OS</th>
<td>All
</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>new bugs
</td>
</tr>
<tr>
<th>Assignee</th>
<td>unassignedbugs@nondot.org
</td>
</tr>
<tr>
<th>Reporter</th>
<td>vladimir@pobox.com
</td>
</tr>
<tr>
<th>CC</th>
<td>htmldeveloper@gmail.com, llvm-bugs@lists.llvm.org
</td>
</tr></table>
<p>
<div>
<pre>Created <span class=""><a href="attachment.cgi?id=25290" name="attach_25290" title="testcase">attachment 25290</a> <a href="attachment.cgi?id=25290&action=edit" title="testcase">[details]</a></span>
testcase
The attached .ll testcase shows what looks like an error in translating down to
native code for mips. I've annotated the testcase with info & the generated
instructions; it's self-contained and can be compiled to an executable that
should print "hello".
Note the .ll specifies mips/irix (which is mips3/n32), but I've verified the
miscompilation happens with stock LLVM 12 targeting mips64-unknown-unknown and
mips64r3/n32.
The problem is in the `doit` function:
;; %path.coerce is struct StringRef { char *data; int len; }
define void @doit(i8* nonnull align 1 %dst, i64 inreg %path.coerce)
local_unnamed_addr #0 {
%path = alloca i64, align 8
store i64 %path.coerce, i64* %path, align 8
%copyload = load i64, i64* %path, align 8, !tbaa.struct !32
%struct_ptr_pre_trunc = lshr i64 %copyload, 32
%struct_ptr_int = trunc i64 %struct_ptr_pre_trunc to i32
%struct_ptr = inttoptr i32 %struct_ptr_int to i8*
;; this trunc is not actually happening; the result
%struct_len = trunc i64 %copyload to i32
;; at this point
;; a0 = dst, same as input register
;; a1 = a2 >> (32+0)
;; a2 = ^^^ full 64-bit value from original load -- no trunc!
call void @llvm.memcpy.p0i8.p0i8.i32(i8* nonnull align 1 %dst, i8* align 1
%struct_ptr, i32 %struct_len, i1 false) #1
There's a missing `sll a2,a2,0` that I believe should be emitted for the trunc
but is not happening. If I insert a i32 store of %struct_len to the stack, and
then load it back, the sll is emitted properly and the function works
correctly.
Random observation -- the non-truncated value is already in register a2, which
is where it needs to go for the memcpy; could be something trying to take
advantage of that, but doing so incorrectly?</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>