From patchwork Sun Jan 16 23:04:06 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jakub Jelinek X-Patchwork-Id: 79107 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id F2B04B6EF1 for ; Mon, 17 Jan 2011 10:03:27 +1100 (EST) Received: (qmail 31146 invoked by alias); 16 Jan 2011 23:03:24 -0000 Received: (qmail 31127 invoked by uid 22791); 16 Jan 2011 23:03:19 -0000 X-SWARE-Spam-Status: No, hits=-6.2 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_HI, SPF_HELO_PASS, TW_TM, TW_TV, TW_UF, T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Sun, 16 Jan 2011 23:03:08 +0000 Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id p0GN373v027559 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Sun, 16 Jan 2011 18:03:07 -0500 Received: from tyan-ft48-01.lab.bos.redhat.com (tyan-ft48-01.lab.bos.redhat.com [10.16.42.4]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id p0GN36iZ010897 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO) for ; Sun, 16 Jan 2011 18:03:07 -0500 Received: from tyan-ft48-01.lab.bos.redhat.com (localhost.localdomain [127.0.0.1]) by tyan-ft48-01.lab.bos.redhat.com (8.14.4/8.14.4) with ESMTP id p0GN46Af020264 for ; Mon, 17 Jan 2011 00:04:06 +0100 Received: (from jakub@localhost) by tyan-ft48-01.lab.bos.redhat.com (8.14.4/8.14.4/Submit) id p0GN46ZU020263 for gcc-patches@gcc.gnu.org; Mon, 17 Jan 2011 00:04:06 +0100 Date: Mon, 17 Jan 2011 00:04:06 +0100 From: Jakub Jelinek To: gcc-patches@gcc.gnu.org Subject: [committed] Some 4.5/4.4 backports Message-ID: <20110116230406.GD2724@tyan-ft48-01.lab.bos.redhat.com> Reply-To: Jakub Jelinek MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.21 (2010-09-15) X-IsSubscribed: yes Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Hi! Attached is a bunch of 4.5 and 4.4 backports of my recent patches I've committed after bootstrap/regtest on x86_64-linux and i686-linux. Jakub 2011-01-16 Jakub Jelinek Backport from mainline 2010-12-10 Jakub Jelinek PR tree-optimization/46864 * tree-ssa-loop-im.c (loop_suitable_for_sm): Return false even when there are EDGE_EH exit edges. * g++.dg/opt/pr46864.C: New test. 2011-01-16 Jakub Jelinek Backport from mainline 2010-12-16 Jakub Jelinek PR debug/46893 * cfgexpand.c (expand_debug_expr): If GET_MODE (op0) is VOIDmode, use TYPE_MODE (TREE_TYPE (tem)) instead of mode1. * gcc.dg/pr46893.c: New test. --- gcc/cfgexpand.c (revision 167948) +++ gcc/cfgexpand.c (revision 167949) @@ -2703,7 +2703,7 @@ expand_debug_expr (tree exp) enum machine_mode opmode = GET_MODE (op0); if (opmode == VOIDmode) - opmode = mode1; + opmode = TYPE_MODE (TREE_TYPE (tem)); /* This condition may hold if we're expanding the address right past the end of an array that turned out not to @@ -2724,7 +2724,8 @@ expand_debug_expr (tree exp) ? SIGN_EXTRACT : ZERO_EXTRACT, mode, GET_MODE (op0) != VOIDmode - ? GET_MODE (op0) : mode1, + ? GET_MODE (op0) + : TYPE_MODE (TREE_TYPE (tem)), op0, GEN_INT (bitsize), GEN_INT (bitpos)); } --- gcc/testsuite/gcc.dg/pr46893.c (revision 0) +++ gcc/testsuite/gcc.dg/pr46893.c (revision 167949) @@ -0,0 +1,13 @@ +/* PR debug/46893 */ +/* { dg-do compile } */ +/* { dg-options "-O -g" } */ + +void +foo (void) +{ + union { unsigned long long l; double d; } u = { 0x7ff0000000000000ULL }; + double v = 0, w = -u.d; + + if (w) + w = v; +} 2011-01-16 Jakub Jelinek Backport from mainline 2010-12-14 Jakub Jelinek PR fortran/46874 * trans-openmp.c (gfc_trans_omp_array_reduction): Handle allocatable dummy variables. * libgomp.fortran/allocatable6.f90: New test. --- gcc/fortran/trans-openmp.c (revision 167797) +++ gcc/fortran/trans-openmp.c (revision 167799) @@ -482,13 +482,23 @@ gfc_trans_omp_array_reduction (tree c, g gfc_symbol init_val_sym, outer_sym, intrinsic_sym; gfc_expr *e1, *e2, *e3, *e4; gfc_ref *ref; - tree decl, backend_decl, stmt; + tree decl, backend_decl, stmt, type, outer_decl; locus old_loc = gfc_current_locus; const char *iname; gfc_try t; decl = OMP_CLAUSE_DECL (c); gfc_current_locus = where; + type = TREE_TYPE (decl); + outer_decl = create_tmp_var_raw (type, NULL); + if (TREE_CODE (decl) == PARM_DECL + && TREE_CODE (type) == REFERENCE_TYPE + && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (type)) + && GFC_TYPE_ARRAY_AKIND (TREE_TYPE (type)) == GFC_ARRAY_ALLOCATABLE) + { + decl = build_fold_indirect_ref (decl); + type = TREE_TYPE (type); + } /* Create a fake symbol for init value. */ memset (&init_val_sym, 0, sizeof (init_val_sym)); @@ -507,7 +517,9 @@ gfc_trans_omp_array_reduction (tree c, g outer_sym.attr.dummy = 0; outer_sym.attr.result = 0; outer_sym.attr.flavor = FL_VARIABLE; - outer_sym.backend_decl = create_tmp_var_raw (TREE_TYPE (decl), NULL); + outer_sym.backend_decl = outer_decl; + if (decl != OMP_CLAUSE_DECL (c)) + outer_sym.backend_decl = build_fold_indirect_ref (outer_decl); /* Create fake symtrees for it. */ symtree1 = gfc_new_symtree (&root1, sym->name); @@ -624,12 +636,12 @@ gfc_trans_omp_array_reduction (tree c, g /* Create the init statement list. */ pushlevel (0); - if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (decl)) - && GFC_TYPE_ARRAY_AKIND (TREE_TYPE (decl)) == GFC_ARRAY_ALLOCATABLE) + if (GFC_DESCRIPTOR_TYPE_P (type) + && GFC_TYPE_ARRAY_AKIND (type) == GFC_ARRAY_ALLOCATABLE) { /* If decl is an allocatable array, it needs to be allocated with the same bounds as the outer var. */ - tree type = TREE_TYPE (decl), rank, size, esize, ptr; + tree rank, size, esize, ptr; stmtblock_t block; gfc_start_block (&block); @@ -669,8 +681,8 @@ gfc_trans_omp_array_reduction (tree c, g /* Create the merge statement list. */ pushlevel (0); - if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (decl)) - && GFC_TYPE_ARRAY_AKIND (TREE_TYPE (decl)) == GFC_ARRAY_ALLOCATABLE) + if (GFC_DESCRIPTOR_TYPE_P (type) + && GFC_TYPE_ARRAY_AKIND (type) == GFC_ARRAY_ALLOCATABLE) { /* If decl is an allocatable array, it needs to be deallocated afterwards. */ @@ -691,7 +703,7 @@ gfc_trans_omp_array_reduction (tree c, g OMP_CLAUSE_REDUCTION_MERGE (c) = stmt; /* And stick the placeholder VAR_DECL into the clause as well. */ - OMP_CLAUSE_REDUCTION_PLACEHOLDER (c) = outer_sym.backend_decl; + OMP_CLAUSE_REDUCTION_PLACEHOLDER (c) = outer_decl; gfc_current_locus = old_loc; --- libgomp/testsuite/libgomp.fortran/allocatable6.f90 (revision 0) +++ libgomp/testsuite/libgomp.fortran/allocatable6.f90 (revision 167799) @@ -0,0 +1,45 @@ +! PR fortran/46874 +! { dg-do run } + + interface + subroutine sub (a, b, c, d, n) + integer :: n + integer, allocatable :: a(:), b(:), c(:), d(:) + end subroutine + end interface + + integer, allocatable :: a(:), b(:), c(:), d(:) + integer :: i, j + allocate (a(50), b(50), c(50), d(50)) + do i = 1, 50 + a(i) = 2 + modulo (i, 7) + b(i) = 179 - modulo (i, 11) + end do + c = 0 + d = 2147483647 + call sub (a, b, c, d, 50) + do i = 1, 50 + j = 0 + if (i .eq. 3) then + j = 8 + else if (i .gt. 1 .and. i .lt. 9) then + j = 7 + end if + if (c(i) .ne. j) call abort + j = 179 - modulo (i, 11) + if (i .gt. 1 .and. i .lt. 9) j = i + if (d(i) .ne. j) call abort + end do + deallocate (a, b, c, d) +end + +subroutine sub (a, b, c, d, n) + integer :: n + integer, allocatable :: a(:), b(:), c(:), d(:) +!$omp parallel do shared(a, b) reduction(+:c) reduction(min:d) + do i = 1, n + c(a(i)) = c(a(i)) + 1 + d(i) = min(d(i), b(i)) + d(a(i)) = min(d(a(i)), a(i)) + end do +end 2011-01-16 Jakub Jelinek Backport from mainline 2011-01-07 Jakub Jelinek PR target/47201 * config/i386/i386.c (ix86_delegitimize_address): If simplify_gen_subreg fails, return orig_x. * gcc.dg/pr47201.c: New test. --- gcc/config/i386/i386.c (revision 168581) +++ gcc/config/i386/i386.c (revision 168582) @@ -13254,7 +13254,11 @@ ix86_delegitimize_address (rtx x) return ix86_delegitimize_tls_address (orig_x); x = XVECEXP (XEXP (x, 0), 0, 0); if (GET_MODE (orig_x) != Pmode) - return simplify_gen_subreg (GET_MODE (orig_x), x, Pmode, 0); + { + x = simplify_gen_subreg (GET_MODE (orig_x), x, Pmode, 0); + if (x == NULL_RTX) + return orig_x; + } return x; } @@ -13323,7 +13327,11 @@ ix86_delegitimize_address (rtx x) return orig_x; } if (GET_MODE (orig_x) != Pmode && MEM_P (orig_x)) - return simplify_gen_subreg (GET_MODE (orig_x), result, Pmode, 0); + { + result = simplify_gen_subreg (GET_MODE (orig_x), result, Pmode, 0); + if (result == NULL_RTX) + return orig_x; + } return result; } --- gcc/testsuite/gcc.dg/pr47201.c (revision 0) +++ gcc/testsuite/gcc.dg/pr47201.c (revision 168582) @@ -0,0 +1,18 @@ +/* PR target/47201 */ +/* { dg-do compile } */ +/* { dg-options "-O -fpic -g" { target fpic } } */ + +union U +{ + __UINTPTR_TYPE__ m; + float d; +} u; + +int +foo (void) +{ + union U v = { + (__UINTPTR_TYPE__)&u + }; + return u.d == v.d; +} 2011-01-16 Jakub Jelinek Backport from mainline 2011-01-06 Jakub Jelinek PR c/47150 * c-convert.c (convert): When converting a complex expression other than COMPLEX_EXPR to a different complex type, ensure c_save_expr is called instead of save_expr, unless in_late_binary_op. * c-typeck.c (convert_for_assignment): Set in_late_binary_op also when converting COMPLEX_TYPE. * gcc.c-torture/compile/pr47150.c: New test. --- gcc/c-typeck.c (revision 168536) +++ gcc/c-typeck.c (revision 168537) @@ -5274,10 +5274,10 @@ convert_for_assignment (location_t locat { tree ret; bool save = in_late_binary_op; - if (codel == BOOLEAN_TYPE) + if (codel == BOOLEAN_TYPE || codel == COMPLEX_TYPE) in_late_binary_op = true; ret = convert_and_check (type, orig_rhs); - if (codel == BOOLEAN_TYPE) + if (codel == BOOLEAN_TYPE || codel == COMPLEX_TYPE) in_late_binary_op = save; return ret; } --- gcc/c-convert.c (revision 168536) +++ gcc/c-convert.c (revision 168537) @@ -130,6 +130,32 @@ convert (tree type, tree expr) goto maybe_fold; case COMPLEX_TYPE: + /* If converting from COMPLEX_TYPE to a different COMPLEX_TYPE + and e is not COMPLEX_EXPR, convert_to_complex uses save_expr, + but for the C FE c_save_expr needs to be called instead. */ + if (TREE_CODE (TREE_TYPE (e)) == COMPLEX_TYPE) + { + tree subtype = TREE_TYPE (type); + tree elt_type = TREE_TYPE (TREE_TYPE (e)); + + if (TYPE_MAIN_VARIANT (elt_type) != TYPE_MAIN_VARIANT (subtype) + && TREE_CODE (e) != COMPLEX_EXPR) + { + if (in_late_binary_op) + e = save_expr (e); + else + e = c_save_expr (e); + ret + = fold_build2 (COMPLEX_EXPR, type, + convert (subtype, + fold_build1 (REALPART_EXPR, + elt_type, e)), + convert (subtype, + fold_build1 (IMAGPART_EXPR, + elt_type, e))); + goto maybe_fold; + } + } ret = convert_to_complex (type, e); goto maybe_fold; --- gcc/testsuite/gcc.c-torture/compile/pr47150.c (revision 0) +++ gcc/testsuite/gcc.c-torture/compile/pr47150.c (revision 168537) @@ -0,0 +1,11 @@ +/* PR c/47150 */ + +float _Complex foo (float, float); + +void +bar () +{ + float w = 2; + float _Complex b; + b = 0.5 * (foo (0, w) + foo (1, w) / w); +} 2011-01-16 Jakub Jelinek Backport from mainline 2010-12-21 Jakub Jelinek PR target/46880 * config/i386/sse.md (sse2_loadlpd, sse2_movsd): Fix shufpd source operand. * gcc.target/i386/pr46880.c: New test. --- gcc/config/i386/sse.md (revision 168134) +++ gcc/config/i386/sse.md (revision 168135) @@ -4990,7 +4990,7 @@ (define_insn "sse2_loadlpd" movsd\t{%2, %0|%0, %2} movlpd\t{%2, %0|%0, %2} movsd\t{%2, %0|%0, %2} - shufpd\t{$2, %2, %0|%0, %2, 2} + shufpd\t{$2, %1, %0|%0, %1, 2} movhpd\t{%H1, %0|%0, %H1} # # @@ -5067,7 +5067,7 @@ (define_insn "sse2_movsd" movsd\t{%2, %0|%0, %2} movlpd\t{%2, %0|%0, %2} movlpd\t{%2, %0|%0, %2} - shufpd\t{$2, %2, %0|%0, %2, 2} + shufpd\t{$2, %1, %0|%0, %1, 2} movhps\t{%H1, %0|%0, %H1} movhps\t{%1, %H0|%H0, %1}" [(set_attr "type" "ssemov,ssemov,ssemov,sselog,ssemov,ssemov") --- gcc/testsuite/gcc.target/i386/pr46880.c (revision 0) +++ gcc/testsuite/gcc.target/i386/pr46880.c (revision 168135) @@ -0,0 +1,28 @@ +/* PR target/46880 */ +/* { dg-do run } */ +/* { dg-options "-O2 -fno-strict-aliasing -msse2" } */ +/* { dg-require-effective-target sse2_runtime } */ + +typedef double __m128d __attribute__ ((__vector_size__ (16), __may_alias__)); +typedef double (*T)[2]; + +static __attribute__ ((noinline, noclone)) __m128d +foo (__m128d c, __m128d d) +{ + T cp = (T) &c; + T dp = (T) &d; + __m128d e = { (*cp)[1], (*dp)[1] }; + return e; +} + +int +main () +{ + __m128d c = { 1.0, 2.0 }; + __m128d d = { 3.0, 4.0 }; + union { __m128d x; double d[2]; } u; + u.x = foo (c, d); + if (u.d[0] != 2.0 || u.d[1] != 4.0) + __builtin_abort (); + return 0; +} 2011-01-16 Jakub Jelinek Backport from mainline 2010-12-21 Jakub Jelinek PR middle-end/45852 * expr.c (store_expr): Ignore alt_rtl if equal to target, but has side-effects. * gcc.target/i386/pr45852.c: New test. --- gcc/expr.c (revision 168104) +++ gcc/expr.c (revision 168105) @@ -4712,7 +4712,10 @@ store_expr (tree exp, rtx target, int ca /* If store_expr stores a DECL whose DECL_RTL(exp) == TARGET, but TARGET is not valid memory reference, TEMP will differ from TARGET although it is really the same location. */ - && !(alt_rtl && rtx_equal_p (alt_rtl, target)) + && !(alt_rtl + && rtx_equal_p (alt_rtl, target) + && !side_effects_p (alt_rtl) + && !side_effects_p (target)) /* If there's nothing to copy, don't bother. Don't call expr_size unless necessary, because some front-ends (C++) expr_size-hook must not be given objects that are not --- gcc/testsuite/gcc.target/i386/pr45852.c (revision 0) +++ gcc/testsuite/gcc.target/i386/pr45852.c (revision 168105) @@ -0,0 +1,16 @@ +/* PR middle-end/45852 */ +/* { dg-options "-O2 -mcmodel=small" } */ +/* { dg-do compile { target { { i?86-*-linux* x86_64-*-linux* } && lp64 } } } */ +/* { dg-require-visibility "" } */ + +struct S { int s; }; + +volatile struct S globvar __attribute__((visibility ("hidden"))) = { -6 }; + +void +foo (void) +{ + globvar = globvar; +} + +/* { dg-final { scan-assembler-times "globvar.%?rip" 2 } } */ 2011-01-16 Jakub Jelinek Backport from mainline 2010-12-16 Jakub Jelinek PR tree-optimization/43655 * tree-ssa-ter.c (is_replaceable_p): Don't use gimple_references_memory_p for -O0, instead check for load by looking at rhs. * g++.dg/opt/pr43655.C: New test. --- gcc/tree-ssa-ter.c (revision 167954) +++ gcc/tree-ssa-ter.c (revision 167955) @@ -416,7 +416,9 @@ is_replaceable_p (gimple stmt) return false; /* Without alias info we can't move around loads. */ - if (gimple_references_memory_p (stmt) && !optimize) + if (!optimize + && gimple_assign_single_p (stmt) + && !is_gimple_val (gimple_assign_rhs1 (stmt))) return false; /* Float expressions must go through memory if float-store is on. */ --- gcc/testsuite/g++.dg/opt/pr43655.C (revision 0) +++ gcc/testsuite/g++.dg/opt/pr43655.C (revision 167955) @@ -0,0 +1,34 @@ +// PR tree-optimization/43655 +// { dg-do run } +// { dg-options "-O0 -ftree-ter" } + +extern "C" void abort (); + +struct C +{ + C (int i) : val(i) { } + C (const C& c) : val(c.val) { } + ~C (void) { val = 999; } + C& operator = (const C& c) { val = c.val; return *this; } + C& inc (int i) { val += i; return *this; } + int val; +}; + +C +f () +{ + return C (3); +} + +C +f (int i) +{ + return f ().inc (i); +} + +int +main () +{ + if (f (2).val != 5) + abort (); +} 2011-01-16 Jakub Jelinek Backport from mainline 2010-12-10 Jakub Jelinek PR rtl-optimization/46804 * regmove.c (optimize_reg_copy_3): Look for REG_EQUAL note on the setter of src_reg rather than on insn. If it is equal to the setter's original SET_SRC, replace it with its zero or sign extension instead of dropping it. * gfortran.dg/pr46804.f90: New test. --- gcc/regmove.c (revision 167694) +++ gcc/regmove.c (revision 167695) @@ -514,7 +514,7 @@ optimize_reg_copy_3 (rtx insn, rtx dest, rtx src_reg = XEXP (src, 0); int src_no = REGNO (src_reg); int dst_no = REGNO (dest); - rtx p, set; + rtx p, set, set_insn; enum machine_mode old_mode; basic_block bb = BLOCK_FOR_INSN (insn); @@ -552,6 +552,7 @@ optimize_reg_copy_3 (rtx insn, rtx dest, GET_MODE_BITSIZE (GET_MODE (src_reg)))) return; + set_insn = p; old_mode = GET_MODE (src_reg); PUT_MODE (src_reg, GET_MODE (src)); XEXP (src, 0) = SET_SRC (set); @@ -584,9 +585,19 @@ optimize_reg_copy_3 (rtx insn, rtx dest, } else { - rtx note = find_reg_note (p, REG_EQUAL, NULL_RTX); + rtx note = find_reg_note (set_insn, REG_EQUAL, NULL_RTX); if (note) - remove_note (p, note); + { + if (rtx_equal_p (XEXP (note, 0), XEXP (src, 0))) + { + XEXP (note, 0) + = gen_rtx_fmt_e (GET_CODE (src), GET_MODE (src), + XEXP (note, 0)); + df_notes_rescan (set_insn); + } + else + remove_note (set_insn, note); + } } } --- gcc/testsuite/gfortran.dg/pr46804.f90 (revision 0) +++ gcc/testsuite/gfortran.dg/pr46804.f90 (revision 167695) @@ -0,0 +1,36 @@ +! PR rtl-optimization/46804 +! { dg-do run } +! { dg-options "-O -fPIC -fexpensive-optimizations -fgcse -foptimize-register-move -fpeel-loops -fno-tree-loop-optimize" } + +program main + integer, parameter :: n1 = 2, n2 = 3, n3 = 4, slen = 3 + character (len = slen), dimension (n1, n2, n3) :: a + integer (kind = 1), dimension (2, 4) :: shift1 + integer (kind = 2), dimension (2, 4) :: shift2 + integer (kind = 4), dimension (2, 4) :: shift3 + do i3 = 1, n3 + do i2 = 1, n2 + do i1 = 1, n1 + a (i1, i2, i3) = 'ab'(i1:i1) // 'cde'(i2:i2) // 'fghi'(i3:i3) + end do + end do + end do + shift1 (1, :) = (/ 4, 11, 19, 20 /) + shift1 (2, :) = (/ 55, 5, 1, 2 /) + shift2 = shift1 + shift3 = shift1 + call test (cshift (a, shift2, 2)) + call test (cshift (a, shift3, 2)) +contains + subroutine test (b) + character (len = slen), dimension (n1, n2, n3) :: b + do i3 = 1, n3 + do i2 = 1, n2 + do i1 = 1, n1 + i2p = mod (shift1 (i1, i3) + i2 - 1, n2) + 1 + if (b (i1, i2, i3) .ne. a (i1, i2p, i3)) call abort + end do + end do + end do + end subroutine test +end program main 2011-01-16 Jakub Jelinek Backport from mainline 2010-12-10 Jakub Jelinek PR rtl-optimization/46865 * rtl.c (rtx_equal_p_cb, rtx_equal_p): For last operand of ASM_OPERANDS and ASM_INPUT if integers are different, call locator_eq. * jump.c (rtx_renumbered_equal_p): Likewise. * gcc.target/i386/pr46865-1.c: New test. * gcc.target/i386/pr46865-2.c: New test. --- gcc/jump.c (revision 167685) +++ gcc/jump.c (revision 167686) @@ -1727,7 +1727,13 @@ rtx_renumbered_equal_p (const_rtx x, con case 'i': if (XINT (x, i) != XINT (y, i)) - return 0; + { + if (((code == ASM_OPERANDS && i == 6) + || (code == ASM_INPUT && i == 1)) + && locator_eq (XINT (x, i), XINT (y, i))) + break; + return 0; + } break; case 't': --- gcc/rtl.c (revision 167685) +++ gcc/rtl.c (revision 167686) @@ -431,7 +431,15 @@ rtx_equal_p_cb (const_rtx x, const_rtx y case 'n': case 'i': if (XINT (x, i) != XINT (y, i)) - return 0; + { +#ifndef GENERATOR_FILE + if (((code == ASM_OPERANDS && i == 6) + || (code == ASM_INPUT && i == 1)) + && locator_eq (XINT (x, i), XINT (y, i))) + break; +#endif + return 0; + } break; case 'V': @@ -555,7 +563,15 @@ rtx_equal_p (const_rtx x, const_rtx y) case 'n': case 'i': if (XINT (x, i) != XINT (y, i)) - return 0; + { +#ifndef GENERATOR_FILE + if (((code == ASM_OPERANDS && i == 6) + || (code == ASM_INPUT && i == 1)) + && locator_eq (XINT (x, i), XINT (y, i))) + break; +#endif + return 0; + } break; case 'V': --- gcc/testsuite/gcc.target/i386/pr46865-1.c (revision 0) +++ gcc/testsuite/gcc.target/i386/pr46865-1.c (revision 167686) @@ -0,0 +1,31 @@ +/* PR rtl-optimization/46865 */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +extern unsigned long f; + +#define m1(f) \ + if (f & 1) \ + asm volatile ("nop /* asmnop */\n"); \ + else \ + asm volatile ("nop /* asmnop */\n"); + +#define m2(f) \ + if (f & 1) \ + asm volatile ("nop /* asmnop */\n" : : "i" (6) : "cx"); \ + else \ + asm volatile ("nop /* asmnop */\n" : : "i" (6) : "cx"); + +void +foo (void) +{ + m1 (f); +} + +void +bar (void) +{ + m2 (f); +} + +/* { dg-final { scan-assembler-times "asmnop" 2 } } */ --- gcc/testsuite/gcc.target/i386/pr46865-2.c (revision 0) +++ gcc/testsuite/gcc.target/i386/pr46865-2.c (revision 167686) @@ -0,0 +1,32 @@ +/* PR rtl-optimization/46865 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -save-temps" } */ + +extern unsigned long f; + +#define m1(f) \ + if (f & 1) \ + asm volatile ("nop /* asmnop */\n"); \ + else \ + asm volatile ("nop /* asmnop */\n"); + +#define m2(f) \ + if (f & 1) \ + asm volatile ("nop /* asmnop */\n" : : "i" (6) : "cx"); \ + else \ + asm volatile ("nop /* asmnop */\n" : : "i" (6) : "cx"); + +void +foo (void) +{ + m1 (f); +} + +void +bar (void) +{ + m2 (f); +} + +/* { dg-final { scan-assembler-times "asmnop" 2 } } */ +/* { dg-final { cleanup-saved-temps } } */ 2011-01-16 Jakub Jelinek Backport from mainline 2010-12-09 Jakub Jelinek PR target/41082 * config/rs6000/rs6000.c (rs6000_expand_vector_extract): Use stvx instead of stve*x. (altivec_expand_stv_builtin): For op0 use mode of operand 1 instead of operand 0. * config/rs6000/altivec.md (VI_scalar): New mode attr. (altivec_stvex, *altivec_stvesfx): Use scalar instead of vector mode for operand 0, put operand 1 into UNSPEC. --- gcc/config/rs6000/rs6000.c (revision 167628) +++ gcc/config/rs6000/rs6000.c (revision 167629) @@ -5436,7 +5436,7 @@ rs6000_expand_vector_extract (rtx target { enum machine_mode mode = GET_MODE (vec); enum machine_mode inner_mode = GET_MODE_INNER (mode); - rtx mem, x; + rtx mem; if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode)) { @@ -5449,17 +5449,11 @@ rs6000_expand_vector_extract (rtx target /* Allocate mode-sized buffer. */ mem = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0); + emit_move_insn (mem, vec); + /* Add offset to field within buffer matching vector element. */ - mem = adjust_address_nv (mem, mode, elt * GET_MODE_SIZE (inner_mode)); + mem = adjust_address_nv (mem, inner_mode, elt * GET_MODE_SIZE (inner_mode)); - /* Store single field into mode-sized buffer. */ - x = gen_rtx_UNSPEC (VOIDmode, - gen_rtvec (1, const0_rtx), UNSPEC_STVE); - emit_insn (gen_rtx_PARALLEL (VOIDmode, - gen_rtvec (2, - gen_rtx_SET (VOIDmode, - mem, vec), - x))); emit_move_insn (target, adjust_address_nv (mem, inner_mode, 0)); } @@ -11114,6 +11108,7 @@ altivec_expand_stv_builtin (enum insn_co rtx op2 = expand_normal (arg2); rtx pat, addr; enum machine_mode tmode = insn_data[icode].operand[0].mode; + enum machine_mode smode = insn_data[icode].operand[1].mode; enum machine_mode mode1 = Pmode; enum machine_mode mode2 = Pmode; @@ -11123,8 +11118,8 @@ altivec_expand_stv_builtin (enum insn_co || arg2 == error_mark_node) return const0_rtx; - if (! (*insn_data[icode].operand[1].predicate) (op0, tmode)) - op0 = copy_to_mode_reg (tmode, op0); + if (! (*insn_data[icode].operand[1].predicate) (op0, smode)) + op0 = copy_to_mode_reg (smode, op0); op2 = copy_to_mode_reg (mode2, op2); --- gcc/config/rs6000/altivec.md (revision 167628) +++ gcc/config/rs6000/altivec.md (revision 167629) @@ -169,6 +169,7 @@ (define_mode_iterator VM [V4SI V8HI V16Q (define_mode_iterator VM2 [V4SI V8HI V16QI V4SF V2DF V2DI]) (define_mode_attr VI_char [(V4SI "w") (V8HI "h") (V16QI "b")]) +(define_mode_attr VI_scalar [(V4SI "SI") (V8HI "HI") (V16QI "QI")]) ;; Vector move instructions. (define_insn "*altivec_mov" @@ -1775,19 +1776,15 @@ (define_insn "altivec_stvxl" [(set_attr "type" "vecstore")]) (define_insn "altivec_stvex" - [(parallel - [(set (match_operand:VI 0 "memory_operand" "=Z") - (match_operand:VI 1 "register_operand" "v")) - (unspec [(const_int 0)] UNSPEC_STVE)])] + [(set (match_operand: 0 "memory_operand" "=Z") + (unspec: [(match_operand:VI 1 "register_operand" "v")] UNSPEC_STVE))] "TARGET_ALTIVEC" "stvex %1,%y0" [(set_attr "type" "vecstore")]) (define_insn "*altivec_stvesfx" - [(parallel - [(set (match_operand:V4SF 0 "memory_operand" "=Z") - (match_operand:V4SF 1 "register_operand" "v")) - (unspec [(const_int 0)] UNSPEC_STVE)])] + [(set (match_operand:SF 0 "memory_operand" "=Z") + (unspec:SF [(match_operand:V4SF 1 "register_operand" "v")] UNSPEC_STVE))] "TARGET_ALTIVEC" "stvewx %1,%y0" [(set_attr "type" "vecstore")]) 2011-01-16 Jakub Jelinek Backport from mainline 2010-12-10 Jakub Jelinek PR rtl-optimization/46865 * rtl.c (rtx_equal_p_cb): For last operand of ASM_OPERANDS and ASM_INPUT if integers are different, call locator_eq. * jump.c (rtx_renumbered_equal_p): Likewise. * gcc.target/i386/pr46865-1.c: New test. * gcc.target/i386/pr46865-2.c: New test. --- gcc/jump.c (revision 167685) +++ gcc/jump.c (revision 167686) @@ -1727,7 +1727,13 @@ rtx_renumbered_equal_p (const_rtx x, con case 'i': if (XINT (x, i) != XINT (y, i)) - return 0; + { + if (((code == ASM_OPERANDS && i == 5) + || (code == ASM_INPUT && i == 1)) + && locator_eq (XINT (x, i), XINT (y, i))) + break; + return 0; + } break; case 't': --- gcc/rtl.c (revision 167685) +++ gcc/rtl.c (revision 167686) @@ -431,7 +431,15 @@ rtx_equal_p_cb (const_rtx x, const_rtx y case 'n': case 'i': if (XINT (x, i) != XINT (y, i)) - return 0; + { +#ifndef GENERATOR_FILE + if (((code == ASM_OPERANDS && i == 5) + || (code == ASM_INPUT && i == 1)) + && locator_eq (XINT (x, i), XINT (y, i))) + break; +#endif + return 0; + } break; case 'V': --- gcc/testsuite/gcc.target/i386/pr46865-1.c (revision 0) +++ gcc/testsuite/gcc.target/i386/pr46865-1.c (revision 167686) @@ -0,0 +1,31 @@ +/* PR rtl-optimization/46865 */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +extern unsigned long f; + +#define m1(f) \ + if (f & 1) \ + asm volatile ("nop /* asmnop */\n"); \ + else \ + asm volatile ("nop /* asmnop */\n"); + +#define m2(f) \ + if (f & 1) \ + asm volatile ("nop /* asmnop */\n" : : "i" (6) : "cx"); \ + else \ + asm volatile ("nop /* asmnop */\n" : : "i" (6) : "cx"); + +void +foo (void) +{ + m1 (f); +} + +void +bar (void) +{ + m2 (f); +} + +/* { dg-final { scan-assembler-times "asmnop" 2 } } */ --- gcc/testsuite/gcc.target/i386/pr46865-2.c (revision 0) +++ gcc/testsuite/gcc.target/i386/pr46865-2.c (revision 167686) @@ -0,0 +1,32 @@ +/* PR rtl-optimization/46865 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -save-temps" } */ + +extern unsigned long f; + +#define m1(f) \ + if (f & 1) \ + asm volatile ("nop /* asmnop */\n"); \ + else \ + asm volatile ("nop /* asmnop */\n"); + +#define m2(f) \ + if (f & 1) \ + asm volatile ("nop /* asmnop */\n" : : "i" (6) : "cx"); \ + else \ + asm volatile ("nop /* asmnop */\n" : : "i" (6) : "cx"); + +void +foo (void) +{ + m1 (f); +} + +void +bar (void) +{ + m2 (f); +} + +/* { dg-final { scan-assembler-times "asmnop" 2 } } */ +/* { dg-final { cleanup-saved-temps } } */ 2011-01-16 Jakub Jelinek Backport from mainline 2010-12-14 Jakub Jelinek PR fortran/46874 * trans-openmp.c (gfc_trans_omp_array_reduction): Handle allocatable dummy variables. * libgomp.fortran/allocatable6.f90: New test. --- gcc/fortran/trans-openmp.c (revision 167797) +++ gcc/fortran/trans-openmp.c (revision 167799) @@ -482,13 +482,23 @@ gfc_trans_omp_array_reduction (tree c, g gfc_symbol init_val_sym, outer_sym, intrinsic_sym; gfc_expr *e1, *e2, *e3, *e4; gfc_ref *ref; - tree decl, backend_decl, stmt; + tree decl, backend_decl, stmt, type, outer_decl; locus old_loc = gfc_current_locus; const char *iname; gfc_try t; decl = OMP_CLAUSE_DECL (c); gfc_current_locus = where; + type = TREE_TYPE (decl); + outer_decl = create_tmp_var_raw (type, NULL); + if (TREE_CODE (decl) == PARM_DECL + && TREE_CODE (type) == REFERENCE_TYPE + && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (type)) + && GFC_TYPE_ARRAY_AKIND (TREE_TYPE (type)) == GFC_ARRAY_ALLOCATABLE) + { + decl = build_fold_indirect_ref (decl); + type = TREE_TYPE (type); + } /* Create a fake symbol for init value. */ memset (&init_val_sym, 0, sizeof (init_val_sym)); @@ -507,7 +517,9 @@ gfc_trans_omp_array_reduction (tree c, g outer_sym.attr.dummy = 0; outer_sym.attr.result = 0; outer_sym.attr.flavor = FL_VARIABLE; - outer_sym.backend_decl = create_tmp_var_raw (TREE_TYPE (decl), NULL); + outer_sym.backend_decl = outer_decl; + if (decl != OMP_CLAUSE_DECL (c)) + outer_sym.backend_decl = build_fold_indirect_ref (outer_decl); /* Create fake symtrees for it. */ symtree1 = gfc_new_symtree (&root1, sym->name); @@ -624,12 +636,12 @@ gfc_trans_omp_array_reduction (tree c, g /* Create the init statement list. */ pushlevel (0); - if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (decl)) - && GFC_TYPE_ARRAY_AKIND (TREE_TYPE (decl)) == GFC_ARRAY_ALLOCATABLE) + if (GFC_DESCRIPTOR_TYPE_P (type) + && GFC_TYPE_ARRAY_AKIND (type) == GFC_ARRAY_ALLOCATABLE) { /* If decl is an allocatable array, it needs to be allocated with the same bounds as the outer var. */ - tree type = TREE_TYPE (decl), rank, size, esize, ptr; + tree rank, size, esize, ptr; stmtblock_t block; gfc_start_block (&block); @@ -669,8 +681,8 @@ gfc_trans_omp_array_reduction (tree c, g /* Create the merge statement list. */ pushlevel (0); - if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (decl)) - && GFC_TYPE_ARRAY_AKIND (TREE_TYPE (decl)) == GFC_ARRAY_ALLOCATABLE) + if (GFC_DESCRIPTOR_TYPE_P (type) + && GFC_TYPE_ARRAY_AKIND (type) == GFC_ARRAY_ALLOCATABLE) { /* If decl is an allocatable array, it needs to be deallocated afterwards. */ @@ -691,7 +703,7 @@ gfc_trans_omp_array_reduction (tree c, g OMP_CLAUSE_REDUCTION_MERGE (c) = stmt; /* And stick the placeholder VAR_DECL into the clause as well. */ - OMP_CLAUSE_REDUCTION_PLACEHOLDER (c) = outer_sym.backend_decl; + OMP_CLAUSE_REDUCTION_PLACEHOLDER (c) = outer_decl; gfc_current_locus = old_loc; --- libgomp/testsuite/libgomp.fortran/allocatable6.f90 (revision 0) +++ libgomp/testsuite/libgomp.fortran/allocatable6.f90 (revision 167799) @@ -0,0 +1,45 @@ +! PR fortran/46874 +! { dg-do run } + + interface + subroutine sub (a, b, c, d, n) + integer :: n + integer, allocatable :: a(:), b(:), c(:), d(:) + end subroutine + end interface + + integer, allocatable :: a(:), b(:), c(:), d(:) + integer :: i, j + allocate (a(50), b(50), c(50), d(50)) + do i = 1, 50 + a(i) = 2 + modulo (i, 7) + b(i) = 179 - modulo (i, 11) + end do + c = 0 + d = 2147483647 + call sub (a, b, c, d, 50) + do i = 1, 50 + j = 0 + if (i .eq. 3) then + j = 8 + else if (i .gt. 1 .and. i .lt. 9) then + j = 7 + end if + if (c(i) .ne. j) call abort + j = 179 - modulo (i, 11) + if (i .gt. 1 .and. i .lt. 9) j = i + if (d(i) .ne. j) call abort + end do + deallocate (a, b, c, d) +end + +subroutine sub (a, b, c, d, n) + integer :: n + integer, allocatable :: a(:), b(:), c(:), d(:) +!$omp parallel do shared(a, b) reduction(+:c) reduction(min:d) + do i = 1, n + c(a(i)) = c(a(i)) + 1 + d(i) = min(d(i), b(i)) + d(a(i)) = min(d(a(i)), a(i)) + end do +end 2011-01-16 Jakub Jelinek Backport from mainline 2010-12-21 Jakub Jelinek PR middle-end/45852 * expr.c (store_expr): Ignore alt_rtl if equal to target, but has side-effects. * gcc.target/i386/pr45852.c: New test. --- gcc/expr.c (revision 168104) +++ gcc/expr.c (revision 168105) @@ -4712,7 +4712,10 @@ store_expr (tree exp, rtx target, int ca /* If store_expr stores a DECL whose DECL_RTL(exp) == TARGET, but TARGET is not valid memory reference, TEMP will differ from TARGET although it is really the same location. */ - && !(alt_rtl && rtx_equal_p (alt_rtl, target)) + && !(alt_rtl + && rtx_equal_p (alt_rtl, target) + && !side_effects_p (alt_rtl) + && !side_effects_p (target)) /* If there's nothing to copy, don't bother. Don't call expr_size unless necessary, because some front-ends (C++) expr_size-hook must not be given objects that are not --- gcc/testsuite/gcc.target/i386/pr45852.c (revision 0) +++ gcc/testsuite/gcc.target/i386/pr45852.c (revision 168105) @@ -0,0 +1,16 @@ +/* PR middle-end/45852 */ +/* { dg-options "-O2 -mcmodel=small" } */ +/* { dg-do compile { target { { i?86-*-linux* x86_64-*-linux* } && lp64 } } } */ +/* { dg-require-visibility "" } */ + +struct S { int s; }; + +volatile struct S globvar __attribute__((visibility ("hidden"))) = { -6 }; + +void +foo (void) +{ + globvar = globvar; +} + +/* { dg-final { scan-assembler-times "globvar.%?rip" 2 } } */ 2011-01-16 Jakub Jelinek Backport from mainline 2010-12-21 Jakub Jelinek PR target/46880 * config/i386/sse.md (sse2_loadlpd, sse2_movsd): Fix shufpd source operand. * gcc.target/i386/pr46880.c: New test. --- gcc/config/i386/sse.md (revision 168134) +++ gcc/config/i386/sse.md (revision 168135) @@ -4990,7 +4990,7 @@ (define_insn "sse2_loadlpd" movsd\t{%2, %0|%0, %2} movlpd\t{%2, %0|%0, %2} movsd\t{%2, %0|%0, %2} - shufpd\t{$2, %2, %0|%0, %2, 2} + shufpd\t{$2, %1, %0|%0, %1, 2} movhpd\t{%H1, %0|%0, %H1} # # @@ -5067,7 +5067,7 @@ (define_insn "sse2_movsd" movsd\t{%2, %0|%0, %2} movlpd\t{%2, %0|%0, %2} movlpd\t{%2, %0|%0, %2} - shufpd\t{$2, %2, %0|%0, %2, 2} + shufpd\t{$2, %1, %0|%0, %1, 2} movhps\t{%H1, %0|%0, %H1} movhps\t{%1, %H0|%H0, %1}" [(set_attr "type" "ssemov,ssemov,ssemov,sselog,ssemov,ssemov") --- gcc/testsuite/gcc.target/i386/pr46880.c (revision 0) +++ gcc/testsuite/gcc.target/i386/pr46880.c (revision 168135) @@ -0,0 +1,28 @@ +/* PR target/46880 */ +/* { dg-do run } */ +/* { dg-options "-O2 -fno-strict-aliasing -msse2" } */ +/* { dg-require-effective-target sse2_runtime } */ + +typedef double __m128d __attribute__ ((__vector_size__ (16), __may_alias__)); +typedef double (*T)[2]; + +static __attribute__ ((noinline)) __m128d +foo (__m128d c, __m128d d) +{ + T cp = (T) &c; + T dp = (T) &d; + __m128d e = { (*cp)[1], (*dp)[1] }; + return e; +} + +int +main () +{ + __m128d c = { 1.0, 2.0 }; + __m128d d = { 3.0, 4.0 }; + union { __m128d x; double d[2]; } u; + u.x = foo (c, d); + if (u.d[0] != 2.0 || u.d[1] != 4.0) + __builtin_abort (); + return 0; +} --- gcc/tree-ssa-loop-im.c (revision 167684) +++ gcc/tree-ssa-loop-im.c (revision 167685) @@ -2139,7 +2139,7 @@ loop_suitable_for_sm (struct loop *loop edge ex; for (i = 0; VEC_iterate (edge, exits, i, ex); i++) - if (ex->flags & EDGE_ABNORMAL) + if (ex->flags & (EDGE_ABNORMAL | EDGE_EH)) return false; return true; --- gcc/testsuite/g++.dg/opt/pr46864.C (revision 0) +++ gcc/testsuite/g++.dg/opt/pr46864.C (revision 167685) @@ -0,0 +1,26 @@ +// PR tree-optimization/46864 +// { dg-do compile } +// { dg-options "-O -fnon-call-exceptions" } + +int baz (); + +struct S +{ + int k; + bool bar () throw () + { + int m = baz (); + for (int i = 0; i < m; i++) + k = i; + return m; + } +}; + +extern S *s; + +void +foo () +{ + while (baz () && s->bar ()) + ; +}