020-gcc_bug_54295.patch 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. diff -urN a/gcc/tree-ssa-math-opts.c b/gcc/tree-ssa-math-opts.c
  2. --- a/gcc/tree-ssa-math-opts.c 2012-12-12 18:05:23.000000000 +0100
  3. +++ b/gcc/tree-ssa-math-opts.c 2013-04-29 15:54:00.051998936 +0200
  4. @@ -1280,6 +1280,47 @@
  5. return result;
  6. }
  7. +/* Return true if stmt is a type conversion operation that can be stripped
  8. + when used in a widening multiply operation. */
  9. +static bool
  10. +widening_mult_conversion_strippable_p (tree result_type, gimple stmt)
  11. +{
  12. + enum tree_code rhs_code = gimple_assign_rhs_code (stmt);
  13. +
  14. + if (TREE_CODE (result_type) == INTEGER_TYPE)
  15. + {
  16. + tree op_type;
  17. + tree inner_op_type;
  18. +
  19. + if (!CONVERT_EXPR_CODE_P (rhs_code))
  20. + return false;
  21. +
  22. + op_type = TREE_TYPE (gimple_assign_lhs (stmt));
  23. +
  24. + /* If the type of OP has the same precision as the result, then
  25. + we can strip this conversion. The multiply operation will be
  26. + selected to create the correct extension as a by-product. */
  27. + if (TYPE_PRECISION (result_type) == TYPE_PRECISION (op_type))
  28. + return true;
  29. +
  30. + /* We can also strip a conversion if it preserves the signed-ness of
  31. + the operation and doesn't narrow the range. */
  32. + inner_op_type = TREE_TYPE (gimple_assign_rhs1 (stmt));
  33. +
  34. + /* If the inner-most type is unsigned, then we can strip any
  35. + intermediate widening operation. If it's signed, then the
  36. + intermediate widening operation must also be signed. */
  37. + if ((TYPE_UNSIGNED (inner_op_type)
  38. + || TYPE_UNSIGNED (op_type) == TYPE_UNSIGNED (inner_op_type))
  39. + && TYPE_PRECISION (op_type) > TYPE_PRECISION (inner_op_type))
  40. + return true;
  41. +
  42. + return false;
  43. + }
  44. +
  45. + return rhs_code == FIXED_CONVERT_EXPR;
  46. +}
  47. +
  48. /* Return true if RHS is a suitable operand for a widening multiplication,
  49. assuming a target type of TYPE.
  50. There are two cases:
  51. @@ -1296,17 +1337,13 @@
  52. {
  53. gimple stmt;
  54. tree type1, rhs1;
  55. - enum tree_code rhs_code;
  56. if (TREE_CODE (rhs) == SSA_NAME)
  57. {
  58. stmt = SSA_NAME_DEF_STMT (rhs);
  59. if (is_gimple_assign (stmt))
  60. {
  61. - rhs_code = gimple_assign_rhs_code (stmt);
  62. - if (TREE_CODE (type) == INTEGER_TYPE
  63. - ? !CONVERT_EXPR_CODE_P (rhs_code)
  64. - : rhs_code != FIXED_CONVERT_EXPR)
  65. + if (! widening_mult_conversion_strippable_p (type, stmt))
  66. rhs1 = rhs;
  67. else
  68. {