https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91510
Bug ID: 91510 Summary: r253207 fixed a wrong-code bug Product: gcc Version: 7.4.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: tree-optimization Assignee: unassigned at gcc dot gnu.org Reporter: rguenth at gcc dot gnu.org Target Milestone: --- For GCC 8, r253207 fixed a wrong-code bug with SRA where we end up using the 'double' member in union { unsigned long long int uint_val; long long int int_val; double double_val; }; to copy the aggregate which, when using x87 instructions fldl/fstpl can alter the bit-pattern. See also PR88240 for a related issue. It requires the correct amount of "luck" to hit, the following simplified testcase doesn't hit it: struct S { int key; union { unsigned long long int uint_val; long long int int_val; double double_val; } u; }; struct S get(); void copy (struct S *dst, struct S *src) { struct S tem = get (); switch (tem.key) { case 0: dst->u.uint_val = tem.u.uint_val; break; case 1: dst->u.int_val = tem.u.int_val; break; case 2: dst->u.double_val = tem.u.double_val; break; } dst->key = tem.key; } while from the full testcase the late SRA dump shows value_base* test(std::istream&) (struct istream & source) { + const double num$D37803$double_val; double D.44239; long long int D.44232; long long unsigned int D.44225; @@ -733,11 +743,12 @@ <bb 2> [100.00%]: num = parseNumber (source_5(D)); [return slot optimization] + num$D37803$double_val_52 = MEM[(struct number_t *)&num + 4B]; _1 = num.type; switch (_1) <default: <L3> [25.00%], case 0: <L14> [25.00%], case 1: <L20> [25.00%], case 2: <L26> [25.00%]> <L14> [25.00%]: - _30 = num.D.37803.uint_val; + _30 = VIEW_CONVERT_EXPR<long long unsigned int>(num$D37803$double_val_52); ... <L26> [25.00%]: - _50 = num.D.37803.double_val; + _50 = num$D37803$double_val_52;