From 365b78396abf18a1d9be7962c0831ea61b3f4dc1 Mon Sep 17 00:00:00 2001 From: Francis Visoiu Mistrih Date: Mon, 1 Mar 2021 13:07:02 -0800 Subject: [PATCH] [Remarks] Emit variable info in auto-init remarks This enhances the auto-init remark with information about the variable that is auto-initialized. This is based of debug info if available, or alloca names (mostly for development purposes). ``` auto-init.c:4:7: remark: Call to memset inserted by -ftrivial-auto-var-init. Memory operation size: 4096 bytes.Variables: var (4096 bytes). [-Rpass-missed=annotation-remarks] int var[1024]; ^ ``` This allows to see things like partial initialization of a variable that the optimizer won't be able to completely remove. Differential Revision: https://reviews.llvm.org/D97734 --- .../include/llvm/Transforms/Utils/AutoInitRemark.h | 20 ++++++ llvm/lib/Transforms/Utils/AutoInitRemark.cpp | 77 ++++++++++++++++++++++ .../Transforms/Util/trivial-auto-var-init-call.ll | 56 ++++++++++++++++ .../Transforms/Util/trivial-auto-var-init-store.ll | 18 ++++- 4 files changed, 169 insertions(+), 2 deletions(-) diff --git a/llvm/include/llvm/Transforms/Utils/AutoInitRemark.h b/llvm/include/llvm/Transforms/Utils/AutoInitRemark.h index 83805cc..61be76f 100644 --- a/llvm/include/llvm/Transforms/Utils/AutoInitRemark.h +++ b/llvm/include/llvm/Transforms/Utils/AutoInitRemark.h @@ -41,17 +41,37 @@ struct AutoInitRemark { const DataLayout &DL, const TargetLibraryInfo &TLI) : ORE(ORE), RemarkPass(RemarkPass), DL(DL), TLI(TLI) {} + /// Emit a remark using information from the store's destination, size, etc. void inspectStore(StoreInst &SI); + /// Emit a generic auto-init remark. void inspectUnknown(Instruction &I); + /// Emit a remark using information from known intrinsic calls. void inspectIntrinsicCall(IntrinsicInst &II); + /// Emit a remark using information from known function calls. void inspectCall(CallInst &CI); private: + /// Add callee information to a remark: whether it's known, the function name, + /// etc. template void inspectCallee(FTy F, bool KnownLibCall, OptimizationRemarkMissed &R); + /// Add operand information to a remark based on knowledge we have for known + /// libcalls. void inspectKnownLibCall(CallInst &CI, LibFunc LF, OptimizationRemarkMissed &R); + /// Add the memory operation size to a remark. void inspectSizeOperand(Value *V, OptimizationRemarkMissed &R); + + struct VariableInfo { + Optional Name; + Optional Size; + bool isEmpty() const { return !Name && !Size; } + }; + /// Gather more information about \p V as a variable. This can be debug info, + /// information from the alloca, etc. Since \p V can represent more than a + /// single variable, they will all be added to the remark. + void inspectDst(Value *Dst, OptimizationRemarkMissed &R); + void inspectVariable(const Value *V, SmallVectorImpl &Result); }; } // namespace llvm diff --git a/llvm/lib/Transforms/Utils/AutoInitRemark.cpp b/llvm/lib/Transforms/Utils/AutoInitRemark.cpp index 9e74a4a..0c72ee5b 100644 --- a/llvm/lib/Transforms/Utils/AutoInitRemark.cpp +++ b/llvm/lib/Transforms/Utils/AutoInitRemark.cpp @@ -12,8 +12,11 @@ #include "llvm/Transforms/Utils/AutoInitRemark.h" #include "llvm/Analysis/OptimizationRemarkEmitter.h" +#include "llvm/Analysis/ValueTracking.h" +#include "llvm/IR/DebugInfoMetadata.h" #include "llvm/IR/Instructions.h" #include "llvm/IR/IntrinsicInst.h" +#include "llvm/Transforms/Utils/Local.h" using namespace llvm; using namespace llvm::ore; @@ -35,6 +38,12 @@ static void volatileOrAtomicWithExtraArgs(bool Volatile, bool Atomic, R << " Atomic: " << NV("StoreAtomic", false) << "."; } +static Optional getSizeInBytes(Optional SizeInBits) { + if (!SizeInBits || *SizeInBits % 8 != 0) + return None; + return *SizeInBits / 8; +} + void AutoInitRemark::inspectStore(StoreInst &SI) { bool Volatile = SI.isVolatile(); bool Atomic = SI.isAtomic(); @@ -43,6 +52,7 @@ void AutoInitRemark::inspectStore(StoreInst &SI) { OptimizationRemarkMissed R(RemarkPass.data(), "AutoInitStore", &SI); R << "Store inserted by -ftrivial-auto-var-init.\nStore size: " << NV("StoreSize", Size) << " bytes."; + inspectDst(SI.getOperand(1), R); volatileOrAtomicWithExtraArgs(Volatile, Atomic, R); ORE.emit(R); } @@ -89,6 +99,7 @@ void AutoInitRemark::inspectIntrinsicCall(IntrinsicInst &II) { auto *CIVolatile = dyn_cast(II.getOperand(3)); // No such thing as a memory intrinsic that is both atomic and volatile. bool Volatile = !Atomic && CIVolatile && CIVolatile->getZExtValue(); + inspectDst(II.getOperand(0), R); volatileOrAtomicWithExtraArgs(Volatile, Atomic, R); ORE.emit(R); } @@ -122,6 +133,7 @@ void AutoInitRemark::inspectKnownLibCall(CallInst &CI, LibFunc LF, return; case LibFunc_bzero: inspectSizeOperand(CI.getOperand(1), R); + inspectDst(CI.getOperand(0), R); break; } } @@ -132,3 +144,68 @@ void AutoInitRemark::inspectSizeOperand(Value *V, OptimizationRemarkMissed &R) { R << " Memory operation size: " << NV("StoreSize", Size) << " bytes."; } } + +void AutoInitRemark::inspectVariable(const Value *V, + SmallVectorImpl &Result) { + // If we find some information in the debug info, take that. + bool FoundDI = false; + // Try to get an llvm.dbg.declare, which has a DILocalVariable giving us the + // real debug info name and size of the variable. + for (const DbgVariableIntrinsic *DVI : + FindDbgAddrUses(const_cast(V))) { + if (DILocalVariable *DILV = DVI->getVariable()) { + Optional DISize = getSizeInBytes(DILV->getSizeInBits()); + VariableInfo Var{DILV->getName(), DISize}; + if (!Var.isEmpty()) { + Result.push_back(std::move(Var)); + FoundDI = true; + } + } + } + if (FoundDI) { + assert(!Result.empty()); + return; + } + + const auto *AI = dyn_cast(V); + if (!AI) + return; + + // If not, get it from the alloca. + Optional Name = AI->hasName() + ? Optional(AI->getName()) + : Optional(None); + Optional TySize = AI->getAllocationSizeInBits(DL); + Optional Size = + TySize ? getSizeInBytes(TySize->getFixedSize()) : None; + VariableInfo Var{Name, Size}; + if (!Var.isEmpty()) + Result.push_back(std::move(Var)); +} + +void AutoInitRemark::inspectDst(Value *Dst, OptimizationRemarkMissed &R) { + // Find if Dst is a known variable we can give more information on. + SmallVector Objects; + getUnderlyingObjects(Dst, Objects); + SmallVector VIs; + for (const Value *V : Objects) + inspectVariable(V, VIs); + + if (VIs.empty()) + return; + + R << "\nVariables: "; + for (unsigned i = 0; i < VIs.size(); ++i) { + const VariableInfo &VI = VIs[i]; + assert(!VI.isEmpty() && "No extra content to display."); + if (i != 0) + R << ", "; + if (VI.Name) + R << NV("VarName", *VI.Name); + else + R << NV("VarName", ""); + if (VI.Size) + R << " (" << NV("VarSize", *VI.Size) << " bytes)"; + } + R << "."; +} diff --git a/llvm/test/Transforms/Util/trivial-auto-var-init-call.ll b/llvm/test/Transforms/Util/trivial-auto-var-init-call.ll index 65c40ae..79c69bd 100644 --- a/llvm/test/Transforms/Util/trivial-auto-var-init-call.ll +++ b/llvm/test/Transforms/Util/trivial-auto-var-init-call.ll @@ -290,6 +290,7 @@ define void @known_call_atomic(i8* %src, i8* %dst, i64 %size) { ; an alloca. define void @known_call_with_size_alloca(i8* %src) { ; CHECK-NEXT: Call to memset inserted by -ftrivial-auto-var-init. Memory operation size: 1 bytes. +; CHECK-NEXT: Variables: dst (1 bytes). ; YAML-LABEL: --- !Missed ; YAML-NEXT: Pass: annotation-remarks ; YAML-NEXT: Name: AutoInitIntrinsic @@ -302,6 +303,12 @@ define void @known_call_with_size_alloca(i8* %src) { ; YAML-NEXT: - String: ' Memory operation size: ' ; YAML-NEXT: - StoreSize: '1' ; YAML-NEXT: - String: ' bytes.' +; YAML-NEXT: - String: "\nVariables: " +; YAML-NEXT: - VarName: dst +; YAML-NEXT: - String: ' (' +; YAML-NEXT: - VarSize: '1' +; YAML-NEXT: - String: ' bytes)' +; YAML-NEXT: - String: . ; YAML-NEXT: - String: ' Volatile: ' ; YAML-NEXT: - StoreVolatile: 'false' ; YAML-NEXT: - String: . @@ -312,6 +319,7 @@ define void @known_call_with_size_alloca(i8* %src) { %dst = alloca i8 call void @llvm.memset.p0i8.i64(i8* %dst, i8 0, i64 1, i1 false), !annotation !0, !dbg !DILocation(scope: !4) ; CHECK-NEXT: Call to memcpy inserted by -ftrivial-auto-var-init. Memory operation size: 1 bytes. +; CHECK-NEXT: Variables: dst (1 bytes). ; YAML-LABEL: --- !Missed ; YAML-NEXT: Pass: annotation-remarks ; YAML-NEXT: Name: AutoInitIntrinsic @@ -324,6 +332,12 @@ define void @known_call_with_size_alloca(i8* %src) { ; YAML-NEXT: - String: ' Memory operation size: ' ; YAML-NEXT: - StoreSize: '1' ; YAML-NEXT: - String: ' bytes.' +; YAML-NEXT: - String: "\nVariables: " +; YAML-NEXT: - VarName: dst +; YAML-NEXT: - String: ' (' +; YAML-NEXT: - VarSize: '1' +; YAML-NEXT: - String: ' bytes)' +; YAML-NEXT: - String: . ; YAML-NEXT: - String: ' Volatile: ' ; YAML-NEXT: - StoreVolatile: 'false' ; YAML-NEXT: - String: . @@ -333,6 +347,7 @@ define void @known_call_with_size_alloca(i8* %src) { ; YAML-NEXT: ... call void @llvm.memcpy.p0i8.p0i8.i64(i8* %dst, i8* %src, i64 1, i1 false), !annotation !0, !dbg !DILocation(scope: !4) ; CHECK-NEXT: Call to memmove inserted by -ftrivial-auto-var-init. Memory operation size: 1 bytes. +; CHECK-NEXT: Variables: dst (1 bytes). ; YAML-LABEL: --- !Missed ; YAML-NEXT: Pass: annotation-remarks ; YAML-NEXT: Name: AutoInitIntrinsic @@ -345,6 +360,12 @@ define void @known_call_with_size_alloca(i8* %src) { ; YAML-NEXT: - String: ' Memory operation size: ' ; YAML-NEXT: - StoreSize: '1' ; YAML-NEXT: - String: ' bytes.' +; YAML-NEXT: - String: "\nVariables: " +; YAML-NEXT: - VarName: dst +; YAML-NEXT: - String: ' (' +; YAML-NEXT: - VarSize: '1' +; YAML-NEXT: - String: ' bytes)' +; YAML-NEXT: - String: . ; YAML-NEXT: - String: ' Volatile: ' ; YAML-NEXT: - StoreVolatile: 'false' ; YAML-NEXT: - String: . @@ -354,6 +375,7 @@ define void @known_call_with_size_alloca(i8* %src) { ; YAML-NEXT: ... call void @llvm.memmove.p0i8.p0i8.i64(i8* %dst, i8* %src, i64 1, i1 false), !annotation !0, !dbg !DILocation(scope: !4) ; CHECK-NEXT: Call to bzero inserted by -ftrivial-auto-var-init. Memory operation size: 1 bytes. +; CHECK-NEXT: Variables: dst (1 bytes). ; YAML-LABEL: --- !Missed ; YAML-NEXT: Pass: annotation-remarks ; YAML-NEXT: Name: AutoInitCall @@ -366,6 +388,12 @@ define void @known_call_with_size_alloca(i8* %src) { ; YAML-NEXT: - String: ' Memory operation size: ' ; YAML-NEXT: - StoreSize: '1' ; YAML-NEXT: - String: ' bytes.' +; YAML-NEXT: - String: "\nVariables: " +; YAML-NEXT: - VarName: dst +; YAML-NEXT: - String: ' (' +; YAML-NEXT: - VarSize: '1' +; YAML-NEXT: - String: ' bytes)' +; YAML-NEXT: - String: . ; YAML-NEXT: ... call void @bzero(i8* %dst, i64 1), !annotation !0, !dbg !DILocation(scope: !4) @@ -376,14 +404,18 @@ define void @known_call_with_size_alloca(i8* %src) { ; an alloca through a GEP. define void @known_call_with_size_alloca_gep(i8* %src) { ; CHECK-NEXT: Call to memset inserted by -ftrivial-auto-var-init. Memory operation size: 1 bytes. +; CHECK-NEXT: Variables: dst (1 bytes). %dst = alloca i8 %gep = getelementptr i8, i8* %dst, i32 0 call void @llvm.memset.p0i8.i64(i8* %gep, i8 0, i64 1, i1 false), !annotation !0, !dbg !DILocation(scope: !4) ; CHECK-NEXT: Call to memcpy inserted by -ftrivial-auto-var-init. Memory operation size: 1 bytes. +; CHECK-NEXT: Variables: dst (1 bytes). call void @llvm.memcpy.p0i8.p0i8.i64(i8* %gep, i8* %src, i64 1, i1 false), !annotation !0, !dbg !DILocation(scope: !4) ; CHECK-NEXT: Call to memmove inserted by -ftrivial-auto-var-init. Memory operation size: 1 bytes. +; CHECK-NEXT: Variables: dst (1 bytes). call void @llvm.memmove.p0i8.p0i8.i64(i8* %gep, i8* %src, i64 1, i1 false), !annotation !0, !dbg !DILocation(scope: !4) ; CHECK-NEXT: Call to bzero inserted by -ftrivial-auto-var-init. Memory operation size: 1 bytes. +; CHECK-NEXT: Variables: dst (1 bytes). call void @bzero(i8* %gep, i64 1), !annotation !0, !dbg !DILocation(scope: !4) ret void } @@ -392,14 +424,18 @@ define void @known_call_with_size_alloca_gep(i8* %src) { ; an alloca through a GEP in an array. define void @known_call_with_size_alloca_gep_array(i8* %src) { ; CHECK-NEXT: Call to memset inserted by -ftrivial-auto-var-init. Memory operation size: 1 bytes. +; CHECK-NEXT: Variables: dst (2 bytes). %dst = alloca [2 x i8] %gep = getelementptr [2 x i8], [2 x i8]* %dst, i64 0, i64 0 call void @llvm.memset.p0i8.i64(i8* %gep, i8 0, i64 1, i1 false), !annotation !0, !dbg !DILocation(scope: !4) ; CHECK-NEXT: Call to memcpy inserted by -ftrivial-auto-var-init. Memory operation size: 1 bytes. +; CHECK-NEXT: Variables: dst (2 bytes). call void @llvm.memcpy.p0i8.p0i8.i64(i8* %gep, i8* %src, i64 1, i1 false), !annotation !0, !dbg !DILocation(scope: !4) ; CHECK-NEXT: Call to memmove inserted by -ftrivial-auto-var-init. Memory operation size: 1 bytes. +; CHECK-NEXT: Variables: dst (2 bytes). call void @llvm.memmove.p0i8.p0i8.i64(i8* %gep, i8* %src, i64 1, i1 false), !annotation !0, !dbg !DILocation(scope: !4) ; CHECK-NEXT: Call to bzero inserted by -ftrivial-auto-var-init. Memory operation size: 1 bytes. +; CHECK-NEXT: Variables: dst (2 bytes). call void @bzero(i8* %gep, i64 1), !annotation !0, !dbg !DILocation(scope: !4) ret void } @@ -408,14 +444,18 @@ define void @known_call_with_size_alloca_gep_array(i8* %src) { ; an alloca through a bitcast. define void @known_call_with_size_alloca_bitcast(i8* %src) { ; CHECK-NEXT: Call to memset inserted by -ftrivial-auto-var-init. Memory operation size: 1 bytes. +; CHECK-NEXT: Variables: dst (2 bytes). %dst = alloca [2 x i8] %bc = bitcast [2 x i8]* %dst to i8* call void @llvm.memset.p0i8.i64(i8* %bc, i8 0, i64 1, i1 false), !annotation !0, !dbg !DILocation(scope: !4) ; CHECK-NEXT: Call to memcpy inserted by -ftrivial-auto-var-init. Memory operation size: 1 bytes. +; CHECK-NEXT: Variables: dst (2 bytes). call void @llvm.memcpy.p0i8.p0i8.i64(i8* %bc, i8* %src, i64 1, i1 false), !annotation !0, !dbg !DILocation(scope: !4) ; CHECK-NEXT: Call to memmove inserted by -ftrivial-auto-var-init. Memory operation size: 1 bytes. +; CHECK-NEXT: Variables: dst (2 bytes). call void @llvm.memmove.p0i8.p0i8.i64(i8* %bc, i8* %src, i64 1, i1 false), !annotation !0, !dbg !DILocation(scope: !4) ; CHECK-NEXT: Call to bzero inserted by -ftrivial-auto-var-init. Memory operation size: 1 bytes. +; CHECK-NEXT: Variables: dst (2 bytes). call void @bzero(i8* %bc, i64 1), !annotation !0, !dbg !DILocation(scope: !4) ret void } @@ -423,14 +463,18 @@ define void @known_call_with_size_alloca_bitcast(i8* %src) { ; Emit remarks for memcpy, memmove, memset, bzero with known constant sizes to an alloca that has a DILocalVariable attached. define void @known_call_with_size_alloca_di(i8* %src) { ; CHECK-NEXT: Call to memset inserted by -ftrivial-auto-var-init. Memory operation size: 1 bytes. +; CHECK-NEXT: Variables: destination (1 bytes). %dst = alloca i8 call void @llvm.dbg.declare(metadata i8* %dst, metadata !6, metadata !DIExpression()), !dbg !DILocation(scope: !4) call void @llvm.memset.p0i8.i64(i8* %dst, i8 0, i64 1, i1 false), !annotation !0, !dbg !DILocation(scope: !4) ; CHECK-NEXT: Call to memcpy inserted by -ftrivial-auto-var-init. Memory operation size: 1 bytes. +; CHECK-NEXT: Variables: destination (1 bytes). call void @llvm.memcpy.p0i8.p0i8.i64(i8* %dst, i8* %src, i64 1, i1 false), !annotation !0, !dbg !DILocation(scope: !4) ; CHECK-NEXT: Call to memmove inserted by -ftrivial-auto-var-init. Memory operation size: 1 bytes. +; CHECK-NEXT: Variables: destination (1 bytes). call void @llvm.memmove.p0i8.p0i8.i64(i8* %dst, i8* %src, i64 1, i1 false), !annotation !0, !dbg !DILocation(scope: !4) ; CHECK-NEXT: Call to bzero inserted by -ftrivial-auto-var-init. Memory operation size: 1 bytes. +; CHECK-NEXT: Variables: destination (1 bytes). call void @bzero(i8* %dst, i64 1), !annotation !0, !dbg !DILocation(scope: !4) ret void } @@ -439,14 +483,18 @@ define void @known_call_with_size_alloca_di(i8* %src) { ; an alloca that has more than one DILocalVariable attached. define void @known_call_with_size_alloca_di_multiple(i8* %src) { ; CHECK-NEXT: Call to memset inserted by -ftrivial-auto-var-init. Memory operation size: 1 bytes. +; CHECK-NEXT: Variables: destination (1 bytes). %dst = alloca i8 call void @llvm.dbg.declare(metadata i8* %dst, metadata !6, metadata !DIExpression()), !dbg !DILocation(scope: !4) call void @llvm.memset.p0i8.i64(i8* %dst, i8 0, i64 1, i1 false), !annotation !0, !dbg !DILocation(scope: !4) ; CHECK-NEXT: Call to memcpy inserted by -ftrivial-auto-var-init. Memory operation size: 1 bytes. +; CHECK-NEXT: Variables: destination (1 bytes). call void @llvm.memcpy.p0i8.p0i8.i64(i8* %dst, i8* %src, i64 1, i1 false), !annotation !0, !dbg !DILocation(scope: !4) ; CHECK-NEXT: Call to memmove inserted by -ftrivial-auto-var-init. Memory operation size: 1 bytes. +; CHECK-NEXT: Variables: destination (1 bytes). call void @llvm.memmove.p0i8.p0i8.i64(i8* %dst, i8* %src, i64 1, i1 false), !annotation !0, !dbg !DILocation(scope: !4) ; CHECK-NEXT: Call to bzero inserted by -ftrivial-auto-var-init. Memory operation size: 1 bytes. +; CHECK-NEXT: Variables: destination (1 bytes). call void @bzero(i8* %dst, i64 1), !annotation !0, !dbg !DILocation(scope: !4) ret void } @@ -455,6 +503,7 @@ define void @known_call_with_size_alloca_di_multiple(i8* %src) { ; a PHI node that can be two different allocas. define void @known_call_with_size_alloca_phi(i8* %src) { ; CHECK-NEXT: Call to memset inserted by -ftrivial-auto-var-init. Memory operation size: 1 bytes. +; CHECK-NEXT: Variables: dst2 (1 bytes), dst (1 bytes). entry: %dst = alloca i8 %dst2 = alloca i8 @@ -468,10 +517,13 @@ l2: %phidst = phi i8* [ %dst, %l0 ], [ %dst2, %l1 ] call void @llvm.memset.p0i8.i64(i8* %phidst, i8 0, i64 1, i1 false), !annotation !0, !dbg !DILocation(scope: !4) ; CHECK-NEXT: Call to memcpy inserted by -ftrivial-auto-var-init. Memory operation size: 1 bytes. +; CHECK-NEXT: Variables: dst2 (1 bytes), dst (1 bytes). call void @llvm.memcpy.p0i8.p0i8.i64(i8* %phidst, i8* %src, i64 1, i1 false), !annotation !0, !dbg !DILocation(scope: !4) ; CHECK-NEXT: Call to memmove inserted by -ftrivial-auto-var-init. Memory operation size: 1 bytes. +; CHECK-NEXT: Variables: dst2 (1 bytes), dst (1 bytes). call void @llvm.memmove.p0i8.p0i8.i64(i8* %phidst, i8* %src, i64 1, i1 false), !annotation !0, !dbg !DILocation(scope: !4) ; CHECK-NEXT: Call to bzero inserted by -ftrivial-auto-var-init. Memory operation size: 1 bytes. +; CHECK-NEXT: Variables: dst2 (1 bytes), dst (1 bytes). call void @bzero(i8* %phidst, i64 1), !annotation !0, !dbg !DILocation(scope: !4) ret void } @@ -481,6 +533,7 @@ l2: ; DILocalVariable. define void @known_call_with_size_alloca_phi_di_multiple(i8* %src) { ; CHECK-NEXT: Call to memset inserted by -ftrivial-auto-var-init. Memory operation size: 1 bytes. +; CHECK-NEXT: Variables: dst2 (1 bytes), destination2 (1 bytes), destination (1 bytes). entry: %dst = alloca i8 %dst2 = alloca i8 @@ -496,10 +549,13 @@ l2: %phidst = phi i8* [ %dst, %l0 ], [ %dst2, %l1 ] call void @llvm.memset.p0i8.i64(i8* %phidst, i8 0, i64 1, i1 false), !annotation !0, !dbg !DILocation(scope: !4) ; CHECK-NEXT: Call to memcpy inserted by -ftrivial-auto-var-init. Memory operation size: 1 bytes. +; CHECK-NEXT: Variables: dst2 (1 bytes), destination2 (1 bytes), destination (1 bytes). call void @llvm.memcpy.p0i8.p0i8.i64(i8* %phidst, i8* %src, i64 1, i1 false), !annotation !0, !dbg !DILocation(scope: !4) ; CHECK-NEXT: Call to memmove inserted by -ftrivial-auto-var-init. Memory operation size: 1 bytes. +; CHECK-NEXT: Variables: dst2 (1 bytes), destination2 (1 bytes), destination (1 bytes). call void @llvm.memmove.p0i8.p0i8.i64(i8* %phidst, i8* %src, i64 1, i1 false), !annotation !0, !dbg !DILocation(scope: !4) ; CHECK-NEXT: Call to bzero inserted by -ftrivial-auto-var-init. Memory operation size: 1 bytes. +; CHECK-NEXT: Variables: dst2 (1 bytes), destination2 (1 bytes), destination (1 bytes). call void @bzero(i8* %phidst, i64 1), !annotation !0, !dbg !DILocation(scope: !4) ret void } diff --git a/llvm/test/Transforms/Util/trivial-auto-var-init-store.ll b/llvm/test/Transforms/Util/trivial-auto-var-init-store.ll index adff4de..2286d00 100644 --- a/llvm/test/Transforms/Util/trivial-auto-var-init-store.ll +++ b/llvm/test/Transforms/Util/trivial-auto-var-init-store.ll @@ -77,6 +77,7 @@ define void @atomic_store(i32* %dst) { define void @store_alloca() { ; CHECK-NEXT: Store inserted by -ftrivial-auto-var-init. ; CHECK-NEXT: Store size: 4 bytes. +; CHECK-NEXT: Variables: dst (4 bytes). ; YAML-LABEL: --- !Missed ; YAML-NEXT: Pass: annotation-remarks ; YAML-NEXT: Name: AutoInitStore @@ -86,11 +87,17 @@ define void @store_alloca() { ; YAML-NEXT: - String: "Store inserted by -ftrivial-auto-var-init.\nStore size: " ; YAML-NEXT: - StoreSize: '4' ; YAML-NEXT: - String: ' bytes.' +; YAML-NEXT: - String: "\nVariables: " +; YAML-NEXT: - VarName: dst +; YAML-NEXT: - String: ' (' +; YAML-NEXT: - VarSize: '4' +; YAML-NEXT: - String: ' bytes)' +; YAML-NEXT: - String: . ; YAML-NEXT: - String: ' Volatile: ' -; YAML-NEXT: - StoreVolatile: 'false' +; YAML-NEXT: - StoreVolatile: 'false' ; YAML-NEXT: - String: . ; YAML-NEXT: - String: ' Atomic: ' -; YAML-NEXT: - StoreAtomic: 'false' +; YAML-NEXT: - StoreAtomic: 'false' ; YAML-NEXT: - String: . ; YAML-NEXT: ... %dst = alloca i32 @@ -102,6 +109,7 @@ define void @store_alloca() { define void @store_alloca_gep() { ; CHECK-NEXT: Store inserted by -ftrivial-auto-var-init. ; CHECK-NEXT: Store size: 4 bytes. +; CHECK-NEXT: Variables: dst (4 bytes). %dst = alloca i32 %gep = getelementptr i32, i32* %dst, i32 0 store i32 0, i32* %gep, !annotation !0, !dbg !DILocation(scope: !4) @@ -112,6 +120,7 @@ define void @store_alloca_gep() { define void @store_alloca_gep_array() { ; CHECK-NEXT: Store inserted by -ftrivial-auto-var-init. ; CHECK-NEXT: Store size: 4 bytes. +; CHECK-NEXT: Variables: dst (8 bytes). %dst = alloca [2 x i32] %gep = getelementptr [2 x i32], [2 x i32]* %dst, i64 0, i64 0 store i32 0, i32* %gep, !annotation !0, !dbg !DILocation(scope: !4) @@ -122,6 +131,7 @@ define void @store_alloca_gep_array() { define void @store_alloca_bitcast() { ; CHECK-NEXT: Store inserted by -ftrivial-auto-var-init. ; CHECK-NEXT: Store size: 4 bytes. +; CHECK-NEXT: Variables: dst (4 bytes). %dst = alloca [2 x i16] %bc = bitcast [2 x i16]* %dst to i32* store i32 0, i32* %bc, !annotation !0, !dbg !DILocation(scope: !4) @@ -133,6 +143,7 @@ define void @store_alloca_bitcast() { define void @store_alloca_di() { ; CHECK-NEXT: Store inserted by -ftrivial-auto-var-init. ; CHECK-NEXT: Store size: 4 bytes. +; CHECK-NEXT: Variables: destination (4 bytes). %dst = alloca i32 store i32 0, i32* %dst, !annotation !0, !dbg !DILocation(scope: !4) call void @llvm.dbg.declare(metadata i32* %dst, metadata !6, metadata !DIExpression()), !dbg !DILocation(scope: !4) @@ -144,6 +155,7 @@ define void @store_alloca_di() { define void @store_alloca_di_multiple() { ; CHECK-NEXT: Store inserted by -ftrivial-auto-var-init. ; CHECK-NEXT: Store size: 4 bytes. +; CHECK-NEXT: Variables: destination2 (4 bytes), destination (4 bytes). %dst = alloca i32 store i32 0, i32* %dst, !annotation !0, !dbg !DILocation(scope: !4) call void @llvm.dbg.declare(metadata i32* %dst, metadata !6, metadata !DIExpression()), !dbg !DILocation(scope: !4) @@ -156,6 +168,7 @@ define void @store_alloca_di_multiple() { define void @store_alloca_phi() { ; CHECK-NEXT: Store inserted by -ftrivial-auto-var-init. ; CHECK-NEXT: Store size: 4 bytes. +; CHECK-NEXT: Variables: dst2 (4 bytes), dst (4 bytes). entry: %dst = alloca i32 %dst2 = alloca i32 @@ -176,6 +189,7 @@ l2: define void @store_alloca_phi_di_multiple() { ; CHECK-NEXT: Store inserted by -ftrivial-auto-var-init. ; CHECK-NEXT: Store size: 4 bytes. +; CHECK-NEXT: Variables: dst2 (4 bytes), destination2 (4 bytes), destination (4 bytes). entry: %dst = alloca i32 %dst2 = alloca i32 -- 2.7.4