Hello,
while writing a new LLVM backend I have observed that in some cases the
optimizer produces an "icmp sgt i32 %a, 0" where I would have expected
an
"icmp ugt i32 %a, 0".
For example when I feed "opt -O3 -S ..." (LLVM 2.9, Windows) with
------------------------------------------------------------------------
target datalayout = "E-p:32:32:32"
define void @foo(i8* %buf, i32 %bufLen, i32* %ret) nounwind {
entry:
%add.ptr = getelementptr inbounds i8* %buf, i32 %bufLen
%cmp = icmp ult i8* %buf, %add.ptr
br i1 %cmp, label %if.then, label %if.end
if.then: ; preds = %entry
store i32 0, i32* %ret
br label %if.end
if.end: ; preds = %if.then, %entry
ret void
}
------------------------------------------------------------------------
I get as output
------------------------------------------------------------------------
...
entry:
%cmp = icmp sgt i32 %bufLen, 0
br i1 %cmp, label %if.then, label %if.end
...
------------------------------------------------------------------------
This is no problem if one thinks of "icmp sgt %a, 0" as "compute
%a - 0
and set flags accordingly" because then signedness makes no difference.
But if I understand things correctly, it is a problem according to the
LLVM IR reference which states "sgt: interprets the operands as signed
values and yields true if op1 is greater than op2". Under this definition
and for %a=0xFFFFFFFF "ugt" would return true while "sgt"
would return
false, wouldn't it?
Is this a bug in my thinking, a bug in the reference manual, or is this a
bug in some pass which introduces the "sgt"?
Cheers,
Jonas
Icmp sgt is correct. Note that "ugt x, 0" is the same as "x != 0" which is not what you want. -Chris On Aug 1, 2011, at 9:11 AM, Jonas Gefele <llvm.org at schrieb.de> wrote:> Hello, > > while writing a new LLVM backend I have observed that in some cases the > optimizer produces an "icmp sgt i32 %a, 0" where I would have expected an > "icmp ugt i32 %a, 0". > > For example when I feed "opt -O3 -S ..." (LLVM 2.9, Windows) with > > > ------------------------------------------------------------------------ > target datalayout = "E-p:32:32:32" > > define void @foo(i8* %buf, i32 %bufLen, i32* %ret) nounwind { > entry: > %add.ptr = getelementptr inbounds i8* %buf, i32 %bufLen > %cmp = icmp ult i8* %buf, %add.ptr > br i1 %cmp, label %if.then, label %if.end > > if.then: ; preds = %entry > store i32 0, i32* %ret > br label %if.end > > if.end: ; preds = %if.then, %entry > ret void > } > ------------------------------------------------------------------------ > > > I get as output > > > ------------------------------------------------------------------------ > ... > entry: > %cmp = icmp sgt i32 %bufLen, 0 > br i1 %cmp, label %if.then, label %if.end > ... > ------------------------------------------------------------------------ > > > This is no problem if one thinks of "icmp sgt %a, 0" as "compute %a - 0 > and set flags accordingly" because then signedness makes no difference. > But if I understand things correctly, it is a problem according to the > LLVM IR reference which states "sgt: interprets the operands as signed > values and yields true if op1 is greater than op2". Under this definition > and for %a=0xFFFFFFFF "ugt" would return true while "sgt" would return > false, wouldn't it? > > Is this a bug in my thinking, a bug in the reference manual, or is this a > bug in some pass which introduces the "sgt"? > > > Cheers, > Jonas > _______________________________________________ > LLVM Developers mailing list > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
Hi Chris,> Icmp sgt is correct.while ugt would be wrong, I think sgt is too! For example, suppose %buf is 0 and %bufLen is ~0U. Then %add.ptr is ~0U, and %cmp is true, so control branches to %if.then. However in the optimized version %cmp is false and control branches to %if.end. The GEP does have an inbounds attribute, I'm not sure if that is relevant here. Ciao, Duncan. Note that "ugt x, 0" is the same as "x != 0" which is not what you want.> > -Chris > > On Aug 1, 2011, at 9:11 AM, Jonas Gefele<llvm.org at schrieb.de> wrote: > >> Hello, >> >> while writing a new LLVM backend I have observed that in some cases the >> optimizer produces an "icmp sgt i32 %a, 0" where I would have expected an >> "icmp ugt i32 %a, 0". >> >> For example when I feed "opt -O3 -S ..." (LLVM 2.9, Windows) with >> >> >> ------------------------------------------------------------------------ >> target datalayout = "E-p:32:32:32" >> >> define void @foo(i8* %buf, i32 %bufLen, i32* %ret) nounwind { >> entry: >> %add.ptr = getelementptr inbounds i8* %buf, i32 %bufLen >> %cmp = icmp ult i8* %buf, %add.ptr >> br i1 %cmp, label %if.then, label %if.end >> >> if.then: ; preds = %entry >> store i32 0, i32* %ret >> br label %if.end >> >> if.end: ; preds = %if.then, %entry >> ret void >> } >> ------------------------------------------------------------------------ >> >> >> I get as output >> >> >> ------------------------------------------------------------------------ >> ... >> entry: >> %cmp = icmp sgt i32 %bufLen, 0 >> br i1 %cmp, label %if.then, label %if.end >> ... >> ------------------------------------------------------------------------ >> >> >> This is no problem if one thinks of "icmp sgt %a, 0" as "compute %a - 0 >> and set flags accordingly" because then signedness makes no difference. >> But if I understand things correctly, it is a problem according to the >> LLVM IR reference which states "sgt: interprets the operands as signed >> values and yields true if op1 is greater than op2". Under this definition >> and for %a=0xFFFFFFFF "ugt" would return true while "sgt" would return >> false, wouldn't it? >> >> Is this a bug in my thinking, a bug in the reference manual, or is this a >> bug in some pass which introduces the "sgt"? >> >> >> Cheers, >> Jonas >> _______________________________________________ >> LLVM Developers mailing list >> LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu >> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev > _______________________________________________ > LLVM Developers mailing list > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev