ig25@linux-fd1f:~/Krempel/Compare> cat op.f90 program main integer, volatile :: j if (j>j) call notfound end program main ig25@linux-fd1f:~/Krempel/Compare> gfortran op.f90 ig25@linux-fd1f:~/Krempel/Compare> The call to notfound should not be elided.
Apparently, VOLATILE has no effect at all. Another test case: ig25@linux-fd1f:~/Krempel/Volatile> cat op2.f90 subroutine foo(j) integer, volatile :: j integer :: b b = j + j + j + j print *,b end ig25@linux-fd1f:~/Krempel/Volatile> gfortran -S -O3 -fdump-tree-optimized op2.f90 ig25@linux-fd1f:~/Krempel/Volatile> cat op2.f90.144t.optimized ;; Function foo (foo_) foo (integer(kind=4) & restrict j) { struct __st_parameter_dt dt_parm.0; integer(kind=4) b; integer(kind=4) b.1; integer(kind=4) D.1504; integer(kind=4) D.1503; integer(kind=4) D.1502; <bb 2>: D.1502_3 = *j_1(D); D.1503_4 = D.1502_3 + D.1502_3; D.1504_6 = D.1502_3 + D.1503_4; b.1_8 = D.1502_3 + D.1504_6; b = b.1_8; dt_parm.0.common.filename = &"op2.f90"[1]{lb: 1 sz: 1}; dt_parm.0.common.line = 5; dt_parm.0.common.flags = 128; dt_parm.0.common.unit = 6; _gfortran_st_write (&dt_parm.0); _gfortran_transfer_integer_write (&dt_parm.0, &b, 4); _gfortran_st_write_done (&dt_parm.0); return; } Tobias, any ideas? You implemented this a few years ago, if I remember correctly :-)
(In reply to comment #1) > Apparently, VOLATILE has no effect at all. Another test case: [...] > Tobias, any ideas? No idea: $ LANG= gfortran -v 2>&1|grep -E 'experi|Targ' Target: x86_64-unknown-linux-gnu gcc version 4.6.0 20101111 (experimental) [trunk revision 166614] (GCC) $ gfortran -fdump-tree-original -fdump-tree-optimized -O3 -c test.f90 $ cat test.f90.003t.original ... integer(kind=4) b; volatile integer(kind=4) j; b = ((j + j) + j) + j; ... $ cat test.f90.144t.optimized ... j.1_1 ={v} j; j.1_2 ={v} j; D.1508_3 = j.1_2 + j.1_2; j.1_4 ={v} j; D.1509_5 = D.1508_3 + j.1_4; j.1_6 ={v} j; b.2_7 = D.1509_5 + j.1_6; Looks good!
I think the first test case is wrongly folded already by the front end: program main integer, volatile :: j if (j>j) call notfound end program main Gives the original dump: MAIN__ () { volatile integer(kind=4) j; L.1:; } * * * For some reason, also: program main integer, volatile :: j, k if (j>k) call notfound end program main does not give a link error. The optimized dump has: j.1_8 ={v} j; k.2_9 ={v} k; if (j.1_8 > k.2_9) goto <bb 3>; <bb 3>: notfound (); which looks OK, but there is no link error?!?
(In reply to comment #2) > (In reply to comment #1) > > Apparently, VOLATILE has no effect at all. Another test case: > [...] > > Tobias, any ideas? > > No idea: > > $ cat test.f90.003t.original > ... > integer(kind=4) b; > volatile integer(kind=4) j; > > b = ((j + j) + j) + j; I see: foo (integer(kind=4) & restrict j) { integer(kind=4) b; b = ((*j + *j) + *j) + *j; { struct __st_parameter_dt dt_parm.0; so the volatile is missing. Huh? This may be a Heisenbug. Unfortunately, valgrind doesn't work on my system.
(In reply to comment #4) > > volatile integer(kind=4) j; > I see: > foo (integer(kind=4) & restrict j) > so the volatile is missing. Huh? Seemingly, we have tested different things - I looked a local variable "j" which works while you looked at a dummy variable, which does not seem to work. Thus, not a Heisenbug. If one prints the symbol "j" one gets as backend declaration: (gdb) p debug_tree (...->symtree->n.sym->backend_decl) <parm_decl 0x2aaaace2e880 j type <reference_type 0x2aaaacf1d930 type <integer_type 0x2aaaace37498 integer(kind=4) public SI size <integer_cst 0x2aaaace276e0 constant 32> unit size <integer_cst 0x2aaaace273e8 constant 4> align 32 symtab 0 alias set -1 canonical type 0x2aaaace37498 precision 32 min <integer_cst 0x2aaaace27668 -2147483648> max <integer_cst 0x2aaaace27690 2147483647> pointer_to_this <pointer_type 0x2aaaace443f0> reference_to_this <reference_type 0x2aaaacf1d888>> unsigned restrict DI size <integer_cst 0x2aaaace277a8 constant 64> unit size <integer_cst 0x2aaaace277d0 constant 8> align 64 symtab 0 alias set -1 canonical type 0x2aaaacf1d930> readonly used unsigned DI passed-by-reference file jfff4322.f90 line 1 col 0 size <integer_cst 0x2aaaace277a8 64> unit size <integer_cst 0x2aaaace277d0 8> align 64 context <function_decl 0x2aaaacf1e600 foo> arg-type <reference_type 0x2aaaacf1d930>> While for my local variable, one gets: <var_decl 0x2aaaacf200a0 j type <integer_type 0x2aaaacf1d9d8 integer(kind=4) volatile SI size <integer_cst 0x2aaaace276e0 constant 32> unit size <integer_cst 0x2aaaace273e8 constant 4> align 32 symtab 0 alias set -1 canonical type 0x2aaaacf1d9d8 precision 32 min <integer_cst 0x2aaaace27668 -2147483648> max <integer_cst 0x2aaaace27690 2147483647>> volatile used SI file jfff4322.f90 line 2 col 0 size <integer_cst 0x2aaaace276e0 32> unit size <integer_cst 0x2aaaace273e8 4> align 32 context <function_decl 0x2aaaacf1e600 foo> chain <var_decl 0x2aaaacf20000 b>> Thus, the latter properly has the proper values. Seemingly, a THREE_IS_VOLATILE or TYPE_QUAL_VOLATILE is missing somewhere. * * * For the test case in comment 0 alias comment 3 part one, the reason is clear: The fold-const.c's fold_build2_stat_loc with code=GT_EXPR always and unconditionally folds "j > j" to "false". I have no idea whether that's OK or not - but as a C test case behaves differently, that's now tracked as PR 46458. * * * Second test case of comment 3: Why is the "volatile" lost between the SSA tree (-fdump-tree-optimize still has it) and RTL (-fdump-rtl-all, which does not have any "mem/v" reference)? I am currently looking into that issue.
*** Bug 46458 has been marked as a duplicate of this bug. ***
OK. The (j>j) and the tree->RTL issue are solved by the following patch. Thanks to Andrew, Ian, Richard et al. (at #gcc) for the debugging help. diff --git a/gcc/fortran/trans-common.c b/gcc/fortran/trans-common.c index 486fbbb..1f59a69 100644 --- a/gcc/fortran/trans-common.c +++ b/gcc/fortran/trans-common.c @@ -322,6 +322,7 @@ build_field (segment_info *h, tree union_type, record_layout_info rli) { tree new_type; TREE_THIS_VOLATILE (field) = 1; + TREE_SIDE_EFFECTS (field) = 1; new_type = build_qualified_type (TREE_TYPE (field), TYPE_QUAL_VOLATILE); TREE_TYPE (field) = new_type; } diff --git a/gcc/fortran/trans-decl.c b/gcc/fortran/trans-decl.c index 3f068de..845c96b 100644 --- a/gcc/fortran/trans-decl.c +++ b/gcc/fortran/trans-decl.c @@ -555,6 +555,7 @@ gfc_finish_var_decl (tree decl, gfc_symbol * sym) if (sym->attr.volatile_) { TREE_THIS_VOLATILE (decl) = 1; + TREE_SIDE_EFFECTS (decl) = 1; new_type = build_qualified_type (TREE_TYPE (decl), TYPE_QUAL_VOLATILE); TREE_TYPE (decl) = new_type; }
The issue with the dummy is: Volatile will be set in gfc_get_symbol_decl - but only if there is no backend declaration. For DUMMY arguments there is. Thus, one needs to handle them differently. Patch: --- a/gcc/fortran/trans-decl.c +++ b/gcc/fortran/trans-decl.c @@ -1944,10 +1945,19 @@ create_function_arglist (gfc_symbol * sym) if (f->sym->attr.proc_pointer) type = build_pointer_type (type); + if (f->sym->attr.volatile_) + type = build_qualified_type (type, TYPE_QUAL_VOLATILE); + /* Build the argument declaration. */ parm = build_decl (input_location, PARM_DECL, gfc_sym_identifier (f->sym), type); + if (f->sym->attr.volatile_) + { + TREE_THIS_VOLATILE (parm) = 1; + TREE_SIDE_EFFECTS (parm) = 1; + } + /* Fill in arg stuff. */ DECL_CONTEXT (parm) = fndecl; DECL_ARG_TYPE (parm) = TREE_VALUE (typelist);
Test case: --- /dev/null +++ b/gcc/testsuite/gfortran.dg/volatile12.f90 @@ -0,0 +1,16 @@ +! { dg-do compile } +! { dg-options "-fdump-tree-optimized -O3" } +! +! PR fortran/45742 +! + +subroutine sub(arg) + integer, volatile :: arg + if (arg /= arg) call I_dont_exist() +end + +! { dg-final { scan-tree-dump "integer.kind=.. . volatile arg" "optimized" } } +! { dg-final { scan-tree-dump-times " =.v. arg;" 2 "optimized" } } +! { dg-final { scan-tree-dump "i_dont_exist" "optimized" } } +! { dg-final { cleanup-tree-dump "original" } }
Author: burnus Date: Sat Nov 13 10:29:04 2010 New Revision: 166701 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=166701 Log: 2010-11-13 Tobias Burnus <burnus@net-b.de> PR fortran/45742 * trans-common.c (build_field): Add TREE_SIDE_EFFECTS for * volatile. * trans-decl.c (gfc_finish_var_decl): Ditto. (create_function_arglist): Handle volatile dummy arguments. 2010-11-13 Tobias Burnus <burnus@net-b.de> PR fortran/45742 * gfortran.dg/volatile12.f90: New. Added: trunk/gcc/testsuite/gfortran.dg/volatile12.f90 Modified: trunk/gcc/fortran/ChangeLog trunk/gcc/fortran/trans-common.c trunk/gcc/fortran/trans-decl.c trunk/gcc/testsuite/ChangeLog
Author: burnus Date: Sat Nov 13 11:46:25 2010 New Revision: 166702 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=166702 Log: 2010-11-13 Tobias Burnus <burnus@net-b.de> PR fortran/45742 * gfortran.dg/volatile12.f90: Use the right three in * cleanup-tree-dump. Modified: trunk/gcc/testsuite/ChangeLog trunk/gcc/testsuite/gfortran.dg/volatile12.f90
Author: burnus Date: Sat Nov 13 17:23:49 2010 New Revision: 166714 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=166714 Log: 2010-11-13 Tobias Burnus <burnus@net-b.de> PR fortran/45742 * trans-common.c (build_field): Add TREE_SIDE_EFFECTS for * volatile. * trans-decl.c (gfc_finish_var_decl): Ditto. (create_function_arglist): Handle volatile dummy arguments. 2010-11-13 Tobias Burnus <burnus@net-b.de> PR fortran/45742 * gfortran.dg/volatile12.f90: New. Added: branches/gcc-4_5-branch/gcc/testsuite/gfortran.dg/volatile12.f90 Modified: branches/gcc-4_5-branch/gcc/fortran/ChangeLog branches/gcc-4_5-branch/gcc/fortran/trans-common.c branches/gcc-4_5-branch/gcc/fortran/trans-decl.c branches/gcc-4_5-branch/gcc/testsuite/ChangeLog
Author: burnus Date: Sat Nov 13 17:25:28 2010 New Revision: 166715 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=166715 Log: 2010-11-13 Tobias Burnus <burnus@net-b.de> PR fortran/45742 * trans-common.c (build_field): Add TREE_SIDE_EFFECTS for * volatile. * trans-decl.c (gfc_finish_var_decl): Ditto. (create_function_arglist): Handle volatile dummy arguments. 2010-11-13 Tobias Burnus <burnus@net-b.de> PR fortran/45742 * gfortran.dg/volatile12.f90: New. Added: branches/gcc-4_4-branch/gcc/testsuite/gfortran.dg/volatile12.f90 Modified: branches/gcc-4_4-branch/gcc/fortran/ChangeLog branches/gcc-4_4-branch/gcc/fortran/trans-common.c branches/gcc-4_4-branch/gcc/fortran/trans-decl.c branches/gcc-4_4-branch/gcc/testsuite/ChangeLog
FIXED on the trunk (4.6) and the 4.5 and 4.4 branches. Thanks for the report.