http://gcc.gnu.org/bugzilla/show_bug.cgi?id=60930

--- Comment #8 from Bill Schmidt <wschmidt at gcc dot gnu.org> ---
Hi Richi,

What you suggest won't quite work, as the ctype just represents the type of the
base expression and not necessarily the type of the result.  (We're doing a
pure-forward analysis and don't know how the result will be used downstream.) 
It's common for the code we deal with here to multiply an unsigned value by a
negative number and then cast it to a sizetype as part of array addressing. 
The temp.ext () call would preclude optimizing that case.  So I think the
correct way to do this is as you specified but without that call to change the
value of temp.  I'll test that today.

An example test case where ctype is unsigned but negative address calculations 
are effectively used is gcc.dg/tree-ssa/slsr-8.c.  Prior to SLSR the code looks
like below:

;; Function f (f, funcdef_no=0, decl_uid=2213, symbol_order=0)

;; 1 loops found
;;
;; Loop 0
;;  header 0, latch 1
;;  depth 0, outer -1
;;  nodes: 0 1 2 3 4
;; 2 succs { 4 3 }
;; 3 succs { 4 }
;; 4 succs { 1 }
f (int s, int * c)
{
  int * x3;
  int * x2;
  int * x1;
  int a3;
  int a2;
  int a1;
  int * iftmp.0_1;
  long unsigned int _4;
  long unsigned int _5;
  sizetype _6;
  long unsigned int _10;
  long unsigned int _11;
  sizetype _12;
  long unsigned int _15;
  long unsigned int _16;
  sizetype _17;

  <bb 2>:
  a1_3 = s_2(D) * 2;
  _4 = (long unsigned int) a1_3;
  _5 = _4 * 4;
  _6 = -_5;
  x1_8 = c_7(D) + _6;
  a2_9 = s_2(D) * 4;
  _10 = (long unsigned int) a2_9;
  _11 = _10 * 4;
  _12 = -_11;
  x2_13 = c_7(D) + _12;
  if (x1_8 != 0B)
    goto <bb 4>;
  else
    goto <bb 3>;

  <bb 3>:
  a3_14 = s_2(D) * 6;
  _15 = (long unsigned int) a3_14;
  _16 = _15 * 4;
  _17 = -_16;
  x3_18 = c_7(D) + _17;

  <bb 4>:
  # iftmp.0_1 = PHI <x2_13(2), x3_18(3)>
  return iftmp.0_1;

}

With SLSR, we can get rid of some of the multiply/negate sequences and produce:

;; Function f (f, funcdef_no=0, decl_uid=2213, symbol_order=0)

Removing basic block 5
f (int s, int * c)
{
  int * x3;
  int * x2;
  int * x1;
  int a1;
  int * iftmp.0_1;
  long unsigned int _4;
  long unsigned int _5;
  sizetype _6;

  <bb 2>:
  a1_3 = s_2(D) * 2;
  _4 = (long unsigned int) a1_3;
  _5 = _4 * 4;
  _6 = -_5;
  x1_8 = c_7(D) + _6;
  x2_13 = x1_8 + _6;
  if (x1_8 != 0B)
    goto <bb 4>;
  else
    goto <bb 3>;

  <bb 3>:
  x3_18 = x2_13 + _6;

  <bb 4>:
  # iftmp.0_1 = PHI <x2_13(2), x3_18(3)>
  return iftmp.0_1;

}

Restricting the folded multiplicand to an unsigned type causes us to miss this
opportunity.

Reply via email to