[4bsd-f77 #29] F77 sometimes does improper code motion
4.2 BSD f77 bug reports
4bsd-f77 at utah-cs.UUCP
Tue Aug 28 14:46:12 AEST 1984
From: Donn Seeley <donn at utah-cs.arpa>
Subject: F77 sometimes does improper code motion
Index: usr.bin/f77/src/f77pass1/optloop.c 4.2BSD
Description:
If a subroutine or function is passed as an EXTERNAL object to
another routine, the code motion optimization in f77 fails to
recognize that the EXTERNAL routine can modify its arguments.
This bug was found by Jerry Berkman at Berkeley and fixed by a
friend of his.
Repeat-By:
The following program is courtesy Jerry Berkman. Clip it out
and compile it with the optimizer on:
----------------------------------------------------------------
c bug in optimizer - does improper code motion:
c in sub1 ASSUMES iter not
c changed in call on sub
c same bug exists for functions - change 'call sub(iter)' to
c y = sub(iter) and have sub2 return 0.0
external sub2
call sub1(sub2)
end
subroutine sub1( sub )
external sub
iter = -5
do 10 i = 1, 10
call sub( iter )
if(iter.gt.0) go to 40
10 continue
40 print *, ' all done ', iter
end
subroutine sub2( iter )
iter = iter + 1
end
----------------------------------------------------------------
When you run it, it prints 'all done 5' instead of 'all done 1'
like it should.
Fix:
From looking at the assembly output, the problem is obvious --
here is the loop in sub1 (prettied up some):
----------------------------------------------------------------
mnegl $5,{iter}
tstl {iter} # Compute iter.gt.0
jleq L9999
movl $1,r0 # r0 is 1 if iter.gt.0 is true
jbr L9998
L9999:
clrl r0 # 0 otherwise
L9998:
movl r0,-4(fp)
movl r0,r10
movl $1,{i} # Start the loop
L23:
pushab {iter}
calls $1,*4(ap) # Call sub(iter)
tstl r10 # Use the result of iter.gt.0
jneq L27
aobleq $10,{i},L23
L27:
----------------------------------------------------------------
The problem is that the computation 'iter.gt.0' is treated as a
loop invariant and is moved in front of the loop. The compiler
doesn't realize that the subroutine call can alter the argument
'iter' -- thus the loop is run the full 10 times instead of
stopping when 'iter' reaches 1.
One way of fixing this is to force the compiler to assume that
all routines except those it explicitly knows are intrinsic
can alter their arguments. The change is in setsuses() in
optloop.c:
----------------------------------------------------------------
*** /tmp/,RCSt1006165 Fri Jul 20 23:33:15 1984
--- optloop.c Thu Jul 19 11:53:31 1984
***************
*** 347,353
fatal("O8: subprogram expected");
setsuses(p->exprblock.rightp);
setsuses(p->exprblock.vleng);
! if (p->exprblock.leftp->addrblock.vstg != STGEXT) break;
commonset = YES;
if (p->exprblock.rightp == NULL) break;
args = p->exprblock.rightp->listblock.listp;
--- 362,368 -----
fatal("O8: subprogram expected");
setsuses(p->exprblock.rightp);
setsuses(p->exprblock.vleng);
! if (p->exprblock.leftp->addrblock.vstg == STGINTR) break;
commonset = YES;
if (p->exprblock.rightp == NULL) break;
args = p->exprblock.rightp->listblock.listp;
----------------------------------------------------------------
Donn Seeley University of Utah CS Dept donn at utah-cs.arpa
40 46' 6"N 111 50' 34"W (801) 581-5668 decvax!utah-cs!donn
More information about the Comp.bugs.4bsd.ucb-fixes
mailing list