[llvm-bugs] [Bug 49688] New: WRONG code CFGOpt? InstCombine?
via llvm-bugs
llvm-bugs at lists.llvm.org
Mon Mar 22 16:01:22 PDT 2021
https://bugs.llvm.org/show_bug.cgi?id=49688
Bug ID: 49688
Summary: WRONG code CFGOpt? InstCombine?
Product: libraries
Version: trunk
Hardware: PC
OS: Linux
Status: NEW
Severity: normal
Priority: P
Component: Scalar Optimizations
Assignee: unassignedbugs at nondot.org
Reporter: paulsson at linux.vnet.ibm.com
CC: llvm-bugs at lists.llvm.org
Created attachment 24682
--> https://bugs.llvm.org/attachment.cgi?id=24682&action=edit
reduced testcase
This program (wrong0.i):
static int *a;
int b, d;
int *c = &b;
int main() {
int e[3] = {2, 1, -2139220656};
a = &e[0];
d = (e[2] < 0) || (e[2] > (7 >> e[2]));
*c = d;
printf("%d\n", b);
}
I beleive the right-shift with a known negative value is undefined, but since
the first expression is always true, the program as a whole is still
well-defined, or?
Since e[2] is always less than 0, I would expect the second expression (after
the '||') to never be evaluated. However, SimplifyCFGPass does not understand
that the first expression is always true and so merges them so that they are
always both executed. I wonder why this is allowed...?
%1 = load i32, i32* %arrayidx1, align 4, !tbaa !6
%cmp = icmp slt i32 %1, 0
%shr = ashr i32 7, %1
%cmp4 = icmp sgt i32 %1, %shr
%2 = select i1 %cmp, i1 true, i1 %cmp4
Then InstCombine decides to remove the first check against less than zero:
%arrayidx1 = getelementptr inbounds [3 x i32], [3 x i32]* %e, i64 0, i64 2
%1 = load i32, i32* %arrayidx1, align 4, !tbaa !6
%shr = lshr i32 7, %1
%2 = icmp ugt i32 %1, %shr
%lor.ext = zext i1 %2 to i32
store i32 %lor.ext, i32* @d, align 4, !tbaa !6
So it seems that the user has written a well-defined program, but the compiler
has failed to realize this through the known constants.
clang -march=arch13 -O1 wrong0.i -o a.out -w; ./a.out
1
clang -march=arch13 -O2 wrong0.i -o a.out -w; ./a.out
0
clang -march=arch13 -O2 wrong0.i -o a.out -mllvm -enable-gvn-memdep=false -w;
./a.out
1
clang -march=arch13 -O2 wrong0.i -o a.out -mllvm -memssa-check-limit=0 -w;
./a.out
0
The store of '0' to @d is then later produced by GVN:
*** IR Dump After MergedLoadStoreMotionPass ***
; Function Attrs: nofree nounwind
define dso_local signext i32 @main() local_unnamed_addr #0 {
entry:
%e = alloca [3 x i32], align 4
%0 = bitcast [3 x i32]* %e to i8*
call void @llvm.lifetime.start.p0i8(i64 12, i8* nonnull %0) #2
call void @llvm.memcpy.p0i8.p0i8.i64(i8* noundef nonnull align 4
dereferenceable(12) %0, i8* noundef nonnull align 4 dereferenceable(12) bitcast
([3 x i32]* @__const.main.e to i8*), i64 12, i1 false)
%arrayidx = getelementptr inbounds [3 x i32], [3 x i32]* %e, i64 0, i64 0
store i32* %arrayidx, i32** @a, align 8, !tbaa !2
%arrayidx1 = getelementptr inbounds [3 x i32], [3 x i32]* %e, i64 0, i64 2
%1 = load i32, i32* %arrayidx1, align 4, !tbaa !6
%shr = lshr i32 7, %1
%2 = icmp ugt i32 %1, %shr
%lor.ext = zext i1 %2 to i32
store i32 %lor.ext, i32* @d, align 4, !tbaa !6
%3 = load i32*, i32** @c, align 8, !tbaa !2
store i32 %lor.ext, i32* %3, align 4, !tbaa !6
%4 = load i32, i32* @b, align 4, !tbaa !6
%call = call signext i32 (i8*, ...) @printf(i8* nonnull dereferenceable(1)
getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i64 0, i64 0), i32 signext
%4)
call void @llvm.lifetime.end.p0i8(i64 12, i8* nonnull %0) #2
ret i32 0
}
*** IR Dump After GVN ***
; Function Attrs: nofree nounwind
define dso_local signext i32 @main() local_unnamed_addr #0 {
entry:
%e = alloca [3 x i32], align 4
%0 = bitcast [3 x i32]* %e to i8*
call void @llvm.lifetime.start.p0i8(i64 12, i8* nonnull %0) #2
call void @llvm.memcpy.p0i8.p0i8.i64(i8* noundef nonnull align 4
dereferenceable(12) %0, i8* noundef nonnull align 4 dereferenceable(12) bitcast
([3 x i32]* @__const.main.e to i8*), i64 12, i1 false)
%arrayidx = getelementptr inbounds [3 x i32], [3 x i32]* %e, i64 0, i64 0
store i32* %arrayidx, i32** @a, align 8, !tbaa !2
%arrayidx1 = getelementptr inbounds [3 x i32], [3 x i32]* %e, i64 0, i64 2
store i32 0, i32* @d, align 4, !tbaa !6
%1 = load i32*, i32** @c, align 8, !tbaa !2
store i32 0, i32* %1, align 4, !tbaa !6
%2 = load i32, i32* @b, align 4, !tbaa !6
%call = call signext i32 (i8*, ...) @printf(i8* nonnull dereferenceable(1)
getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i64 0, i64 0), i32 signext
%2)
call void @llvm.lifetime.end.p0i8(i64 12, i8* nonnull %0) #2
ret i32 0
}
--
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20210322/fe9d67c7/attachment-0001.html>
More information about the llvm-bugs
mailing list