Bug 6877 – [XMM] regression, clobbered float value

Status
RESOLVED
Resolution
FIXED
Severity
normal
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
x86_64
OS
Linux
Creation time
2011-11-01T16:04:00Z
Last change time
2011-11-01T21:19:12Z
Keywords
wrong-code
Assigned to
nobody
Creator
code

Comments

Comment #0 by code — 2011-11-01T16:04:48Z
struct Matrix { float[3][3] data; ref float[3] opIndex(size_t idx) { assert(0 <= idx && idx <= 2); return this.data[idx]; } static Matrix identityMatrix() { Matrix id; id.data[0][0] = 1.0f; id.data[0][1] = 0.0f; id.data[0][2] = 0.0f; id.data[1][0] = 0.0f; id.data[1][1] = 1.0f; id.data[1][2] = 0.0f; id.data[2][0] = 0.0f; id.data[2][1] = 0.0f; id.data[2][2] = 1.0f; return id; } void setRotate(float deg) { this = identityMatrix(); setSinCos(0.5f * deg, 0.2f * deg); } void setSinCos(float sinV, float cosV) { this[0][0] = cosV; this[0][1] = -sinV; // <- !!! BUG HERE BUG !!! // alternatively with this // *(cast(uint*)&(this[0][1])) = (*cast(uint*)&sinV) ^ 0x80000000; // thus it is not the OPneg that fails this[1][0] = sinV; this[1][1] = cosV; } } extern(C) int printf(in char* format, ...); void main() { Matrix m; m.setRotate(4); // should be -2 printf("%g\n", m.data[0][1]); } --- Needed Flags: -O -inline, NOT -release, compilation with config.fpxmmregs The is NaN where it should have been -2. I could not reduce this test case any further. This regression was introduced with: https://github.com/D-Programming-Language/dmd/commit/82b5c12653c16097426ce990ecacc97525666302
Comment #1 by code — 2011-11-01T19:28:58Z
struct Matrix { void setSinCos(float sinV) { // use parameter, so it becomes a register veriable a = sinV * sinV; // refer to value of parameter version (none) val = -sinV; else // which 'eleq' optimizes to *cast(uint*)&val = (*cast(uint*)&sinV) ^ 0x80000000; } float a, val; } extern(C) int printf(in char* format, ...); void main() { Matrix m; printf("%g\n", m.val); // indirect to prevent CTFE auto dg = &m.setSinCos; dg(2.0); printf("%g\n", m.val); } ----------------------------------------------------- sinV is a register variable residing in xmm2. The load for the left xor operand is done with mov %edx, %eax which should be movd %xmm2, %eax instead, same modrm though.
Comment #2 by bugzilla — 2011-11-01T21:19:12Z