<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 - [InstCombine] Miscompile (?) of select with poison case"
href="https://bugs.llvm.org/show_bug.cgi?id=48435">48435</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>[InstCombine] Miscompile (?) of select with poison case
</td>
</tr>
<tr>
<th>Product</th>
<td>libraries
</td>
</tr>
<tr>
<th>Version</th>
<td>trunk
</td>
</tr>
<tr>
<th>Hardware</th>
<td>PC
</td>
</tr>
<tr>
<th>OS</th>
<td>All
</td>
</tr>
<tr>
<th>Status</th>
<td>NEW
</td>
</tr>
<tr>
<th>Severity</th>
<td>enhancement
</td>
</tr>
<tr>
<th>Priority</th>
<td>P
</td>
</tr>
<tr>
<th>Component</th>
<td>Scalar Optimizations
</td>
</tr>
<tr>
<th>Assignee</th>
<td>unassignedbugs@nondot.org
</td>
</tr>
<tr>
<th>Reporter</th>
<td>meheff@google.com
</td>
</tr>
<tr>
<th>CC</th>
<td>llvm-bugs@lists.llvm.org
</td>
</tr></table>
<p>
<div>
<pre>I'm not totally sure this is a bug as I don't know the semantics of a select
which has a poison value in the non-selected position. Anyway, the input is
basically a shift followed by select with some other cruft. The select guards
against use of an overshifted value by selecting zero in the case of overshift.
Input:
define i1 @test() local_unnamed_addr {
so_basic:
%x5 = call i32 @f(i32 100)
%ne_42 = icmp ne i32 %x5, 0
%_z3 = zext i32 %x5 to i64
%_z4 = icmp uge i64 %_z3, 64
%_z5 = lshr i64 256, %_z3
%_z6 = trunc i64 %_z5 to i32
%x15 = select i1 %_z4, i32 0, i32 %_z6
%ne_44 = icmp ne i32 %x15, 0
%x18 = or i1 %ne_42, %ne_44
ret i1 %x18
}
define i32 @f(i32 %x) {
ret i32 %x
}
Result of opt -O2:
define i1 @test() local_unnamed_addr #0 {
so_basic:
ret i1 poison
}
Looks like the problematic xform replaces the select(p, false, x) with
and(not(p), x) where x is poison in this case.
Alive:
----------------------------------------
define i1 @src() {
%0:
%x5 = call i32 @f(i32 100)
%ne_42 = icmp ne i32 %x5, 0
%_z3 = zext i32 %x5 to i64
%_z4 = icmp ugt i32 %x5, 63
%_z5 = lshr i64 256, %_z3
%_z6 = trunc i64 %_z5 to i32
%ne_441 = icmp ne i32 %_z6, 0
%not._z4 = xor i1 %_z4, 1
%ne_44 = and i1 %not._z4, %ne_441
%x18 = or i1 %ne_42, %ne_44
ret i1 %x18
}
=>
define i1 @tgt() {
%0:
ret i1 poison
}
Transformation doesn't verify!
ERROR: Target is more poisonous than source
Example:
Source:
i32 %x5 = #x00000000 (0)
i1 %ne_42 = #x0 (0)
i64 %_z3 = #x0000000000000000 (0)
i1 %_z4 = #x0 (0)
i64 %_z5 = #x0000000000000100 (256)
i32 %_z6 = #x00000100 (256)
i1 %ne_441 = #x1 (1)
i1 %not._z4 = #x1 (1)
i1 %ne_44 = #x1 (1)
i1 %x18 = #x1 (1)
SOURCE MEMORY STATE
===================
NON-LOCAL BLOCKS:
Block 0 > size: 0 align: 1 alloc type: 0
Block 1 > size: 0 align: 2 alloc type: 0
Target:
Source value: #x1 (1)
Target value: poison</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>