From 59a47d7b6e63da780ed51e9b1c0c5d306d2a0564 Mon Sep 17 00:00:00 2001 From: Jonas Gorski Date: Tue, 30 Apr 2013 11:56:54 +0000 Subject: [PATCH] AA: toolchain: gcc: backport fixes for gcc bug 54295 Backport of r36486. Signed-off-by: Jonas Gorski SVN-Revision: 36500 --- .../4.6-linaro/020-gcc_bug_54295.patch | 70 +++++++++++++++++++ .../4.7-linaro/020-gcc_bug_54295.patch | 70 +++++++++++++++++++ .../gcc/patches/4.7.0/020-gcc_bug_54295.patch | 70 +++++++++++++++++++ 3 files changed, 210 insertions(+) create mode 100644 toolchain/gcc/patches/4.6-linaro/020-gcc_bug_54295.patch create mode 100644 toolchain/gcc/patches/4.7-linaro/020-gcc_bug_54295.patch create mode 100644 toolchain/gcc/patches/4.7.0/020-gcc_bug_54295.patch 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 0000000000..ef10571ca2 --- /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-02-07 11:33:31.000000000 +0100 ++++ b/gcc/tree-ssa-math-opts.c 2013-04-30 10:55:27.000000000 +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 0000000000..0c11b9a6f2 --- /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 2012-04-10 11:54:47.000000000 +0200 ++++ b/gcc/tree-ssa-math-opts.c 2013-04-30 10:57:13.000000000 +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 + { diff --git a/toolchain/gcc/patches/4.7.0/020-gcc_bug_54295.patch b/toolchain/gcc/patches/4.7.0/020-gcc_bug_54295.patch new file mode 100644 index 0000000000..404cb154f9 --- /dev/null +++ b/toolchain/gcc/patches/4.7.0/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-30 10:56:52.000000000 +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 + { -- 2.30.2