Message ID | 1291839756-26718-1-git-send-email-sebpop@gmail.com |
---|---|
State | New |
Headers | show |
On Wed, 8 Dec 2010, Sebastian Pop wrote: > Hi, > > I am testing this patch on amd64-linux. Ok for trunk if that passes? Ok. Thanks, Richard. > Thanks, > Sebastian > > 2010-12-08 Richard Guenther <rguenther@suse.de> > Sebastian Pop <sebastian.pop@amd.com> > > PR tree-optimization/45230 > PR tree-optimization/45231 > PR tree-optimization/45370 > * sese.c (rename_uses): Returns a bool. Call > recompute_tree_invariant_for_addr_expr only on the RHS of a > GIMPLE_ASSIGN. > (graphite_copy_stmts_from_block): Call fold_stmt_inplace when > rename_uses returns true. > * tree-ssa-copy.c (replace_exp): Add a comment about calling > fold_stmt_inplace after replace_exp. > > * gcc.dg/graphite/id-pr45230-1.c: New. > * gcc.dg/graphite/id-pr45231.c: New. > * gfortran.dg/graphite/id-pr45370.f90: New. > --- > gcc/ChangeLog | 14 ++ > gcc/sese.c | 17 ++- > gcc/testsuite/ChangeLog | 10 ++ > gcc/testsuite/gcc.dg/graphite/id-pr45230-1.c | 140 +++++++++++++++++++++ > gcc/testsuite/gcc.dg/graphite/id-pr45231.c | 37 ++++++ > gcc/testsuite/gfortran.dg/graphite/id-pr45370.f90 | 100 +++++++++++++++ > gcc/tree-ssa-copy.c | 5 +- > 7 files changed, 316 insertions(+), 7 deletions(-) > create mode 100644 gcc/testsuite/gcc.dg/graphite/id-pr45230-1.c > create mode 100644 gcc/testsuite/gcc.dg/graphite/id-pr45231.c > create mode 100644 gcc/testsuite/gfortran.dg/graphite/id-pr45370.f90 > > diff --git a/gcc/ChangeLog b/gcc/ChangeLog > index ff52686..95bd5c0 100644 > --- a/gcc/ChangeLog > +++ b/gcc/ChangeLog > @@ -1,3 +1,17 @@ > +2010-12-08 Richard Guenther <rguenther@suse.de> > + Sebastian Pop <sebastian.pop@amd.com> > + > + PR tree-optimization/45230 > + PR tree-optimization/45231 > + PR tree-optimization/45370 > + * sese.c (rename_uses): Returns a bool. Call > + recompute_tree_invariant_for_addr_expr only on the RHS of a > + GIMPLE_ASSIGN. > + (graphite_copy_stmts_from_block): Call fold_stmt_inplace when > + rename_uses returns true. > + * tree-ssa-copy.c (replace_exp): Add a comment about calling > + fold_stmt_inplace after replace_exp. > + > 2010-12-07 Paul Koning <ni1d@arrl.net> > > * config/pdp11/pdp11.c (TARGET_ASM_FUNCTION_SECTION): Define. > diff --git a/gcc/sese.c b/gcc/sese.c > index 65f8556..3bf6bea 100644 > --- a/gcc/sese.c > +++ b/gcc/sese.c > @@ -470,14 +470,15 @@ set_rename (htab_t rename_map, tree old_name, tree expr) > substitution map RENAME_MAP, inserting the gimplification code at > GSI_TGT, for the translation REGION, with the original copied > statement in LOOP, and using the induction variable renaming map > - IV_MAP. */ > + IV_MAP. Returns true when something has been renamed. */ > > -static void > +static bool > rename_uses (gimple copy, htab_t rename_map, gimple_stmt_iterator *gsi_tgt, > sese region, loop_p loop, VEC (tree, heap) *iv_map) > { > use_operand_p use_p; > ssa_op_iter op_iter; > + bool changed = false; > > if (is_gimple_debug (copy)) > { > @@ -486,7 +487,7 @@ rename_uses (gimple copy, htab_t rename_map, gimple_stmt_iterator *gsi_tgt, > else > gcc_unreachable (); > > - return; > + return false; > } > > FOR_EACH_SSA_USE_OPERAND (use_p, copy, op_iter, SSA_OP_ALL_USES) > @@ -500,6 +501,7 @@ rename_uses (gimple copy, htab_t rename_map, gimple_stmt_iterator *gsi_tgt, > || SSA_NAME_IS_DEFAULT_DEF (old_name)) > continue; > > + changed = true; > new_expr = get_rename (rename_map, old_name); > if (new_expr) > { > @@ -547,8 +549,8 @@ rename_uses (gimple copy, htab_t rename_map, gimple_stmt_iterator *gsi_tgt, > gsi_insert_seq_before (gsi_tgt, stmts, GSI_SAME_STMT); > replace_exp (use_p, new_expr); > > - > - if (TREE_CODE (new_expr) == INTEGER_CST) > + if (TREE_CODE (new_expr) == INTEGER_CST > + && is_gimple_assign (copy)) > { > tree rhs = gimple_assign_rhs1 (copy); > > @@ -558,6 +560,8 @@ rename_uses (gimple copy, htab_t rename_map, gimple_stmt_iterator *gsi_tgt, > > set_rename (rename_map, old_name, new_expr); > } > + > + return changed; > } > > /* Duplicates the statements of basic block BB into basic block NEW_BB > @@ -611,7 +615,8 @@ graphite_copy_stmts_from_block (basic_block bb, basic_block new_bb, > set_rename (rename_map, old_name, new_name); > } > > - rename_uses (copy, rename_map, &gsi_tgt, region, loop, iv_map); > + if (rename_uses (copy, rename_map, &gsi_tgt, region, loop, iv_map)) > + fold_stmt_inplace (copy); > > update_stmt (copy); > } > diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog > index 96275ed..3cf399d 100644 > --- a/gcc/testsuite/ChangeLog > +++ b/gcc/testsuite/ChangeLog > @@ -1,3 +1,13 @@ > +2010-12-08 Richard Guenther <rguenther@suse.de> > + Sebastian Pop <sebastian.pop@amd.com> > + > + PR tree-optimization/45230 > + PR tree-optimization/45231 > + PR tree-optimization/45370 > + * gcc.dg/graphite/id-pr45230-1.c: New. > + * gcc.dg/graphite/id-pr45231.c: New. > + * gfortran.dg/graphite/id-pr45370.f90: New. > + > 2010-12-07 Sebastian Pop <sebastian.pop@amd.com> > > PR tree-optimization/44676 > diff --git a/gcc/testsuite/gcc.dg/graphite/id-pr45230-1.c b/gcc/testsuite/gcc.dg/graphite/id-pr45230-1.c > new file mode 100644 > index 0000000..ba14fe5 > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/graphite/id-pr45230-1.c > @@ -0,0 +1,140 @@ > +/* Copyright (C) 2002 Free Software Foundation. > + > + Test strncmp with various combinations of pointer alignments and lengths to > + make sure any optimizations in the library are correct. > + > + Written by Michael Meissner, March 9, 2002. */ > + > +#include <string.h> > +#include <stddef.h> > + > +#ifndef MAX_OFFSET > +#define MAX_OFFSET (sizeof (long long)) > +#endif > + > +#ifndef MAX_TEST > +#define MAX_TEST (8 * sizeof (long long)) > +#endif > + > +#ifndef MAX_EXTRA > +#define MAX_EXTRA (sizeof (long long)) > +#endif > + > +#define MAX_LENGTH (MAX_OFFSET + MAX_TEST + MAX_EXTRA) > + > +static union { > + unsigned char buf[MAX_LENGTH]; > + long long align_int; > + long double align_fp; > +} u1, u2; > + > +void > +test (const unsigned char *s1, const unsigned char *s2, size_t len, int expected) > +{ > + int value = strncmp ((char *) s1, (char *) s2, len); > + > + if (expected < 0 && value >= 0) > + __builtin_abort (); > + else if (expected == 0 && value != 0) > + __builtin_abort (); > + else if (expected > 0 && value <= 0) > + __builtin_abort (); > +} > + > +main () > +{ > + size_t off1, off2, len, i; > + unsigned char *buf1, *buf2; > + unsigned char *mod1, *mod2; > + unsigned char *p1, *p2; > + > + for (off1 = 0; off1 < MAX_OFFSET; off1++) > + for (off2 = 0; off2 < MAX_OFFSET; off2++) > + for (len = 0; len < MAX_TEST; len++) > + { > + p1 = u1.buf; > + for (i = 0; i < off1; i++) > + *p1++ = '\0'; > + > + buf1 = p1; > + for (i = 0; i < len; i++) > + *p1++ = 'a'; > + > + mod1 = p1; > + for (i = 0; i < MAX_EXTRA; i++) > + *p1++ = 'x'; > + > + p2 = u2.buf; > + for (i = 0; i < off2; i++) > + *p2++ = '\0'; > + > + buf2 = p2; > + for (i = 0; i < len; i++) > + *p2++ = 'a'; > + > + mod2 = p2; > + for (i = 0; i < MAX_EXTRA; i++) > + *p2++ = 'x'; > + > + mod1[0] = '\0'; > + mod2[0] = '\0'; > + test (buf1, buf2, MAX_LENGTH, 0); > + test (buf1, buf2, len, 0); > + > + mod1[0] = 'a'; > + mod1[1] = '\0'; > + mod2[0] = '\0'; > + test (buf1, buf2, MAX_LENGTH, +1); > + test (buf1, buf2, len, 0); > + > + mod1[0] = '\0'; > + mod2[0] = 'a'; > + mod2[1] = '\0'; > + test (buf1, buf2, MAX_LENGTH, -1); > + test (buf1, buf2, len, 0); > + > + mod1[0] = 'b'; > + mod1[1] = '\0'; > + mod2[0] = 'c'; > + mod2[1] = '\0'; > + test (buf1, buf2, MAX_LENGTH, -1); > + test (buf1, buf2, len, 0); > + > + mod1[0] = 'c'; > + mod1[1] = '\0'; > + mod2[0] = 'b'; > + mod2[1] = '\0'; > + test (buf1, buf2, MAX_LENGTH, +1); > + test (buf1, buf2, len, 0); > + > + mod1[0] = 'b'; > + mod1[1] = '\0'; > + mod2[0] = (unsigned char)'\251'; > + mod2[1] = '\0'; > + test (buf1, buf2, MAX_LENGTH, -1); > + test (buf1, buf2, len, 0); > + > + mod1[0] = (unsigned char)'\251'; > + mod1[1] = '\0'; > + mod2[0] = 'b'; > + mod2[1] = '\0'; > + test (buf1, buf2, MAX_LENGTH, +1); > + test (buf1, buf2, len, 0); > + > + mod1[0] = (unsigned char)'\251'; > + mod1[1] = '\0'; > + mod2[0] = (unsigned char)'\252'; > + mod2[1] = '\0'; > + test (buf1, buf2, MAX_LENGTH, -1); > + test (buf1, buf2, len, 0); > + > + mod1[0] = (unsigned char)'\252'; > + mod1[1] = '\0'; > + mod2[0] = (unsigned char)'\251'; > + mod2[1] = '\0'; > + test (buf1, buf2, MAX_LENGTH, +1); > + test (buf1, buf2, len, 0); > + } > + > + __builtin_exit (0); > +} > diff --git a/gcc/testsuite/gcc.dg/graphite/id-pr45231.c b/gcc/testsuite/gcc.dg/graphite/id-pr45231.c > new file mode 100644 > index 0000000..01e9a67 > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/graphite/id-pr45231.c > @@ -0,0 +1,37 @@ > +void > +f (n, ppt, xrot) > +{ > + int tileWidth; > + int nlwSrc; > + int srcx; > + int v3, v4; > + register unsigned long ca1, cx1, ca2, cx2; > + unsigned long *pSrcLine; > + register unsigned long *pDst; > + register unsigned long *pSrc; > + register unsigned long b, tmp; > + unsigned long tileEndMask; > + int v1, v2; > + int tileEndPart; > + int needFirst; > + tileEndPart = 0; > + v1 = tileEndPart << 5; > + v2 = 32 - v1; > + while (n--) > + { > + if ((srcx = (ppt - xrot) % tileWidth) < 0) > + if (needFirst) > + if (nlwSrc == 1) > + { > + tmp = b; > + if (tileEndPart) > + b = (*pSrc & tileEndMask) | (*pSrcLine >> v1); > + } > + if (tileEndPart) > + b = (tmp << v1) | (b >> v2); > + if (v4 != 32) > + *pDst = (*pDst & ((tmp << v3) | (b >> v4) & ca1 ^ cx1) > + ^ (((tmp << v3) | (b >> v4)) & ca2 ^ cx2)); > + *pDst = *pDst & tmp; > + } > +} > diff --git a/gcc/testsuite/gfortran.dg/graphite/id-pr45370.f90 b/gcc/testsuite/gfortran.dg/graphite/id-pr45370.f90 > new file mode 100644 > index 0000000..94eebd1 > --- /dev/null > +++ b/gcc/testsuite/gfortran.dg/graphite/id-pr45370.f90 > @@ -0,0 +1,100 @@ > +! > + type :: t > + real :: r > + integer :: i > + character(3) :: chr > + end type t > + > + type :: t2 > + real :: r(2, 2) > + integer :: i > + character(3) :: chr > + end type t2 > + > + type :: s > + type(t), pointer :: t(:) > + end type s > + > + integer, parameter :: sh(2) = (/2,2/) > + real, parameter :: a1(2,2) = reshape ((/1.0,2.0,3.0,4.0/),sh) > + real, parameter :: a2(2,2) = reshape ((/5.0,6.0,7.0,8.0/),sh) > + > + type(t), target :: tar1(2) = (/t(1.0, 2, "abc"), t(3.0, 4, "efg")/) > + character(4), target :: tar2(2) = (/"abcd","efgh"/) > + type(s), target :: tar3 > + character(2), target :: tar4(2) = (/"ab","cd"/) > + type(t2), target :: tar5(2) = (/t2(a1, 2, "abc"), t2(a2, 4, "efg")/) > + > + integer, pointer :: ptr(:) > + character(2), pointer :: ptr2(:) > + real, pointer :: ptr3(:) > + > +!_______________component subreference___________ > + ptr => tar1%i > + ptr = ptr + 1 ! check the scalarizer is OK > + > + if (any (ptr .ne. (/3, 5/))) call abort () > + if (any ((/ptr(1), ptr(2)/) .ne. (/3, 5/))) call abort () > + if (any (tar1%i .ne. (/3, 5/))) call abort () > + > +! Make sure that the other components are not touched. > + if (any (tar1%r .ne. (/1.0, 3.0/))) call abort () > + if (any (tar1%chr .ne. (/"abc", "efg"/))) call abort () > + > +! Check that the pointer is passed correctly as an actual argument. > + call foo (ptr) > + if (any (tar1%i .ne. (/2, 4/))) call abort () > + > +! And that dummy pointers are OK too. > + call bar (ptr) > + if (any (tar1%i .ne. (/101, 103/))) call abort () > + > +!_______________substring subreference___________ > + ptr2 => tar2(:)(2:3) > + ptr2 = ptr2(:)(2:2)//"z" ! again, check the scalarizer > + > + if (any (ptr2 .ne. (/"cz", "gz"/))) call abort () > + if (any ((/ptr2(1), ptr2(2)/) .ne. (/"cz", "gz"/))) call abort () > + if (any (tar2 .ne. (/"aczd", "egzh"/))) call abort () > + > +!_______________substring component subreference___________ > + ptr2 => tar1(:)%chr(1:2) > + ptr2 = ptr2(:)(2:2)//"q" ! yet again, check the scalarizer > + if (any (ptr2 .ne. (/"bq","fq"/))) call abort () > + if (any (tar1%chr .ne. (/"bqc","fqg"/))) call abort () > + > +!_______________trailing array element subreference___________ > + ptr3 => tar5%r(1,2) > + ptr3 = (/99.0, 999.0/) > + if (any (tar5(1)%r .ne. reshape ((/1.0,2.0,99.0,4.0/), sh))) call abort () > + if (any (tar5(2)%r .ne. reshape ((/5.0,6.0,999.0,8.0/), sh))) call abort () > + > +!_______________forall assignment___________ > + ptr2 => tar2(:)(1:2) > + forall (i = 1:2) ptr2(i)(1:1) = "z" > + if (any (tar2 .ne. (/"zczd", "zgzh"/))) call abort () > + > +!_______________something more complicated___________ > + tar3%t => tar1 > + ptr3 => tar3%t%r > + ptr3 = cos (ptr3) > + if (any (abs(ptr3 - (/cos(1.0_4), cos(3.0_4)/)) >= epsilon(1.0_4))) call abort () > + > + ptr2 => tar3%t(:)%chr(2:3) > + ptr2 = " x" > + if (any (tar1%chr .ne. (/"b x", "f x"/))) call abort () > + > +!_______________check non-subref works still___________ > + ptr2 => tar4 > + if (any (ptr2 .ne. (/"ab","cd"/))) call abort () > + > +contains > + subroutine foo (arg) > + integer :: arg(:) > + arg = arg - 1 > + end subroutine > + subroutine bar (arg) > + integer, pointer :: arg(:) > + arg = arg + 99 > + end subroutine > +end > diff --git a/gcc/tree-ssa-copy.c b/gcc/tree-ssa-copy.c > index d552c3a..8897275 100644 > --- a/gcc/tree-ssa-copy.c > +++ b/gcc/tree-ssa-copy.c > @@ -191,7 +191,10 @@ propagate_value (use_operand_p op_p, tree val) > > Use this version when not const/copy propagating values. For example, > PRE uses this version when building expressions as they would appear > - in specific blocks taking into account actions of PHI nodes. */ > + in specific blocks taking into account actions of PHI nodes. > + > + The statement in which an expression has been replaced should be > + folded using fold_stmt_inplace. */ > > void > replace_exp (use_operand_p op_p, tree val) >
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index ff52686..95bd5c0 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,17 @@ +2010-12-08 Richard Guenther <rguenther@suse.de> + Sebastian Pop <sebastian.pop@amd.com> + + PR tree-optimization/45230 + PR tree-optimization/45231 + PR tree-optimization/45370 + * sese.c (rename_uses): Returns a bool. Call + recompute_tree_invariant_for_addr_expr only on the RHS of a + GIMPLE_ASSIGN. + (graphite_copy_stmts_from_block): Call fold_stmt_inplace when + rename_uses returns true. + * tree-ssa-copy.c (replace_exp): Add a comment about calling + fold_stmt_inplace after replace_exp. + 2010-12-07 Paul Koning <ni1d@arrl.net> * config/pdp11/pdp11.c (TARGET_ASM_FUNCTION_SECTION): Define. diff --git a/gcc/sese.c b/gcc/sese.c index 65f8556..3bf6bea 100644 --- a/gcc/sese.c +++ b/gcc/sese.c @@ -470,14 +470,15 @@ set_rename (htab_t rename_map, tree old_name, tree expr) substitution map RENAME_MAP, inserting the gimplification code at GSI_TGT, for the translation REGION, with the original copied statement in LOOP, and using the induction variable renaming map - IV_MAP. */ + IV_MAP. Returns true when something has been renamed. */ -static void +static bool rename_uses (gimple copy, htab_t rename_map, gimple_stmt_iterator *gsi_tgt, sese region, loop_p loop, VEC (tree, heap) *iv_map) { use_operand_p use_p; ssa_op_iter op_iter; + bool changed = false; if (is_gimple_debug (copy)) { @@ -486,7 +487,7 @@ rename_uses (gimple copy, htab_t rename_map, gimple_stmt_iterator *gsi_tgt, else gcc_unreachable (); - return; + return false; } FOR_EACH_SSA_USE_OPERAND (use_p, copy, op_iter, SSA_OP_ALL_USES) @@ -500,6 +501,7 @@ rename_uses (gimple copy, htab_t rename_map, gimple_stmt_iterator *gsi_tgt, || SSA_NAME_IS_DEFAULT_DEF (old_name)) continue; + changed = true; new_expr = get_rename (rename_map, old_name); if (new_expr) { @@ -547,8 +549,8 @@ rename_uses (gimple copy, htab_t rename_map, gimple_stmt_iterator *gsi_tgt, gsi_insert_seq_before (gsi_tgt, stmts, GSI_SAME_STMT); replace_exp (use_p, new_expr); - - if (TREE_CODE (new_expr) == INTEGER_CST) + if (TREE_CODE (new_expr) == INTEGER_CST + && is_gimple_assign (copy)) { tree rhs = gimple_assign_rhs1 (copy); @@ -558,6 +560,8 @@ rename_uses (gimple copy, htab_t rename_map, gimple_stmt_iterator *gsi_tgt, set_rename (rename_map, old_name, new_expr); } + + return changed; } /* Duplicates the statements of basic block BB into basic block NEW_BB @@ -611,7 +615,8 @@ graphite_copy_stmts_from_block (basic_block bb, basic_block new_bb, set_rename (rename_map, old_name, new_name); } - rename_uses (copy, rename_map, &gsi_tgt, region, loop, iv_map); + if (rename_uses (copy, rename_map, &gsi_tgt, region, loop, iv_map)) + fold_stmt_inplace (copy); update_stmt (copy); } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 96275ed..3cf399d 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,13 @@ +2010-12-08 Richard Guenther <rguenther@suse.de> + Sebastian Pop <sebastian.pop@amd.com> + + PR tree-optimization/45230 + PR tree-optimization/45231 + PR tree-optimization/45370 + * gcc.dg/graphite/id-pr45230-1.c: New. + * gcc.dg/graphite/id-pr45231.c: New. + * gfortran.dg/graphite/id-pr45370.f90: New. + 2010-12-07 Sebastian Pop <sebastian.pop@amd.com> PR tree-optimization/44676 diff --git a/gcc/testsuite/gcc.dg/graphite/id-pr45230-1.c b/gcc/testsuite/gcc.dg/graphite/id-pr45230-1.c new file mode 100644 index 0000000..ba14fe5 --- /dev/null +++ b/gcc/testsuite/gcc.dg/graphite/id-pr45230-1.c @@ -0,0 +1,140 @@ +/* Copyright (C) 2002 Free Software Foundation. + + Test strncmp with various combinations of pointer alignments and lengths to + make sure any optimizations in the library are correct. + + Written by Michael Meissner, March 9, 2002. */ + +#include <string.h> +#include <stddef.h> + +#ifndef MAX_OFFSET +#define MAX_OFFSET (sizeof (long long)) +#endif + +#ifndef MAX_TEST +#define MAX_TEST (8 * sizeof (long long)) +#endif + +#ifndef MAX_EXTRA +#define MAX_EXTRA (sizeof (long long)) +#endif + +#define MAX_LENGTH (MAX_OFFSET + MAX_TEST + MAX_EXTRA) + +static union { + unsigned char buf[MAX_LENGTH]; + long long align_int; + long double align_fp; +} u1, u2; + +void +test (const unsigned char *s1, const unsigned char *s2, size_t len, int expected) +{ + int value = strncmp ((char *) s1, (char *) s2, len); + + if (expected < 0 && value >= 0) + __builtin_abort (); + else if (expected == 0 && value != 0) + __builtin_abort (); + else if (expected > 0 && value <= 0) + __builtin_abort (); +} + +main () +{ + size_t off1, off2, len, i; + unsigned char *buf1, *buf2; + unsigned char *mod1, *mod2; + unsigned char *p1, *p2; + + for (off1 = 0; off1 < MAX_OFFSET; off1++) + for (off2 = 0; off2 < MAX_OFFSET; off2++) + for (len = 0; len < MAX_TEST; len++) + { + p1 = u1.buf; + for (i = 0; i < off1; i++) + *p1++ = '\0'; + + buf1 = p1; + for (i = 0; i < len; i++) + *p1++ = 'a'; + + mod1 = p1; + for (i = 0; i < MAX_EXTRA; i++) + *p1++ = 'x'; + + p2 = u2.buf; + for (i = 0; i < off2; i++) + *p2++ = '\0'; + + buf2 = p2; + for (i = 0; i < len; i++) + *p2++ = 'a'; + + mod2 = p2; + for (i = 0; i < MAX_EXTRA; i++) + *p2++ = 'x'; + + mod1[0] = '\0'; + mod2[0] = '\0'; + test (buf1, buf2, MAX_LENGTH, 0); + test (buf1, buf2, len, 0); + + mod1[0] = 'a'; + mod1[1] = '\0'; + mod2[0] = '\0'; + test (buf1, buf2, MAX_LENGTH, +1); + test (buf1, buf2, len, 0); + + mod1[0] = '\0'; + mod2[0] = 'a'; + mod2[1] = '\0'; + test (buf1, buf2, MAX_LENGTH, -1); + test (buf1, buf2, len, 0); + + mod1[0] = 'b'; + mod1[1] = '\0'; + mod2[0] = 'c'; + mod2[1] = '\0'; + test (buf1, buf2, MAX_LENGTH, -1); + test (buf1, buf2, len, 0); + + mod1[0] = 'c'; + mod1[1] = '\0'; + mod2[0] = 'b'; + mod2[1] = '\0'; + test (buf1, buf2, MAX_LENGTH, +1); + test (buf1, buf2, len, 0); + + mod1[0] = 'b'; + mod1[1] = '\0'; + mod2[0] = (unsigned char)'\251'; + mod2[1] = '\0'; + test (buf1, buf2, MAX_LENGTH, -1); + test (buf1, buf2, len, 0); + + mod1[0] = (unsigned char)'\251'; + mod1[1] = '\0'; + mod2[0] = 'b'; + mod2[1] = '\0'; + test (buf1, buf2, MAX_LENGTH, +1); + test (buf1, buf2, len, 0); + + mod1[0] = (unsigned char)'\251'; + mod1[1] = '\0'; + mod2[0] = (unsigned char)'\252'; + mod2[1] = '\0'; + test (buf1, buf2, MAX_LENGTH, -1); + test (buf1, buf2, len, 0); + + mod1[0] = (unsigned char)'\252'; + mod1[1] = '\0'; + mod2[0] = (unsigned char)'\251'; + mod2[1] = '\0'; + test (buf1, buf2, MAX_LENGTH, +1); + test (buf1, buf2, len, 0); + } + + __builtin_exit (0); +} diff --git a/gcc/testsuite/gcc.dg/graphite/id-pr45231.c b/gcc/testsuite/gcc.dg/graphite/id-pr45231.c new file mode 100644 index 0000000..01e9a67 --- /dev/null +++ b/gcc/testsuite/gcc.dg/graphite/id-pr45231.c @@ -0,0 +1,37 @@ +void +f (n, ppt, xrot) +{ + int tileWidth; + int nlwSrc; + int srcx; + int v3, v4; + register unsigned long ca1, cx1, ca2, cx2; + unsigned long *pSrcLine; + register unsigned long *pDst; + register unsigned long *pSrc; + register unsigned long b, tmp; + unsigned long tileEndMask; + int v1, v2; + int tileEndPart; + int needFirst; + tileEndPart = 0; + v1 = tileEndPart << 5; + v2 = 32 - v1; + while (n--) + { + if ((srcx = (ppt - xrot) % tileWidth) < 0) + if (needFirst) + if (nlwSrc == 1) + { + tmp = b; + if (tileEndPart) + b = (*pSrc & tileEndMask) | (*pSrcLine >> v1); + } + if (tileEndPart) + b = (tmp << v1) | (b >> v2); + if (v4 != 32) + *pDst = (*pDst & ((tmp << v3) | (b >> v4) & ca1 ^ cx1) + ^ (((tmp << v3) | (b >> v4)) & ca2 ^ cx2)); + *pDst = *pDst & tmp; + } +} diff --git a/gcc/testsuite/gfortran.dg/graphite/id-pr45370.f90 b/gcc/testsuite/gfortran.dg/graphite/id-pr45370.f90 new file mode 100644 index 0000000..94eebd1 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/graphite/id-pr45370.f90 @@ -0,0 +1,100 @@ +! + type :: t + real :: r + integer :: i + character(3) :: chr + end type t + + type :: t2 + real :: r(2, 2) + integer :: i + character(3) :: chr + end type t2 + + type :: s + type(t), pointer :: t(:) + end type s + + integer, parameter :: sh(2) = (/2,2/) + real, parameter :: a1(2,2) = reshape ((/1.0,2.0,3.0,4.0/),sh) + real, parameter :: a2(2,2) = reshape ((/5.0,6.0,7.0,8.0/),sh) + + type(t), target :: tar1(2) = (/t(1.0, 2, "abc"), t(3.0, 4, "efg")/) + character(4), target :: tar2(2) = (/"abcd","efgh"/) + type(s), target :: tar3 + character(2), target :: tar4(2) = (/"ab","cd"/) + type(t2), target :: tar5(2) = (/t2(a1, 2, "abc"), t2(a2, 4, "efg")/) + + integer, pointer :: ptr(:) + character(2), pointer :: ptr2(:) + real, pointer :: ptr3(:) + +!_______________component subreference___________ + ptr => tar1%i + ptr = ptr + 1 ! check the scalarizer is OK + + if (any (ptr .ne. (/3, 5/))) call abort () + if (any ((/ptr(1), ptr(2)/) .ne. (/3, 5/))) call abort () + if (any (tar1%i .ne. (/3, 5/))) call abort () + +! Make sure that the other components are not touched. + if (any (tar1%r .ne. (/1.0, 3.0/))) call abort () + if (any (tar1%chr .ne. (/"abc", "efg"/))) call abort () + +! Check that the pointer is passed correctly as an actual argument. + call foo (ptr) + if (any (tar1%i .ne. (/2, 4/))) call abort () + +! And that dummy pointers are OK too. + call bar (ptr) + if (any (tar1%i .ne. (/101, 103/))) call abort () + +!_______________substring subreference___________ + ptr2 => tar2(:)(2:3) + ptr2 = ptr2(:)(2:2)//"z" ! again, check the scalarizer + + if (any (ptr2 .ne. (/"cz", "gz"/))) call abort () + if (any ((/ptr2(1), ptr2(2)/) .ne. (/"cz", "gz"/))) call abort () + if (any (tar2 .ne. (/"aczd", "egzh"/))) call abort () + +!_______________substring component subreference___________ + ptr2 => tar1(:)%chr(1:2) + ptr2 = ptr2(:)(2:2)//"q" ! yet again, check the scalarizer + if (any (ptr2 .ne. (/"bq","fq"/))) call abort () + if (any (tar1%chr .ne. (/"bqc","fqg"/))) call abort () + +!_______________trailing array element subreference___________ + ptr3 => tar5%r(1,2) + ptr3 = (/99.0, 999.0/) + if (any (tar5(1)%r .ne. reshape ((/1.0,2.0,99.0,4.0/), sh))) call abort () + if (any (tar5(2)%r .ne. reshape ((/5.0,6.0,999.0,8.0/), sh))) call abort () + +!_______________forall assignment___________ + ptr2 => tar2(:)(1:2) + forall (i = 1:2) ptr2(i)(1:1) = "z" + if (any (tar2 .ne. (/"zczd", "zgzh"/))) call abort () + +!_______________something more complicated___________ + tar3%t => tar1 + ptr3 => tar3%t%r + ptr3 = cos (ptr3) + if (any (abs(ptr3 - (/cos(1.0_4), cos(3.0_4)/)) >= epsilon(1.0_4))) call abort () + + ptr2 => tar3%t(:)%chr(2:3) + ptr2 = " x" + if (any (tar1%chr .ne. (/"b x", "f x"/))) call abort () + +!_______________check non-subref works still___________ + ptr2 => tar4 + if (any (ptr2 .ne. (/"ab","cd"/))) call abort () + +contains + subroutine foo (arg) + integer :: arg(:) + arg = arg - 1 + end subroutine + subroutine bar (arg) + integer, pointer :: arg(:) + arg = arg + 99 + end subroutine +end diff --git a/gcc/tree-ssa-copy.c b/gcc/tree-ssa-copy.c index d552c3a..8897275 100644 --- a/gcc/tree-ssa-copy.c +++ b/gcc/tree-ssa-copy.c @@ -191,7 +191,10 @@ propagate_value (use_operand_p op_p, tree val) Use this version when not const/copy propagating values. For example, PRE uses this version when building expressions as they would appear - in specific blocks taking into account actions of PHI nodes. */ + in specific blocks taking into account actions of PHI nodes. + + The statement in which an expression has been replaced should be + folded using fold_stmt_inplace. */ void replace_exp (use_operand_p op_p, tree val)