Closed as not planned
Description
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:
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:
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