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

Evan Cheng evan.cheng at apple.com
Sun Jan 11 19:44:12 PST 2009


Author: evancheng
Date: Sun Jan 11 21:44:12 2009
New Revision: 62076

URL: http://llvm.org/viewvc/llvm-project?rev=62076&view=rev
Log:
Load / store alignments should be the alignments of the memory object used to construct the LValue, not the alignments of the values being loaded / stored.

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=62076&r1=62075&r2=62076&view=diff

==============================================================================
--- llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp (original)
+++ llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Sun Jan 11 21:44:12 2009
@@ -1150,9 +1150,18 @@
   case IMAGPART_EXPR: return EmitLV_XXXXPART_EXPR(exp, 1);
 
   // Constants.
-  case LABEL_DECL:   return TreeConstantToLLVM::EmitLV_LABEL_DECL(exp);
-  case COMPLEX_CST:  return LValue(TreeConstantToLLVM::EmitLV_COMPLEX_CST(exp));
-  case STRING_CST:   return LValue(TreeConstantToLLVM::EmitLV_STRING_CST(exp));
+  case LABEL_DECL: {
+    Value *Ptr = TreeConstantToLLVM::EmitLV_LABEL_DECL(exp);
+    return LValue(Ptr, DECL_ALIGN(exp) / 8);
+  }
+  case COMPLEX_CST: {
+    Value *Ptr = TreeConstantToLLVM::EmitLV_COMPLEX_CST(exp);
+    return LValue(Ptr, TYPE_ALIGN(TREE_TYPE(exp)) / 8);
+  }
+  case STRING_CST: {
+    Value *Ptr = TreeConstantToLLVM::EmitLV_STRING_CST(exp);
+    return LValue(Ptr, TYPE_ALIGN(TREE_TYPE(exp)) / 8);
+  }
 
   // Type Conversion.
   case VIEW_CONVERT_EXPR: return EmitLV_VIEW_CONVERT_EXPR(exp);
@@ -1165,9 +1174,11 @@
   case WITH_SIZE_EXPR:
     // The address is the address of the operand.
     return EmitLV(TREE_OPERAND(exp, 0));
-  case INDIRECT_REF:
+  case INDIRECT_REF: {
     // The lvalue is just the address.
-    return Emit(TREE_OPERAND(exp, 0), 0);
+    tree Op = TREE_OPERAND(exp, 0);
+    return LValue(Emit(Op, 0), expr_align(Op) / 8);
+  }
   }
 }
 
@@ -2290,7 +2301,7 @@
   LValue LV = EmitLV(exp);
   bool isVolatile = TREE_THIS_VOLATILE(exp);
   const Type *Ty = ConvertType(TREE_TYPE(exp));
-  unsigned Alignment = expr_align(exp) / 8;
+  unsigned Alignment = LV.getAlignment();
   if (TREE_CODE(exp) == COMPONENT_REF) 
     if (const StructType *STy = 
         dyn_cast<StructType>(ConvertType(TREE_TYPE(TREE_OPERAND(exp, 0)))))
@@ -2963,7 +2974,7 @@
 
   LValue LV = EmitLV(lhs);
   bool isVolatile = TREE_THIS_VOLATILE(lhs);
-  unsigned Alignment = expr_align(lhs) / 8;
+  unsigned Alignment = LV.getAlignment();
   if (TREE_CODE(lhs) == COMPONENT_REF) 
     if (const StructType *STy = 
         dyn_cast<StructType>(ConvertType(TREE_TYPE(TREE_OPERAND(lhs, 0)))))
@@ -3157,7 +3168,7 @@
       LValue LV = EmitLV(Op);
       assert(!LV.isBitfield() && "Expected an aggregate operand!");
       bool isVolatile = TREE_THIS_VOLATILE(Op);
-      unsigned Alignment = expr_align(Op) / 8;
+      unsigned Alignment = LV.getAlignment();
 
       EmitAggregateCopy(Target, MemRef(LV.Ptr, Alignment, isVolatile),
                         TREE_TYPE(exp));
@@ -5885,9 +5896,10 @@
   Value *Decl = DECL_LLVM(exp);
   if (Decl == 0) {
     if (errorcount || sorrycount) {
-      const PointerType *Ty = 
-        PointerType::getUnqual(ConvertType(TREE_TYPE(exp)));
-      return ConstantPointerNull::get(Ty);
+      const Type *Ty = ConvertType(TREE_TYPE(exp));
+      const PointerType *PTy = PointerType::getUnqual(Ty);
+      LValue LV(ConstantPointerNull::get(PTy), 1);
+      return LV;
     }
     assert(0 && "INTERNAL ERROR: Referencing decl that hasn't been laid out");
     abort();
@@ -5924,7 +5936,13 @@
   // type void.
   if (Ty == Type::VoidTy) Ty = StructType::get(NULL, NULL);
   const PointerType *PTy = PointerType::getUnqual(Ty);
-  return BitCastToType(Decl, PTy);
+  unsigned Alignment = Ty->isSized() ? TD.getABITypeAlignment(Ty) : 1;
+  if (DECL_ALIGN_UNIT(exp)) {
+    if (DECL_USER_ALIGN(exp) || Alignment < (unsigned)DECL_ALIGN_UNIT(exp))
+      Alignment = DECL_ALIGN_UNIT(exp);
+  }
+
+  return LValue(BitCastToType(Decl, PTy), Alignment);
 }
 
 LValue TreeToLLVM::EmitLV_ARRAY_REF(tree exp) {
@@ -5932,22 +5950,23 @@
   // of ElementTy in the case of ARRAY_RANGE_REF.
 
   tree Array = TREE_OPERAND(exp, 0);
-  tree ArrayType = TREE_TYPE(Array);
+  tree ArrayTreeType = TREE_TYPE(Array);
   tree Index = TREE_OPERAND(exp, 1);
   tree IndexType = TREE_TYPE(Index);
-  tree ElementType = TREE_TYPE(ArrayType);
+  tree ElementType = TREE_TYPE(ArrayTreeType);
 
-  assert((TREE_CODE (ArrayType) == ARRAY_TYPE ||
-          TREE_CODE (ArrayType) == POINTER_TYPE ||
-          TREE_CODE (ArrayType) == REFERENCE_TYPE ||
-          TREE_CODE (ArrayType) == BLOCK_POINTER_TYPE) &&
+  assert((TREE_CODE (ArrayTreeType) == ARRAY_TYPE ||
+          TREE_CODE (ArrayTreeType) == POINTER_TYPE ||
+          TREE_CODE (ArrayTreeType) == REFERENCE_TYPE ||
+          TREE_CODE (ArrayTreeType) == BLOCK_POINTER_TYPE) &&
          "Unknown ARRAY_REF!");
 
   // As an LLVM extension, we allow ARRAY_REF with a pointer as the first
   // operand.  This construct maps directly to a getelementptr instruction.
   Value *ArrayAddr;
+  unsigned ArrayAlign;
 
-  if (TREE_CODE(ArrayType) == ARRAY_TYPE) {
+  if (TREE_CODE(ArrayTreeType) == 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))
@@ -5956,8 +5975,10 @@
     LValue ArrayAddrLV = EmitLV(Array);
     assert(!ArrayAddrLV.isBitfield() && "Arrays cannot be bitfields!");
     ArrayAddr = ArrayAddrLV.Ptr;
+    ArrayAlign = ArrayAddrLV.Alignment;
   } else {
     ArrayAddr = Emit(Array, 0);
+    ArrayAlign = expr_align(ArrayTreeType) / 8;
   }
 
   Value *IndexVal = Emit(Index, 0);
@@ -5971,20 +5992,27 @@
     IndexVal = CastToSIntType(IndexVal, IntPtrTy);
 
   // If this is an index into an LLVM array, codegen as a GEP.
-  if (isArrayCompatible(ArrayType)) {
+  if (isArrayCompatible(ArrayTreeType)) {
     Value *Idxs[2] = { ConstantInt::get(Type::Int32Ty, 0), IndexVal };
     Value *Ptr = Builder.CreateGEP(ArrayAddr, Idxs, Idxs + 2);
-    return BitCastToType(Ptr, 
-                         PointerType::getUnqual(ConvertType(TREE_TYPE(exp))));
+    const Type *ATy = cast<PointerType>(ArrayAddr->getType())->getElementType();
+    const Type *ElementTy = cast<ArrayType>(ATy)->getElementType();
+    unsigned Alignment = MinAlign(ArrayAlign, TD.getABITypeSize(ElementTy));
+    return LValue(BitCastToType(Ptr,
+                           PointerType::getUnqual(ConvertType(TREE_TYPE(exp)))),
+                  Alignment);
   }
 
   // If we are indexing over a fixed-size type, just use a GEP.
-  if (isSequentialCompatible(ArrayType)) {
-    const Type *PtrElementTy = PointerType::getUnqual(ConvertType(ElementType));
+  if (isSequentialCompatible(ArrayTreeType)) {
+    const Type *ElementTy = ConvertType(ElementType);
+    const Type *PtrElementTy = PointerType::getUnqual(ElementTy);
     ArrayAddr = BitCastToType(ArrayAddr, PtrElementTy);
     Value *Ptr = Builder.CreateGEP(ArrayAddr, IndexVal);
-    return BitCastToType(Ptr, 
-                         PointerType::getUnqual(ConvertType(TREE_TYPE(exp))));
+    unsigned Alignment = MinAlign(ArrayAlign, TD.getABITypeAlignment(ElementTy));
+    return LValue(BitCastToType(Ptr,
+                           PointerType::getUnqual(ConvertType(TREE_TYPE(exp)))),
+                  Alignment);
   }
 
   // Otherwise, just do raw, low-level pointer arithmetic.  FIXME: this could be
@@ -5992,14 +6020,21 @@
   //   float foo(int w, float A[][w], int g) { return A[g][0]; }
 
   ArrayAddr = BitCastToType(ArrayAddr, PointerType::getUnqual(Type::Int8Ty));
-  if (VOID_TYPE_P(TREE_TYPE(ArrayType))) 
-    return Builder.CreateGEP(ArrayAddr, IndexVal);
+  if (VOID_TYPE_P(TREE_TYPE(ArrayTreeType))) {
+    unsigned Alignment = MinAlign(ArrayAlign,
+                                  TD.getABITypeAlignment(Type::Int8Ty));
+    return LValue(Builder.CreateGEP(ArrayAddr, IndexVal), Alignment);
+  }
 
   Value *TypeSize = Emit(array_ref_element_size(exp), 0);
   TypeSize = CastToUIntType(TypeSize, IntPtrTy);
   IndexVal = Builder.CreateMul(IndexVal, TypeSize);
   Value *Ptr = Builder.CreateGEP(ArrayAddr, IndexVal);
-  return BitCastToType(Ptr,PointerType::getUnqual(ConvertType(TREE_TYPE(exp))));
+  unsigned Alignment = MinAlign(ArrayAlign,
+                                cast<ConstantInt>(IndexVal)->getZExtValue());
+  return LValue(BitCastToType(Ptr,
+                           PointerType::getUnqual(ConvertType(TREE_TYPE(exp)))),
+                Alignment);
 }
 
 /// getFieldOffsetInBits - Return the offset (in bits) of a FIELD_DECL in a
@@ -6028,8 +6063,9 @@
 
 LValue TreeToLLVM::EmitLV_COMPONENT_REF(tree exp) {
   LValue StructAddrLV = EmitLV(TREE_OPERAND(exp, 0));
-  tree FieldDecl = TREE_OPERAND(exp, 1);
-  
+  tree FieldDecl = TREE_OPERAND(exp, 1); 
+  unsigned LVAlign = DECL_PACKED(FieldDecl) ? 1 : StructAddrLV.Alignment;
+ 
   assert((TREE_CODE(DECL_CONTEXT(FieldDecl)) == RECORD_TYPE ||
           TREE_CODE(DECL_CONTEXT(FieldDecl)) == UNION_TYPE  ||
           TREE_CODE(DECL_CONTEXT(FieldDecl)) == QUAL_UNION_TYPE));
@@ -6064,7 +6100,9 @@
     // the offset from BitStart.
     if (MemberIndex) {
       const StructLayout *SL = TD.getStructLayout(cast<StructType>(StructTy));
-      BitStart -= SL->getElementOffset(MemberIndex) * 8;
+      unsigned Offset = SL->getElementOffset(MemberIndex);
+      BitStart -= Offset * 8;
+      LVAlign = MinAlign(LVAlign, Offset);
     }
     
     // If the FIELD_DECL has an annotate attribute on it, emit it.
@@ -6130,7 +6168,7 @@
         if (AnnotateAttr)
           AnnotateAttr = lookup_attribute("annotate", AnnotateAttr);
       }
-    }      
+    }
   } else {
     Value *Offset = Emit(field_offset, 0);
 
@@ -6150,6 +6188,7 @@
       Offset = Builder.CreateAdd(Offset,
         ConstantInt::get(Offset->getType(), ByteOffset));
       BitStart -= ByteOffset*8;
+      LVAlign = MinAlign(LVAlign, ByteOffset);
     }
 
     Value *Ptr = CastToType(Instruction::PtrToInt, StructAddrLV.Ptr, 
@@ -6221,6 +6260,7 @@
 
       // Compute the byte offset, and add it to the pointer.
       unsigned ByteOffset = NumAlignmentUnits*ByteAlignment;
+      LVAlign = MinAlign(LVAlign, ByteOffset);
 
       Constant *Offset = ConstantInt::get(TD.getIntPtrType(), ByteOffset);
       FieldPtr = CastToType(Instruction::PtrToInt, FieldPtr,
@@ -6242,17 +6282,18 @@
 
     // Okay, everything is good.  Return this as a bitfield if we can't
     // return it as a normal l-value. (e.g. "struct X { int X : 32 };" ).
+    // Conservatively return LValue with alignment 1.
     if (BitfieldSize != LLVMValueBitSize || BitStart != 0)
-      return LValue(FieldPtr, BitStart, BitfieldSize);
+      return LValue(FieldPtr, 1, BitStart, BitfieldSize);
   } else {
     // Make sure we return a pointer to the right type.
-    FieldPtr = BitCastToType(FieldPtr,
-                          PointerType::getUnqual(ConvertType(TREE_TYPE(exp))));
+    const Type *EltTy = ConvertType(TREE_TYPE(exp));
+    FieldPtr = BitCastToType(FieldPtr, PointerType::getUnqual(EltTy));
   }
   
   assert(BitStart == 0 &&
          "It's a bitfield reference or we didn't get to the field!");
-  return LValue(FieldPtr);
+  return LValue(FieldPtr, LVAlign);
 }
 
 LValue TreeToLLVM::EmitLV_BIT_FIELD_REF(tree exp) {
@@ -6284,17 +6325,27 @@
   }
   
   // If this is referring to the whole field, return the whole thing.
-  if (BitStart == 0 && BitSize == ValueSizeInBits)
-    return LValue(BitCastToType(Ptr.Ptr, PointerType::getUnqual(ValTy)));
+  if (BitStart == 0 && BitSize == ValueSizeInBits) {
+    return LValue(BitCastToType(Ptr.Ptr, PointerType::getUnqual(ValTy)),
+                  Ptr.Alignment);
+  }
   
-  return LValue(BitCastToType(Ptr.Ptr, PointerType::getUnqual(ValTy)), BitStart,
-                BitSize);
+  return LValue(BitCastToType(Ptr.Ptr, PointerType::getUnqual(ValTy)), 1,
+                BitStart, BitSize);
 }
 
 LValue TreeToLLVM::EmitLV_XXXXPART_EXPR(tree exp, unsigned Idx) {
   LValue Ptr = EmitLV(TREE_OPERAND(exp, 0));
-  assert(!Ptr.isBitfield() && "BIT_FIELD_REF operands cannot be bitfields!");
-  return LValue(Builder.CreateStructGEP(Ptr.Ptr, Idx));
+  assert(!Ptr.isBitfield() &&
+         "REALPART_EXPR / IMAGPART_EXPR operands cannot be bitfields!");
+  unsigned Alignment;
+  if (Idx == 0)
+    // REALPART alignment is same as the complex operand.
+    Alignment = Ptr.Alignment;
+  else
+    // IMAGPART alignment = MinAlign(Ptr.Alignment, sizeof field);
+    Alignment = MinAlign(Ptr.Alignment, TD.getABITypeSize(Ptr.Ptr->getType()));
+  return LValue(Builder.CreateStructGEP(Ptr.Ptr, Idx), Alignment);
 }
 
 LValue TreeToLLVM::EmitLV_VIEW_CONVERT_EXPR(tree exp) {
@@ -6310,24 +6361,30 @@
   } else {
     // If the input is a scalar, emit to a temporary.
     Value *Dest = CreateTemporary(ConvertType(TREE_TYPE(Op)));
-    Builder.CreateStore(Emit(Op, 0), Dest);
+    StoreInst *S = Builder.CreateStore(Emit(Op, 0), Dest);
     // The type is the type of the expression.
     Dest = BitCastToType(Dest,  
                          PointerType::getUnqual(ConvertType(TREE_TYPE(exp))));
-    return LValue(Dest);
+    return LValue(Dest, S->getAlignment());
   }
 }
 
 LValue TreeToLLVM::EmitLV_EXC_PTR_EXPR(tree exp) {
   CreateExceptionValues();
   // Cast the address pointer to the expected type.
-  return BitCastToType(ExceptionValue,
-                       PointerType::getUnqual(ConvertType(TREE_TYPE(exp))));
+  unsigned Alignment = TD.getABITypeAlignment(cast<PointerType>(ExceptionValue->
+                                                  getType())->getElementType());
+  return LValue(BitCastToType(ExceptionValue,
+                              PointerType::getUnqual(ConvertType(TREE_TYPE(exp)))),
+                Alignment);
 }
 
 LValue TreeToLLVM::EmitLV_FILTER_EXPR(tree exp) {
   CreateExceptionValues();
-  return ExceptionSelectorValue;
+  unsigned Alignment =
+    TD.getABITypeAlignment(cast<PointerType>(ExceptionSelectorValue->
+                                             getType())->getElementType());
+  return LValue(ExceptionSelectorValue, Alignment);
 }
 
 //===----------------------------------------------------------------------===//





More information about the llvm-commits mailing list