[llvm-commits] [124441] Fix PR1233 and test/CFrontend/2007-03-01-VarSizeArrayIdx.c.

clattner at apple.com clattner at apple.com
Thu Mar 1 23:30:13 PST 2007


Revision: 124441
Author:   clattner
Date:     2007-03-01 23:30:11 -0800 (Thu, 01 Mar 2007)

Log Message:
-----------
Fix PR1233 and test/CFrontend/2007-03-01-VarSizeArrayIdx.c.

Modified Paths:
--------------
    apple-local/branches/llvm/gcc/llvm-convert.cpp

Modified: apple-local/branches/llvm/gcc/llvm-convert.cpp
===================================================================
--- apple-local/branches/llvm/gcc/llvm-convert.cpp	2007-03-02 07:25:59 UTC (rev 124440)
+++ apple-local/branches/llvm/gcc/llvm-convert.cpp	2007-03-02 07:30:11 UTC (rev 124441)
@@ -2988,11 +2988,11 @@
   
   Value *RHS = Emit(TREE_OPERAND(exp, 1), 0);
 
-  const Type *UIntPtrTy = TD.getIntPtrType();
+  const Type *IntPtrTy = TD.getIntPtrType();
   bool LHSIsSigned = !TYPE_UNSIGNED(TREE_TYPE(TREE_OPERAND(exp, 0)));
   bool RHSIsSigned = !TYPE_UNSIGNED(TREE_TYPE(TREE_OPERAND(exp, 1)));
-  LHS = CastToAnyType(LHS, LHSIsSigned, UIntPtrTy, false);
-  RHS = CastToAnyType(RHS, RHSIsSigned, UIntPtrTy, false);
+  LHS = CastToAnyType(LHS, LHSIsSigned, IntPtrTy, false);
+  RHS = CastToAnyType(RHS, RHSIsSigned, IntPtrTy, false);
   Value *V = BinaryOperator::create((Instruction::BinaryOps)Opc, LHS, RHS,
                                     "tmp", CurBB);
   return CastToType(Instruction::IntToPtr, V, ConvertType(TREE_TYPE(exp)));
@@ -4504,7 +4504,7 @@
   // operand.  This construct maps directly to a getelementptr instruction.
   Value *ArrayAddr;
   
-  if (TREE_CODE (TREE_TYPE(Array)) == ARRAY_TYPE) {
+  if (TREE_CODE(TREE_TYPE(Array)) == ARRAY_TYPE) {
     // First subtract the lower bound, if any, in the type of the index.
     tree LowerBound = array_ref_low_bound(exp);
     if (!integer_zerop(LowerBound))
@@ -4523,17 +4523,19 @@
   // element type, insert explicit pointer arithmetic here.
   //tree ElementSizeInBytes = array_ref_element_size(exp);
   
-  if (IndexVal->getType() != Type::Int32Ty &&
-      IndexVal->getType() != Type::Int64Ty)
+  const Type *IntPtrTy = getTargetData().getIntPtrType();
+  if (IndexVal->getType() != IntPtrTy) {
     if (TYPE_UNSIGNED(TREE_TYPE(Index))) // if the index is unsigned
       // ZExt it to retain its value in the larger type
-      IndexVal = CastToType(Instruction::ZExt, IndexVal, Type::Int64Ty);
+      IndexVal = CastToUIntType(IndexVal, IntPtrTy);
     else
       // SExt it to retain its value in the larger type
-      IndexVal = CastToType(Instruction::SExt, IndexVal, Type::Int64Ty);
+      IndexVal = CastToSIntType(IndexVal, IntPtrTy);
+  }
 
-  // Check for variable sized array reference.
+  // If this is an index into an array, codegen as a GEP.
   if (TREE_CODE(TREE_TYPE(Array)) == ARRAY_TYPE) {
+    // Check for variable sized array reference.
     tree Domain = TYPE_DOMAIN(TREE_TYPE(Array));
     if (Domain && TYPE_MAX_VALUE(Domain) &&
         TREE_CODE(TYPE_MAX_VALUE(Domain)) != INTEGER_CST) {
@@ -4544,14 +4546,37 @@
           ArrayAddr, PointerType::get(ConvertType(ElTy)), "tmp", CurBB);
       return new GetElementPtrInst(ArrayAddr, IndexVal, "tmp", CurBB);
     }
+
+    // Otherwise, this is not a variable-sized array, use a GEP to index.
+    return new GetElementPtrInst(ArrayAddr, ConstantInt::get(Type::Int32Ty, 0),
+                                 IndexVal, "tmp", CurBB);
   }
+
+  // Otherwise, this is an index off a pointer, codegen as a 2-idx GEP.
+  assert(TREE_CODE(TREE_TYPE(Array)) == POINTER_TYPE);
+  tree IndexedType = TREE_TYPE(TREE_TYPE(Array));
   
-  if (TREE_CODE (TREE_TYPE(Array)) == ARRAY_TYPE) {
-    return new GetElementPtrInst(ArrayAddr, ConstantInt::get(Type::Int32Ty, 0),
-                                 IndexVal, "tmp", CurBB);
-  } else {
+  // If we are indexing over a fixed-size type, just use a GEP.
+  if (TREE_CODE(TYPE_SIZE(IndexedType)) == INTEGER_CST) {
+    const Type *PtrIndexedTy = PointerType::get(ConvertType(IndexedType));
+    ArrayAddr = BitCastToType(ArrayAddr, PtrIndexedTy);
     return new GetElementPtrInst(ArrayAddr, IndexVal, "tmp", CurBB);
   }
+  
+  // Otherwise, just do raw, low-level pointer arithmetic.  FIXME: this could be
+  // much nicer in cases like:
+  //   float foo(int w, float A[][w], int g) { return A[g][0]; }
+  
+  ArrayAddr = BitCastToType(ArrayAddr, PointerType::get(Type::Int8Ty));
+  Value *TypeSize = Emit(TYPE_SIZE_UNIT(IndexedType), 0);
+
+  if (TypeSize->getType() != IntPtrTy)
+    TypeSize = CastToUIntType(TypeSize, IntPtrTy);
+  
+  IndexVal = BinaryOperator::createMul(IndexVal, TypeSize, "tmp", CurBB);
+  Value *Ptr = new GetElementPtrInst(ArrayAddr, IndexVal, "tmp", CurBB);
+
+  return BitCastToType(Ptr, PointerType::get(ConvertType(TREE_TYPE(exp))));
 }
 
 /// getFieldOffsetInBits - Return the offset (in bits) of a FIELD_DECL in a
@@ -5015,11 +5040,11 @@
   bool RHSIsSigned = !TYPE_UNSIGNED(TREE_TYPE(TREE_OPERAND(exp,1)));
   Instruction::CastOps opcode;
   if (isa<PointerType>(LHS->getType())) {
-    const Type *UIntPtrTy = getTargetData().getIntPtrType();
-    opcode = CastInst::getCastOpcode(LHS, LHSIsSigned, UIntPtrTy, false);
-    LHS = ConstantExpr::getCast(opcode, LHS, UIntPtrTy);
-    opcode = CastInst::getCastOpcode(RHS, RHSIsSigned, UIntPtrTy, false);
-    RHS = ConstantExpr::getCast(opcode, RHS, UIntPtrTy);
+    const Type *IntPtrTy = getTargetData().getIntPtrType();
+    opcode = CastInst::getCastOpcode(LHS, LHSIsSigned, IntPtrTy, false);
+    LHS = ConstantExpr::getCast(opcode, LHS, IntPtrTy);
+    opcode = CastInst::getCastOpcode(RHS, RHSIsSigned, IntPtrTy, false);
+    RHS = ConstantExpr::getCast(opcode, RHS, IntPtrTy);
   }
 
   Constant *Result;





More information about the llvm-commits mailing list