From b6b198cac722a8dcaa046f0589fe2c2c7caa6a01 Mon Sep 17 00:00:00 2001 From: Jing Yu Date: Thu, 4 Nov 2010 17:50:54 -0700 Subject: Backport upstream 4.6 patches to fix 2 gcc bugs. Fix a bad interaction of inliner x return slot optimization x named value optimization Replace tst instruction with lsls for a single bit test Change-Id: I30c212d9e99c79eae182da66b97d9d9f4d738faf --- gcc-4.4.3/README.google | 12 ++ gcc-4.4.3/gcc/config/arm/thumb2.md | 123 +++++++++------------ gcc-4.4.3/gcc/testsuite/g++.dg/torture/pr45709-2.C | 20 ++++ gcc-4.4.3/gcc/testsuite/g++.dg/torture/pr45709.C | 19 ++++ gcc-4.4.3/gcc/tree-inline.c | 11 +- 5 files changed, 112 insertions(+), 73 deletions(-) create mode 100644 gcc-4.4.3/gcc/testsuite/g++.dg/torture/pr45709-2.C create mode 100644 gcc-4.4.3/gcc/testsuite/g++.dg/torture/pr45709.C diff --git a/gcc-4.4.3/README.google b/gcc-4.4.3/README.google index 83b757e21..bcb9ca671 100644 --- a/gcc-4.4.3/README.google +++ b/gcc-4.4.3/README.google @@ -2066,7 +2066,19 @@ gcc/config/arm/arm.h Owner: jingyu Status: keep it local +gcc/config/arm/thumb2.md + Replace tst instruction with lsls for a single bit test. + Owner: carrot + Status: back port of upstream GCC 4.6.0 patches 161344, 161929, 161930. + libiberty/getpagesize.c Local work around for building C++ library for Android toolchain. Owner: jingyu Status: keep it local + +gcc/testsuite/g++.dg/torture/pr45709-2.C +gcc/testsuite/g++.dg/torture/pr45709.C +gcc/tree-inline.c + Backport r164399 from upstream gcc-4_4-branch (b/3068369). + Owner: raksit + Status: In upstream branches 4.3 and onwards. diff --git a/gcc-4.4.3/gcc/config/arm/thumb2.md b/gcc-4.4.3/gcc/config/arm/thumb2.md index 085ce828a..2243172e6 100644 --- a/gcc-4.4.3/gcc/config/arm/thumb2.md +++ b/gcc-4.4.3/gcc/config/arm/thumb2.md @@ -1268,76 +1268,57 @@ (set_attr "length" "2")] ) -(define_insn "*thumb2_tlobits_cbranch" - [(set (pc) - (if_then_else - (match_operator 0 "equality_operator" - [(zero_extract:SI (match_operand:SI 1 "s_register_operand" "l,?h") - (match_operand:SI 2 "const_int_operand" "i,i") - (const_int 0)) - (const_int 0)]) - (label_ref (match_operand 3 "" "")) - (pc))) - (clobber (match_scratch:SI 4 "=l,X"))] - "TARGET_THUMB2" - "* - { - if (which_alternative == 0) - { - rtx op[3]; - op[0] = operands[4]; - op[1] = operands[1]; - op[2] = GEN_INT (32 - INTVAL (operands[2])); - - output_asm_insn (\"lsls\\t%0, %1, %2\", op); - switch (get_attr_length (insn)) - { - case 4: return \"b%d0\\t%l3\"; - case 6: return \"b%D0\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\"; - default: return \"b%D0\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\"; - } - } - else - { - rtx op[2]; - op[0] = operands[1]; - op[1] = GEN_INT ((1 << INTVAL (operands[2])) - 1); +(define_peephole2 + [(set (match_operand:CC_NOOV 0 "cc_register" "") + (compare:CC_NOOV (zero_extract:SI + (match_operand:SI 1 "low_register_operand" "") + (const_int 1) + (match_operand:SI 2 "const_int_operand" "")) + (const_int 0))) + (match_scratch:SI 3 "l") + (set (pc) + (if_then_else (match_operator:CC_NOOV 4 "equality_operator" + [(match_dup 0) (const_int 0)]) + (match_operand 5 "" "") + (match_operand 6 "" "")))] + "TARGET_THUMB2 + && (INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) < 32)" + [(parallel [(set (match_dup 0) + (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2)) + (const_int 0))) + (clobber (match_dup 3))]) + (set (pc) + (if_then_else (match_op_dup 4 [(match_dup 0) (const_int 0)]) + (match_dup 5) (match_dup 6)))] + " + operands[2] = GEN_INT (31 - INTVAL (operands[2])); + operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[4]) == NE ? LT : GE, + VOIDmode, operands[0], const0_rtx); + ") - output_asm_insn (\"tst\\t%0, %1\", op); - switch (get_attr_length (insn)) - { - case 6: return \"b%d0\\t%l3\"; - case 8: return \"b%D0\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\"; - default: return \"b%D0\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\"; - } - } - }" - [(set (attr "far_jump") - (if_then_else - (and (ge (minus (match_dup 3) (pc)) (const_int -2040)) - (le (minus (match_dup 3) (pc)) (const_int 2048))) - (const_string "no") - (const_string "yes"))) - (set (attr "length") - (if_then_else - (eq (symbol_ref ("which_alternative")) +(define_peephole2 + [(set (match_operand:CC_NOOV 0 "cc_register" "") + (compare:CC_NOOV (zero_extract:SI + (match_operand:SI 1 "low_register_operand" "") + (match_operand:SI 2 "const_int_operand" "") (const_int 0)) - (if_then_else - (and (ge (minus (match_dup 3) (pc)) (const_int -250)) - (le (minus (match_dup 3) (pc)) (const_int 256))) - (const_int 4) - (if_then_else - (and (ge (minus (match_dup 3) (pc)) (const_int -2040)) - (le (minus (match_dup 3) (pc)) (const_int 2048))) - (const_int 6) - (const_int 8))) - (if_then_else - (and (ge (minus (match_dup 3) (pc)) (const_int -250)) - (le (minus (match_dup 3) (pc)) (const_int 256))) - (const_int 6) - (if_then_else - (and (ge (minus (match_dup 3) (pc)) (const_int -2040)) - (le (minus (match_dup 3) (pc)) (const_int 2048))) - (const_int 8) - (const_int 10)))))] -) + (const_int 0))) + (match_scratch:SI 3 "l") + (set (pc) + (if_then_else (match_operator:CC_NOOV 4 "equality_operator" + [(match_dup 0) (const_int 0)]) + (match_operand 5 "" "") + (match_operand 6 "" "")))] + "TARGET_THUMB2 + && (INTVAL (operands[2]) > 0 && INTVAL (operands[2]) < 32)" + [(parallel [(set (match_dup 0) + (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2)) + (const_int 0))) + (clobber (match_dup 3))]) + (set (pc) + (if_then_else (match_op_dup 4 [(match_dup 0) (const_int 0)]) + (match_dup 5) (match_dup 6)))] + " + operands[2] = GEN_INT (32 - INTVAL (operands[2])); + ") + diff --git a/gcc-4.4.3/gcc/testsuite/g++.dg/torture/pr45709-2.C b/gcc-4.4.3/gcc/testsuite/g++.dg/torture/pr45709-2.C new file mode 100644 index 000000000..1f6a2344f --- /dev/null +++ b/gcc-4.4.3/gcc/testsuite/g++.dg/torture/pr45709-2.C @@ -0,0 +1,20 @@ +// { dg-do compile } + +struct Region { + int storage[4]; + int count; +}; +static inline Region subtract(int lhs) +{ + Region reg; + int* storage = reg.storage; + int* storage2 = reg.storage; + if (lhs > 0) + storage++, storage2--; + reg.count = storage - reg.storage + storage2 - reg.storage; + return reg; +} +void bar(int a) +{ + const Region copyBack(subtract(a)); +} diff --git a/gcc-4.4.3/gcc/testsuite/g++.dg/torture/pr45709.C b/gcc-4.4.3/gcc/testsuite/g++.dg/torture/pr45709.C new file mode 100644 index 000000000..1584ec76a --- /dev/null +++ b/gcc-4.4.3/gcc/testsuite/g++.dg/torture/pr45709.C @@ -0,0 +1,19 @@ +// { dg-do compile } + +struct Region { + int storage[4]; + int count; +}; +static inline Region subtract(int lhs) +{ + Region reg; + int* storage = reg.storage; + if (lhs > 0) + storage++; + reg.count = storage - reg.storage; + return reg; +} +void bar(int a) +{ + const Region copyBack(subtract(a)); +} diff --git a/gcc-4.4.3/gcc/tree-inline.c b/gcc-4.4.3/gcc/tree-inline.c index 579fd81fb..decae7a4c 100644 --- a/gcc-4.4.3/gcc/tree-inline.c +++ b/gcc-4.4.3/gcc/tree-inline.c @@ -1740,12 +1740,13 @@ copy_phis_for_bb (basic_block bb, copy_body_data *id) edge_iterator ei; gimple phi; gimple_stmt_iterator si; + edge new_edge; + bool inserted = false; for (si = gsi_start (phi_nodes (bb)); !gsi_end_p (si); gsi_next (&si)) { tree res, new_res; gimple new_phi; - edge new_edge; phi = gsi_stmt (si); res = PHI_RESULT (phi); @@ -1774,13 +1775,19 @@ copy_phis_for_bb (basic_block bb, copy_body_data *id) { gimple_seq stmts = NULL; new_arg = force_gimple_operand (new_arg, &stmts, true, NULL); - gsi_insert_seq_on_edge_immediate (new_edge, stmts); + gsi_insert_seq_on_edge (new_edge, stmts); + inserted = true; } add_phi_arg (new_phi, new_arg, new_edge, gimple_phi_arg_location_from_edge (phi, old_edge)); } } } + + /* Commit the delayed edge insertions. */ + if (inserted) + FOR_EACH_EDGE (new_edge, ei, new_bb->preds) + gsi_commit_one_edge_insert (new_edge, NULL); } -- cgit v1.2.3