Bugzilla – Bug 157
[llvmgcc] Pointer & constant results in invalid shift
Last modified: 2003-11-26 01:38:21
You need to log in before you can comment on or make changes to this bug.
I'm not honestly sure how to describe what is going on here, but the generated code for this C function fails to make it through gccas, because the if condition turns into a shr instruction that gccas doesn't like. I suspect the C frontend may simply be casting the shift amount to the wrong type. Here's the code: 306 zion> cat c-checksum.c static unsigned long do_csum(const unsigned char *buff, int len, unsigned long result) { if (2 & (unsigned long) buff) result += 1; return result; } We get: 304 zion> llvm-gcc -c -save-temps c-checksum.c gccas: c-checksum.s:219: Shift constant expression requires integer operand! Value still in symbol table! Type = 'int' Name = 'len' Value still in symbol table! Type = 'uint' Name = 'result.0' Value still in symbol table! Type = 'int *' Name = 'len_addr' Value still in symbol table! Type = 'uint *' Name = 'result.1' Value still in symbol table! Type = 'uint *' Name = 'result_addr' Value still in symbol table! Type = 'ubyte *' Name = 'buff' Value still in symbol table! Type = 'ubyte *' Name = 'tmp.0' Value still in symbol table! Type = 'ubyte * *' Name = 'buff_addr' gccas: SymbolTable.cpp:51: virtual llvm::SymbolTable::~SymbolTable(): Assertion `LeftoverValues && "Values remain in symbol table!"' failed. gcc: Internal error: Aborted (program as) Please submit a full bug report. See <URL:http://llvm.cs.uiuc.edu> for instructions. (as an aside: I seem to have been seeing this assertion a lot lately. Maybe it should be turned into a regular std::cerr << <message>; exit(1); sequence?) This is reduced from linux-2.4.22.
Fixed. Testcase here: llvm/test/Regression/CFrontend/2003-11-26-PointerShift.c Two bug fixes here: 1. The silly asmparser should not spew tons of problems then assert out when a problem occurs. Instead of handling this at every "ThrowException" call, we just handle it in ONE place, if an exception is thrown: http://mail.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20031124/009890.html 2. The C front-end is generating illegal shr instructions. This is bad. :) $ diff -u llvm-expand.c~ llvm-expand.c --- llvm-expand.c~ 2003-11-26 01:27:26.000000000 -0600 +++ llvm-expand.c 2003-11-26 01:32:35.000000000 -0600 @@ -5452,6 +5452,8 @@ case LSHIFT_EXPR: case RSHIFT_EXPR: /* Shift amount -> ubyte */ op1 = cast_if_type_not_equal(Fn, op1, UByteTy); + if (op0->Ty->ID == PointerTyID) + op0 = cast_if_type_not_equal(Fn, op0, LongTy); break; case NE_EXPR: $ diff -u llvm-representation.c~ llvm-representation.c --- llvm-representation.c~ 2003-11-06 10:24:52.000000000 -0600 +++ llvm-representation.c 2003-11-26 01:28:29.000000000 -0600 @@ -533,7 +533,10 @@ New->Operands[0] = Op1; New->Operands[1] = Op2; - if (Opc != O_Shr && Opc != O_Shl) + if (Opc == O_Shr || Opc == O_Shl) + assert(llvm_type_is_integer(Op1->Ty) && Op2->Ty == UByteTy && + "Illegal operands for shift instructions!"); + else assert(Op1->Ty == Op2->Ty && "Binary operator operands must have compatible types!"); if (Opc == O_Add || Opc == O_Sub || Opc == O_Mul || Opc == O_Div ||