Skip to content
This repository has been archived by the owner on Oct 9, 2019. It is now read-only.

LLVM-SPIRV crashes on struct with vector-content #206

Open
doe300 opened this issue Feb 28, 2017 · 2 comments
Open

LLVM-SPIRV crashes on struct with vector-content #206

doe300 opened this issue Feb 28, 2017 · 2 comments
Labels
migrate To be moved to the new repo

Comments

@doe300
Copy link
Contributor

doe300 commented Feb 28, 2017

The original OpenCL-C code:

struct SomeStruct
{
float16 f;
int i;
};

__kernel void test_struct(const __global struct SomeStruct* in, __global struct SomeStruct* out)
{
struct SomeStruct tmp = *in;
tmp.i = 42;
*out = tmp;
}

The LLVM-IR code (excerpt), compiled with clang version 3.6.1 (https://github.com/KhronosGroup/SPIR d7e44c3b27581e54ca0e522987d1ade2bd29b70d) (https://github.com/KhronosGroup/SPIRV-LLVM.git fffc52b7fb3552c045c398d68e22216c8d770c00):

%struct.SomeStruct = type { <16 x float>, i32, [60 x i8] }

define spir_kernel void @test_struct(%struct.SomeStruct addrspace(1)* nocapture readonly %in, %struct.SomeStruct addrspace(1)* nocapture %out) #0 {
  %tmp.sroa.5 = alloca [60 x i8], align 4
  %1 = getelementptr inbounds [60 x i8]* %tmp.sroa.5, i32 0, i32 0
  call void @llvm.lifetime.start(i64 60, i8* %1)
  %2 = getelementptr inbounds %struct.SomeStruct addrspace(1)* %in, i32 0, i32 0
  %3 = load <16 x float> addrspace(1)* %2, align 64
  %4 = getelementptr inbounds %struct.SomeStruct addrspace(1)* %in, i32 0, i32 2, i32 0
  call void @llvm.memcpy.p0i8.p1i8.i32(i8* %1, i8 addrspace(1)* %4, i32 60, i32 4, i1 false)
  %5 = getelementptr inbounds %struct.SomeStruct addrspace(1)* %out, i32 0, i32 0
  store <16 x float> %3, <16 x float> addrspace(1)* %5, align 64
  %6 = getelementptr inbounds %struct.SomeStruct addrspace(1)* %out, i32 0, i32 1
  store i32 42, i32 addrspace(1)* %6, align 64
  %7 = getelementptr inbounds %struct.SomeStruct addrspace(1)* %out, i32 0, i32 2, i32 0
  call void @llvm.memcpy.p1i8.p0i8.i32(i8 addrspace(1)* %7, i8* %1, i32 60, i32 4, i1 false)
  call void @llvm.lifetime.end(i64 60, i8* %1)
  ret void
}
declare void @llvm.lifetime.start(i64, i8* nocapture)
declare void @llvm.memcpy.p0i8.p1i8.i32(i8* nocapture, i8 addrspace(1)* nocapture readonly, i32, i32, i1)
declare void @llvm.memcpy.p1i8.p0i8.i32(i8 addrspace(1)* nocapture, i8* nocapture readonly, i32, i32, i1)
declare void @llvm.lifetime.end(i64, i8* nocapture)

llvm-spirv crashes with following stack-trace:

Stack dump:
0.	Program arguments: /opt/SPIRV-LLVM/build/bin/llvm-spirv -o /tmp/out.spv 
0  llvm-spirv      0x00000000005f5972
1  llvm-spirv      0x00000000005f4241
2  libpthread.so.0 0x00007f09af1ab5c0
3  llvm-spirv      0x00000000004b0d70
4  llvm-spirv      0x00000000004b1683
5  llvm-spirv      0x00000000004acefd
6  llvm-spirv      0x00000000004ad256
7  llvm-spirv      0x00000000004b1f08
8  llvm-spirv      0x00000000004b2240
9  llvm-spirv      0x00000000004b226b
10 llvm-spirv      0x000000000058bcac
11 llvm-spirv      0x00000000004b22ce
12 llvm-spirv      0x0000000000407a73
13 libc.so.6       0x00007f09ae54c401 __libc_start_main + 241
14 llvm-spirv      0x000000000040abea
Segmentation fault (core dumped)

Analysis with valgrind prints this:

Process terminating with default action of signal 11 (SIGSEGV)
Access not within mapped region at address 0x8
  at 0x4CED70: SPIRV::SPIRVEntry::setModule(SPIRV::SPIRVModule*) (in /opt/SPIRV-LLVM/build/bin/llvm-spirv)
  by 0x45F298: SPIRV::SPIRVDecoder::getEntry() (in /opt/SPIRV-LLVM/build/bin/llvm-spirv)
  by 0x44793F: SPIRV::operator>>(std::istream&, SPIRV::SPIRVModule&) (in /opt/SPIRV-LLVM/build/bin/llvm-spirv)
  by 0x458F13: SPIRV::ConvertSPIRV(std::istream&, llvm::raw_ostream&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&, bool, bool) (in /opt/SPIRV-LLVM/build/bin/llvm-spirv)
  by 0x40AFBB: convertSPIRV()::{lambda(llvm::raw_ostream&)#1}::operator()(llvm::raw_ostream&) const (in /opt/SPIRV-LLVM/build/bin/llvm-spirv)
  by 0x40B2DB: convertSPIRV() (in /opt/SPIRV-LLVM/build/bin/llvm-spirv)
  by 0x40798B: main (in /opt/SPIRV-LLVM/build/bin/llvm-spirv)

... which looks like access to a nullptr

@AlexeySotkin
Copy link
Contributor

Could you try with debug build (with enabled assert functions) of llvm-spirv?
This code worked for me, when I commented out calls to llvm.lifetime.* intrinsics.

@doe300
Copy link
Contributor Author

doe300 commented Mar 3, 2017

You are right, seems like the llvm.lifetime.* intrinsics arethe culprits.

Here the new valgrind output:

Process terminating with default action of signal 6 (SIGABRT)
  at 0x5D4191F: raise (raise.c:58)
  by 0x5D43632: abort (abort.c:118)
  by 0x5D39DA6: __assert_fail_base (assert.c:92)
  by 0x5D39E51: __assert_fail (assert.c:101)
  by 0x56AA54: SPIRV::LLVMToSPIRV::transLifetimeIntrinsicInst(spv::Op, llvm::IntrinsicInst*, SPIRV::SPIRVBasicBlock*) (SPIRVWriter.cpp:855)
  by 0x56DF1D: SPIRV::LLVMToSPIRV::transIntrinsicInst(llvm::IntrinsicInst*, SPIRV::SPIRVBasicBlock*) (SPIRVWriter.cpp:1307)
  by 0x56D17B: SPIRV::LLVMToSPIRV::transValueWithoutDecoration(llvm::Value*, SPIRV::SPIRVBasicBlock*, bool) (SPIRVWriter.cpp:1157)
  by 0x56A5DF: SPIRV::LLVMToSPIRV::transValue(llvm::Value*, SPIRV::SPIRVBasicBlock*, bool) (SPIRVWriter.cpp:812)
  by 0x56ED83: SPIRV::LLVMToSPIRV::transFunction(llvm::Function*) (SPIRVWriter.cpp:1464)
  by 0x56F2E3: SPIRV::LLVMToSPIRV::translate() (SPIRVWriter.cpp:1508)
  by 0x5663E3: SPIRV::LLVMToSPIRV::runOnModule(llvm::Module&) (SPIRVWriter.cpp:178)
  by 0x6CF415: (anonymous namespace)::MPPassManager::runOnModule(llvm::Module&) (LegacyPassManager.cpp:1616)

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
migrate To be moved to the new repo
Projects
None yet
Development

No branches or pull requests

2 participants