[cfe-commits] r162425 - in /cfe/trunk: lib/CodeGen/CGBuiltin.cpp lib/CodeGen/CodeGenFunction.h test/CodeGen/builtin-memfns.c

Eli Friedman eli.friedman at gmail.com
Wed Aug 22 20:10:17 PDT 2012


Author: efriedma
Date: Wed Aug 22 22:10:17 2012
New Revision: 162425

URL: http://llvm.org/viewvc/llvm-project?rev=162425&view=rev
Log:
Use the alignment from lvalue emission to more accurately compute the alignment
of a pointer for builtin emission, instead of just depending on the type of the
pointee.  <rdar://problem/11314941>.


Modified:
    cfe/trunk/lib/CodeGen/CGBuiltin.cpp
    cfe/trunk/lib/CodeGen/CodeGenFunction.h
    cfe/trunk/test/CodeGen/builtin-memfns.c

Modified: cfe/trunk/lib/CodeGen/CGBuiltin.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGBuiltin.cpp?rev=162425&r1=162424&r2=162425&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGBuiltin.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGBuiltin.cpp Wed Aug 22 22:10:17 2012
@@ -573,38 +573,41 @@
   }
   case Builtin::BIbzero:
   case Builtin::BI__builtin_bzero: {
-    Value *Address = EmitScalarExpr(E->getArg(0));
+    std::pair<llvm::Value*, unsigned> Dest =
+        EmitPointerWithAlignment(E->getArg(0));
     Value *SizeVal = EmitScalarExpr(E->getArg(1));
-    unsigned Align = GetPointeeAlignment(E->getArg(0));
-    Builder.CreateMemSet(Address, Builder.getInt8(0), SizeVal, Align, false);
-    return RValue::get(Address);
+    Builder.CreateMemSet(Dest.first, Builder.getInt8(0), SizeVal,
+                         Dest.second, false);
+    return RValue::get(Dest.first);
   }
   case Builtin::BImemcpy:
   case Builtin::BI__builtin_memcpy: {
-    Value *Address = EmitScalarExpr(E->getArg(0));
-    Value *SrcAddr = EmitScalarExpr(E->getArg(1));
+    std::pair<llvm::Value*, unsigned> Dest =
+        EmitPointerWithAlignment(E->getArg(0));
+    std::pair<llvm::Value*, unsigned> Src =
+        EmitPointerWithAlignment(E->getArg(1));
     Value *SizeVal = EmitScalarExpr(E->getArg(2));
-    unsigned Align = std::min(GetPointeeAlignment(E->getArg(0)),
-                              GetPointeeAlignment(E->getArg(1)));
-    Builder.CreateMemCpy(Address, SrcAddr, SizeVal, Align, false);
-    return RValue::get(Address);
+    unsigned Align = std::min(Dest.second, Src.second);
+    Builder.CreateMemCpy(Dest.first, Src.first, SizeVal, Align, false);
+    return RValue::get(Dest.first);
   }
       
   case Builtin::BI__builtin___memcpy_chk: {
-    // fold __builtin_memcpy_chk(x, y, cst1, cst2) to memset iff cst1<=cst2.
+    // fold __builtin_memcpy_chk(x, y, cst1, cst2) to memcpy iff cst1<=cst2.
     llvm::APSInt Size, DstSize;
     if (!E->getArg(2)->EvaluateAsInt(Size, CGM.getContext()) ||
         !E->getArg(3)->EvaluateAsInt(DstSize, CGM.getContext()))
       break;
     if (Size.ugt(DstSize))
       break;
-    Value *Dest = EmitScalarExpr(E->getArg(0));
-    Value *Src = EmitScalarExpr(E->getArg(1));
+    std::pair<llvm::Value*, unsigned> Dest =
+        EmitPointerWithAlignment(E->getArg(0));
+    std::pair<llvm::Value*, unsigned> Src =
+        EmitPointerWithAlignment(E->getArg(1));
     Value *SizeVal = llvm::ConstantInt::get(Builder.getContext(), Size);
-    unsigned Align = std::min(GetPointeeAlignment(E->getArg(0)),
-                              GetPointeeAlignment(E->getArg(1)));
-    Builder.CreateMemCpy(Dest, Src, SizeVal, Align, false);
-    return RValue::get(Dest);
+    unsigned Align = std::min(Dest.second, Src.second);
+    Builder.CreateMemCpy(Dest.first, Src.first, SizeVal, Align, false);
+    return RValue::get(Dest.first);
   }
       
   case Builtin::BI__builtin_objc_memmove_collectable: {
@@ -617,41 +620,43 @@
   }
 
   case Builtin::BI__builtin___memmove_chk: {
-    // fold __builtin_memmove_chk(x, y, cst1, cst2) to memset iff cst1<=cst2.
+    // fold __builtin_memmove_chk(x, y, cst1, cst2) to memmove iff cst1<=cst2.
     llvm::APSInt Size, DstSize;
     if (!E->getArg(2)->EvaluateAsInt(Size, CGM.getContext()) ||
         !E->getArg(3)->EvaluateAsInt(DstSize, CGM.getContext()))
       break;
     if (Size.ugt(DstSize))
       break;
-    Value *Dest = EmitScalarExpr(E->getArg(0));
-    Value *Src = EmitScalarExpr(E->getArg(1));
+    std::pair<llvm::Value*, unsigned> Dest =
+        EmitPointerWithAlignment(E->getArg(0));
+    std::pair<llvm::Value*, unsigned> Src =
+        EmitPointerWithAlignment(E->getArg(1));
     Value *SizeVal = llvm::ConstantInt::get(Builder.getContext(), Size);
-    unsigned Align = std::min(GetPointeeAlignment(E->getArg(0)),
-                              GetPointeeAlignment(E->getArg(1)));
-    Builder.CreateMemMove(Dest, Src, SizeVal, Align, false);
-    return RValue::get(Dest);
+    unsigned Align = std::min(Dest.second, Src.second);
+    Builder.CreateMemMove(Dest.first, Src.first, SizeVal, Align, false);
+    return RValue::get(Dest.first);
   }
 
   case Builtin::BImemmove:
   case Builtin::BI__builtin_memmove: {
-    Value *Address = EmitScalarExpr(E->getArg(0));
-    Value *SrcAddr = EmitScalarExpr(E->getArg(1));
+    std::pair<llvm::Value*, unsigned> Dest =
+        EmitPointerWithAlignment(E->getArg(0));
+    std::pair<llvm::Value*, unsigned> Src =
+        EmitPointerWithAlignment(E->getArg(1));
     Value *SizeVal = EmitScalarExpr(E->getArg(2));
-    unsigned Align = std::min(GetPointeeAlignment(E->getArg(0)),
-                              GetPointeeAlignment(E->getArg(1)));
-    Builder.CreateMemMove(Address, SrcAddr, SizeVal, Align, false);
-    return RValue::get(Address);
+    unsigned Align = std::min(Dest.second, Src.second);
+    Builder.CreateMemMove(Dest.first, Src.first, SizeVal, Align, false);
+    return RValue::get(Dest.first);
   }
   case Builtin::BImemset:
   case Builtin::BI__builtin_memset: {
-    Value *Address = EmitScalarExpr(E->getArg(0));
+    std::pair<llvm::Value*, unsigned> Dest =
+        EmitPointerWithAlignment(E->getArg(0));
     Value *ByteVal = Builder.CreateTrunc(EmitScalarExpr(E->getArg(1)),
                                          Builder.getInt8Ty());
     Value *SizeVal = EmitScalarExpr(E->getArg(2));
-    unsigned Align = GetPointeeAlignment(E->getArg(0));
-    Builder.CreateMemSet(Address, ByteVal, SizeVal, Align, false);
-    return RValue::get(Address);
+    Builder.CreateMemSet(Dest.first, ByteVal, SizeVal, Dest.second, false);
+    return RValue::get(Dest.first);
   }
   case Builtin::BI__builtin___memset_chk: {
     // fold __builtin_memset_chk(x, y, cst1, cst2) to memset iff cst1<=cst2.
@@ -661,14 +666,13 @@
       break;
     if (Size.ugt(DstSize))
       break;
-    Value *Address = EmitScalarExpr(E->getArg(0));
+    std::pair<llvm::Value*, unsigned> Dest =
+        EmitPointerWithAlignment(E->getArg(0));
     Value *ByteVal = Builder.CreateTrunc(EmitScalarExpr(E->getArg(1)),
                                          Builder.getInt8Ty());
     Value *SizeVal = llvm::ConstantInt::get(Builder.getContext(), Size);
-    unsigned Align = GetPointeeAlignment(E->getArg(0));
-    Builder.CreateMemSet(Address, ByteVal, SizeVal, Align, false);
-    
-    return RValue::get(Address);
+    Builder.CreateMemSet(Dest.first, ByteVal, SizeVal, Dest.second, false);
+    return RValue::get(Dest.first);
   }
   case Builtin::BI__builtin_dwarf_cfa: {
     // The offset in bytes from the first argument to the CFA.
@@ -1469,34 +1473,35 @@
 /// GetPointeeAlignment - Given an expression with a pointer type, find the
 /// alignment of the type referenced by the pointer.  Skip over implicit
 /// casts.
-unsigned CodeGenFunction::GetPointeeAlignment(const Expr *Addr) {
-  unsigned Align = 1;
-  // Check if the type is a pointer.  The implicit cast operand might not be.
-  while (Addr->getType()->isPointerType()) {
-    QualType PtTy = Addr->getType()->getPointeeType();
-    
-    // Can't get alignment of incomplete types.
-    if (!PtTy->isIncompleteType()) {
-      unsigned NewA = getContext().getTypeAlignInChars(PtTy).getQuantity();
-      if (NewA > Align)
-        Align = NewA;
+std::pair<llvm::Value*, unsigned>
+CodeGenFunction::EmitPointerWithAlignment(const Expr *Addr) {
+  assert(Addr->getType()->isPointerType());
+  Addr = Addr->IgnoreParens();
+  if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Addr)) {
+    if (ICE->getCastKind() == CK_BitCast || ICE->getCastKind() == CK_NoOp) {
+      std::pair<llvm::Value*, unsigned> Ptr = 
+          EmitPointerWithAlignment(ICE->getSubExpr());
+      Ptr.first = Builder.CreateBitCast(Ptr.first,
+                                        ConvertType(Addr->getType()));
+      return Ptr;
+    } else if (ICE->getCastKind() == CK_ArrayToPointerDecay) {
+      LValue LV = EmitLValue(ICE->getSubExpr());
+      return std::make_pair(LV.getAddress(), LV.getAlignment().getQuantity());
+    }
+  }
+  if (const UnaryOperator *UO = dyn_cast<UnaryOperator>(Addr)) {
+    if (UO->getOpcode() == UO_AddrOf) {
+      LValue LV = EmitLValue(UO->getSubExpr());
+      return std::make_pair(LV.getAddress(), LV.getAlignment().getQuantity());
     }
-
-    // If the address is an implicit cast, repeat with the cast operand.
-    if (const ImplicitCastExpr *CastAddr = dyn_cast<ImplicitCastExpr>(Addr)) {
-      Addr = CastAddr->getSubExpr();
-      continue;
-    }
-    break;
   }
-  return Align;
-}
 
-/// GetPointeeAlignmentValue - Given an expression with a pointer type, find
-/// the alignment of the type referenced by the pointer.  Skip over implicit
-/// casts.  Return the alignment as an llvm::Value.
-Value *CodeGenFunction::GetPointeeAlignmentValue(const Expr *Addr) {
-  return llvm::ConstantInt::get(Int32Ty, GetPointeeAlignment(Addr));
+  unsigned Align = 1;
+  QualType PtTy = Addr->getType()->getPointeeType();
+  if (!PtTy->isIncompleteType())
+    Align = getContext().getTypeAlignInChars(PtTy).getQuantity();
+
+  return std::make_pair(EmitScalarExpr(Addr), Align);
 }
 
 Value *CodeGenFunction::EmitARMBuiltinExpr(unsigned BuiltinID,
@@ -1549,8 +1554,69 @@
   }
 
   SmallVector<Value*, 4> Ops;
-  for (unsigned i = 0, e = E->getNumArgs() - 1; i != e; i++)
+  llvm::Value *Align = 0;
+  for (unsigned i = 0, e = E->getNumArgs() - 1; i != e; i++) {
+    if (i == 0) {
+      switch (BuiltinID) {
+      case ARM::BI__builtin_neon_vld1_v:
+      case ARM::BI__builtin_neon_vld1q_v:
+      case ARM::BI__builtin_neon_vld1q_lane_v:
+      case ARM::BI__builtin_neon_vld1_lane_v:
+      case ARM::BI__builtin_neon_vld1_dup_v:
+      case ARM::BI__builtin_neon_vld1q_dup_v:
+      case ARM::BI__builtin_neon_vst1_v:
+      case ARM::BI__builtin_neon_vst1q_v:
+      case ARM::BI__builtin_neon_vst1q_lane_v:
+      case ARM::BI__builtin_neon_vst1_lane_v:
+      case ARM::BI__builtin_neon_vst2_v:
+      case ARM::BI__builtin_neon_vst2q_v:
+      case ARM::BI__builtin_neon_vst2_lane_v:
+      case ARM::BI__builtin_neon_vst2q_lane_v:
+      case ARM::BI__builtin_neon_vst3_v:
+      case ARM::BI__builtin_neon_vst3q_v:
+      case ARM::BI__builtin_neon_vst3_lane_v:
+      case ARM::BI__builtin_neon_vst3q_lane_v:
+      case ARM::BI__builtin_neon_vst4_v:
+      case ARM::BI__builtin_neon_vst4q_v:
+      case ARM::BI__builtin_neon_vst4_lane_v:
+      case ARM::BI__builtin_neon_vst4q_lane_v:
+        // Get the alignment for the argument in addition to the value;
+        // we'll use it later.
+        std::pair<llvm::Value*, unsigned> Src =
+            EmitPointerWithAlignment(E->getArg(0));
+        Ops.push_back(Src.first);
+        Align = Builder.getInt32(Src.second);
+        continue;
+      }
+    }
+    if (i == 1) {
+      switch (BuiltinID) {
+      case ARM::BI__builtin_neon_vld2_v:
+      case ARM::BI__builtin_neon_vld2q_v:
+      case ARM::BI__builtin_neon_vld3_v:
+      case ARM::BI__builtin_neon_vld3q_v:
+      case ARM::BI__builtin_neon_vld4_v:
+      case ARM::BI__builtin_neon_vld4q_v:
+      case ARM::BI__builtin_neon_vld2_lane_v:
+      case ARM::BI__builtin_neon_vld2q_lane_v:
+      case ARM::BI__builtin_neon_vld3_lane_v:
+      case ARM::BI__builtin_neon_vld3q_lane_v:
+      case ARM::BI__builtin_neon_vld4_lane_v:
+      case ARM::BI__builtin_neon_vld4q_lane_v:
+      case ARM::BI__builtin_neon_vld2_dup_v:
+      case ARM::BI__builtin_neon_vld3_dup_v:
+      case ARM::BI__builtin_neon_vld4_dup_v:
+        // Get the alignment for the argument in addition to the value;
+        // we'll use it later.
+        std::pair<llvm::Value*, unsigned> Src =
+            EmitPointerWithAlignment(E->getArg(1));
+        Ops.push_back(Src.first);
+        Align = Builder.getInt32(Src.second);
+        continue;
+      }
+    }
     Ops.push_back(EmitScalarExpr(E->getArg(i)));
+  }
 
   // vget_lane and vset_lane are not overloaded and do not have an extra
   // argument that specifies the vector type.
@@ -1746,7 +1812,7 @@
     return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vhsub");
   case ARM::BI__builtin_neon_vld1_v:
   case ARM::BI__builtin_neon_vld1q_v:
-    Ops.push_back(GetPointeeAlignmentValue(E->getArg(0)));
+    Ops.push_back(Align);
     return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vld1, Ty),
                         Ops, "vld1");
   case ARM::BI__builtin_neon_vld1q_lane_v:
@@ -1761,8 +1827,7 @@
       // Load the value as a one-element vector.
       Ty = llvm::VectorType::get(VTy->getElementType(), 1);
       Function *F = CGM.getIntrinsic(Intrinsic::arm_neon_vld1, Ty);
-      Value *Ld = Builder.CreateCall2(F, Ops[0],
-                                      GetPointeeAlignmentValue(E->getArg(0)));
+      Value *Ld = Builder.CreateCall2(F, Ops[0], Align);
       // Combine them.
       SmallVector<Constant*, 2> Indices;
       Indices.push_back(ConstantInt::get(Int32Ty, 1-Lane));
@@ -1776,7 +1841,6 @@
     Ty = llvm::PointerType::getUnqual(VTy->getElementType());
     Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
     LoadInst *Ld = Builder.CreateLoad(Ops[0]);
-    Value *Align = GetPointeeAlignmentValue(E->getArg(0));
     Ld->setAlignment(cast<ConstantInt>(Align)->getZExtValue());
     return Builder.CreateInsertElement(Ops[1], Ld, Ops[2], "vld1_lane");
   }
@@ -1786,7 +1850,6 @@
     Ty = llvm::PointerType::getUnqual(VTy->getElementType());
     Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
     LoadInst *Ld = Builder.CreateLoad(Ops[0]);
-    Value *Align = GetPointeeAlignmentValue(E->getArg(0));
     Ld->setAlignment(cast<ConstantInt>(Align)->getZExtValue());
     llvm::Constant *CI = ConstantInt::get(Int32Ty, 0);
     Ops[0] = Builder.CreateInsertElement(V, Ld, CI);
@@ -1795,7 +1858,6 @@
   case ARM::BI__builtin_neon_vld2_v:
   case ARM::BI__builtin_neon_vld2q_v: {
     Function *F = CGM.getIntrinsic(Intrinsic::arm_neon_vld2, Ty);
-    Value *Align = GetPointeeAlignmentValue(E->getArg(1));
     Ops[1] = Builder.CreateCall2(F, Ops[1], Align, "vld2");
     Ty = llvm::PointerType::getUnqual(Ops[1]->getType());
     Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
@@ -1804,7 +1866,6 @@
   case ARM::BI__builtin_neon_vld3_v:
   case ARM::BI__builtin_neon_vld3q_v: {
     Function *F = CGM.getIntrinsic(Intrinsic::arm_neon_vld3, Ty);
-    Value *Align = GetPointeeAlignmentValue(E->getArg(1));
     Ops[1] = Builder.CreateCall2(F, Ops[1], Align, "vld3");
     Ty = llvm::PointerType::getUnqual(Ops[1]->getType());
     Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
@@ -1813,7 +1874,6 @@
   case ARM::BI__builtin_neon_vld4_v:
   case ARM::BI__builtin_neon_vld4q_v: {
     Function *F = CGM.getIntrinsic(Intrinsic::arm_neon_vld4, Ty);
-    Value *Align = GetPointeeAlignmentValue(E->getArg(1));
     Ops[1] = Builder.CreateCall2(F, Ops[1], Align, "vld4");
     Ty = llvm::PointerType::getUnqual(Ops[1]->getType());
     Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
@@ -1824,7 +1884,7 @@
     Function *F = CGM.getIntrinsic(Intrinsic::arm_neon_vld2lane, Ty);
     Ops[2] = Builder.CreateBitCast(Ops[2], Ty);
     Ops[3] = Builder.CreateBitCast(Ops[3], Ty);
-    Ops.push_back(GetPointeeAlignmentValue(E->getArg(1)));
+    Ops.push_back(Align);
     Ops[1] = Builder.CreateCall(F, makeArrayRef(Ops).slice(1), "vld2_lane");
     Ty = llvm::PointerType::getUnqual(Ops[1]->getType());
     Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
@@ -1836,7 +1896,7 @@
     Ops[2] = Builder.CreateBitCast(Ops[2], Ty);
     Ops[3] = Builder.CreateBitCast(Ops[3], Ty);
     Ops[4] = Builder.CreateBitCast(Ops[4], Ty);
-    Ops.push_back(GetPointeeAlignmentValue(E->getArg(1)));
+    Ops.push_back(Align);
     Ops[1] = Builder.CreateCall(F, makeArrayRef(Ops).slice(1), "vld3_lane");
     Ty = llvm::PointerType::getUnqual(Ops[1]->getType());
     Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
@@ -1849,7 +1909,7 @@
     Ops[3] = Builder.CreateBitCast(Ops[3], Ty);
     Ops[4] = Builder.CreateBitCast(Ops[4], Ty);
     Ops[5] = Builder.CreateBitCast(Ops[5], Ty);
-    Ops.push_back(GetPointeeAlignmentValue(E->getArg(1)));
+    Ops.push_back(Align);
     Ops[1] = Builder.CreateCall(F, makeArrayRef(Ops).slice(1), "vld3_lane");
     Ty = llvm::PointerType::getUnqual(Ops[1]->getType());
     Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
@@ -1873,7 +1933,6 @@
       default: llvm_unreachable("unknown vld_dup intrinsic?");
       }
       Function *F = CGM.getIntrinsic(Int, Ty);
-      Value *Align = GetPointeeAlignmentValue(E->getArg(1));
       Ops[1] = Builder.CreateCall2(F, Ops[1], Align, "vld_dup");
       Ty = llvm::PointerType::getUnqual(Ops[1]->getType());
       Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
@@ -1900,7 +1959,7 @@
 
     llvm::Constant *CI = ConstantInt::get(Int32Ty, 0);
     Args.push_back(CI);
-    Args.push_back(GetPointeeAlignmentValue(E->getArg(1)));
+    Args.push_back(Align);
     
     Ops[1] = Builder.CreateCall(F, Args, "vld_dup");
     // splat lane 0 to all elts in each vector of the result.
@@ -2133,7 +2192,7 @@
     return Builder.CreateAdd(Ops[0], Ops[1]);
   case ARM::BI__builtin_neon_vst1_v:
   case ARM::BI__builtin_neon_vst1q_v:
-    Ops.push_back(GetPointeeAlignmentValue(E->getArg(0)));
+    Ops.push_back(Align);
     return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vst1, Ty),
                         Ops, "");
   case ARM::BI__builtin_neon_vst1q_lane_v:
@@ -2143,7 +2202,7 @@
       Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
       Value *SV = llvm::ConstantVector::get(cast<llvm::Constant>(Ops[2]));
       Ops[1] = Builder.CreateShuffleVector(Ops[1], Ops[1], SV);
-      Ops[2] = GetPointeeAlignmentValue(E->getArg(0));
+      Ops[2] = Align;
       return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::arm_neon_vst1,
                                                  Ops[1]->getType()), Ops);
     }
@@ -2154,38 +2213,37 @@
     Ty = llvm::PointerType::getUnqual(Ops[1]->getType());
     StoreInst *St = Builder.CreateStore(Ops[1],
                                         Builder.CreateBitCast(Ops[0], Ty));
-    Value *Align = GetPointeeAlignmentValue(E->getArg(0));
     St->setAlignment(cast<ConstantInt>(Align)->getZExtValue());
     return St;
   }
   case ARM::BI__builtin_neon_vst2_v:
   case ARM::BI__builtin_neon_vst2q_v:
-    Ops.push_back(GetPointeeAlignmentValue(E->getArg(0)));
+    Ops.push_back(Align);
     return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vst2, Ty),
                         Ops, "");
   case ARM::BI__builtin_neon_vst2_lane_v:
   case ARM::BI__builtin_neon_vst2q_lane_v:
-    Ops.push_back(GetPointeeAlignmentValue(E->getArg(0)));
+    Ops.push_back(Align);
     return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vst2lane, Ty),
                         Ops, "");
   case ARM::BI__builtin_neon_vst3_v:
   case ARM::BI__builtin_neon_vst3q_v:
-    Ops.push_back(GetPointeeAlignmentValue(E->getArg(0)));
+    Ops.push_back(Align);
     return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vst3, Ty),
                         Ops, "");
   case ARM::BI__builtin_neon_vst3_lane_v:
   case ARM::BI__builtin_neon_vst3q_lane_v:
-    Ops.push_back(GetPointeeAlignmentValue(E->getArg(0)));
+    Ops.push_back(Align);
     return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vst3lane, Ty),
                         Ops, "");
   case ARM::BI__builtin_neon_vst4_v:
   case ARM::BI__builtin_neon_vst4q_v:
-    Ops.push_back(GetPointeeAlignmentValue(E->getArg(0)));
+    Ops.push_back(Align);
     return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vst4, Ty),
                         Ops, "");
   case ARM::BI__builtin_neon_vst4_lane_v:
   case ARM::BI__builtin_neon_vst4q_lane_v:
-    Ops.push_back(GetPointeeAlignmentValue(E->getArg(0)));
+    Ops.push_back(Align);
     return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vst4lane, Ty),
                         Ops, "");
   case ARM::BI__builtin_neon_vsubhn_v:

Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.h?rev=162425&r1=162424&r2=162425&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenFunction.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.h Wed Aug 22 22:10:17 2012
@@ -2624,15 +2624,9 @@
 
   void AddObjCARCExceptionMetadata(llvm::Instruction *Inst);
 
-  /// GetPointeeAlignment - Given an expression with a pointer type, find the
-  /// alignment of the type referenced by the pointer.  Skip over implicit
-  /// casts.
-  unsigned GetPointeeAlignment(const Expr *Addr);
-
-  /// GetPointeeAlignmentValue - Given an expression with a pointer type, find
-  /// the alignment of the type referenced by the pointer.  Skip over implicit
-  /// casts.  Return the alignment as an llvm::Value.
-  llvm::Value *GetPointeeAlignmentValue(const Expr *Addr);
+  /// GetPointeeAlignment - Given an expression with a pointer type, emit the
+  /// value and compute our best estimate of the alignment of the pointee.
+  std::pair<llvm::Value*, unsigned> EmitPointerWithAlignment(const Expr *Addr);
 };
 
 /// Helper class with most of the code for saving a value for a

Modified: cfe/trunk/test/CodeGen/builtin-memfns.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/builtin-memfns.c?rev=162425&r1=162424&r2=162425&view=diff
==============================================================================
--- cfe/trunk/test/CodeGen/builtin-memfns.c (original)
+++ cfe/trunk/test/CodeGen/builtin-memfns.c Wed Aug 22 22:10:17 2012
@@ -63,3 +63,23 @@
   __builtin_memset(hwparams, 0, 256);  // No crash alignment = 1
   // CHECK: call void @llvm.memset{{.*}}256, i32 1, i1 false)
 }
+
+// <rdar://problem/11314941>
+// Make sure we don't over-estimate the alignment of fields of
+// packed structs.
+struct PS {
+  int modes[4];
+} __attribute__((packed));
+struct PS ps;
+void test8(int *arg) {
+  // CHECK: @test8
+  // CHECK: call void @llvm.memcpy{{.*}} 16, i32 1, i1 false)
+  __builtin_memcpy(arg, ps.modes, sizeof(struct PS));
+}
+
+__attribute((aligned(16))) int x[4], y[4];
+void test9() {
+  // CHECK: @test9
+  // CHECK: call void @llvm.memcpy{{.*}} 16, i32 16, i1 false)
+  __builtin_memcpy(x, y, sizeof(y));
+}





More information about the cfe-commits mailing list