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;