[llvm-commits] [llvm-gcc-4.2] r79597 - /llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp

Bill Wendling isanbard at gmail.com
Thu Aug 20 23:11:55 PDT 2009


Author: void
Date: Fri Aug 21 01:11:55 2009
New Revision: 79597

URL: http://llvm.org/viewvc/llvm-project?rev=79597&view=rev
Log:
People might want to do a "rotate" on a pointer. I don't know why either. This
is a reduced testcase from real code:

void func(void *A) {
  unsigned int b = ((((unsigned long long) A) >> 5) | (((unsigned long long) A) << 27));
}

The problem is that GCC's front-end realizes that the size of A and the result
type are the same in 32-bit mode. So it strips the cast of A away. GCC also
realizes that this is a rotate operation. It marks it as so. However, LLVM
couldn't handle a rotate on of a pointer. It wants `A' to be of the same type as
`5' or `27' in this case. But that information was removed.

My "solution", such as it is, is to check for a pointer type in the EmitRotateOp
method. If it *is* a pointer, go ahead and convert the pointer to an integer
type that's the same as the constant. This way, we will get the rotate command
that we so desperately wish for.

Modified:
    llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp

Modified: llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp?rev=79597&r1=79596&r2=79597&view=diff

==============================================================================
--- llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp (original)
+++ llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Fri Aug 21 01:11:55 2009
@@ -3472,13 +3472,18 @@
 Value *TreeToLLVM::EmitRotateOp(tree exp, unsigned Opc1, unsigned Opc2) {
   Value *In  = Emit(TREE_OPERAND(exp, 0), 0);
   Value *Amt = Emit(TREE_OPERAND(exp, 1), 0);
+
+  if (isa<PointerType>(In->getType()))
+    In = Builder.CreatePtrToInt(In, Amt->getType(),
+                                (In->getNameStr()+".cast").c_str());
+
   if (Amt->getType() != In->getType())
     Amt = Builder.CreateIntCast(Amt, In->getType(), false,
                                 (Amt->getNameStr()+".cast").c_str());
 
   Value *TypeSize =
     ConstantInt::get(In->getType(),
-                           In->getType()->getPrimitiveSizeInBits());
+                     In->getType()->getPrimitiveSizeInBits());
   
   // Do the two shifts.
   Value *V1 = Builder.CreateBinOp((Instruction::BinaryOps)Opc1, In, Amt);





More information about the llvm-commits mailing list