diff options
Diffstat (limited to 'toolchain/gcc/patches')
3 files changed, 210 insertions, 0 deletions
diff --git a/toolchain/gcc/patches/4.6-linaro/020-gcc_bug_54295.patch b/toolchain/gcc/patches/4.6-linaro/020-gcc_bug_54295.patch new file mode 100644 index 000000000..5bef9eab0 --- /dev/null +++ b/toolchain/gcc/patches/4.6-linaro/020-gcc_bug_54295.patch @@ -0,0 +1,70 @@ +diff -urN a/gcc/tree-ssa-math-opts.c b/gcc/tree-ssa-math-opts.c +--- a/gcc/tree-ssa-math-opts.c	2012-12-12 18:05:23.000000000 +0100 ++++ b/gcc/tree-ssa-math-opts.c	2013-04-29 15:54:00.051998936 +0200 +@@ -1280,6 +1280,47 @@ +   return result; + } +  ++/* Return true if stmt is a type conversion operation that can be stripped ++   when used in a widening multiply operation.  */ ++static bool ++widening_mult_conversion_strippable_p (tree result_type, gimple stmt) ++{ ++  enum tree_code rhs_code = gimple_assign_rhs_code (stmt); ++ ++  if (TREE_CODE (result_type) == INTEGER_TYPE) ++    { ++      tree op_type; ++      tree inner_op_type; ++ ++      if (!CONVERT_EXPR_CODE_P (rhs_code)) ++	return false; ++ ++      op_type = TREE_TYPE (gimple_assign_lhs (stmt)); ++ ++      /* If the type of OP has the same precision as the result, then ++	 we can strip this conversion.  The multiply operation will be ++	 selected to create the correct extension as a by-product.  */ ++      if (TYPE_PRECISION (result_type) == TYPE_PRECISION (op_type)) ++	return true; ++ ++      /* We can also strip a conversion if it preserves the signed-ness of ++	 the operation and doesn't narrow the range.  */ ++      inner_op_type = TREE_TYPE (gimple_assign_rhs1 (stmt)); ++ ++      /* If the inner-most type is unsigned, then we can strip any ++	 intermediate widening operation.  If it's signed, then the ++	 intermediate widening operation must also be signed.  */ ++      if ((TYPE_UNSIGNED (inner_op_type) ++	   || TYPE_UNSIGNED (op_type) == TYPE_UNSIGNED (inner_op_type)) ++	  && TYPE_PRECISION (op_type) > TYPE_PRECISION (inner_op_type)) ++	return true; ++ ++      return false; ++    } ++ ++  return rhs_code == FIXED_CONVERT_EXPR; ++} ++ + /* Return true if RHS is a suitable operand for a widening multiplication, +    assuming a target type of TYPE. +    There are two cases: +@@ -1296,17 +1337,13 @@ + { +   gimple stmt; +   tree type1, rhs1; +-  enum tree_code rhs_code; +  +   if (TREE_CODE (rhs) == SSA_NAME) +     { +       stmt = SSA_NAME_DEF_STMT (rhs); +       if (is_gimple_assign (stmt)) + 	{ +-	  rhs_code = gimple_assign_rhs_code (stmt); +-	  if (TREE_CODE (type) == INTEGER_TYPE +-	      ? !CONVERT_EXPR_CODE_P (rhs_code) +-	      : rhs_code != FIXED_CONVERT_EXPR) ++	  if (! widening_mult_conversion_strippable_p (type, stmt)) + 	    rhs1 = rhs; + 	  else + 	    { diff --git a/toolchain/gcc/patches/4.7-linaro/020-gcc_bug_54295.patch b/toolchain/gcc/patches/4.7-linaro/020-gcc_bug_54295.patch new file mode 100644 index 000000000..7ceda06c3 --- /dev/null +++ b/toolchain/gcc/patches/4.7-linaro/020-gcc_bug_54295.patch @@ -0,0 +1,70 @@ +diff -urN a/gcc/tree-ssa-math-opts.c b/gcc/tree-ssa-math-opts.c +--- a/gcc/tree-ssa-math-opts.c	2013-03-11 22:01:34.000000000 +0100 ++++ b/gcc/tree-ssa-math-opts.c	2013-04-29 15:55:34.906809377 +0200 +@@ -2007,6 +2007,47 @@ +  } + }; +  ++/* Return true if stmt is a type conversion operation that can be stripped ++   when used in a widening multiply operation.  */ ++static bool ++widening_mult_conversion_strippable_p (tree result_type, gimple stmt) ++{ ++  enum tree_code rhs_code = gimple_assign_rhs_code (stmt); ++ ++  if (TREE_CODE (result_type) == INTEGER_TYPE) ++    { ++      tree op_type; ++      tree inner_op_type; ++ ++      if (!CONVERT_EXPR_CODE_P (rhs_code)) ++	return false; ++ ++      op_type = TREE_TYPE (gimple_assign_lhs (stmt)); ++ ++      /* If the type of OP has the same precision as the result, then ++	 we can strip this conversion.  The multiply operation will be ++	 selected to create the correct extension as a by-product.  */ ++      if (TYPE_PRECISION (result_type) == TYPE_PRECISION (op_type)) ++	return true; ++ ++      /* We can also strip a conversion if it preserves the signed-ness of ++	 the operation and doesn't narrow the range.  */ ++      inner_op_type = TREE_TYPE (gimple_assign_rhs1 (stmt)); ++ ++      /* If the inner-most type is unsigned, then we can strip any ++	 intermediate widening operation.  If it's signed, then the ++	 intermediate widening operation must also be signed.  */ ++      if ((TYPE_UNSIGNED (inner_op_type) ++	   || TYPE_UNSIGNED (op_type) == TYPE_UNSIGNED (inner_op_type)) ++	  && TYPE_PRECISION (op_type) > TYPE_PRECISION (inner_op_type)) ++	return true; ++ ++      return false; ++    } ++ ++  return rhs_code == FIXED_CONVERT_EXPR; ++} ++ + /* Return true if RHS is a suitable operand for a widening multiplication, +    assuming a target type of TYPE. +    There are two cases: +@@ -2023,17 +2064,13 @@ + { +   gimple stmt; +   tree type1, rhs1; +-  enum tree_code rhs_code; +  +   if (TREE_CODE (rhs) == SSA_NAME) +     { +       stmt = SSA_NAME_DEF_STMT (rhs); +       if (is_gimple_assign (stmt)) + 	{ +-	  rhs_code = gimple_assign_rhs_code (stmt); +-	  if (TREE_CODE (type) == INTEGER_TYPE +-	      ? !CONVERT_EXPR_CODE_P (rhs_code) +-	      : rhs_code != FIXED_CONVERT_EXPR) ++	  if (! widening_mult_conversion_strippable_p (type, stmt)) + 	    rhs1 = rhs; + 	  else + 	    { diff --git a/toolchain/gcc/patches/4.7.2/020-gcc_bug_54295.patch b/toolchain/gcc/patches/4.7.2/020-gcc_bug_54295.patch new file mode 100644 index 000000000..0d519758a --- /dev/null +++ b/toolchain/gcc/patches/4.7.2/020-gcc_bug_54295.patch @@ -0,0 +1,70 @@ +diff -urN a/gcc/tree-ssa-math-opts.c b/gcc/tree-ssa-math-opts.c +--- a/gcc/tree-ssa-math-opts.c	2011-12-20 22:33:48.000000000 +0100 ++++ b/gcc/tree-ssa-math-opts.c	2013-04-29 16:39:54.413585206 +0200 +@@ -1968,6 +1968,47 @@ +  } + }; +  ++/* Return true if stmt is a type conversion operation that can be stripped ++   when used in a widening multiply operation.  */ ++static bool ++widening_mult_conversion_strippable_p (tree result_type, gimple stmt) ++{ ++  enum tree_code rhs_code = gimple_assign_rhs_code (stmt); ++ ++  if (TREE_CODE (result_type) == INTEGER_TYPE) ++    { ++      tree op_type; ++      tree inner_op_type; ++ ++      if (!CONVERT_EXPR_CODE_P (rhs_code)) ++	return false; ++ ++      op_type = TREE_TYPE (gimple_assign_lhs (stmt)); ++ ++      /* If the type of OP has the same precision as the result, then ++	 we can strip this conversion.  The multiply operation will be ++	 selected to create the correct extension as a by-product.  */ ++      if (TYPE_PRECISION (result_type) == TYPE_PRECISION (op_type)) ++	return true; ++ ++      /* We can also strip a conversion if it preserves the signed-ness of ++	 the operation and doesn't narrow the range.  */ ++      inner_op_type = TREE_TYPE (gimple_assign_rhs1 (stmt)); ++ ++      /* If the inner-most type is unsigned, then we can strip any ++	 intermediate widening operation.  If it's signed, then the ++	 intermediate widening operation must also be signed.  */ ++      if ((TYPE_UNSIGNED (inner_op_type) ++	   || TYPE_UNSIGNED (op_type) == TYPE_UNSIGNED (inner_op_type)) ++	  && TYPE_PRECISION (op_type) > TYPE_PRECISION (inner_op_type)) ++	return true; ++ ++      return false; ++    } ++ ++  return rhs_code == FIXED_CONVERT_EXPR; ++} ++ + /* Return true if RHS is a suitable operand for a widening multiplication, +    assuming a target type of TYPE. +    There are two cases: +@@ -1984,17 +2025,13 @@ + { +   gimple stmt; +   tree type1, rhs1; +-  enum tree_code rhs_code; +  +   if (TREE_CODE (rhs) == SSA_NAME) +     { +       stmt = SSA_NAME_DEF_STMT (rhs); +       if (is_gimple_assign (stmt)) + 	{ +-	  rhs_code = gimple_assign_rhs_code (stmt); +-	  if (TREE_CODE (type) == INTEGER_TYPE +-	      ? !CONVERT_EXPR_CODE_P (rhs_code) +-	      : rhs_code != FIXED_CONVERT_EXPR) ++	  if (! widening_mult_conversion_strippable_p (type, stmt)) + 	    rhs1 = rhs; + 	  else + 	    {  | 
