Open ZY546 opened 7 months ago
Reduced:
declare void @dummy()
define void @func(i32 noundef %size_) {
entry:
%add = add i32 %size_, 1
%cmp12 = icmp sgt i32 %add, 1
br i1 %cmp12, label %for.body, label %for.cond.cleanup
for.body: ; preds = %entry, %if.end
%i = phi i32 [ %inc, %if.end ], [ 1, %entry ]
%size.iv = phi i32 [ %size.next, %if.end ], [ %size_, %entry ]
%tobool.not = icmp eq i32 %size.iv, 0
br i1 %tobool.not, label %if.end, label %if.then
if.then: ; preds = %for.body
tail call void @dummy()
br label %if.end
if.end: ; preds = %if.then, %for.body
%size.next = phi i32 [ %size.iv, %if.then ], [ -1, %for.body ]
%inc = add nuw nsw i32 %i, 1
%cmp = icmp slt i32 %i, %size.next
br i1 %cmp, label %for.body, label %for.cond.cleanup
for.cond.cleanup: ; preds = %if.end, %entry
ret void
}
For this example with -fwrapv
flag, the root cause should be that GVN fails to propagate complex condition 1 < size_ + 1
and infer that size_t != 0
is false. A possible fix is to take such complex condition pattern into account.
Hello, we notice in the code below that
size_
is a loop invariant (if size_==0 then it won't go into the loop).https://godbolt.org/z/Wxo38e4jG
But Clang -O3 -fwrapv:
GCC -O3 -fwrapv: