← Back to index
|
Original Bugzilla link
Bug 23307 – [REG][CODEGEN][SIMD] wrong codegen with inlined local functions + SIMD
Status
RESOLVED
Resolution
FIXED
Severity
regression
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
x86_64
OS
Linux
Creation time
2022-08-28T12:34:54Z
Last change time
2022-12-22T09:52:54Z
Keywords
backend, pull, SIMD, wrong-code
Assigned to
No Owner
Creator
Guillaume Piolat
Comments
Comment #0
by contact — 2022-08-28T12:34:54Z
Consider the following program: ------ main.d -------- import core.simd; alias __m128i = int4; uint bitwiseRotateRight_uint(const uint value, const uint count) { assert(count < 8 * uint.sizeof); return cast(uint) ((value >> count) | (value << (uint.sizeof * 8 - count))); } __m128i _mm_sha256rnds2_epu32(__m128i a, __m128i b, __m128i k) { static uint Ch(uint x, uint y, uint z) { return z ^ (x & (y ^ z)); } static uint Maj(uint x, uint y, uint z) { return (x & y) | (z & (x ^ y)); } static uint sum0(uint x) { return bitwiseRotateRight_uint(x, 2) ^ bitwiseRotateRight_uint(x, 13) ^ bitwiseRotateRight_uint(x, 22); } static uint sum1(uint x) { return bitwiseRotateRight_uint(x, 6) ^ bitwiseRotateRight_uint(x, 11) ^ bitwiseRotateRight_uint(x, 25); } int4 dst; int4 a4 = cast(int4) a; int4 b4 = cast(int4) b; int4 k4 = cast(int4) k; const A0 = b4.array[3]; const B0 = b4.array[2]; const C0 = a4.array[3]; const D0 = a4.array[2]; const E0 = b4.array[1]; const F0 = b4.array[0]; const G0 = a4.array[1]; const H0 = a4.array[0]; const W_K0 = k4.array[0]; const W_K1 = k4.array[1]; const A1 = Ch(E0, F0, G0) + sum1(E0) + W_K0 + H0 + Maj(A0, B0, C0) + sum0(A0); const B1 = A0; const C1 = B0; const D1 = C0; const E1 = Ch(E0, F0, G0) + sum1(E0) + W_K0 + H0 + D0; const F1 = E0; const G1 = F0; const H1 = G0; const A2 = Ch(E1, F1, G1) + sum1(E1) + W_K1 + H1 + Maj(A1, B1, C1) + sum0(A1); const B2 = A1; const C2 = B1; const D2 = C1; const E2 = Ch(E1, F1, G1) + sum1(E1) + W_K1 + H1 + D1; const F2 = E1; const G2 = F1; const H2 = G1; dst.ptr[3] = A2; dst.ptr[2] = B2; dst.ptr[1] = E2; dst.ptr[0] = F2; return cast(__m128i) dst; } void main(string[] args) { __m128i a = [15, 20, 130, 12345]; __m128i b = [15, 20, 130, 12345]; __m128i k = [15, 20, 130, 12345]; __m128i result = _mm_sha256rnds2_epu32(a, b, k); assert(result.array == [1384123044, -2050674062, 327754346, 956342016]); } ----------------------- Crash it with dmd -O -inline, it won't pass the assertion. Result is a wrong value. Workarounds: - LDC - DMD without -O - DMD without -inline - pragma(inline, false) in the sub-functions This worked on DMD 2.095 to 2.097, so I labelled as regression. Thanks!!!!
Comment #1
by bugzilla — 2022-12-22T08:18:01Z
This works for me with the current master.
Comment #2
by dlang-bot — 2022-12-22T08:22:05Z
@WalterBright created dlang/dmd pull request #14733 "fix Issue 23307 - [REG][CODEGEN][SIMD] wrong codegen with inlined loc…" fixing this issue: - fix Issue 23307 - [REG][CODEGEN][SIMD] wrong codegen with inlined local functions + SIMD
https://github.com/dlang/dmd/pull/14733
Comment #3
by dlang-bot — 2022-12-22T09:52:54Z
dlang/dmd pull request #14733 "fix Issue 23307 - [REG][CODEGEN][SIMD] wrong codegen with inlined loc…" was merged into master: - 357c712b903c55b52099780caa7c9f5784cad494 by Walter Bright: fix Issue 23307 - [REG][CODEGEN][SIMD] wrong codegen with inlined local functions + SIMD
https://github.com/dlang/dmd/pull/14733