[Bug target/67351] Missed optimisation on 64-bit field compared to 32-bit

2015-08-26 Thread rguenth at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67351

Richard Biener rguenth at gcc dot gnu.org changed:

   What|Removed |Added

 Status|UNCONFIRMED |NEW
   Last reconfirmed||2015-08-26
 Ever confirmed|0   |1

--- Comment #6 from Richard Biener rguenth at gcc dot gnu.org ---
Yes,  N  N can be converted (but only for unsigned right shift or in VRP
with range information).  Convert the following fold-const.c code to match.pd:

  /* Transform (x  c)  c into x  (-1c), or transform (x  c)  c
 into x  ((unsigned)-1  c) for unsigned types.  */
  if (((code == LSHIFT_EXPR  TREE_CODE (arg0) == RSHIFT_EXPR)
   || (TYPE_UNSIGNED (type)
code == RSHIFT_EXPR  TREE_CODE (arg0) == LSHIFT_EXPR))
   tree_fits_uhwi_p (arg1)
   tree_to_uhwi (arg1)  prec
   tree_fits_uhwi_p (TREE_OPERAND (arg0, 1))
   tree_to_uhwi (TREE_OPERAND (arg0, 1))  prec)
{ 
  HOST_WIDE_INT low0 = tree_to_uhwi (TREE_OPERAND (arg0, 1));
  HOST_WIDE_INT low1 = tree_to_uhwi (arg1);
  tree lshift;
  tree arg00;

  if (low0 == low1)
{ 
  arg00 = fold_convert_loc (loc, type, TREE_OPERAND (arg0, 0));

  lshift = build_minus_one_cst (type);
  lshift = const_binop (code, lshift, arg1);

  return fold_build2_loc (loc, BIT_AND_EXPR, type, arg00, lshift);
}
}


[Bug target/67351] Missed optimisation on 64-bit field compared to 32-bit

2015-08-25 Thread ubizjak at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67351

Uroš Bizjak ubizjak at gmail dot com changed:

   What|Removed |Added

 CC||rguenth at gcc dot gnu.org,
   ||ubizjak at gmail dot com

--- Comment #3 from Uroš Bizjak ubizjak at gmail dot com ---
(In reply to Uroš Bizjak from comment #2)
 (In reply to Allan Jensen from comment #0)
 
  Gcc will expand and detect field setting on 32-bit integers, but for some
  reason miss the opportunity on 64-bit.
 
 The immediates for 64bit logic insns are limited to sign-extended 32bit
 values, so this probably limits combine to combine several insns into one.

One example is:

(insn 8 6 9 2 (parallel [
(set (reg:DI 100)
(lshiftrt:DI (reg/v:DI 98 [ a ])
(const_int 48 [0x30])))
(clobber (reg:CC 17 flags))
]) test.cpp:63 538 {*lshrdi3_1}
 (expr_list:REG_UNUSED (reg:CC 17 flags)
(nil)))
(insn 9 8 10 2 (parallel [
(set (reg:DI 101)
(ashift:DI (reg:DI 100)
(const_int 48 [0x30])))
(clobber (reg:CC 17 flags))
]) test.cpp:63 504 {*ashldi3_1}
 (expr_list:REG_DEAD (reg:DI 100)
(expr_list:REG_UNUSED (reg:CC 17 flags)
(nil

combine tries to:

Trying 8 - 9:
Failed to match this instruction:
(parallel [
(set (reg:DI 101)
(and:DI (reg/v:DI 98 [ a ])
(const_int -281474976710656 [0x])))
(clobber (reg:CC 17 flags))
])

However, tree optimizers pass to expand the following sequence:

  a = giveMe64 ();
  a$rgba_5 = MEM[(struct MyRgba64 *)a];
  _6 = a$rgba_5  16;
  _7 = a$rgba_5  48;
  _8 = _7  48;
  _10 = _6  16;
  _11 = _10  4294967295;
  _13 = a$rgba_5  65535;
  _15 = _13 | 264913582817280;
  _16 = _8 | _15;
  _14 = _11 | _16;
  MEM[(struct MyRgba64 *)D.2451] = _14;
  return D.2451;

Richi, can these shifts be converted to equivalent masking in tree optimizers?

[Bug target/67351] Missed optimisation on 64-bit field compared to 32-bit

2015-08-25 Thread pinskia at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67351

--- Comment #4 from Andrew Pinski pinskia at gcc dot gnu.org ---
(In reply to Uroš Bizjak from comment #3)
 (In reply to Uroš Bizjak from comment #2)
  (In reply to Allan Jensen from comment #0)
  
   Gcc will expand and detect field setting on 32-bit integers, but for some
   reason miss the opportunity on 64-bit.
  
  The immediates for 64bit logic insns are limited to sign-extended 32bit
  values, so this probably limits combine to combine several insns into one.
 
 One example is:
 
 (insn 8 6 9 2 (parallel [
 (set (reg:DI 100)
 (lshiftrt:DI (reg/v:DI 98 [ a ])
 (const_int 48 [0x30])))
 (clobber (reg:CC 17 flags))
 ]) test.cpp:63 538 {*lshrdi3_1}
  (expr_list:REG_UNUSED (reg:CC 17 flags)
 (nil)))
 (insn 9 8 10 2 (parallel [
 (set (reg:DI 101)
 (ashift:DI (reg:DI 100)
 (const_int 48 [0x30])))
 (clobber (reg:CC 17 flags))
 ]) test.cpp:63 504 {*ashldi3_1}
  (expr_list:REG_DEAD (reg:DI 100)
 (expr_list:REG_UNUSED (reg:CC 17 flags)
 (nil
 
 combine tries to:
 
 Trying 8 - 9:
 Failed to match this instruction:
 (parallel [
 (set (reg:DI 101)
 (and:DI (reg/v:DI 98 [ a ])
 (const_int -281474976710656 [0x])))
 (clobber (reg:CC 17 flags))
 ])
 
 However, tree optimizers pass to expand the following sequence:
 
   a = giveMe64 ();
   a$rgba_5 = MEM[(struct MyRgba64 *)a];
   _6 = a$rgba_5  16;
   _7 = a$rgba_5  48;
   _8 = _7  48;
   _10 = _6  16;
   _11 = _10  4294967295;
   _13 = a$rgba_5  65535;
   _15 = _13 | 264913582817280;
   _16 = _8 | _15;
   _14 = _11 | _16;
   MEM[(struct MyRgba64 *)D.2451] = _14;
   return D.2451;
 
 Richi, can these shifts be converted to equivalent masking in tree
 optimizers?


They should be or at least Naveen's patches should handle them.  There is an
open bug filed doing a  N  N and one filed for a  N  N already (I filed
it).

[Bug target/67351] Missed optimisation on 64-bit field compared to 32-bit

2015-08-25 Thread pinskia at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67351

--- Comment #5 from Andrew Pinski pinskia at gcc dot gnu.org ---
Oh his patch only handled multiplies/divide and not shifts.  But it should be
easy to add them to match.pd to simplify this at the tree level.


[Bug target/67351] Missed optimisation on 64-bit field compared to 32-bit

2015-08-25 Thread ubizjak at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67351

--- Comment #2 from Uroš Bizjak ubizjak at gmail dot com ---
(In reply to Allan Jensen from comment #0)

 Gcc will expand and detect field setting on 32-bit integers, but for some
 reason miss the opportunity on 64-bit.

The immediates for 64bit logic insns are limited to sign-extended 32bit values,
so this probably limits combine to combine several insns into one.