[PATCH] Fix PR 91708

Richard Biener richard.guenther@gmail.com
Wed Sep 11 15:38:00 GMT 2019


On September 11, 2019 4:41:10 PM GMT+02:00, Bernd Edlinger <bernd.edlinger@hotmail.de> wrote:
>On 9/11/19 3:55 PM, Richard Biener wrote:
>> On Wed, 11 Sep 2019, Bernd Edlinger wrote:
>> 
>>> On 9/11/19 9:23 AM, Richard Biener wrote:
>>>> On Tue, 10 Sep 2019, Bernd Edlinger wrote:
>>>>
>>>>> 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.
>>>>
>>>> I think the appropriate fix is to retain the mem_attrs of the
>original
>>>> MEM since obviously the replacement does not change those?  It's a
>mere
>>>> change of the MEMs address but implementation-wise CSE replaces the
>whole
>>>> MEM?
>>>>
>>>> For CSE exp_equiv_p simply compares the addresses, only if for_gcse
>>>> we do further checks like mem_attrs_eq_p.  IMHO that is correct.
>>>>
>>>> I'm not sure what CSE does above, that is, what does it think it
>does?
>>>> It doesn't replace the loaded value, it seems to do sth else which
>>>> is odd for CSE (replaces a REG with a PLUS - but why?)
>>>>  
>>>
>>> What I think CSE is thinking there is this:
>>>
>>> insn 181 stores the value of (reg:SI 320) at (mem:SI (reg:SI 319) [0
>MEM <charD.7[1:24]> [(voidD.73 *)r_77(D)]+0 S4 A8]
>>> that is the same address as where insn 234 reads the value back but
>there we know it is aligned.
>>>
>>> insn 186 stores the same value at (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]
>>>
>>> But since both reg:SI 320 is dead and reg:SI 319 is dead as well,
>when
>>> insn 234 processed, it replaces one mem with another mem that has
>the same
>>> value.
>> 
>> But why?  I see zero benefit doing that.  Note the addresses are
>equal,
>> so if it for some reason is beneficial CSE could still simply 
>> _preserve_ the original mem_attrs.
>> 
>
>Yes, but the addresses are simply *not* equal.
>
>--- cse.c.orig	2019-07-24 21:21:53.590065924 +0200
>+++ cse.c	2019-09-11 16:03:43.429236836 +0200
>@@ -4564,6 +4564,10 @@
>   else if (GET_CODE (x) == PARALLEL)
>     sets = XALLOCAVEC (struct set, XVECLEN (x, 0));
> 
>+  if (INSN_UID(insn) == 234 && GET_CODE(x) == SET
>+      && GET_CODE(SET_DEST(x)) == REG && REGNO(SET_DEST(x)) == 340
>+      && getenv("debug")) asm("int3");
>+
>   this_insn = insn;
>   /* Records what this insn does to set CC0.  */
>   this_insn_cc0 = 0;
>
>(gdb) n
>4809		elt = lookup (src, sets[i].src_hash, mode);
>(gdb) call debug(src)
>(mem:SI (reg/v/f:SI 273 [ r ]) [52 MEM <unsigned int> [(struct
>real_value *)r_77(D)]+0 S4 A32])
>(gdb) call dump_class(elt)
>Equivalence chain for (mem:SI (reg/v/f:SI 273 [ r ]) [0 MEM
><char[1:24]> [(void *)r_77(D)]+0 S4 A8]): 
>(unspec:SI [
>        (reg:SI 320)
>    ] UNSPEC_UNALIGNED_STORE)
>(mem:SI (plus:SI (reg/v/f:SI 273 [ r ])
>(const_int 20 [0x14])) [0 MEM <char[1:24]> [(void *)r_77(D)]+20 S4 A8])
>(mem:SI (plus:SI (reg/v/f:SI 273 [ r ])
>(const_int 16 [0x10])) [0 MEM <char[1:24]> [(void *)r_77(D)]+16 S4 A8])
>(mem:SI (plus:SI (reg/v/f:SI 273 [ r ])
> (const_int 12 [0xc])) [0 MEM <char[1:24]> [(void *)r_77(D)]+12 S4 A8])
>(mem:SI (plus:SI (reg/v/f:SI 273 [ r ])
>   (const_int 8 [0x8])) [0 MEM <char[1:24]> [(void *)r_77(D)]+8 S4 A8])
>(mem:SI (plus:SI (reg/v/f:SI 273 [ r ])
>   (const_int 4 [0x4])) [0 MEM <char[1:24]> [(void *)r_77(D)]+4 S4 A8])
>(mem:SI (reg/v/f:SI 273 [ r ]) [0 MEM <char[1:24]> [(void *)r_77(D)]+0
>S4 A8])
>
>[...]
>5393		  else if (validate_unshare_change (insn, &SET_SRC (sets[i].rtl),
>(gdb) call debug(insn)
>(insn 234 233 235 11 (set (reg:SI 340 [ MEM <unsigned int> [(struct
>real_value *)r_77(D)] ])
>(mem:SI (reg/v/f:SI 273 [ r ]) [52 MEM <unsigned int> [(struct
>real_value *)r_77(D)]+0 S4 A32])) "../../gcc-trunk-1/gcc/real.c":5185:9
>643 {*thumb2_movsi_vfp}
>     (nil))
>(gdb) call debug(trial)
>(mem:SI (plus:SI (reg/v/f:SI 273 [ r ])
>(const_int 20 [0x14])) [0 MEM <char[1:24]> [(void *)r_77(D)]+20 S4 A8])
>(gdb) n
>5396		      rtx new_rtx = canon_reg (SET_SRC (sets[i].rtl), insn);
>(gdb) call debug(insn)
>(insn 234 233 235 11 (set (reg:SI 340 [ MEM <unsigned int> [(struct
>real_value *)r_77(D)] ])
>        (mem:SI (plus:SI (reg/v/f:SI 273 [ r ])
>(const_int 20 [0x14])) [0 MEM <char[1:24]> [(void *)r_77(D)]+20 S4
>A8])) "../../gcc-trunk-1/gcc/real.c":5185:9 643 {*thumb2_movsi_vfp}
>     (nil))
>
>
>It  looks like it is designed to pick a different mem with a different
>address,
>but the same value.
>
>Right?

But the function you originally patched recursed into the MEM operands and thus the address, comparing them. So I conclude that CSE thinks they have the same value. 

Richard. 

>
>Bernd.



More information about the Gcc-patches mailing list