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; _______________________________________________ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits