In this, the expression a>0 is evaluated twice, both in the *.original and the *.optimized dump:
function average(a, n) real :: average real :: a(n) average = sum(a, a>0)/count(a>0) end function average $ cat average.f90.003t.original average (a, n) { int4 ubound.0; int4 size.1; real4 __result_average; int4 D.1012; bit_size_type D.1013; <unnamed type> D.1014; ubound.0 = *n; size.1 = NON_LVALUE_EXPR <ubound.0>; size.1 = size.1 >= 0 ? size.1 : 0; D.1012 = size.1 - 1; D.1013 = (bit_size_type) (<unnamed type>) size.1 * 32; D.1014 = (<unnamed type>) size.1 * 4; { int4 D.1008; int4 count.4; int4 D.1004; int4 D.1003; real4 val.2; val.2 = 0.0; D.1003 = ubound.0; D.1004 = ubound.0; { int4 S.3; S.3 = 1; while (1) { if (S.3 > ubound.0) goto L.1; if ((*a)[S.3 + -1] > 0.0) { val.2 = val.2 + (*a)[S.3 + -1]; } S.3 = S.3 + 1; } L.1:; } count.4 = 0; D.1008 = ubound.0; { int4 S.5; S.5 = 1; while (1) { if (S.5 > ubound.0) goto L.2; if ((*a)[S.5 + -1] > 0.0) { count.4 = count.4 + 1; } S.5 = S.5 + 1; } L.2:; } __result_average = val.2 / (real4) count.4; } return __result_average; } $ cat average.f90.113t.optimized ;; Function average (average_) Analyzing Edge Insertions. average (a, n) { <unnamed type> ivtmp.49; <unnamed type> ivtmp.44; real4 prephitmp.36; real4 val.2; int4 count.4; int4 size.1; real4 D.1020; <bb 2>: size.1 = *n; if (size.1 <= 0) goto <L39>; else goto <L37>; <L39>:; val.2 = 0.0; prephitmp.36 = 0.0; goto <bb 10> (L.2); <L37>:; val.2 = 0.0; ivtmp.49 = 1; <L4>:; D.1020 = MEM[base: a, index: (<unnamed type>) ivtmp.49, step: 4, offset: 0x0fffffffc]; if (D.1020 > 0.0) goto <L5>; else goto <L6>; <L5>:; val.2 = val.2 + D.1020; <L6>:; ivtmp.49 = ivtmp.49 + 1; if (size.1 < (int4) ivtmp.49) goto <L38>; else goto <L4>; <L38>:; count.4 = 0; ivtmp.44 = 1; <L9>:; if (MEM[base: a, index: (<unnamed type>) ivtmp.44, step: 4, offset: 0x0fffffffc] > 0.0) goto <L10>; else goto <L11>; <L10>:; count.4 = count.4 + 1; <L11>:; ivtmp.44 = ivtmp.44 + 1; if (size.1 < (int4) ivtmp.44) goto <L30>; else goto <L9>; <L30>:; prephitmp.36 = (real4) count.4; L.2:; return val.2 / prephitmp.36; } -- Summary: Calculating masks twice Product: gcc Version: 4.3.0 Status: UNCONFIRMED Keywords: missed-optimization Severity: enhancement Priority: P3 Component: fortran AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: tkoenig at gcc dot gnu dot org http://gcc.gnu.org/bugzilla/show_bug.cgi?id=30609