<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 - Truncation to i1 generates invalid value"
   href="https://bugs.llvm.org/show_bug.cgi?id=51529">51529</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>Truncation to i1 generates invalid value
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>libraries
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>12.0
          </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>Backend: X86
          </td>
        </tr>

        <tr>
          <th>Assignee</th>
          <td>unassignedbugs@nondot.org
          </td>
        </tr>

        <tr>
          <th>Reporter</th>
          <td>robin@voetter.nl
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>craig.topper@gmail.com, llvm-bugs@lists.llvm.org, llvm-dev@redking.me.uk, pengfei.wang@intel.com, spatel+llvm@rotateright.com
          </td>
        </tr></table>
      <p>
        <div>
        <pre>Created <span class=""><a href="attachment.cgi?id=25166" name="attach_25166" title="Test case">attachment 25166</a> <a href="attachment.cgi?id=25166&action=edit" title="Test case">[details]</a></span>
Test case

In order to load a value from a packed struct of 8 bools, the Zig compiler
generates code as follows:

%1 = load i8, i8* %ptr_to_packed_struct, align 1
%2 = lshr i8 %1, %target_bit_offset
%3 = trunc i8 %2 to i1

This seems to cause LLVM to not actually perform the truncation in very
esoteric cases, and the upper bits of %3 are not cleared. This would be fine of
course, i expect those to be allowed to be undefined, though when the resulting
value is compared with another i1 with the same truthiness (but a differing
backing bit value), an incorrect result is generated. See the attached test
case, which prints "error" when this case is detected. The incorrect value is
generated in %14 in function @b, and is later compared for equality with 1 in
function @a to produce `false` in %17 in @a.

This only seems to manifest itself when two components are available: the
original packed struct needs to be part of a union, and the resulting bit value
(after the pointer load) needs to be passed on the stack.

The related Zig issue is <a href="https://github.com/ziglang/zig/pull/9584">https://github.com/ziglang/zig/pull/9584</a>. Note that
the attached test case was made by creating a similar case in C, and rewriting
it a bit to trigger the incorrect behavior. For this kind of code, clang
generates an additional and operation between the lshr and trunc, though
according to the semantics of trunc i would expect that to be included.

In Zig, this case is only triggered in debug mode. When I tested that with the
attached test case, clang crashed (see below). The test case is to be compiled
simply with `clang -otest test.ll` to create the incorrect code described
above, and adding `-O2` yields the segmentation fault below. 


Stack dump:
0.      Program arguments: /usr/bin/clang-12 -cc1 -triple
x86_64-unknown-linux-gnu -emit-obj --mrelax-relocations -disable-free
-disable-llvm-verifier -discard-value-names -main-file-name test.ll
-mrelocation-model static -mframe-pointer=none -fmath-errno -fno-rounding-math
-mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic
-fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir
/usr/lib/clang/12.0.0 -O2 -fdebug-compilation-dir
/home/robin/programming/zooi/llvm-bug -ferror-limit 19 -fgnuc-version=4.2.1
-vectorize-loops -vectorize-slp -faddrsig -o /tmp/test-cbb751.o -x ir test.ll
1.      Code generation
2.      Running pass 'Function Pass Manager' on module 'test.ll'.
3.      Running pass 'Simple Register Coalescing' on function '@a'
 #0 0x00007f69eb76db4d llvm::sys::PrintStackTrace(llvm::raw_ostream&, int)
(/usr/bin/../lib/libLLVM-12.so+0xbddb4d)
 #1 0x00007f69eb76b824 llvm::sys::RunSignalHandlers()
(/usr/bin/../lib/libLLVM-12.so+0xbdb824)
 #2 0x00007f69eb76b99b (/usr/bin/../lib/libLLVM-12.so+0xbdb99b)
 #3 0x00007f69ea79e000 __restore_rt (/usr/bin/../lib/libc.so.6+0x3d000)
 #4 0x00007f69ebc18897 (/usr/bin/../lib/libLLVM-12.so+0x1088897)
 #5 0x00007f69ebcdb914 (/usr/bin/../lib/libLLVM-12.so+0x114b914)
 #6 0x00007f69ebcdbaa1 (/usr/bin/../lib/libLLVM-12.so+0x114baa1)
 #7 0x00007f69ebce165a (/usr/bin/../lib/libLLVM-12.so+0x115165a)
 #8 0x00007f69ebce268e (/usr/bin/../lib/libLLVM-12.so+0x115268e)
 #9 0x00007f69ebce4c66 (/usr/bin/../lib/libLLVM-12.so+0x1154c66)
#10 0x00007f69ebce7196 (/usr/bin/../lib/libLLVM-12.so+0x1157196)
#11 0x00007f69ebb584e4
llvm::MachineFunctionPass::runOnFunction(llvm::Function&)
(/usr/bin/../lib/libLLVM-12.so+0xfc84e4)
#12 0x00007f69eb8c4310 llvm::FPPassManager::runOnFunction(llvm::Function&)
(/usr/bin/../lib/libLLVM-12.so+0xd34310)
#13 0x00007f69eb8c58fc llvm::FPPassManager::runOnModule(llvm::Module&)
(/usr/bin/../lib/libLLVM-12.so+0xd358fc)
#14 0x00007f69eb8c3c28 llvm::legacy::PassManagerImpl::run(llvm::Module&)
(/usr/bin/../lib/libLLVM-12.so+0xd33c28)
#15 0x00007f69f2804209 clang::EmitBackendOutput(clang::DiagnosticsEngine&,
clang::HeaderSearchOptions const&, clang::CodeGenOptions const&,
clang::TargetOptions const&, clang::LangOptions const&, llvm::DataLayout
const&, llvm::Module*, clang::BackendAction,
std::unique_ptr<llvm::raw_pwrite_stream,
std::default_delete<llvm::raw_pwrite_stream> >)
(/usr/bin/../lib/libclang-cpp.so.12+0x1967209)
#16 0x00007f69f2b7550a clang::CodeGenAction::ExecuteAction()
(/usr/bin/../lib/libclang-cpp.so.12+0x1cd850a)
#17 0x00007f69f32eca89 clang::FrontendAction::Execute()
(/usr/bin/../lib/libclang-cpp.so.12+0x244fa89)
#18 0x00007f69f3282b0b
clang::CompilerInstance::ExecuteAction(clang::FrontendAction&)
(/usr/bin/../lib/libclang-cpp.so.12+0x23e5b0b)
#19 0x00007f69f3367498
clang::ExecuteCompilerInvocation(clang::CompilerInstance*)
(/usr/bin/../lib/libclang-cpp.so.12+0x24ca498)
#20 0x0000564529d65479 cc1_main(llvm::ArrayRef<char const*>, char const*,
void*) (/usr/bin/clang-12+0x14479)
#21 0x0000564529d629e7 (/usr/bin/clang-12+0x119e7)
#22 0x0000564529d5f0ac main (/usr/bin/clang-12+0xe0ac)
#23 0x00007f69ea788e0a __libc_start_main
/builddir/glibc-2.32/csu/../csu/libc-start.c:314:16
#24 0x0000564529d6238a _start (/usr/bin/clang-12+0x1138a)
clang-12: error: unable to execute command: Segmentation fault
clang-12: error: clang frontend command failed due to signal (use -v to see
invocation)
clang version 12.0.0
Target: x86_64-unknown-linux-gnu
Thread model: posix
InstalledDir: /usr/bin
clang-12: note: diagnostic msg: Error generating preprocessed source(s) - no
preprocessable inputs.</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>