First Last Prev Next    No search results available
Details
: [llvmgcc] Pointer & constant results in invalid shift
Bug#: 157
: tools
: llvm-gcc
Status: RESOLVED
Resolution: FIXED
: All
: All
: 1.0
: P2
: normal
: 1.1

:
: compile-fail
:
:
  Show dependency tree - Show dependency graph
People
Reporter: Brian R. Gaeke <gaeke+bugs@uiuc.edu>
Assigned To: Chris Lattner <sabre@nondot.org>

Attachments


Note

You need to log in before you can comment on or make changes to this bug.

Related actions


Description:   Opened: 2003-11-25 23:25
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.
------- Comment #1 From Chris Lattner 2003-11-26 01:38:21 -------
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 ||

First Last Prev Next    No search results available