diff mbox

Fix PR77916

Message ID 36e7b4de-3d53-88c8-7819-54a2dacca710@linux.vnet.ibm.com
State New
Headers show

Commit Message

Bill Schmidt Oct. 17, 2016, 10:23 p.m. UTC
Hi,

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77916 identifies a situation
where SLSR will ICE when exposed to a cast from integer to pointer.  This
is because we try to convert a PLUS_EXPR with an addend of -1 * S into a
MINUS_EXPR with a subtrahend of S, but the base operand is unexpectedly
of pointer type.  This patch recognizes when pointer arithmetic is taking
place and ensures that we use a POINTER_PLUS_EXPR at all such times.  In
the case of the PR, this occurs in the logic where the stride S is a known
constant value, but the same problem could occur when it is an SSA_NAME
without known value.  Both possibilities are handled here.

Fixing the code to ensure that the unknown stride case always uses an 
initializer for a negative increment allows us to remove the stopgap fix
added for PR77937 as well.

Bootstrapped and tested on powerpc64le-unknown-linux-gnu with no
regressions, committed.

Thanks,
Bill


[gcc]

2016-10-17  Bill Schmidt  <wschmidt@linux.vnet.ibm.com>

	PR tree-optimization/77916
	* gimple-ssa-strength-reduction.c (create_add_on_incoming_edge):
	Don't allow a MINUS_EXPR for pointer arithmetic for either known
	or unknown strides.
	(record_increment): Increments of -1 for unknown strides just use
	a multiply initializer like other negative values.
	(analyze_increments): Remove stopgap solution for -1 increment
	applied to pointer arithmetic.

[gcc/testsuite]

2016-10-17  Bill Schmidt  <wschmidt@linux.vnet.ibm.com>

	PR tree-optimization/77916
	* gcc.dg/torture/pr77916.c: New.

Comments

Markus Trippelsdorf Oct. 18, 2016, 3:13 a.m. UTC | #1
On 2016.10.17 at 17:23 -0500, Bill Schmidt wrote:
> Hi,
> 
> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77916 identifies a situation
> where SLSR will ICE when exposed to a cast from integer to pointer.  This
> is because we try to convert a PLUS_EXPR with an addend of -1 * S into a
> MINUS_EXPR with a subtrahend of S, but the base operand is unexpectedly
> of pointer type.  This patch recognizes when pointer arithmetic is taking
> place and ensures that we use a POINTER_PLUS_EXPR at all such times.  In
> the case of the PR, this occurs in the logic where the stride S is a known
> constant value, but the same problem could occur when it is an SSA_NAME
> without known value.  Both possibilities are handled here.
> 
> Fixing the code to ensure that the unknown stride case always uses an 
> initializer for a negative increment allows us to remove the stopgap fix
> added for PR77937 as well.
> 
> Bootstrapped and tested on powerpc64le-unknown-linux-gnu with no
> regressions, committed.

Perhaps you should consider building ffmpeg with -O3 -march=amdfam10 on
X86_64 before committing these patches, because you broke it for the
third time in the last couple of days.

markus@x4 ffmpeg % cat h264dsp.i
extern int fn2(int);
extern int fn3(int);
int a, b, c;
void fn1(long p1) {
  char *d;
  for (;; d += p1) {
    d[0] = fn2(1 >> c >> 1);
    fn2(c >> a);
    d[1] = fn3(d[1]) >> 1;
    d[6] = fn3(d[6] * b + 1) >> 1;
    d[7] = fn3(d[7] * b + 1) >> 1;
    d[8] = fn3(d[8] * b + 1) >> 1;
  }
}

markus@x4 ffmpeg % gcc -O3 -march=amdfam10 -c h264dsp.i
h264dsp.i: In function ‘fn1’:
h264dsp.i:4:6: internal compiler error: in replace_one_candidate, at gimple-ssa-strength-reduction.c:3375
 void fn1(long p1) {
      ^~~
0x12773a9 replace_one_candidate
        ../../gcc/gcc/gimple-ssa-strength-reduction.c:3375
0x127af77 replace_profitable_candidates
        ../../gcc/gcc/gimple-ssa-strength-reduction.c:3486
0x127aeeb replace_profitable_candidates
        ../../gcc/gcc/gimple-ssa-strength-reduction.c:3495
0x127f3ee analyze_candidates_and_replace
        ../../gcc/gcc/gimple-ssa-strength-reduction.c:3574
0x127f3ee execute
        ../../gcc/gcc/gimple-ssa-strength-reduction.c:3648
Markus Trippelsdorf Oct. 18, 2016, 3:18 a.m. UTC | #2
On 2016.10.18 at 05:13 +0200, Markus Trippelsdorf wrote:
> On 2016.10.17 at 17:23 -0500, Bill Schmidt wrote:
> > Hi,
> > 
> > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77916 identifies a situation
> > where SLSR will ICE when exposed to a cast from integer to pointer.  This
> > is because we try to convert a PLUS_EXPR with an addend of -1 * S into a
> > MINUS_EXPR with a subtrahend of S, but the base operand is unexpectedly
> > of pointer type.  This patch recognizes when pointer arithmetic is taking
> > place and ensures that we use a POINTER_PLUS_EXPR at all such times.  In
> > the case of the PR, this occurs in the logic where the stride S is a known
> > constant value, but the same problem could occur when it is an SSA_NAME
> > without known value.  Both possibilities are handled here.
> > 
> > Fixing the code to ensure that the unknown stride case always uses an 
> > initializer for a negative increment allows us to remove the stopgap fix
> > added for PR77937 as well.
> > 
> > Bootstrapped and tested on powerpc64le-unknown-linux-gnu with no
> > regressions, committed.
> 
> Perhaps you should consider building ffmpeg with -O3 -march=amdfam10 on
> X86_64 before committing these patches, because you broke it for the
> third time in the last couple of days.
> 
> markus@x4 ffmpeg % cat h264dsp.i
> extern int fn2(int);
> extern int fn3(int);
> int a, b, c;
> void fn1(long p1) {
>   char *d;
>   for (;; d += p1) {
>     d[0] = fn2(1 >> c >> 1);
>     fn2(c >> a);
>     d[1] = fn3(d[1]) >> 1;
>     d[6] = fn3(d[6] * b + 1) >> 1;
>     d[7] = fn3(d[7] * b + 1) >> 1;
>     d[8] = fn3(d[8] * b + 1) >> 1;
>   }
> }
> 
> markus@x4 ffmpeg % gcc -O3 -march=amdfam10 -c h264dsp.i
> h264dsp.i: In function ‘fn1’:
> h264dsp.i:4:6: internal compiler error: in replace_one_candidate, at gimple-ssa-strength-reduction.c:3375
>  void fn1(long p1) {
>       ^~~
> 0x12773a9 replace_one_candidate
>         ../../gcc/gcc/gimple-ssa-strength-reduction.c:3375
> 0x127af77 replace_profitable_candidates
>         ../../gcc/gcc/gimple-ssa-strength-reduction.c:3486
> 0x127aeeb replace_profitable_candidates
>         ../../gcc/gcc/gimple-ssa-strength-reduction.c:3495
> 0x127f3ee analyze_candidates_and_replace
>         ../../gcc/gcc/gimple-ssa-strength-reduction.c:3574
> 0x127f3ee execute
>         ../../gcc/gcc/gimple-ssa-strength-reduction.c:3648

Just figured out that this testcase is identical to:
gcc/testsuite/gcc.dg/torture/pr77937-2.c 

So please run the testsuite on X86_64 in the future.
Christophe Lyon Oct. 18, 2016, 9:19 a.m. UTC | #3
On 18 October 2016 at 05:18, Markus Trippelsdorf <markus@trippelsdorf.de> wrote:
> On 2016.10.18 at 05:13 +0200, Markus Trippelsdorf wrote:
>> On 2016.10.17 at 17:23 -0500, Bill Schmidt wrote:
>> > Hi,
>> >
>> > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77916 identifies a situation
>> > where SLSR will ICE when exposed to a cast from integer to pointer.  This
>> > is because we try to convert a PLUS_EXPR with an addend of -1 * S into a
>> > MINUS_EXPR with a subtrahend of S, but the base operand is unexpectedly
>> > of pointer type.  This patch recognizes when pointer arithmetic is taking
>> > place and ensures that we use a POINTER_PLUS_EXPR at all such times.  In
>> > the case of the PR, this occurs in the logic where the stride S is a known
>> > constant value, but the same problem could occur when it is an SSA_NAME
>> > without known value.  Both possibilities are handled here.
>> >
>> > Fixing the code to ensure that the unknown stride case always uses an
>> > initializer for a negative increment allows us to remove the stopgap fix
>> > added for PR77937 as well.
>> >
>> > Bootstrapped and tested on powerpc64le-unknown-linux-gnu with no
>> > regressions, committed.
>>
>> Perhaps you should consider building ffmpeg with -O3 -march=amdfam10 on
>> X86_64 before committing these patches, because you broke it for the
>> third time in the last couple of days.
>>
>> markus@x4 ffmpeg % cat h264dsp.i
>> extern int fn2(int);
>> extern int fn3(int);
>> int a, b, c;
>> void fn1(long p1) {
>>   char *d;
>>   for (;; d += p1) {
>>     d[0] = fn2(1 >> c >> 1);
>>     fn2(c >> a);
>>     d[1] = fn3(d[1]) >> 1;
>>     d[6] = fn3(d[6] * b + 1) >> 1;
>>     d[7] = fn3(d[7] * b + 1) >> 1;
>>     d[8] = fn3(d[8] * b + 1) >> 1;
>>   }
>> }
>>
>> markus@x4 ffmpeg % gcc -O3 -march=amdfam10 -c h264dsp.i
>> h264dsp.i: In function ‘fn1’:
>> h264dsp.i:4:6: internal compiler error: in replace_one_candidate, at gimple-ssa-strength-reduction.c:3375
>>  void fn1(long p1) {
>>       ^~~
>> 0x12773a9 replace_one_candidate
>>         ../../gcc/gcc/gimple-ssa-strength-reduction.c:3375
>> 0x127af77 replace_profitable_candidates
>>         ../../gcc/gcc/gimple-ssa-strength-reduction.c:3486
>> 0x127aeeb replace_profitable_candidates
>>         ../../gcc/gcc/gimple-ssa-strength-reduction.c:3495
>> 0x127f3ee analyze_candidates_and_replace
>>         ../../gcc/gcc/gimple-ssa-strength-reduction.c:3574
>> 0x127f3ee execute
>>         ../../gcc/gcc/gimple-ssa-strength-reduction.c:3648
>
> Just figured out that this testcase is identical to:
> gcc/testsuite/gcc.dg/torture/pr77937-2.c
>
> So please run the testsuite on X86_64 in the future.
>


I'm not sure whether Markus means that pr77937-2 fails since this commit?

I'm seeing ICEs on pr77937-2 on some arm targets:
http://people.linaro.org/~christophe.lyon/cross-validation/gcc/trunk/241285/report-build-info.html

but I'm not 100% sure it was caused by this patch (the regression
happened between
r241273 and r241285), I haven't looked in details yet.

Christophe

> --
> Markus
Markus Trippelsdorf Oct. 18, 2016, 9:31 a.m. UTC | #4
On 2016.10.18 at 11:19 +0200, Christophe Lyon wrote:
> On 18 October 2016 at 05:18, Markus Trippelsdorf <markus@trippelsdorf.de> wrote:
> > On 2016.10.18 at 05:13 +0200, Markus Trippelsdorf wrote:
> >> On 2016.10.17 at 17:23 -0500, Bill Schmidt wrote:
> >> > Hi,
> >> >
> >> > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77916 identifies a situation
> >> > where SLSR will ICE when exposed to a cast from integer to pointer.  This
> >> > is because we try to convert a PLUS_EXPR with an addend of -1 * S into a
> >> > MINUS_EXPR with a subtrahend of S, but the base operand is unexpectedly
> >> > of pointer type.  This patch recognizes when pointer arithmetic is taking
> >> > place and ensures that we use a POINTER_PLUS_EXPR at all such times.  In
> >> > the case of the PR, this occurs in the logic where the stride S is a known
> >> > constant value, but the same problem could occur when it is an SSA_NAME
> >> > without known value.  Both possibilities are handled here.
> >> >
> >> > Fixing the code to ensure that the unknown stride case always uses an
> >> > initializer for a negative increment allows us to remove the stopgap fix
> >> > added for PR77937 as well.
> >> >
> >> > Bootstrapped and tested on powerpc64le-unknown-linux-gnu with no
> >> > regressions, committed.
> >>
> >> Perhaps you should consider building ffmpeg with -O3 -march=amdfam10 on
> >> X86_64 before committing these patches, because you broke it for the
> >> third time in the last couple of days.
> >>
> >> markus@x4 ffmpeg % cat h264dsp.i
> >> extern int fn2(int);
> >> extern int fn3(int);
> >> int a, b, c;
> >> void fn1(long p1) {
> >>   char *d;
> >>   for (;; d += p1) {
> >>     d[0] = fn2(1 >> c >> 1);
> >>     fn2(c >> a);
> >>     d[1] = fn3(d[1]) >> 1;
> >>     d[6] = fn3(d[6] * b + 1) >> 1;
> >>     d[7] = fn3(d[7] * b + 1) >> 1;
> >>     d[8] = fn3(d[8] * b + 1) >> 1;
> >>   }
> >> }
> >>
> >> markus@x4 ffmpeg % gcc -O3 -march=amdfam10 -c h264dsp.i
> >> h264dsp.i: In function ‘fn1’:
> >> h264dsp.i:4:6: internal compiler error: in replace_one_candidate, at gimple-ssa-strength-reduction.c:3375
> >>  void fn1(long p1) {
> >>       ^~~
> >> 0x12773a9 replace_one_candidate
> >>         ../../gcc/gcc/gimple-ssa-strength-reduction.c:3375
> >> 0x127af77 replace_profitable_candidates
> >>         ../../gcc/gcc/gimple-ssa-strength-reduction.c:3486
> >> 0x127aeeb replace_profitable_candidates
> >>         ../../gcc/gcc/gimple-ssa-strength-reduction.c:3495
> >> 0x127f3ee analyze_candidates_and_replace
> >>         ../../gcc/gcc/gimple-ssa-strength-reduction.c:3574
> >> 0x127f3ee execute
> >>         ../../gcc/gcc/gimple-ssa-strength-reduction.c:3648
> >
> > Just figured out that this testcase is identical to:
> > gcc/testsuite/gcc.dg/torture/pr77937-2.c
> >
> > So please run the testsuite on X86_64 in the future.
> >
> 
> 
> I'm not sure whether Markus means that pr77937-2 fails since this
> commit?
> 
> I'm seeing ICEs on pr77937-2 on some arm targets:
> http://people.linaro.org/~christophe.lyon/cross-validation/gcc/trunk/241285/report-build-info.html
> 
> but I'm not 100% sure it was caused by this patch (the regression
> happened between r241273 and r241285), I haven't looked in details
> yet.

Yes, this is caused by this patch.
Bill Schmidt Oct. 18, 2016, 1:15 p.m. UTC | #5
On Tue, 2016-10-18 at 05:13 +0200, Markus Trippelsdorf wrote:
> On 2016.10.17 at 17:23 -0500, Bill Schmidt wrote:
> > Hi,
> > 
> > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77916 identifies a situation
> > where SLSR will ICE when exposed to a cast from integer to pointer.  This
> > is because we try to convert a PLUS_EXPR with an addend of -1 * S into a
> > MINUS_EXPR with a subtrahend of S, but the base operand is unexpectedly
> > of pointer type.  This patch recognizes when pointer arithmetic is taking
> > place and ensures that we use a POINTER_PLUS_EXPR at all such times.  In
> > the case of the PR, this occurs in the logic where the stride S is a known
> > constant value, but the same problem could occur when it is an SSA_NAME
> > without known value.  Both possibilities are handled here.
> > 
> > Fixing the code to ensure that the unknown stride case always uses an 
> > initializer for a negative increment allows us to remove the stopgap fix
> > added for PR77937 as well.
> > 
> > Bootstrapped and tested on powerpc64le-unknown-linux-gnu with no
> > regressions, committed.
> 
> Perhaps you should consider building ffmpeg with -O3 -march=amdfam10 on
> X86_64 before committing these patches, because you broke it for the
> third time in the last couple of days.

Sorry, sorry.  I did intend to build another stage1 cross and try this,
but it just slipped my mind.  Looks like I'll need to put the stopgap
fix back in.  I'll do that shortly.

Meantime, -fno-slsr is a workaround.  If I have trouble building ffmpeg
with a cross, I'll check with you on testing a future patch.

Bill

> 
> markus@x4 ffmpeg % cat h264dsp.i
> extern int fn2(int);
> extern int fn3(int);
> int a, b, c;
> void fn1(long p1) {
>   char *d;
>   for (;; d += p1) {
>     d[0] = fn2(1 >> c >> 1);
>     fn2(c >> a);
>     d[1] = fn3(d[1]) >> 1;
>     d[6] = fn3(d[6] * b + 1) >> 1;
>     d[7] = fn3(d[7] * b + 1) >> 1;
>     d[8] = fn3(d[8] * b + 1) >> 1;
>   }
> }
> 
> markus@x4 ffmpeg % gcc -O3 -march=amdfam10 -c h264dsp.i
> h264dsp.i: In function ‘fn1’:
> h264dsp.i:4:6: internal compiler error: in replace_one_candidate, at gimple-ssa-strength-reduction.c:3375
>  void fn1(long p1) {
>       ^~~
> 0x12773a9 replace_one_candidate
>         ../../gcc/gcc/gimple-ssa-strength-reduction.c:3375
> 0x127af77 replace_profitable_candidates
>         ../../gcc/gcc/gimple-ssa-strength-reduction.c:3486
> 0x127aeeb replace_profitable_candidates
>         ../../gcc/gcc/gimple-ssa-strength-reduction.c:3495
> 0x127f3ee analyze_candidates_and_replace
>         ../../gcc/gcc/gimple-ssa-strength-reduction.c:3574
> 0x127f3ee execute
>         ../../gcc/gcc/gimple-ssa-strength-reduction.c:3648
> 
> 
> 
>
Markus Trippelsdorf Oct. 18, 2016, 1:30 p.m. UTC | #6
On 2016.10.18 at 08:15 -0500, Bill Schmidt wrote:
> On Tue, 2016-10-18 at 05:13 +0200, Markus Trippelsdorf wrote:
> > On 2016.10.17 at 17:23 -0500, Bill Schmidt wrote:
> > > Hi,
> > > 
> > > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77916 identifies a situation
> > > where SLSR will ICE when exposed to a cast from integer to pointer.  This
> > > is because we try to convert a PLUS_EXPR with an addend of -1 * S into a
> > > MINUS_EXPR with a subtrahend of S, but the base operand is unexpectedly
> > > of pointer type.  This patch recognizes when pointer arithmetic is taking
> > > place and ensures that we use a POINTER_PLUS_EXPR at all such times.  In
> > > the case of the PR, this occurs in the logic where the stride S is a known
> > > constant value, but the same problem could occur when it is an SSA_NAME
> > > without known value.  Both possibilities are handled here.
> > > 
> > > Fixing the code to ensure that the unknown stride case always uses an 
> > > initializer for a negative increment allows us to remove the stopgap fix
> > > added for PR77937 as well.
> > > 
> > > Bootstrapped and tested on powerpc64le-unknown-linux-gnu with no
> > > regressions, committed.
> > 
> > Perhaps you should consider building ffmpeg with -O3 -march=amdfam10 on
> > X86_64 before committing these patches, because you broke it for the
> > third time in the last couple of days.
> 
> Sorry, sorry.  I did intend to build another stage1 cross and try this,
> but it just slipped my mind.  Looks like I'll need to put the stopgap
> fix back in.  I'll do that shortly.
> 
> Meantime, -fno-slsr is a workaround.  If I have trouble building ffmpeg
> with a cross, I'll check with you on testing a future patch.

I you wish I can send you a tarball with the preprocessed *.i files from
ffmpeg, so that you can use a stage1 cross on them.
Bill Schmidt Oct. 18, 2016, 1:47 p.m. UTC | #7
On Tue, 2016-10-18 at 15:30 +0200, Markus Trippelsdorf wrote:

> I you wish I can send you a tarball with the preprocessed *.i files from
> ffmpeg, so that you can use a stage1 cross on them.
> 

That would be very helpful, thanks!

Bill
diff mbox

Patch

Index: gcc/gimple-ssa-strength-reduction.c
===================================================================
--- gcc/gimple-ssa-strength-reduction.c	(revision 241245)
+++ gcc/gimple-ssa-strength-reduction.c	(working copy)
@@ -2154,35 +2154,41 @@  create_add_on_incoming_edge (slsr_cand_t c, tree b
   basis_type = TREE_TYPE (basis_name);
   lhs = make_temp_ssa_name (basis_type, NULL, "slsr");
 
+  /* Occasionally people convert integers to pointers without a 
+     cast, leading us into trouble if we aren't careful.  */
+  enum tree_code plus_code
+    = POINTER_TYPE_P (basis_type) ? POINTER_PLUS_EXPR : PLUS_EXPR;
+
   if (known_stride)
     {
       tree bump_tree;
-      enum tree_code code = PLUS_EXPR;
+      enum tree_code code = plus_code;
       widest_int bump = increment * wi::to_widest (c->stride);
-      if (wi::neg_p (bump))
+      if (wi::neg_p (bump) && !POINTER_TYPE_P (basis_type))
 	{
 	  code = MINUS_EXPR;
 	  bump = -bump;
 	}
 
-      bump_tree = wide_int_to_tree (basis_type, bump);
+      tree stride_type = POINTER_TYPE_P (basis_type) ? sizetype : basis_type;
+      bump_tree = wide_int_to_tree (stride_type, bump);
       new_stmt = gimple_build_assign (lhs, code, basis_name, bump_tree);
     }
   else
     {
       int i;
-      bool negate_incr = (!address_arithmetic_p && wi::neg_p (increment));
+      bool negate_incr = !POINTER_TYPE_P (basis_type) && wi::neg_p (increment);
       i = incr_vec_index (negate_incr ? -increment : increment);
       gcc_assert (i >= 0);
 
       if (incr_vec[i].initializer)
 	{
-	  enum tree_code code = negate_incr ? MINUS_EXPR : PLUS_EXPR;
+	  enum tree_code code = negate_incr ? MINUS_EXPR : plus_code;
 	  new_stmt = gimple_build_assign (lhs, code, basis_name,
 					  incr_vec[i].initializer);
 	}
       else if (increment == 1)
-	new_stmt = gimple_build_assign (lhs, PLUS_EXPR, basis_name, c->stride);
+	new_stmt = gimple_build_assign (lhs, plus_code, basis_name, c->stride);
       else if (increment == -1)
 	new_stmt = gimple_build_assign (lhs, MINUS_EXPR, basis_name,
 					c->stride);
@@ -2500,12 +2506,14 @@  record_increment (slsr_cand_t c, widest_int increm
       /* Optimistically record the first occurrence of this increment
 	 as providing an initializer (if it does); we will revise this
 	 opinion later if it doesn't dominate all other occurrences.
-         Exception:  increments of -1, 0, 1 never need initializers;
-	 and phi adjustments don't ever provide initializers.  */
+         Exception:  increments of 0, 1 never need initializers;
+	 and phi adjustments don't ever provide initializers.  Note
+         that we only will see an increment of -1 here for pointer
+	 arithmetic (otherwise we will have an initializer).  */
       if (c->kind == CAND_ADD
 	  && !is_phi_adjust
 	  && c->index == increment
-	  && (increment > 1 || increment < -1)
+	  && (increment > 1 || increment < 0)
 	  && (gimple_assign_rhs_code (c->cand_stmt) == PLUS_EXPR
 	      || gimple_assign_rhs_code (c->cand_stmt) == POINTER_PLUS_EXPR))
 	{
@@ -2819,11 +2827,6 @@  analyze_increments (slsr_cand_t first_dep, machine
 		   && !POINTER_TYPE_P (first_dep->cand_type)))
 	incr_vec[i].cost = COST_NEUTRAL;
 
-      /* FIXME: We don't handle pointers with a -1 increment yet.
-         They are usually unprofitable anyway.  */
-      else if (incr == -1 && POINTER_TYPE_P (first_dep->cand_type))
-	incr_vec[i].cost = COST_INFINITE;
-      
       /* FORNOW: If we need to add an initializer, give up if a cast from
 	 the candidate's type to its stride's type can lose precision.
 	 This could eventually be handled better by expressly retaining the
Index: gcc/testsuite/gcc.dg/torture/pr77916.c
===================================================================
--- gcc/testsuite/gcc.dg/torture/pr77916.c	(revision 0)
+++ gcc/testsuite/gcc.dg/torture/pr77916.c	(working copy)
@@ -0,0 +1,20 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O3 -Wno-int-conversion" } */
+
+/* PR77916: This failed with "error: invalid (pointer) operands to plus/minus"
+   after SLSR.  */
+
+typedef struct
+{
+  void *f1;
+} S;
+
+S *a;
+int b;
+
+void
+fn1 (void)
+{
+  for (; b; b++, a++)
+    a->f1 = b;
+}