Issue |
123151
|
Summary |
[InstCombine] Miscompilation caused by incorrect ICMP predicate
|
Labels |
new issue
|
Assignees |
|
Reporter |
mshockwave
|
This is discovered from 445.gobmk when compiling it with RISC-V LLVM:
```
clang --target riscv64-linux-gnu -mcpu=sifive-p670 -O1 -mno-implicit-float ...
```
This is the reproducer snippet:
```llvm
define dso_local i1 @gg_sort.do.body.split(i32 %gap.0, i64 %width, ptr %base, ptr %div.out, ptr %add.ptr4.out, i64 noundef %nel) {
newFuncRoot:
%sub = add i64 %nel, -1
%mul = mul i64 %width, %sub
%add.ptr = getelementptr inbounds nuw i8, ptr %base, i64 %mul
br label %do.body.split
do.body.split: ; preds = %newFuncRoot
%mul1 = mul nsw i32 %gap.0, 10
%add = add nsw i32 %mul1, 3
%div = sdiv i32 %add, 13
store i32 %div, ptr %div.out, align 4
%conv2 = sext i32 %div to i64
%mul3 = mul i64 %conv2, %width
%add.ptr4 = getelementptr inbounds nuw i8, ptr %base, i64 %mul3
store ptr %add.ptr4, ptr %add.ptr4.out, align 8
%cmp5.not21 = icmp ugt ptr %add.ptr4, %add.ptr
br i1 %cmp5.not21, label %for.end.exitStub, label %for.body.exitStub
for.end.exitStub: ; preds = %do.body.split
ret i1 true
for.body.exitStub: ; preds = %do.body.split
ret i1 false
}
```
With this command:
```
opt -p instcombine input.ll ...
```
The following code is generated:
```llvm
define dso_local i1 @gg_sort.do.body.split(i32 %gap.0, i64 %width, ptr %base, ptr %div.out, ptr %add.ptr4.out, i64 noundef %nel) {
newFuncRoot:
br label %do.body.split
do.body.split: ; preds = %newFuncRoot
%sub = add i64 %nel, -1
%mul = mul i64 %width, %sub
%mul1 = mul nsw i32 %gap.0, 10
%add = add nsw i32 %mul1, 3
%div = sdiv i32 %add, 13
store i32 %div, ptr %div.out, align 4
%conv2 = sext i32 %div to i64
%mul3 = mul i64 %width, %conv2
%add.ptr4 = getelementptr inbounds nuw i8, ptr %base, i64 %mul3
store ptr %add.ptr4, ptr %add.ptr4.out, align 8
%cmp5.not21 = icmp samesign ugt i64 %mul3, %mul
br i1 %cmp5.not21, label %for.end.exitStub, label %for.body.exitStub
for.end.exitStub: ; preds = %do.body.split
ret i1 true
for.body.exitStub: ; preds = %do.body.split
ret i1 false
}
```
InstCombine reduces ICMP on pointers (i.e. `%add.ptr` and `%add.ptr4`) into ICMP of their offsets (i.e. `%mul3` and `%mul`). I think the problem here is `%mul3` and `%mul` might have different signs.
Changing ICMP into sign comparison solves this issue: `%cmp5.not21 = icmp sgt i64 %mul3, %mul`
_______________________________________________
llvm-bugs mailing list
llvm-bugs@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs