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