kosarev created this revision.
kosarev added reviewers: rjmccall, hfinkel.
kosarev added a project: clang.

We only do this for the new format as the old format does not allow to 
represent accesses to aggregates. This patch significantly improves TBAA 
coverage on -O1 builds.


Repository:
  rL LLVM

https://reviews.llvm.org/D41562

Files:
  lib/CodeGen/CGCall.cpp
  test/CodeGen/tbaa-call.cpp

Index: test/CodeGen/tbaa-call.cpp
===================================================================
--- test/CodeGen/tbaa-call.cpp
+++ test/CodeGen/tbaa-call.cpp
@@ -0,0 +1,110 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -O1 -disable-llvm-passes \
+// RUN:     -new-struct-path-tbaa %s -emit-llvm -o - | FileCheck %s
+//
+// Check that we generate correct TBAA information for instructions that pass
+// function arguments and returning values.
+
+struct A { int : 0; };
+struct B { double d; };
+struct C { A a; B b; };
+struct D { int i; };
+struct E { double d; int i; };
+struct F { float _Complex c; int x; };
+struct G { E e; };
+
+B get_B();
+C get_C();
+D get_D();
+E get_E();
+F get_F();
+
+void set_E(E);
+
+C f1() {
+// CHECK-LABEL: _Z2f1v
+// CHECK: load double, {{.*}}, !tbaa [[TAG_C:!.*]]
+  return C();
+}
+
+D f2() {
+// CHECK-LABEL: _Z2f2v
+// CHECK: load i32, {{.*}}, !tbaa [[TAG_D:!.*]]
+  return D();
+}
+
+E f3() {
+// CHECK-LABEL: _Z2f3v
+// CHECK: load { double, i32 }, {{.*}}, !tbaa [[TAG_E:!.*]]
+  return E();
+}
+
+E f4() {
+// CHECK-LABEL: _Z2f4v
+// CHECK: call { double, i32 } @_Z5get_Ev()
+// CHECK-DAG: store double {{.*}}, !tbaa [[TAG_E]]
+// CHECK-DAG: store i32 {{.*}}, !tbaa [[TAG_E]]
+// CHECK: load { double, i32 }, {{.*}}, !tbaa [[TAG_E]]
+  return get_E();
+}
+
+B f5() {
+// CHECK-LABEL: _Z2f5v
+// CHECK: call double @_Z5get_Bv()
+// CHECK: store double {{.*}}, !tbaa [[TAG_B:!.*]]
+// CHECK: load double, {{.*}}, !tbaa [[TAG_B]]
+  return get_B();
+}
+
+C f6() {
+// CHECK-LABEL: _Z2f6v
+// CHECK: call double @_Z5get_Cv()
+// CHECK: store double {{.*}}, !tbaa [[TAG_C]]
+// CHECK: load double, {{.*}}, !tbaa [[TAG_C]]
+  return get_C();
+}
+
+D f7() {
+// CHECK-LABEL: _Z2f7v
+// CHECK: call i32 @_Z5get_Dv()
+// CHECK: store i32 {{.*}}, !tbaa [[TAG_D]]
+// CHECK: load i32, {{.*}}, !tbaa [[TAG_D]]
+  return get_D();
+}
+
+F f8() {
+// CHECK-LABEL: _Z2f8v
+// CHECK: call { <2 x float>, i32 } @_Z5get_Fv()
+// CHECK: store { <2 x float>, i32 } {{.*}}, !tbaa [[TAG_F:!.*]]
+// CHECK: load { <2 x float>, i32 }, {{.*}}, !tbaa [[TAG_F]]
+  return get_F();
+}
+
+G f9(G g) {
+// CHECK-LABEL: _Z2f91G
+// CHECK-DAG: store double {{.*}}, !tbaa [[TAG_G:!.*]]
+// CHECK-DAG: store i32 {{.*}}, !tbaa [[TAG_G]]
+// CHECK: load { double, i32 }, {{.*}}, !tbaa [[TAG_G]]
+  return g;
+}
+
+void f10() {
+// CHECK-LABEL: _Z3f10v
+// CHECK-DAG: load double, {{.*}}, !tbaa [[TAG_E]]
+// CHECK-DAG: load i32, {{.*}}, !tbaa [[TAG_E]]
+// CHECK: call void @_Z5set_E1E
+  E e;
+  set_E(e);
+}
+
+// CHECK-DAG: [[TYPE_B:!.*]] = !{{{.*}}, !"_ZTS1B", {{.*}}}
+// CHECK-DAG: [[TAG_B]] = !{[[TYPE_B]], [[TYPE_B]], {{.*}}}
+// CHECK-DAG: [[TYPE_C:!.*]] = !{{{.*}}, !"_ZTS1C", {{.*}}}
+// CHECK-DAG: [[TAG_C]] = !{[[TYPE_C]], [[TYPE_C]], {{.*}}}
+// CHECK-DAG: [[TYPE_D:!.*]] = !{{{.*}}, !"_ZTS1D", {{.*}}}
+// CHECK-DAG: [[TAG_D]] = !{[[TYPE_D]], [[TYPE_D]], {{.*}}}
+// CHECK-DAG: [[TYPE_E:!.*]] = !{{{.*}}, !"_ZTS1E", {{.*}}}
+// CHECK-DAG: [[TAG_E]] = !{[[TYPE_E]], [[TYPE_E]], {{.*}}}
+// CHECK-DAG: [[TYPE_F:!.*]] = !{{{.*}}, !"_ZTS1F", {{.*}}}
+// CHECK-DAG: [[TAG_F]] = !{[[TYPE_F]], [[TYPE_F]], {{.*}}}
+// CHECK-DAG: [[TYPE_G:!.*]] = !{{{.*}}, !"_ZTS1G", {{.*}}}
+// CHECK-DAG: [[TAG_G]] = !{[[TYPE_G]], [[TYPE_G]], {{.*}}}
Index: lib/CodeGen/CGCall.cpp
===================================================================
--- lib/CodeGen/CGCall.cpp
+++ lib/CodeGen/CGCall.cpp
@@ -1195,12 +1195,16 @@
 /// destination type; in this situation the values of bits which not
 /// present in the src are undefined.
 static llvm::Value *CreateCoercedLoad(Address Src, llvm::Type *Ty,
+                                      TBAAAccessInfo TBAAInfo,
                                       CodeGenFunction &CGF) {
   llvm::Type *SrcTy = Src.getElementType();
 
   // If SrcTy and Ty are the same, just do a load.
-  if (SrcTy == Ty)
-    return CGF.Builder.CreateLoad(Src);
+  if (SrcTy == Ty) {
+    auto *Load = CGF.Builder.CreateLoad(Src);
+    CGF.CGM.DecorateInstructionWithTBAA(Load, TBAAInfo);
+    return Load;
+  }
 
   uint64_t DstSize = CGF.CGM.getDataLayout().getTypeAllocSize(Ty);
 
@@ -1215,7 +1219,8 @@
   // extension or truncation to the desired type.
   if ((isa<llvm::IntegerType>(Ty) || isa<llvm::PointerType>(Ty)) &&
       (isa<llvm::IntegerType>(SrcTy) || isa<llvm::PointerType>(SrcTy))) {
-    llvm::Value *Load = CGF.Builder.CreateLoad(Src);
+    auto *Load = CGF.Builder.CreateLoad(Src);
+    CGF.CGM.DecorateInstructionWithTBAA(Load, TBAAInfo);
     return CoerceIntOrPtrToIntOrPtr(Load, Ty, CGF);
   }
 
@@ -1229,7 +1234,9 @@
     // to that information.
     Src = CGF.Builder.CreateBitCast(Src,
                                     Ty->getPointerTo(Src.getAddressSpace()));
-    return CGF.Builder.CreateLoad(Src);
+    auto *Load = CGF.Builder.CreateLoad(Src);
+    CGF.CGM.DecorateInstructionWithTBAA(Load, TBAAInfo);
+    return Load;
   }
 
   // Otherwise do coercion through memory. This is stupid, but simple.
@@ -1239,15 +1246,18 @@
   CGF.Builder.CreateMemCpy(Casted, SrcCasted,
       llvm::ConstantInt::get(CGF.IntPtrTy, SrcSize),
       false);
-  return CGF.Builder.CreateLoad(Tmp);
+  auto *Load = CGF.Builder.CreateLoad(Tmp);
+  CGF.CGM.DecorateInstructionWithTBAA(Load, TBAAInfo);
+  return Load;
 }
 
 // Function to store a first-class aggregate into memory.  We prefer to
 // store the elements rather than the aggregate to be more friendly to
 // fast-isel.
 // FIXME: Do we need to recurse here?
 static void BuildAggStore(CodeGenFunction &CGF, llvm::Value *Val,
-                          Address Dest, bool DestIsVolatile) {
+                          Address Dest, bool DestIsVolatile,
+                          TBAAAccessInfo TBAAInfo) {
   // Prefer scalar stores to first-class aggregate stores.
   if (llvm::StructType *STy =
         dyn_cast<llvm::StructType>(Val->getType())) {
@@ -1258,27 +1268,28 @@
       auto EltOffset = CharUnits::fromQuantity(Layout->getElementOffset(i));
       Address EltPtr = CGF.Builder.CreateStructGEP(Dest, i, EltOffset);
       llvm::Value *Elt = CGF.Builder.CreateExtractValue(Val, i);
-      CGF.Builder.CreateStore(Elt, EltPtr, DestIsVolatile);
+      auto *Store = CGF.Builder.CreateStore(Elt, EltPtr, DestIsVolatile);
+      CGF.CGM.DecorateInstructionWithTBAA(Store, TBAAInfo);
     }
   } else {
-    CGF.Builder.CreateStore(Val, Dest, DestIsVolatile);
+    auto *Store = CGF.Builder.CreateStore(Val, Dest, DestIsVolatile);
+    CGF.CGM.DecorateInstructionWithTBAA(Store, TBAAInfo);
   }
 }
 
-/// CreateCoercedStore - Create a store to \arg DstPtr from \arg Src,
-/// where the source and destination may have different types.  The
-/// destination is known to be aligned to \arg DstAlign bytes.
+/// CreateCoercedStore - Create a store to \arg Dst from \arg Src,
+/// where the source and destination may have different types.
 ///
 /// This safely handles the case when the src type is larger than the
 /// destination type; the upper bits of the src will be lost.
-static void CreateCoercedStore(llvm::Value *Src,
-                               Address Dst,
-                               bool DstIsVolatile,
+static void CreateCoercedStore(llvm::Value *Src, Address Dst,
+                               bool DstIsVolatile, TBAAAccessInfo TBAAInfo,
                                CodeGenFunction &CGF) {
   llvm::Type *SrcTy = Src->getType();
   llvm::Type *DstTy = Dst.getType()->getElementType();
   if (SrcTy == DstTy) {
-    CGF.Builder.CreateStore(Src, Dst, DstIsVolatile);
+    auto *Store = CGF.Builder.CreateStore(Src, Dst, DstIsVolatile);
+    CGF.CGM.DecorateInstructionWithTBAA(Store, TBAAInfo);
     return;
   }
 
@@ -1294,16 +1305,17 @@
   if ((isa<llvm::IntegerType>(SrcTy) || isa<llvm::PointerType>(SrcTy)) &&
       (isa<llvm::IntegerType>(DstTy) || isa<llvm::PointerType>(DstTy))) {
     Src = CoerceIntOrPtrToIntOrPtr(Src, DstTy, CGF);
-    CGF.Builder.CreateStore(Src, Dst, DstIsVolatile);
+    auto *Store = CGF.Builder.CreateStore(Src, Dst, DstIsVolatile);
+    CGF.CGM.DecorateInstructionWithTBAA(Store, TBAAInfo);
     return;
   }
 
   uint64_t DstSize = CGF.CGM.getDataLayout().getTypeAllocSize(DstTy);
 
   // If store is legal, just bitcast the src pointer.
   if (SrcSize <= DstSize) {
     Dst = CGF.Builder.CreateElementBitCast(Dst, SrcTy);
-    BuildAggStore(CGF, Src, Dst, DstIsVolatile);
+    BuildAggStore(CGF, Src, Dst, DstIsVolatile, TBAAInfo);
   } else {
     // Otherwise do coercion through memory. This is stupid, but
     // simple.
@@ -1315,7 +1327,8 @@
     // FIXME: Assert that we aren't truncating non-padding bits when have access
     // to that information.
     Address Tmp = CreateTempAllocaForCoercion(CGF, SrcTy, Dst.getAlignment());
-    CGF.Builder.CreateStore(Src, Tmp);
+    auto *Store = CGF.Builder.CreateStore(Src, Tmp);
+    CGF.CGM.DecorateInstructionWithTBAA(Store, TBAAInfo);
     Address Casted = CGF.Builder.CreateBitCast(Tmp, CGF.AllocaInt8PtrTy);
     Address DstCasted = CGF.Builder.CreateBitCast(Dst, CGF.AllocaInt8PtrTy);
     CGF.Builder.CreateMemCpy(DstCasted, Casted,
@@ -2258,6 +2271,10 @@
     QualType Ty = info_it->type;
     const ABIArgInfo &ArgI = info_it->info;
 
+    TBAAAccessInfo ArgTBAAInfo;
+    if (CGM.getCodeGenOpts().NewStructPathTBAA)
+      ArgTBAAInfo = CGM.getTBAAAccessInfo(Ty);
+
     bool isPromoted =
       isa<ParmVarDecl>(Arg) && cast<ParmVarDecl>(Arg)->isKNRPromoted();
 
@@ -2445,7 +2462,8 @@
           auto Offset = CharUnits::fromQuantity(SrcLayout->getElementOffset(i));
           Address EltPtr =
             Builder.CreateStructGEP(AddrToStoreInto, i, Offset);
-          Builder.CreateStore(AI, EltPtr);
+          auto *Store = Builder.CreateStore(AI, EltPtr);
+          CGM.DecorateInstructionWithTBAA(Store, ArgTBAAInfo);
         }
 
         if (SrcSize > DstSize) {
@@ -2457,7 +2475,8 @@
         assert(NumIRArgs == 1);
         auto AI = FnArgs[FirstIRArg];
         AI->setName(Arg->getName() + ".coerce");
-        CreateCoercedStore(AI, Ptr, /*DestIsVolatile=*/false, *this);
+        CreateCoercedStore(AI, Ptr, /*DestIsVolatile=*/false, ArgTBAAInfo,
+                           *this);
       }
 
       // Match to what EmitParmDecl is expecting for this type.
@@ -2781,6 +2800,10 @@
   QualType RetTy = FI.getReturnType();
   const ABIArgInfo &RetAI = FI.getReturnInfo();
 
+  TBAAAccessInfo RetTBAAInfo;
+  if (CGM.getCodeGenOpts().NewStructPathTBAA)
+    RetTBAAInfo = CGM.getTBAAAccessInfo(RetTy);
+
   switch (RetAI.getKind()) {
   case ABIArgInfo::InAlloca:
     // Aggregrates get evaluated directly into the destination.  Sometimes we
@@ -2857,7 +2880,7 @@
       // If the value is offset in memory, apply the offset now.
       Address V = emitAddressAtOffset(*this, ReturnValue, RetAI);
 
-      RV = CreateCoercedLoad(V, RetAI.getCoerceToType(), *this);
+      RV = CreateCoercedLoad(V, RetAI.getCoerceToType(), RetTBAAInfo, *this);
     }
 
     // In ARC, end functions that return a retainable type with a call
@@ -3735,6 +3758,10 @@
   QualType RetTy = CallInfo.getReturnType();
   const ABIArgInfo &RetAI = CallInfo.getReturnInfo();
 
+  TBAAAccessInfo RetTBAAInfo;
+  if (CGM.getCodeGenOpts().NewStructPathTBAA)
+    RetTBAAInfo = CGM.getTBAAAccessInfo(RetTy);
+
   llvm::FunctionType *IRFuncTy = Callee.getFunctionType();
 
   // 1. Set up the arguments.
@@ -3807,6 +3834,9 @@
   for (CallArgList::const_iterator I = CallArgs.begin(), E = CallArgs.end();
        I != E; ++I, ++info_it, ++ArgNo) {
     const ABIArgInfo &ArgInfo = info_it->info;
+    TBAAAccessInfo ArgTBAAInfo;
+    if (CGM.getCodeGenOpts().NewStructPathTBAA)
+      ArgTBAAInfo = CGM.getTBAAAccessInfo(info_it->type);
     RValue RV = I->RV;
 
     // Insert a padding argument to ensure proper alignment.
@@ -3984,14 +4014,15 @@
         for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
           auto Offset = CharUnits::fromQuantity(SrcLayout->getElementOffset(i));
           Address EltPtr = Builder.CreateStructGEP(Src, i, Offset);
-          llvm::Value *LI = Builder.CreateLoad(EltPtr);
+          auto *LI = Builder.CreateLoad(EltPtr);
+          CGM.DecorateInstructionWithTBAA(LI, ArgTBAAInfo);
           IRCallArgs[FirstIRArg + i] = LI;
         }
       } else {
         // In the simple case, just pass the coerced loaded value.
         assert(NumIRArgs == 1);
         IRCallArgs[FirstIRArg] =
-          CreateCoercedLoad(Src, ArgInfo.getCoerceToType(), *this);
+          CreateCoercedLoad(Src, ArgInfo.getCoerceToType(), ArgTBAAInfo, *this);
       }
 
       break;
@@ -4344,7 +4375,7 @@
             DestPtr = CreateMemTemp(RetTy, "agg.tmp");
             DestIsVolatile = false;
           }
-          BuildAggStore(*this, CI, DestPtr, DestIsVolatile);
+          BuildAggStore(*this, CI, DestPtr, DestIsVolatile, RetTBAAInfo);
           return RValue::getAggregate(DestPtr);
         }
         case TEK_Scalar: {
@@ -4369,7 +4400,7 @@
 
       // If the value is offset in memory, apply the offset now.
       Address StorePtr = emitAddressAtOffset(*this, DestPtr, RetAI);
-      CreateCoercedStore(CI, StorePtr, DestIsVolatile, *this);
+      CreateCoercedStore(CI, StorePtr, DestIsVolatile, RetTBAAInfo, *this);
 
       return convertTempToRValue(DestPtr, RetTy, SourceLocation());
     }
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
  • [PATCH] D41562: [CodeGen] Gen... Ivan Kosarev via Phabricator via cfe-commits

Reply via email to