https://gcc.gnu.org/bugzilla/show_bug.cgi?id=127852
--- Comment #2 from Vineet Gupta <vineetg at gcc dot gnu.org> ---
(In reply to Roger Sayle from comment #1)
> Created attachment 65825 [details]
> proposed patch
>
> Proposed patch.
Thanks. Your two MINUS hunks match what I have, but the PLUS side needs the
same:
the (X - 1) * Y + Y and Y + (X - 1) * Y folds in the PLUS case of
simplify_binary_operation_1 aren't guarded.
-O2 on x86_64:
```
int xm1 (volatile int *p, int x)
{
int a = *p;
int b = *p;
return (x - 1) * a + b;
}
```
With your patch,
movl (%rdi), %eax
imull %esi, %eax
ret
so one of the two volatile reads is lost.
I also have a additional change replacing (!MEM_P (lhs) || !MEM_VOLATILE_P
(lhs)), with !side_effects_p (lhs) to match the others for consistency.