[llvm-dev] Bug in pass 'ipsccp' on function attribute 'argmemonly'?
Fangqing Du via llvm-dev
llvm-dev at lists.llvm.org
Fri Jul 10 19:04:41 PDT 2020
Hi all,
Let's see an example (from Alexandre Isoard) first:
****************************************************************************************
; RUN: opt -ipsccp -deadargelim -licm -O2 -S < %s
@g = internal global i32 0
; Function Attrs: argmemonly
define internal void @foo(i32* nonnull dereferenceable(4) %arg, i32 %val) #0
{
entry:
store i32 %val, i32* %arg
ret void
}
define i32 @bar(i32 %n) {
entry:
store i32 1, i32* @g
br label %loop
loop: ; preds = %bb1, %bb
%i = phi i32 [ %i.inc, %loop ], [ 0, %entry ]
%g.val = load i32, i32* @g
%g.inc = add nuw i32 %g.val, 1
tail call void @foo(i32* @g, i32 %g.inc)
%i.inc = add nuw i32 %i, 1
%cond = icmp eq i32 %i.inc, %n
br i1 %cond, label %exit, label %loop
exit: ; preds = %bb1
ret i32 %g.val
}
declare void @llvm.assume(i1)
attributes #0 = { argmemonly }
****************************************************************************************
With opt cmd '-ipsccp -deadargelim -licm -O2', function @bar will return
constant value 1, instead of correct value %n. This is crazy, right?
Let's see what happens here.
Due to pass 'ipsccp' replaced the argument of function '@foo' with global
variable '@g', but keeps attr 'argmemonly' there, so pass 'licm' will hoist
the load of '@g' before the loop (as the value of @g isn't changed, but it
is changed), and will cause function return wrong constant value '1',
instead of '%n' (the correct value) , like following:
****************************************************************************************
; Function Attrs: nofree norecurse nounwind writeonly
define i32 @bar(i32 %n) local_unnamed_addr #0 {
entry:
ret i32 1
}
attributes #0 = { nofree norecurse nounwind writeonly }
****************************************************************************************
And if remove the 'argmemonly' attribute, function @bar will return the
correct value:
****************************************************************************************
; Function Attrs: nofree norecurse nounwind
define i32 @bar(i32 %n) local_unnamed_addr #0 {
entry:
ret i32 %n
}
****************************************************************************************
So if function attribute 'argmemonly' on function @foo is correct, then
there's a bug in pass 'ipsccp'. When it replaces the function local value
with global variable, then it shoud remember to remove this function
attribute.
Thanks,
Fangqing
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20200710/71e12c6e/attachment.html>
More information about the llvm-dev
mailing list