https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67218
Bug ID: 67218 Summary: Combine incorrectly folds (double) (float) (unsigned) Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: rtl-optimization Assignee: unassigned at gcc dot gnu.org Reporter: rsandifo at gcc dot gnu.org Target Milestone: --- simplify-rtx.c folds (double) (float) (some-int) into (double) (some-int) if it can prove that the intermediate (float) doesn't have any effect. This check is based on the number of known "sign bit copies", which inherently assumes a signed interpretation of (some-int) and is therefore only valid for FLOAT. For UNSIGNED_FLOAT we can end up treating a large unsigned value as fitting in a float. The following test case fails at -O and above on aarch64-linux-gnu because of this: extern void abort (void) __attribute__ ((noreturn)); double __attribute__ ((noinline, noclone)) foo (unsigned int x) { return (double) (float) (x | 0xffff0000); } int main () { if (foo (1) != 0x1.fffep31) abort (); return 0; }