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

Reply via email to