Bug 16381 – Wrapping a float4 array leads to segfault.
Status
RESOLVED
Resolution
FIXED
Severity
major
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2016-08-12T18:05:30Z
Last change time
2020-03-21T03:56:37Z
Keywords
ice, SIMD
Assigned to
No Owner
Creator
Bartek Siudeja
Comments
Comment #0 by siudej — 2016-08-12T18:05:30Z
This code leads to segfault in dmd:
module test;
import std.stdio;
import core.simd;
class Array
{
float4[] arr;
this(size_t len)
{
arr = new float4[len];
}
float4 opIndex(size_t idx)
{
return arr[idx];
}
}
unittest
{
// without wrapper
auto arr = new float4[50];
float h = arr[0].ptr[0];
// with wrapper
auto arr2 = new Array(50);
assert(typeid(arr[0]) == typeid(arr2[0]));
// with intermediate
float4 f4 = arr2[0];
float f = f4.ptr[0];
// without intermediate
float g = arr2[0].ptr[0];
writeln("done");
}
Run using: dmd -main -unittest test.d
Commenting `float g` line makes the code run. Typeid also shows the same type for arr[0] and arr2[0], but the latter can be accessed only if saved to intermediate float4.
Comment #1 by siudej — 2016-08-12T18:07:54Z
dmd: 2.068, 2.069 and 2.071
Comment #2 by b2.temp — 2016-08-12T18:43:16Z
If the opIndex header is changed to
ref float4 opIndex(size_t idx)
then no segfault.
Comment #3 by siudej — 2016-08-12T18:52:08Z
True, but:
My wrapper is a superclass of an abstract storage class, and not all implementations can return a reference to float4. Another superclass looks more or less like std.container.Array!bool, so the common interface/base class can't use ref.
Comment #4 by b2.temp — 2016-08-12T18:59:12Z
(In reply to Bartek Siudeja from comment #3)
> True, but:
>
> My wrapper is a superclass of an abstract storage class, and not all
> implementations can return a reference to float4. Another superclass looks
> more or less like std.container.Array!bool, so the common interface/base
> class can't use ref.
I don't suggest you do to do like this. I've added the extra info for the person who'll fix it. The information added by "it works with ref" is that the copy is not valid since any access to ".ptr" leads to an AV.
Comment #5 by siudej — 2016-08-12T19:10:22Z
If you do know a workaround I could use, I would be really grateful.
Was checking some other options. Even changing opIndex into something like:
float4 test(size_t idx)
{
float4 temp = arr[idx];
return temp;
}
does not help. So this seems about the return value of a function.
Comment #6 by b2.temp — 2016-08-12T20:28:34Z
(In reply to Bartek Siudeja from comment #5)
> does not help. So this seems about the return value of a function.
Yes that's also what I said: return value == copy because float[4] doesn't fit in a CPU register. when ref is used it's actually the address of the first float that's returned.
Anyway it's clearly a front-end error, because even LDC returns a run-time error:
> Invalid bitcast
> %63 = bitcast [4 x float] %62 to float
> LLVM ERROR: Broken function found, compilation aborted!
Comment #7 by b2.temp — 2016-08-12T20:30:44Z
(In reply to b2.temp from comment #6)
> (In reply to Bartek Siudeja from comment #5)
> > does not help. So this seems about the return value of a function.
>
> Yes that's also what I said: return value == copy because float[4] doesn't
> fit in a CPU register. when ref is used it's actually the address of the
> first float that's returned.
>
> Anyway it's clearly a front-end error, because even LDC returns a run-time
> error:
>
> > Invalid bitcast
> > %63 = bitcast [4 x float] %62 to float
> > LLVM ERROR: Broken function found, compilation aborted!
"compile-time error" is what I really meant...
Comment #8 by bugzilla — 2016-11-20T10:18:32Z
Simpler test case:
__vector(float[4]) foo();
void bar() {
float g = foo().ptr[0];
}