diff options
author | Ulrich Weigand <Ulrich.Weigand@de.ibm.com> | 2008-07-21 21:26:37 +0000 |
---|---|---|
committer | Ulrich Weigand <Ulrich.Weigand@de.ibm.com> | 2008-07-21 21:26:37 +0000 |
commit | 01800875fc3d590722d0be2db95e159c9581e79c (patch) | |
tree | 8cd29d044deeee26792ca51ff9c93427bcd9e0fe | |
parent | 726b493c1b65045870597ab142d7de73704293cf (diff) |
Merge with gcc-4_3-branch up to revision 138037.
git-svn-id: https://gcc.gnu.org/svn/gcc/branches/cell-4_3-branch@138044 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | gcc/ChangeLog | 45 | ||||
-rw-r--r-- | gcc/DATESTAMP | 2 | ||||
-rw-r--r-- | gcc/config/m32c/m32c.c | 15 | ||||
-rw-r--r-- | gcc/config/sh/sh.h | 12 | ||||
-rw-r--r-- | gcc/config/spu/spu.md | 65 | ||||
-rw-r--r-- | gcc/cp/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/cp/call.c | 4 | ||||
-rw-r--r-- | gcc/expr.c | 6 | ||||
-rw-r--r-- | gcc/fortran/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/fortran/resolve.c | 44 | ||||
-rw-r--r-- | gcc/fwprop.c | 113 | ||||
-rw-r--r-- | gcc/omp-low.c | 1 | ||||
-rw-r--r-- | gcc/reload.c | 2 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 20 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/conversion/op5.C | 20 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/gomp/atomic-11.c | 17 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/pr35281.c | 19 | ||||
-rw-r--r-- | gcc/testsuite/gfortran.dg/used_types_20.f90 | 49 |
18 files changed, 361 insertions, 86 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 878b6792a71..2918d5d3085 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -17,6 +17,51 @@ (rs6000_cpu_cpp_builtins): Enable context-sensitive macros if not compiling an ISO C dialect. +2008-07-19 Ulrich Weigand <Ulrich.Weigand@de.ibm.com> + + * config/spu/spu.md ("div<mode>3"): Convert into expander, move + original insn and splitter contents into ... + ("*div<mode>3_fast"): ... this new pattern. Enable only if + flag_unsafe_math_optimizations. Add dummy scratch register. + ("*div<mode>3_adjusted"): New insn and splitter. Enable only if + !flag_unsafe_math_optimizations. Returns number with next + highest magnitude if this is still less or equal to the true + quotient in magnitude. + +2008-07-19 Jakub Jelinek <jakub@redhat.com> + + PR middle-end/36877 + * omp-low.c (expand_omp_atomic_fetch_op): Make sure the + return value of the builtin is ignored. + +2008-07-19 Joseph Myers <joseph@codesourcery.com> + + PR target/36780 + PR target/36827 + * reload.c (find_reloads_subreg_address): Only reload address if + reloaded == 0, not for reloaded != 1. + + Revert: + 2008-07-16 Joseph Myers <joseph@codesourcery.com> + * config/m32c/m32c.c (BIG_FB_ADJ): Move definition earlier. + (m32c_legitimate_address_p): Handle "++rii" addresses created by + m32c_legitimize_reload_address. + + 2008-07-15 Kaz Kojima <kkojima@gcc.gnu.org> + * config/sh/sh.h (GO_IF_LEGITIMATE_ADDRESS): Allow + (plus (plus (reg) (const_int)) (const_int)) when reload_in_progress. + +2008-07-18 Paolo Bonzini <bonzini@gnu.org> + + PR rtl-optimization/35281 + * expr.c (convert_move): Use a new pseudo for the intermediate + from_mode->word_mode result. + * fwprop.c (PR_CAN_APPEAR, PR_HANDLE_MEM): New. + (propagate_rtx_1): Handle PR_HANDLE_MEM. + (propagate_rtx): Pass PR_HANDLE_MEM if appropriate. + (varying_mem_p): Move above propagate_rtx. + (all_uses_available_at): Do not check MEMs. + 2008-07-17 Ulrich Weigand <Ulrich.Weigand@de.ibm.com> Backport from mainline: diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index bf4dc5b288f..10b4941f285 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20080717 +20080721 diff --git a/gcc/config/m32c/m32c.c b/gcc/config/m32c/m32c.c index 8e347deb52d..2b3bab54ffc 100644 --- a/gcc/config/m32c/m32c.c +++ b/gcc/config/m32c/m32c.c @@ -1777,8 +1777,6 @@ m32c_init_libfuncs (void) /* Addressing Modes */ -#define BIG_FB_ADJ 0 - /* Used by GO_IF_LEGITIMATE_ADDRESS. The r8c/m32c family supports a wide range of non-orthogonal addressing modes, including the ability to double-indirect on *some* of them. Not all insns @@ -1896,17 +1894,6 @@ m32c_legitimate_address_p (enum machine_mode mode, rtx x, int strict) return 0; } } - if (RTX_IS ("++rii")) - { - rtx reg = patternr[2]; - HOST_WIDE_INT offs = INTVAL (patternr[3]); - - /* Avoid reloads for addresses generated by - m32c_legitimize_reload_address being generated by - find_reloads_subreg_address. */ - if (REGNO (reg) == FB_REGNO && offs == -BIG_FB_ADJ) - return 1; - } return 0; } @@ -1954,6 +1941,8 @@ m32c_reg_ok_for_base_p (rtx x, int strict) frame, so the third case seems best. Note that we subtract the zero, but detect that in the addhi3 pattern. */ +#define BIG_FB_ADJ 0 + /* Implements LEGITIMIZE_ADDRESS. The only address we really have to worry about is frame base offsets, as $fb has a limited displacement range. We deal with this by attempting to reload $fb diff --git a/gcc/config/sh/sh.h b/gcc/config/sh/sh.h index 1c0db4b535f..2eb0a2276cb 100644 --- a/gcc/config/sh/sh.h +++ b/gcc/config/sh/sh.h @@ -2496,18 +2496,6 @@ struct sh_args { goto LABEL; \ } \ } \ - /* When reload in progress, find_reloads_subreg_address tries to \ - make a new reload for some types of address. Unfortunately it \ - generates wrong code on SH. See PR36780. The following is to \ - avoid this issue. */ \ - if (!TARGET_SHMEDIA && reload_in_progress \ - && GET_CODE (X) == PLUS \ - && (GET_MODE_SIZE (MODE) == 4 || GET_MODE_SIZE (MODE) == 8) \ - && GET_CODE (XEXP ((X), 0)) == PLUS \ - && GET_CODE (XEXP (XEXP ((X), 0), 1)) == CONST_INT \ - && BASE_REGISTER_RTX_P (XEXP (XEXP ((X), 0), 0)) \ - && GET_CODE (XEXP ((X), 1)) == CONST_INT) \ - goto LABEL; \ } /* Try machine-dependent ways of modifying an illegitimate address diff --git a/gcc/config/spu/spu.md b/gcc/config/spu/spu.md index a89ab15b953..8feeca451a5 100644 --- a/gcc/config/spu/spu.md +++ b/gcc/config/spu/spu.md @@ -1718,20 +1718,33 @@ [(set_attr "type" "multi0") (set_attr "length" "80")]) -(define_insn_and_split "div<mode>3" +(define_expand "div<mode>3" + [(parallel + [(set (match_operand:VSF 0 "spu_reg_operand" "") + (div:VSF (match_operand:VSF 1 "spu_reg_operand" "") + (match_operand:VSF 2 "spu_reg_operand" ""))) + (clobber (match_scratch:VSF 3 "")) + (clobber (match_scratch:VSF 4 "")) + (clobber (match_scratch:VSF 5 ""))])] + "" + "") + +(define_insn_and_split "*div<mode>3_fast" [(set (match_operand:VSF 0 "spu_reg_operand" "=r") (div:VSF (match_operand:VSF 1 "spu_reg_operand" "r") (match_operand:VSF 2 "spu_reg_operand" "r"))) (clobber (match_scratch:VSF 3 "=&r")) - (clobber (match_scratch:VSF 4 "=&r"))] - "" + (clobber (match_scratch:VSF 4 "=&r")) + (clobber (scratch:VSF))] + "flag_unsafe_math_optimizations" "#" "reload_completed" [(set (match_dup:VSF 0) (div:VSF (match_dup:VSF 1) (match_dup:VSF 2))) (clobber (match_dup:VSF 3)) - (clobber (match_dup:VSF 4))] + (clobber (match_dup:VSF 4)) + (clobber (scratch:VSF))] { emit_insn (gen_frest_<mode>(operands[3], operands[2])); emit_insn (gen_fi_<mode>(operands[3], operands[2], operands[3])); @@ -1741,6 +1754,50 @@ DONE; }) +(define_insn_and_split "*div<mode>3_adjusted" + [(set (match_operand:VSF 0 "spu_reg_operand" "=r") + (div:VSF (match_operand:VSF 1 "spu_reg_operand" "r") + (match_operand:VSF 2 "spu_reg_operand" "r"))) + (clobber (match_scratch:VSF 3 "=&r")) + (clobber (match_scratch:VSF 4 "=&r")) + (clobber (match_scratch:VSF 5 "=&r"))] + "!flag_unsafe_math_optimizations" + "#" + "reload_completed" + [(set (match_dup:VSF 0) + (div:VSF (match_dup:VSF 1) + (match_dup:VSF 2))) + (clobber (match_dup:VSF 3)) + (clobber (match_dup:VSF 4)) + (clobber (match_dup:VSF 5))] + { + emit_insn (gen_frest_<mode> (operands[3], operands[2])); + emit_insn (gen_fi_<mode> (operands[3], operands[2], operands[3])); + emit_insn (gen_mul<mode>3 (operands[4], operands[1], operands[3])); + emit_insn (gen_fnms_<mode> (operands[5], operands[4], operands[2], operands[1])); + emit_insn (gen_fma_<mode> (operands[3], operands[5], operands[3], operands[4])); + + /* Due to truncation error, the quotient result may be low by 1 ulp. + Conditionally add one if the estimate is too small in magnitude. */ + + emit_move_insn (gen_lowpart (<F2I>mode, operands[4]), + spu_const (<F2I>mode, 0x80000000ULL)); + emit_move_insn (gen_lowpart (<F2I>mode, operands[5]), + spu_const (<F2I>mode, 0x3f800000ULL)); + emit_insn (gen_selb (operands[5], operands[5], operands[1], operands[4])); + + emit_insn (gen_add<f2i>3 (gen_lowpart (<F2I>mode, operands[4]), + gen_lowpart (<F2I>mode, operands[3]), + spu_const (<F2I>mode, 1))); + emit_insn (gen_fnms_<mode> (operands[0], operands[2], operands[4], operands[1])); + emit_insn (gen_mul<mode>3 (operands[0], operands[0], operands[5])); + emit_insn (gen_cgt_<f2i> (gen_lowpart (<F2I>mode, operands[0]), + gen_lowpart (<F2I>mode, operands[0]), + spu_const (<F2I>mode, -1))); + emit_insn (gen_selb (operands[0], operands[3], operands[4], operands[0])); + DONE; + }) + ;; Taken from STI's gcc ;; Does not correctly handle INF or NAN. (define_expand "divdf3" diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 8a5004f74eb..951d38d2126 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2008-07-18 Dodji Seketeli <dseketel@redhat.com> + + PR c++/36407 + * gcc/cp/call.c (convert_like_real): Don't take the error code path + when a rvalue or base conversion has the bad_p field set. + 2008-07-07 Simon Martin <simartin@users.sourceforge.net> PR c++/34963 diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 023cb7bfff9..13560e21817 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -4354,7 +4354,9 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum, if (convs->bad_p && convs->kind != ck_user && convs->kind != ck_ambig - && convs->kind != ck_ref_bind) + && convs->kind != ck_ref_bind + && convs->kind != ck_rvalue + && convs->kind != ck_base) { conversion *t = convs; for (; t; t = convs->u.next) diff --git a/gcc/expr.c b/gcc/expr.c index e985e3c3990..5dd79d66ebe 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -552,15 +552,15 @@ convert_move (rtx to, rtx from, int unsignedp) && ((code = can_extend_p (to_mode, word_mode, unsignedp)) != CODE_FOR_nothing)) { + rtx word_to = gen_reg_rtx (word_mode); if (REG_P (to)) { if (reg_overlap_mentioned_p (to, from)) from = force_reg (from_mode, from); emit_insn (gen_rtx_CLOBBER (VOIDmode, to)); } - convert_move (gen_lowpart (word_mode, to), from, unsignedp); - emit_unop_insn (code, to, - gen_lowpart (word_mode, to), equiv_code); + convert_move (word_to, from, unsignedp); + emit_unop_insn (code, to, word_to, equiv_code); return; } diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index 67d4598ada1..de910ee28f3 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,10 @@ +2008-07-19 Paul Thomas <pault@gcc.gnu.org> + + PR fortran/36366 + * resolve.c (add_dt_to_dt_list): New function. + (resolve_fl_derived): Call new function for pointer components + and when derived type resolved. + 2008-07-17 Tobias Burnus <burnus@net-b.de> PR fortran/36824 diff --git a/gcc/fortran/resolve.c b/gcc/fortran/resolve.c index f897110510f..ceec21f4673 100644 --- a/gcc/fortran/resolve.c +++ b/gcc/fortran/resolve.c @@ -7467,13 +7467,33 @@ resolve_fl_procedure (gfc_symbol *sym, int mp_flag) } +/* Add a derived type to the dt_list. The dt_list is used in trans-types.c + to give all identical derived types the same backend_decl. */ +static void +add_dt_to_dt_list (gfc_symbol *derived) +{ + gfc_dt_list *dt_list; + + for (dt_list = gfc_derived_types; dt_list; dt_list = dt_list->next) + if (derived == dt_list->derived) + break; + + if (dt_list == NULL) + { + dt_list = gfc_get_dt_list (); + dt_list->next = gfc_derived_types; + dt_list->derived = derived; + gfc_derived_types = dt_list; + } +} + + /* Resolve the components of a derived type. */ static try resolve_fl_derived (gfc_symbol *sym) { gfc_component *c; - gfc_dt_list * dt_list; int i; for (c = sym->components; c != NULL; c = c->next) @@ -7525,6 +7545,16 @@ resolve_fl_derived (gfc_symbol *sym) return FAILURE; } + /* Ensure that all the derived type components are put on the + derived type list; even in formal namespaces, where derived type + pointer components might not have been declared. */ + if (c->ts.type == BT_DERIVED + && c->ts.derived + && c->ts.derived->components + && c->pointer + && sym != c->ts.derived) + add_dt_to_dt_list (c->ts.derived); + if (c->pointer || c->allocatable || c->as == NULL) continue; @@ -7546,17 +7576,7 @@ resolve_fl_derived (gfc_symbol *sym) } /* Add derived type to the derived type list. */ - for (dt_list = gfc_derived_types; dt_list; dt_list = dt_list->next) - if (sym == dt_list->derived) - break; - - if (dt_list == NULL) - { - dt_list = gfc_get_dt_list (); - dt_list->next = gfc_derived_types; - dt_list->derived = sym; - gfc_derived_types = dt_list; - } + add_dt_to_dt_list (sym); return SUCCESS; } diff --git a/gcc/fwprop.c b/gcc/fwprop.c index d43f43447e5..fa4281a0462 100644 --- a/gcc/fwprop.c +++ b/gcc/fwprop.c @@ -208,47 +208,76 @@ should_replace_address (rtx old, rtx new, enum machine_mode mode) return (gain > 0); } + +/* Flags for the last parameter of propagate_rtx_1. */ + +enum { + /* If PR_CAN_APPEAR is true, propagate_rtx_1 always returns true; + if it is false, propagate_rtx_1 returns false if, for at least + one occurrence OLD, it failed to collapse the result to a constant. + For example, (mult:M (reg:M A) (minus:M (reg:M B) (reg:M A))) may + collapse to zero if replacing (reg:M B) with (reg:M A). + + PR_CAN_APPEAR is disregarded inside MEMs: in that case, + propagate_rtx_1 just tries to make cheaper and valid memory + addresses. */ + PR_CAN_APPEAR = 1, + + /* If PR_HANDLE_MEM is not set, propagate_rtx_1 won't attempt any replacement + outside memory addresses. This is needed because propagate_rtx_1 does + not do any analysis on memory; thus it is very conservative and in general + it will fail if non-read-only MEMs are found in the source expression. + + PR_HANDLE_MEM is set when the source of the propagation was not + another MEM. Then, it is safe not to treat non-read-only MEMs as + ``opaque'' objects. */ + PR_HANDLE_MEM = 2, +}; + + /* Replace all occurrences of OLD in *PX with NEW and try to simplify the resulting expression. Replace *PX with a new RTL expression if an occurrence of OLD was found. - If CAN_APPEAR is true, we always return true; if it is false, we - can return false if, for at least one occurrence OLD, we failed to - collapse the result to a constant. For example, (mult:M (reg:M A) - (minus:M (reg:M B) (reg:M A))) may collapse to zero if replacing - (reg:M B) with (reg:M A). - - CAN_APPEAR is disregarded inside MEMs: in that case, we always return - true if the simplification is a cheaper and valid memory address. - This is only a wrapper around simplify-rtx.c: do not add any pattern matching code here. (The sole exception is the handling of LO_SUM, but that is because there is no simplify_gen_* function for LO_SUM). */ static bool -propagate_rtx_1 (rtx *px, rtx old, rtx new, bool can_appear) +propagate_rtx_1 (rtx *px, rtx old, rtx new, int flags) { rtx x = *px, tem = NULL_RTX, op0, op1, op2; enum rtx_code code = GET_CODE (x); enum machine_mode mode = GET_MODE (x); enum machine_mode op_mode; + bool can_appear = (flags & PR_CAN_APPEAR) != 0; bool valid_ops = true; - /* If X is OLD_RTX, return NEW_RTX. Otherwise, if this is an expression, - try to build a new expression from recursive substitution. */ + if (!(flags & PR_HANDLE_MEM) && MEM_P (x) && !MEM_READONLY_P (x)) + { + /* If unsafe, change MEMs to CLOBBERs or SCRATCHes (to preserve whether + they have side effects or not). */ + *px = (side_effects_p (x) + ? gen_rtx_CLOBBER (GET_MODE (x), const0_rtx) + : gen_rtx_SCRATCH (GET_MODE (x))); + return false; + } + /* If X is OLD_RTX, return NEW_RTX. But not if replacing only within an + address, and we are *not* inside one. */ if (x == old) { *px = new; return can_appear; } + /* If this is an expression, try recursive substitution. */ switch (GET_RTX_CLASS (code)) { case RTX_UNARY: op0 = XEXP (x, 0); op_mode = GET_MODE (op0); - valid_ops &= propagate_rtx_1 (&op0, old, new, can_appear); + valid_ops &= propagate_rtx_1 (&op0, old, new, flags); if (op0 == XEXP (x, 0)) return true; tem = simplify_gen_unary (code, mode, op0, op_mode); @@ -258,8 +287,8 @@ propagate_rtx_1 (rtx *px, rtx old, rtx new, bool can_appear) case RTX_COMM_ARITH: op0 = XEXP (x, 0); op1 = XEXP (x, 1); - valid_ops &= propagate_rtx_1 (&op0, old, new, can_appear); - valid_ops &= propagate_rtx_1 (&op1, old, new, can_appear); + valid_ops &= propagate_rtx_1 (&op0, old, new, flags); + valid_ops &= propagate_rtx_1 (&op1, old, new, flags); if (op0 == XEXP (x, 0) && op1 == XEXP (x, 1)) return true; tem = simplify_gen_binary (code, mode, op0, op1); @@ -270,8 +299,8 @@ propagate_rtx_1 (rtx *px, rtx old, rtx new, bool can_appear) op0 = XEXP (x, 0); op1 = XEXP (x, 1); op_mode = GET_MODE (op0) != VOIDmode ? GET_MODE (op0) : GET_MODE (op1); - valid_ops &= propagate_rtx_1 (&op0, old, new, can_appear); - valid_ops &= propagate_rtx_1 (&op1, old, new, can_appear); + valid_ops &= propagate_rtx_1 (&op0, old, new, flags); + valid_ops &= propagate_rtx_1 (&op1, old, new, flags); if (op0 == XEXP (x, 0) && op1 == XEXP (x, 1)) return true; tem = simplify_gen_relational (code, mode, op_mode, op0, op1); @@ -283,9 +312,9 @@ propagate_rtx_1 (rtx *px, rtx old, rtx new, bool can_appear) op1 = XEXP (x, 1); op2 = XEXP (x, 2); op_mode = GET_MODE (op0); - valid_ops &= propagate_rtx_1 (&op0, old, new, can_appear); - valid_ops &= propagate_rtx_1 (&op1, old, new, can_appear); - valid_ops &= propagate_rtx_1 (&op2, old, new, can_appear); + valid_ops &= propagate_rtx_1 (&op0, old, new, flags); + valid_ops &= propagate_rtx_1 (&op1, old, new, flags); + valid_ops &= propagate_rtx_1 (&op2, old, new, flags); if (op0 == XEXP (x, 0) && op1 == XEXP (x, 1) && op2 == XEXP (x, 2)) return true; if (op_mode == VOIDmode) @@ -298,7 +327,7 @@ propagate_rtx_1 (rtx *px, rtx old, rtx new, bool can_appear) if (code == SUBREG) { op0 = XEXP (x, 0); - valid_ops &= propagate_rtx_1 (&op0, old, new, can_appear); + valid_ops &= propagate_rtx_1 (&op0, old, new, flags); if (op0 == XEXP (x, 0)) return true; tem = simplify_gen_subreg (mode, op0, GET_MODE (SUBREG_REG (x)), @@ -317,7 +346,8 @@ propagate_rtx_1 (rtx *px, rtx old, rtx new, bool can_appear) return true; op0 = new_op0 = targetm.delegitimize_address (op0); - valid_ops &= propagate_rtx_1 (&new_op0, old, new, true); + valid_ops &= propagate_rtx_1 (&new_op0, old, new, + flags | PR_CAN_APPEAR); /* Dismiss transformation that we do not want to carry on. */ if (!valid_ops @@ -344,8 +374,8 @@ propagate_rtx_1 (rtx *px, rtx old, rtx new, bool can_appear) /* The only simplification we do attempts to remove references to op0 or make it constant -- in both cases, op0's invalidity will not make the result invalid. */ - propagate_rtx_1 (&op0, old, new, true); - valid_ops &= propagate_rtx_1 (&op1, old, new, can_appear); + propagate_rtx_1 (&op0, old, new, flags | PR_CAN_APPEAR); + valid_ops &= propagate_rtx_1 (&op1, old, new, flags); if (op0 == XEXP (x, 0) && op1 == XEXP (x, 1)) return true; @@ -387,6 +417,18 @@ propagate_rtx_1 (rtx *px, rtx old, rtx new, bool can_appear) return valid_ops || can_appear || CONSTANT_P (tem); } + +/* for_each_rtx traversal function that returns 1 if BODY points to + a non-constant mem. */ + +static int +varying_mem_p (rtx *body, void *data ATTRIBUTE_UNUSED) +{ + rtx x = *body; + return MEM_P (x) && !MEM_READONLY_P (x); +} + + /* Replace all occurrences of OLD in X with NEW and try to simplify the resulting expression (in mode MODE). Return a new expression if it is a constant, otherwise X. @@ -400,14 +442,19 @@ propagate_rtx (rtx x, enum machine_mode mode, rtx old, rtx new) { rtx tem; bool collapsed; + int flags; if (REG_P (new) && REGNO (new) < FIRST_PSEUDO_REGISTER) return NULL_RTX; - new = copy_rtx (new); + flags = 0; + if (REG_P (new) || CONSTANT_P (new)) + flags |= PR_CAN_APPEAR; + if (!for_each_rtx (&new, varying_mem_p, NULL)) + flags |= PR_HANDLE_MEM; tem = x; - collapsed = propagate_rtx_1 (&tem, old, new, REG_P (new) || CONSTANT_P (new)); + collapsed = propagate_rtx_1 (&tem, old, copy_rtx (new), flags); if (tem == x || !collapsed) return NULL_RTX; @@ -521,16 +568,6 @@ use_killed_between (struct df_ref *use, rtx def_insn, rtx target_insn) } -/* for_each_rtx traversal function that returns 1 if BODY points to - a non-constant mem. */ - -static int -varying_mem_p (rtx *body, void *data ATTRIBUTE_UNUSED) -{ - rtx x = *body; - return MEM_P (x) && !MEM_READONLY_P (x); -} - /* Check if all uses in DEF_INSN can be used in TARGET_INSN. This would require full computation of available expressions; we check only restricted conditions, see use_killed_between. */ @@ -582,9 +619,7 @@ all_uses_available_at (rtx def_insn, rtx target_insn) } } - /* We don't do any analysis of memories or aliasing. Reject any - instruction that involves references to non-constant memory. */ - return !for_each_rtx (&SET_SRC (def_set), varying_mem_p, NULL); + return true; } diff --git a/gcc/omp-low.c b/gcc/omp-low.c index 0480e1222c2..3af5017d327 100644 --- a/gcc/omp-low.c +++ b/gcc/omp-low.c @@ -3757,6 +3757,7 @@ expand_omp_atomic_fetch_op (basic_block load_bb, bsi = bsi_last (load_bb); gcc_assert (TREE_CODE (bsi_stmt (bsi)) == OMP_ATOMIC_LOAD); call = build_call_expr (decl, 2, addr, fold_convert (itype, rhs)); + call = fold_convert (void_type_node, call); force_gimple_operand_bsi (&bsi, call, true, NULL_TREE, true, BSI_SAME_STMT); bsi_remove (&bsi, true); diff --git a/gcc/reload.c b/gcc/reload.c index 830a8f383fd..8940fb58251 100644 --- a/gcc/reload.c +++ b/gcc/reload.c @@ -6090,7 +6090,7 @@ find_reloads_subreg_address (rtx x, int force_replace, int opnum, doesn't find any, then we may have just converted a valid address into an invalid one. Check for that here. */ - if (reloaded != 1 + if (reloaded == 0 && !strict_memory_address_p (GET_MODE (tem), XEXP (tem, 0))) push_reload (XEXP (tem, 0), NULL_RTX, &XEXP (tem, 0), (rtx*) 0, diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 70e654bd2e6..1f09b724e0d 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -11,6 +11,26 @@ * gcc.dg/vmx/1b-06-ansi.c: New test for the pre-define method. * gcc.dg/vmx/1b-07-ansi.c: Likewise. +2008-07-19 Jakub Jelinek <jakub@redhat.com> + + PR middle-end/36877 + * gcc.dg/gomp/atomic-11.c: New test. + +2008-07-19 Paul Thomas <pault@gcc.gnu.org> + + PR fortran/36366 + * gfortran.dg/used_types_20.f90: New test. + +2008-07-18 Dodji Seketeli <dseketel@redhat.com> + + PR c++/36407 + * g++.dg/conversion/op5.C: New testcase. + +2008-07-18 Paolo Bonzini <bonzini@gnu.org> + + PR rtl-optimization/35281 + * gcc.target/i386/pr35281.c: New. + 2008-07-17 Ulrich Weigand <Ulrich.Weigand@de.ibm.com> Backport from mainline: diff --git a/gcc/testsuite/g++.dg/conversion/op5.C b/gcc/testsuite/g++.dg/conversion/op5.C new file mode 100644 index 00000000000..69ef996d5c2 --- /dev/null +++ b/gcc/testsuite/g++.dg/conversion/op5.C @@ -0,0 +1,20 @@ +// Contributed by Dodji Seketeli <dseketel@redhat.com> +// Origin: PR c++/36407 +// { dg-do compile } + +struct A +{ + A (const A&); +}; + +struct B +{ + operator A&(); +}; + +void +foo (const B& b) +{ + const A a = b; // { dg-error "conversion from 'const B' to non-scalar type 'const A' requested" } +} + diff --git a/gcc/testsuite/gcc.dg/gomp/atomic-11.c b/gcc/testsuite/gcc.dg/gomp/atomic-11.c new file mode 100644 index 00000000000..397972b3cf2 --- /dev/null +++ b/gcc/testsuite/gcc.dg/gomp/atomic-11.c @@ -0,0 +1,17 @@ +/* PR middle-end/36877 */ +/* { dg-do compile } */ +/* { dg-options "-fopenmp" } */ +/* { dg-options "-fopenmp -march=i386" { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */ + +int i; +float f; + +void foo (void) +{ +#pragma omp atomic + i++; +#pragma omp atomic + f += 1.0; +} + +/* { dg-final { scan-assembler-not "__sync_(fetch|add|bool|val)" { target i?86-*-* x86_64-*-* powerpc*-*-* ia64-*-* s390*-*-* sparc*-*-* } } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr35281.c b/gcc/testsuite/gcc.target/i386/pr35281.c new file mode 100644 index 00000000000..70e93cbeac0 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr35281.c @@ -0,0 +1,19 @@ +/* { dg-options "-O2" } */ +/* { dg-do compile } */ +/* { dg-require-effective-target ilp32 } */ + +unsigned long long a; +unsigned int b; +unsigned short c; + +unsigned long long mul32() +{ + return a * b; +} + +unsigned long long mul16() +{ + return a * c; +} + +/* { dg-final { scan-assembler-not "xor" } } */ diff --git a/gcc/testsuite/gfortran.dg/used_types_20.f90 b/gcc/testsuite/gfortran.dg/used_types_20.f90 new file mode 100644 index 00000000000..c08235c67f2 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/used_types_20.f90 @@ -0,0 +1,49 @@ +! { dg-do compile } +! Tests the fix for PR36366 a regression in which the order of USE statements +! in 'test2' would cause the result of 'test1' not to have a reference to +! the derived type 'inner'. +! +! Contributed by Jakub Jelinek <jakub@gcc.gnu.org> +! +MODULE types + IMPLICIT NONE + TYPE :: inner + INTEGER, POINTER :: i(:) + END TYPE inner + + TYPE :: outer + TYPE(inner), POINTER :: inr(:) + END TYPE outer +END MODULE types + +MODULE mymod + IMPLICIT NONE +CONTAINS + FUNCTION test1() + USE types + IMPLICIT NONE + TYPE(outer), POINTER :: test1 + NULLIFY(test1) + END FUNCTION test1 +END MODULE mymod + +MODULE test + IMPLICIT NONE +CONTAINS + + SUBROUTINE test2(a) + USE mymod + USE types + IMPLICIT NONE + TYPE(outer), INTENT(INOUT) :: a + INTEGER :: i + i = a%inr(1)%i(1) + END SUBROUTINE test2 + + SUBROUTINE test3(a) + USE types + IMPLICIT NONE + TYPE(outer), INTENT(IN) :: a + END SUBROUTINE test3 +END MODULE test +! { dg-final { cleanup-modules "types mymod test" } } |