diff options
Diffstat (limited to 'toolchain/gcc/patches/4.7-linaro/020-gcc_bug_54295.patch')
-rw-r--r-- | toolchain/gcc/patches/4.7-linaro/020-gcc_bug_54295.patch | 70 |
1 files changed, 70 insertions, 0 deletions
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 0000000..7ceda06 --- /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 + { |