[LLVMbugs] [Bug 953] NEW: A bug + a fix in InstructionCombining
bugzilla-daemon at cs.uiuc.edu
bugzilla-daemon at cs.uiuc.edu
Wed Oct 18 01:02:35 PDT 2006
http://llvm.org/bugs/show_bug.cgi?id=953
Summary: A bug + a fix in InstructionCombining
Product: libraries
Version: 1.8
Platform: All
OS/Version: All
Status: NEW
Severity: minor
Priority: P2
Component: Scalar Optimizations
AssignedTo: unassignedbugs at nondot.org
ReportedBy: gil.dogon at mobileye.com
First I'd like to introduce myself.
I am an employee of MobileEye company, and we are using LLVM in order to compile
'C' code for a proprietary chip architceture. Generaly we are very happy with
LLVM and we managed to have a little nice environment, including a debugger up
and running. During the developement ww stumbled upon the following bug:
we are using gccas explicitly and a short program to demonstarte the bug as
follows :
int t(int a,int b)
{
return ((a&1) != 0) != (b != 0);
}
runing gcc4.0 front end with no optimizations :
1360 tirana ~/VMPCompiler/VMP-gcc4> llvm-gcc --emit-llvm -S a.c -o a.s
1361 tirana ~/VMPCompiler/VMP-gcc4> cat a.s
; ModuleID = 'a.c'
target endian = little
target pointersize = 32
target triple = "i686-pc-linux-gnu"
implementation ; Functions:
int %t(int %a, int %b) {
entry:
%a_addr = alloca int ; <int*> [#uses=2]
%b_addr = alloca int ; <int*> [#uses=2]
%retval = alloca int, align 4 ; <int*> [#uses=2]
%tmp = alloca int, align 4 ; <int*> [#uses=2]
"alloca point" = cast int 0 to int ; <int> [#uses=0]
store int %a, int* %a_addr
store int %b, int* %b_addr
%tmp = load int* %a_addr ; <int> [#uses=1]
%tmp1 = and int %tmp, 1 ; <int> [#uses=1]
%tmp1 = cast int %tmp1 to bool ; <bool> [#uses=1]
%tmp2 = load int* %b_addr ; <int> [#uses=1]
%tmp = setne int %tmp2, 0 ; <bool> [#uses=1]
%tmp3 = xor bool %tmp1, %tmp ; <bool> [#uses=1]
%tmp3 = cast bool %tmp3 to int ; <int> [#uses=1]
store int %tmp3, int* %tmp
%tmp4 = load int* %tmp ; <int> [#uses=1]
store int %tmp4, int* %retval
br label %return
return: ; preds = %entry
%retval = load int* %retval ; <int> [#uses=1]
ret int %retval
}
<
declare int %printf(sbyte*, ...)
Gets us a correct program . However after optimizing it with gccas
the bug appears :
< 1386 tirana ~/VMPCompiler/VMP-gcc4> gccas a.s -o a.o
< 1389 tirana ~/VMPCompiler/VMP-gcc4> llvm-dis a.o -f -o a.ll
< 1390 tirana ~/VMPCompiler/VMP-gcc4> cat a.ll
; ModuleID = 'a.o'
target endian = little
target pointersize = 32
target triple = "i686-pc-linux-gnu"
implementation ; Functions:
int %t(int %a, int %b) {
entry:
%tmp1 = setne int %a, 0 ; <bool> [#uses=1]
%tmp = setne int %b, 0 ; <bool> [#uses=1]
%tmp3 = xor bool %tmp, %tmp1 ; <bool> [#uses=1]
%tmp3 = cast bool %tmp3 to int ; <int> [#uses=1]
ret int %tmp3
}
As you can see this code is a bit too optimized and the and operation (a&1)
has been discarded.
I have chased down the bug and found the culprit is at the function
SimplifyDemandedBits in InstructionCombining.cpp . In there the case of
cast from int to boolean is treated incorrectly as plain truncation.
where in fact a zero comparison is needed.
The following code snippet includes the bugfix:
case Instruction::Cast: {
const Type *SrcTy = I->getOperand(0)->getType();
if (!SrcTy->isIntegral()) return false;
//
// GD : Bugfix: Cast from non-bool to bool require all the sources bits as
// it is not just a truncation ...
//
//if (I->getType() == Type::BoolTy && SrcTy != Type::BoolTy) return false;
// If this is an integer truncate or noop, just look in the input.
if (SrcTy->getPrimitiveSizeInBits() >=
I->getType()->getPrimitiveSizeInBits()) {
if (SimplifyDemandedBits(I->getOperand(0), DemandedMask,
KnownZero, KnownOne, Depth+1))
return true;
assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?");
break;
}
I think this bug is rather rare because most of the time llvm does not generate
casts from int to boolean at the first place but have an expilit comparison.
------- You are receiving this mail because: -------
You are on the CC list for the bug, or are watching someone who is.
More information about the llvm-bugs
mailing list