Hi! This ICE happens when compiling real_nextafter in real.c. CSE sees this:
(insn 179 178 180 11 (set (reg:SI 319) (reg/v/f:SI 273 [ rD.73757 ])) "../../gcc-trunk-1/gcc/real.c":120:10 643 {*thumb2_movsi_vfp} (nil)) [...] (insn 181 180 182 11 (set (mem:SI (reg:SI 319) [0 MEM <charD.7[1:24]> [(voidD.73 *)r_77(D)]+0 S4 A8]) (unspec:SI [ (reg:SI 320) ] UNSPEC_UNALIGNED_STORE)) "../../gcc-trunk-1/gcc/real.c":120:10 129 {unaligned_storesi} (nil)) [...] (insn 186 185 187 11 (set (mem:SI (plus:SI (reg/v/f:SI 273 [ rD.73757 ]) (const_int 20 [0x14])) [0 MEM <charD.7[1:24]> [(voidD.73 *)r_77(D)]+20 S4 A8]) (unspec:SI [ (reg:SI 320) ] UNSPEC_UNALIGNED_STORE)) "../../gcc-trunk-1/gcc/real.c":120:10 129 {unaligned_storesi} (expr_list:REG_DEAD (reg:SI 320) (expr_list:REG_DEAD (reg/f:SI 319 [ rD.73757 ]) (nil)))) [...] (insn 234 233 235 11 (set (reg:SI 340) (mem:SI (reg/v/f:SI 273 [ rD.73757 ]) [52 MEM <unsigned int> [(struct real_valueD.28367 *)r_77(D)]+0 S4 A32])) "../../gcc-trunk-1/gcc/real.c":5185:9 643 {*thumb2_movsi_vfp} (nil)) ... and transforms insn 234 in an invalid insn: (insn 234 233 235 11 (set (reg:SI 340 [ MEM <unsigned int> [(struct real_valueD.28367 *)r_77(D)] ]) (mem:SI (plus:SI (reg/v/f:SI 273 [ rD.73757 ]) (const_int 20 [0x14])) [0 MEM <charD.7[1:24]> [(voidD.73 *)r_77(D)]+20 S4 A8])) "../../gcc-trunk-1/gcc/real.c":5185:9 643 {*thumb2_movsi_vfp} (nil)) which triggers the assertion in the arm back-end, because the MEM is not aligned. To fix that I changed exp_equiv_p to consider MEMs with different MEM_ALIGN or ALIAS_SET as different. This patch fixes the arm bootstrap for --with-cpu=cortex-a57 --with-mode=thumb --with-fpu=fp-armv8 --with-float=hard which I confirmed using a cross compiler. And it fixes the test case that is attached to the PR, but it is way too large for the test suite. Bootstrapped and reg-tested on x86_64-pc-linux-gnu. Is it OK for trunk? Thanks Bernd.
2019-09-10 Bernd Edlinger <bernd.edlin...@hotmail.de> PR middle-end/91708 * cse.c (exp_equiv_p): Consider MEMs with different alias set or alignment as different. --- gcc/cse.c.orig 2019-07-24 21:21:53.590065924 +0200 +++ gcc/cse.c 2019-09-10 16:15:37.899933738 +0200 @@ -2637,8 +2637,13 @@ exp_equiv_p (const_rtx x, const_rtx y, i if (GET_MODE (x) != GET_MODE (y)) return 0; - /* MEMs referring to different address space are not equivalent. */ - if (code == MEM && MEM_ADDR_SPACE (x) != MEM_ADDR_SPACE (y)) + /* MEMs referring to different address spaces are not equivalent. + MEMs with different alias sets are not equivalent either. + Also the MEM_ALIGN needs to be identical in order not to break + constraints of insn's that need certain alignment (see PR91708). */ + if (code == MEM && (MEM_ADDR_SPACE (x) != MEM_ADDR_SPACE (y) + || MEM_ALIAS_SET (x) != MEM_ALIAS_SET (y) + || MEM_ALIGN (x) != MEM_ALIGN (y))) return 0; switch (code)