Hi: In general_operand, paradoxical subregs w/ outermode SCALAR_FLOAT_MODE_P are not allowed unless lra_in_progress, so this patch add the restriction to validate_subreg as well. Bootstrapped and regtested on x86_64-linux-gnu{-m32,} Also the newly added tests are compiled with aarch64-linux-gnu-gcc w/o ICE. Ok for trunk?
gcc/ChangeLog: PR middle-end/102254 PR middle-end/102154 * emit-rtl.c (validate_subreg): Disallow paradoxical subregs when omode is SCALAR_FLOAT_MODE_P. gcc/testsuite/ChangeLog: * gcc.target/i386/pr102254.c: New test. --- gcc/emit-rtl.c | 8 ++++++-- gcc/testsuite/gcc.target/i386/pr102254.c | 23 +++++++++++++++++++++++ 2 files changed, 29 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/gcc.target/i386/pr102254.c diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c index 77ea8948ee8..29fa29e1001 100644 --- a/gcc/emit-rtl.c +++ b/gcc/emit-rtl.c @@ -922,9 +922,13 @@ validate_subreg (machine_mode omode, machine_mode imode, poly_uint64 regsize = REGMODE_NATURAL_SIZE (imode); - /* Paradoxical subregs must have offset zero. */ + /* Paradoxical subregs must have offset zero and omode not + SCALAR_FLOAT_MODE_P. + i.e. things like (subreg:DF (reg:SF)) or (subreg:DF (reg:SI)) + are not allowed. */ if (maybe_gt (osize, isize)) - return known_eq (offset, 0U); + return known_eq (offset, 0U) + && (!SCALAR_FLOAT_MODE_P (omode) || lra_in_progress); /* This is a normal subreg. Verify that the offset is representable. */ diff --git a/gcc/testsuite/gcc.target/i386/pr102254.c b/gcc/testsuite/gcc.target/i386/pr102254.c new file mode 100644 index 00000000000..93d25c3d317 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr102254.c @@ -0,0 +1,23 @@ +/* { dg-do compile } */ +/* { dg-options "-Og" } */ + +#define MODFL __builtin_modfl +void +foo (void) +{ + int x; + *((double *) &x) = 0; +} + +void +foo1 (void) +{ + float x; + + *((double *) &x) = 0; +} + +void foo2() { + long iptrll; + MODFL(0.5l, (long double *)&iptrll); +} -- 2.27.0