Bug 1559315 - Various test failures in the LLVM regression tests
Summary: Various test failures in the LLVM regression tests
Keywords:
Status: CLOSED CURRENTRELEASE
Alias: None
Product: Fedora
Classification: Fedora
Component: llvm
Version: 29
Hardware: x86_64
OS: Linux
unspecified
medium
Target Milestone: ---
Assignee: Tom Stellard
QA Contact: Fedora Extras Quality Assurance
URL:
Whiteboard:
Depends On: 1559234 1561373
Blocks:
TreeView+ depends on / blocked
 
Reported: 2018-03-22 09:41 UTC by Tilmann Scheller
Modified: 2018-09-08 06:39 UTC (History)
9 users (show)

Fixed In Version:
Clone Of:
Environment:
Last Closed: 2018-09-08 06:39:25 UTC
Type: Bug
Embargoed:


Attachments (Terms of Use)

Description Tilmann Scheller 2018-03-22 09:41:19 UTC
Description of problem:
There are various failures when running the LLVM regression tests.

Version-Release number of selected component (if applicable):
llvm-6.0.0-9.fc29.x86_6

How reproducible:
100%

Steps to Reproduce:
1. Build the package with Mock and check the build log

Actual results:
Failing Tests (10):
    LLVM :: CodeGen/Mips/Fast-ISel/fastalloca.ll
    LLVM :: CodeGen/Mips/Fast-ISel/fastcc-miss.ll
    LLVM :: CodeGen/Mips/Fast-ISel/memtest1.ll
    LLVM :: CodeGen/Mips/Fast-ISel/mul1.ll
    LLVM :: CodeGen/Mips/Fast-ISel/sel1.ll
    LLVM :: CodeGen/Mips/call-optimization.ll
    LLVM :: DebugInfo/Mips/delay-slot.ll
    LLVM :: DebugInfo/X86/live-debug-vars-discard-invalid.mir
    LLVM :: tools/gold/X86/comdat.ll
    LLVM :: tools/gold/X86/visibility.ll

  Expected Passes    : 21432
  Expected Failures  : 136
  Unsupported Tests  : 1715
  Unexpected Failures: 10


Expected results:
No test failures

Additional info:

Comment 1 Tilmann Scheller 2018-03-22 09:51:17 UTC
Results with a static trunk (r328182) build on rawhide:

cmake .. -G Ninja -DCMAKE_BUILD_TYPE=Release -DLLVM_TARGETS_TO_BUILD='X86;Mips'

Failing Tests (5):
    LLVM :: CodeGen/Mips/Fast-ISel/fastalloca.ll
    LLVM :: CodeGen/Mips/Fast-ISel/memtest1.ll
    LLVM :: CodeGen/Mips/Fast-ISel/sel1.ll
    LLVM :: CodeGen/Mips/call-optimization.ll
    LLVM :: DebugInfo/Mips/delay-slot.ll

  Expected Passes    : 15578
  Expected Failures  : 108
  Unsupported Tests  : 8923
  Unexpected Failures: 5

Comment 2 Tilmann Scheller 2018-03-22 09:52:11 UTC
No failures with a static trunk (r328182) build on Fedora 27.

Comment 3 Tilmann Scheller 2018-03-22 10:03:14 UTC
Does not reproduce with static trunk (r328182) build on rawhide using Clang 6.0 from the Fedora clang package:

  Expected Passes    : 15583
  Expected Failures  : 108
  Unsupported Tests  : 8923

Possible miscompilation by GCC 8? Will continue to investigate.

Comment 4 Tilmann Scheller 2018-03-22 14:24:44 UTC
Does not reproduce when built with GCC 8 in debug mode.

When looking at the fastalloca.ll test case, the hClang-built (both release and debug mode) llc as well GCC-built llc in debug mode are Valgrind-clean (memcheck).

The llc binary built with GCC 8 in release mode shows a read from uninitialized memory (and lots of other errors until the execution ends with a segfault):

$ valgrind /home/tschelle/llvm-project/_build/bin/llc -march=mipsel -relocation-model=pic -O0 -fast-isel-abort=3 -mcpu=mips32r2      < /home/tschelle/llvm-project/llvm/test/CodeGen/Mips/Fast-ISel/fastalloca.ll -verify-machineinstrs
==11041== Memcheck, a memory error detector
==11041== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==11041== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==11041== Command: /home/tschelle/llvm-project/_build/bin/llc -march=mipsel -relocation-model=pic -O0 -fast-isel-abort=3 -mcpu=mips32r2 -verify-machineinstrs
==11041==
        .text
        .abicalls
        .section        .mdebug.abi32,"",@progbits
        .nan    legacy
        .file   "<stdin>"
==11041== Use of uninitialised value of size 8
==11041==    at 0xBA6FE2: llvm::MachineRegisterInfo::addRegOperandToUseList(llvm::MachineOperand*) (MachineRegisterInfo.cpp:273)
==11041==    by 0xB45FE6: llvm::MachineInstr::addOperand(llvm::MachineFunction&, llvm::MachineOperand const&) (MachineInstr.cpp:272)
==11041==    by 0xBA8B1B: addReg (MachineInstrBuilder.h:88)
==11041==    by 0xBA8B1B: llvm::MachineRegisterInfo::EmitLiveInCopies(llvm::MachineBasicBlock*, llvm::TargetRegisterInfo const&, llvm::TargetInstrInfo const&) (MachineRegisterInfo.cpp:486)
==11041==    by 0x11FF85C: llvm::SelectionDAGISel::runOnMachineFunction(llvm::MachineFunction&) [clone .part.945] (SelectionDAGISel.cpp:479)
==11041==    by 0x82ACD9: llvm::MipsDAGToDAGISel::runOnMachineFunction(llvm::MachineFunction&) (MipsISelDAGToDAG.cpp:51)
==11041==    by 0xB41792: llvm::MachineFunctionPass::runOnFunction(llvm::Function&) (MachineFunctionPass.cpp:62)
==11041==    by 0xDFDAA7: llvm::FPPassManager::runOnFunction(llvm::Function&) (LegacyPassManager.cpp:1520)
==11041==    by 0xDFDB02: llvm::FPPassManager::runOnModule(llvm::Module&) (LegacyPassManager.cpp:1541)
==11041==    by 0xDFD3E5: runOnModule (LegacyPassManager.cpp:1597)
==11041==    by 0xDFD3E5: llvm::legacy::PassManagerImpl::run(llvm::Module&) (LegacyPassManager.cpp:1700)
==11041==    by 0x5FE096: compileModule(char**, llvm::LLVMContext&) (llc.cpp:574)
==11041==    by 0x5B6333: main (llc.cpp:347)
...

Will try to find out at which point the execution diverges in the good and bad binary.

Comment 5 Tilmann Scheller 2018-03-26 13:53:17 UTC
Also reproduces with gcc-8.0.1-0.20.fc28 that got built during the weekend.

Comment 6 Tilmann Scheller 2018-03-27 14:24:31 UTC
Stack memory gets corrupted when executing the following minimized test case:

llc -march=mipsel -relocation-model=pic -O0 -fast-isel-abort=3 -mcpu=mips32r2 minimized.ll -verify-machineinstrs -debug

define void @foo(i32 %x) {
entry:
  ret void
}

gdb -q -ex 'b llvm::MachineRegisterInfo::EmitLiveInCopies' -ex 'b MipsFastISel.cpp:1309' -ex 'b MipsFastISel.cpp:1387' -ex r -ex n -ex 'p GPR32ArgRegs' -ex 'x/10x GPR32ArgRegs.Data' -ex 'watch *GPR32ArgRegs.Data' -ex c -ex 'x/10x GPR32ArgRegs.Data' --args /home/tschelle/llvm-project/_build/bin/llc -march=mipsel -relocation-model=pic -O0 -fast-isel-abort=3 -mcpu=mips32r2 minimized.ll -verify-machineinstrs -debug

....
Breakpoint 2, (anonymous namespace)::MipsFastISel::fastLowerArguments (this=0x32a6230)
    at /home/tschelle/llvm-project/llvm/lib/Target/Mips/MipsFastISel.cpp:1309
1309      const ArrayRef<MCPhysReg> GPR32ArgRegs = {Mips::A0, Mips::A1, Mips::A2,
1311      const ArrayRef<MCPhysReg> FGR32ArgRegs = {Mips::F12, Mips::F14};
$1 = {Data = 0x7fffffffc3f0, Length = 4}
0x7fffffffc3f0: 0x00170016      0x00190018      0x00bd1993      0x00000000
0x7fffffffc400: 0xffffc490      0x00007fff      0x01559b74      0x00000000
0x7fffffffc410: 0xffffc3f0      0x00007fff
Hardware watchpoint 4: *GPR32ArgRegs.Data
Continuing.

Hardware watchpoint 4: *GPR32ArgRegs.Data

Old value = 22
New value = 159
0x0000000000ed26c6 in (anonymous namespace)::MipsFastISel::fastLowerArguments (this=0x32a6230)
    at /home/tschelle/llvm-project/llvm/lib/Target/Mips/MipsFastISel.cpp:1311
1311      const ArrayRef<MCPhysReg> FGR32ArgRegs = {Mips::F12, Mips::F14};
0x7fffffffc3f0: 0x00a1009f      0x00190018      0x00bd1993      0x00000000
0x7fffffffc400: 0xffffc490      0x00007fff      0x01559b74      0x00000000
0x7fffffffc410: 0xffffc3f0      0x00007fff
....

It looks like GCC 8 is miscompiling ArrayRef: When looking at GPR32ArgRegs/FGR32ArgRegs/AFGR64ArgRegs their member variable "Data" points to the same stack address in the broken binary while in the working binary the constant arrays are all allocated to different stack addresses. So basically the contents of GPR32ArgRegs already get overwritten when FGR32ArgRegs is initialized.

I will try to extract a minimized ArrayRef test case from LLVM.

Comment 7 Tilmann Scheller 2018-03-28 08:36:40 UTC
Here is a minimized test case that reproduces with gcc-8.0.1-0.19.fc29 (I expect that it reproduces with gcc-8.0.1-0.20.fc29 as well):

$ cat min.sh
#!/bin/bash
set -xe
rm -f test testopt
g++ test.cpp -o testopt -O2
g++ test.cpp -o test -O0 -g
./testopt
./test
$ cat test.cpp
#include <initializer_list>
#include <iostream>

template <typename T> class ArrayRef {
public:
  using size_type = size_t;

private:
  /// The start of the array, in an external buffer.
  const T *Data = nullptr;

  /// The number of elements.
  size_type Length = 0;

public:
  /// Construct an ArrayRef from a std::initializer_list.
  /*implicit*/ ArrayRef(const std::initializer_list<T> &Vec)
      : Data(Vec.begin() == Vec.end() ? (T *)nullptr : Vec.begin()),
        Length(Vec.size()) {}

  const T &operator[](size_t Index) const { return Data[Index]; }
};

int main(int argc, char **argv) {
  const ArrayRef<int> Foo = {42};
  std::cout << "Foo " << Foo[0] << "\n";
  return 0;
}
[$ ./min.sh
+ rm -f test testopt
+ g++ test.cpp -o testopt -O2
+ g++ test.cpp -o test -O0 -g
+ ./testopt
Foo 0
+ ./test
Foo 42

As you can see it doesn't return the correct value for Foo[0] when compiling with -O2.

Comment 8 Tilmann Scheller 2018-03-28 08:53:29 UTC
Filed bug 1561373 against the gcc package.

Comment 9 Tilmann Scheller 2018-03-28 12:42:00 UTC
After reading up on std::initializer_list it's now clear that this is actually wrong code in LLVM (causing undefined behavior). Will try to understand the impact on the overall LLVM codebase and possible ways to fix this.

It seems just wrong to have a constructor taking a std::initializer_list reference in ArrayRef in the first place (given that the std::initializer_list is typically a temporary object with a very limited lifetime).

Comment 10 Tilmann Scheller 2018-04-06 11:07:31 UTC
The MIPS fast isel failures were fixed upstream yesterday: https://reviews.llvm.org/rL329359 and https://reviews.llvm.org/rL329363

I've created merge requests for 6.0.1 with http://llvm.org/PR37031 and http://llvm.org/PR37032

Comment 11 Jan Kurik 2018-08-14 10:56:56 UTC
This bug appears to have been reported against 'rawhide' during the Fedora 29 development cycle.
Changing version to '29'.

Comment 12 Tom Stellard 2018-09-08 06:39:25 UTC
These pass now on f28 and f29


Note You need to log in before you can comment on or make changes to this bug.