diff --git a/clang/test/CodeGen/code-coverage.c b/clang/test/CodeGen/code-coverage.c --- a/clang/test/CodeGen/code-coverage.c +++ b/clang/test/CodeGen/code-coverage.c @@ -18,10 +18,10 @@ // NEWPM: Running pass: GCOVProfilerPass // NEWPM-O3-NOT: Running pass +// NEWPM-O3: Running pass: Annotation2MetadataPass // NEWPM-O3: Running pass: ForceFunctionAttrsPass // NEWPM-O3: Running pass: GCOVProfilerPass - int test1(int a) { switch (a % 2) { case 0: diff --git a/llvm/include/llvm/Analysis/OptimizationRemarkEmitter.h b/llvm/include/llvm/Analysis/OptimizationRemarkEmitter.h --- a/llvm/include/llvm/Analysis/OptimizationRemarkEmitter.h +++ b/llvm/include/llvm/Analysis/OptimizationRemarkEmitter.h @@ -90,10 +90,12 @@ bool allowExtraAnalysis(StringRef PassName) const { return OptimizationRemarkEmitter::allowExtraAnalysis(*F, PassName); } - static bool allowExtraAnalysis(const Function &F, StringRef PassName) { - return F.getContext().getLLVMRemarkStreamer() || - F.getContext().getDiagHandlerPtr()->isAnyRemarkEnabled(PassName); + return allowExtraAnalysis(F.getContext(), PassName); + } + static bool allowExtraAnalysis(LLVMContext &Ctx, StringRef PassName) { + return Ctx.getLLVMRemarkStreamer() || + Ctx.getDiagHandlerPtr()->isAnyRemarkEnabled(PassName); } private: diff --git a/llvm/include/llvm/InitializePasses.h b/llvm/include/llvm/InitializePasses.h --- a/llvm/include/llvm/InitializePasses.h +++ b/llvm/include/llvm/InitializePasses.h @@ -73,6 +73,7 @@ void initializeAlwaysInlinerLegacyPassPass(PassRegistry&); void initializeAssumeSimplifyPassLegacyPassPass(PassRegistry &); void initializeAssumeBuilderPassLegacyPassPass(PassRegistry &); +void initializeAnnotation2MetadataLegacyPass(PassRegistry &); void initializeAnnotationRemarksLegacyPass(PassRegistry &); void initializeOpenMPOptLegacyPassPass(PassRegistry &); void initializeArgPromotionPass(PassRegistry&); diff --git a/llvm/include/llvm/Transforms/IPO.h b/llvm/include/llvm/Transforms/IPO.h --- a/llvm/include/llvm/Transforms/IPO.h +++ b/llvm/include/llvm/Transforms/IPO.h @@ -29,6 +29,13 @@ class GlobalValue; class raw_ostream; +//===----------------------------------------------------------------------===// +// +// This pass adds !annotation metadata to entries in the +// @llvm.global.annotations global constant. +// +ModulePass *createAnnotation2MetadataLegacyPass(); + //===----------------------------------------------------------------------===// // // These functions removes symbols from functions and modules. If OnlyDebugInfo diff --git a/llvm/include/llvm/Transforms/IPO/Annotation2Metadata.h b/llvm/include/llvm/Transforms/IPO/Annotation2Metadata.h new file mode 100644 --- /dev/null +++ b/llvm/include/llvm/Transforms/IPO/Annotation2Metadata.h @@ -0,0 +1,30 @@ +//===- Annotation2Metadata.h - Add !annotation metadata. --------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// New pass manager pass to convert @llvm.global.annotations to !annotation +// metadata. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_TRANSFORMS_IPO_ANNOTATION2METADATA_H +#define LLVM_TRANSFORMS_IPO_ANNOTATION2METADATA_H + +#include "llvm/IR/PassManager.h" + +namespace llvm { + +class Module; + +/// Pass to convert @llvm.global.annotations to !annotation metadata. +struct Annotation2MetadataPass : public PassInfoMixin { + PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM); +}; + +} // end namespace llvm + +#endif // LLVM_TRANSFORMS_IPO_SCCP_H diff --git a/llvm/lib/Passes/PassBuilder.cpp b/llvm/lib/Passes/PassBuilder.cpp --- a/llvm/lib/Passes/PassBuilder.cpp +++ b/llvm/lib/Passes/PassBuilder.cpp @@ -83,6 +83,7 @@ #include "llvm/Transforms/Coroutines/CoroSplit.h" #include "llvm/Transforms/HelloNew/HelloWorld.h" #include "llvm/Transforms/IPO/AlwaysInliner.h" +#include "llvm/Transforms/IPO/Annotation2Metadata.h" #include "llvm/Transforms/IPO/ArgumentPromotion.h" #include "llvm/Transforms/IPO/Attributor.h" #include "llvm/Transforms/IPO/BlockExtractor.h" @@ -1326,6 +1327,9 @@ ModulePassManager MPM(DebugLogging); + // Convert @llvm.global.annotations to !annotation metadata. + MPM.addPass(Annotation2MetadataPass()); + // Force any function attributes we want the rest of the pipeline to observe. MPM.addPass(ForceFunctionAttrsPass()); @@ -1355,6 +1359,9 @@ ModulePassManager MPM(DebugLogging); + // Convert @llvm.global.annotations to !annotation metadata. + MPM.addPass(Annotation2MetadataPass()); + // Force any function attributes we want the rest of the pipeline to observe. MPM.addPass(ForceFunctionAttrsPass()); @@ -1399,6 +1406,9 @@ OptimizationLevel Level, const ModuleSummaryIndex *ImportSummary) { ModulePassManager MPM(DebugLogging); + // Convert @llvm.global.annotations to !annotation metadata. + MPM.addPass(Annotation2MetadataPass()); + if (ImportSummary) { // These passes import type identifier resolutions for whole-program // devirtualization and CFI. They must run early because other passes may @@ -1451,6 +1461,9 @@ ModuleSummaryIndex *ExportSummary) { ModulePassManager MPM(DebugLogging); + // Convert @llvm.global.annotations to !annotation metadata. + MPM.addPass(Annotation2MetadataPass()); + if (Level == OptimizationLevel::O0) { // The WPD and LowerTypeTest passes need to run at -O0 to lower type // metadata and intrinsics. diff --git a/llvm/lib/Passes/PassRegistry.def b/llvm/lib/Passes/PassRegistry.def --- a/llvm/lib/Passes/PassRegistry.def +++ b/llvm/lib/Passes/PassRegistry.def @@ -43,6 +43,7 @@ #endif MODULE_PASS("always-inline", AlwaysInlinerPass()) MODULE_PASS("attributor", AttributorPass()) +MODULE_PASS("annotation2metadata", Annotation2MetadataPass()) MODULE_PASS("called-value-propagation", CalledValuePropagationPass()) MODULE_PASS("canonicalize-aliases", CanonicalizeAliasesPass()) MODULE_PASS("cg-profile", CGProfilePass()) diff --git a/llvm/lib/Transforms/IPO/Annotation2Metadata.cpp b/llvm/lib/Transforms/IPO/Annotation2Metadata.cpp new file mode 100644 --- /dev/null +++ b/llvm/lib/Transforms/IPO/Annotation2Metadata.cpp @@ -0,0 +1,106 @@ +//===-- Annotation2Metadata.cpp - Add !annotation metadata. ---------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// Add !annotation metadata for entries in @llvm.global.anotations, generated +// using __attribute__((annotate("_name"))) on functions in Clang. +// +//===----------------------------------------------------------------------===// + +#include "llvm/Transforms/IPO/Annotation2Metadata.h" +#include "llvm/Analysis/OptimizationRemarkEmitter.h" +#include "llvm/IR/Constants.h" +#include "llvm/IR/Function.h" +#include "llvm/IR/InstIterator.h" +#include "llvm/IR/Module.h" +#include "llvm/InitializePasses.h" +#include "llvm/Pass.h" +#include "llvm/Transforms/IPO.h" + +using namespace llvm; + +#define DEBUG_TYPE "annotation2metadata" + +static bool convertAnnotation2Metadata(Module &M) { + // Only add !annotation metadata if the corresponding remarks pass is also + // enabled. + if (!OptimizationRemarkEmitter::allowExtraAnalysis(M.getContext(), + "annotation-remarks")) + return false; + + auto *Annotations = M.getGlobalVariable("llvm.global.annotations"); + auto *C = dyn_cast_or_null(Annotations); + if (!C || C->getNumOperands() != 1) + return false; + + C = cast(C->getOperand(0)); + + // Iterate over all entries in C and attach !annotation metadata to suitable + // entries. + for (auto &Op : C->operands()) { + // Look at the operands to check if we can use the entry to generate + // !annotation metadata. + auto *OpC = dyn_cast(&Op); + if (!OpC || OpC->getNumOperands() != 4) + continue; + auto *StrGEP = dyn_cast(OpC->getOperand(1)); + if (!StrGEP || StrGEP->getNumOperands() < 2) + continue; + auto *StrC = dyn_cast(StrGEP->getOperand(0)); + if (!StrC) + continue; + auto *StrData = dyn_cast(StrC->getOperand(0)); + if (!StrData) + continue; + // Look through bitcast. + auto *Bitcast = dyn_cast(OpC->getOperand(0)); + if (!Bitcast || Bitcast->getOpcode() != Instruction::BitCast) + continue; + auto *Fn = dyn_cast(Bitcast->getOperand(0)); + if (!Fn) + continue; + + // Add annotation to all instructions in the function. + for (auto &I : instructions(Fn)) + I.addAnnotationMetadata(StrData->getAsCString()); + } + return true; +} + +namespace { +struct Annotation2MetadataLegacy : public ModulePass { + static char ID; + + Annotation2MetadataLegacy() : ModulePass(ID) { + initializeAnnotation2MetadataLegacyPass(*PassRegistry::getPassRegistry()); + } + + bool runOnModule(Module &M) override { return convertAnnotation2Metadata(M); } + + void getAnalysisUsage(AnalysisUsage &AU) const override { + AU.setPreservesAll(); + } +}; + +} // end anonymous namespace + +char Annotation2MetadataLegacy::ID = 0; + +INITIALIZE_PASS_BEGIN(Annotation2MetadataLegacy, DEBUG_TYPE, + "Annotation2Metadata", false, false) +INITIALIZE_PASS_END(Annotation2MetadataLegacy, DEBUG_TYPE, + "Annotation2Metadata", false, false) + +ModulePass *llvm::createAnnotation2MetadataLegacyPass() { + return new Annotation2MetadataLegacy(); +} + +PreservedAnalyses Annotation2MetadataPass::run(Module &M, + ModuleAnalysisManager &AM) { + convertAnnotation2Metadata(M); + return PreservedAnalyses::all(); +} diff --git a/llvm/lib/Transforms/IPO/CMakeLists.txt b/llvm/lib/Transforms/IPO/CMakeLists.txt --- a/llvm/lib/Transforms/IPO/CMakeLists.txt +++ b/llvm/lib/Transforms/IPO/CMakeLists.txt @@ -1,5 +1,6 @@ add_llvm_component_library(LLVMipo AlwaysInliner.cpp + Annotation2Metadata.cpp ArgumentPromotion.cpp Attributor.cpp AttributorAttributes.cpp diff --git a/llvm/lib/Transforms/IPO/IPO.cpp b/llvm/lib/Transforms/IPO/IPO.cpp --- a/llvm/lib/Transforms/IPO/IPO.cpp +++ b/llvm/lib/Transforms/IPO/IPO.cpp @@ -25,6 +25,7 @@ void llvm::initializeIPO(PassRegistry &Registry) { initializeOpenMPOptLegacyPassPass(Registry); initializeArgPromotionPass(Registry); + initializeAnnotation2MetadataLegacyPass(Registry); initializeCalledValuePropagationLegacyPassPass(Registry); initializeConstantMergeLegacyPassPass(Registry); initializeCrossDSOCFIPass(Registry); diff --git a/llvm/lib/Transforms/IPO/PassManagerBuilder.cpp b/llvm/lib/Transforms/IPO/PassManagerBuilder.cpp --- a/llvm/lib/Transforms/IPO/PassManagerBuilder.cpp +++ b/llvm/lib/Transforms/IPO/PassManagerBuilder.cpp @@ -512,6 +512,8 @@ // is handled separately, so just check this is not the ThinLTO post-link. bool DefaultOrPreLinkPipeline = !PerformThinLTO; + MPM.add(createAnnotation2MetadataLegacyPass()); + if (!PGOSampleUse.empty()) { MPM.add(createPruneEHPass()); // In ThinLTO mode, when flattened profile is used, all the available diff --git a/llvm/test/CodeGen/AMDGPU/opt-pipeline.ll b/llvm/test/CodeGen/AMDGPU/opt-pipeline.ll --- a/llvm/test/CodeGen/AMDGPU/opt-pipeline.ll +++ b/llvm/test/CodeGen/AMDGPU/opt-pipeline.ll @@ -19,6 +19,7 @@ ; GCN-O0-NEXT: Assumption Cache Tracker ; GCN-O0-NEXT: Profile summary info ; GCN-O0-NEXT: ModulePass Manager +; GCN-O0-NEXT: Annotation2Metadata ; GCN-O0-NEXT: Force set function attributes ; GCN-O0-NEXT: CallGraph Construction ; GCN-O0-NEXT: Call Graph SCC Pass Manager @@ -59,6 +60,7 @@ ; GCN-O1-NEXT: Assumption Cache Tracker ; GCN-O1-NEXT: Profile summary info ; GCN-O1-NEXT: ModulePass Manager +; GCN-O1-NEXT: Annotation2Metadata ; GCN-O1-NEXT: Force set function attributes ; GCN-O1-NEXT: Infer set function attributes ; GCN-O1-NEXT: Unify multiple OpenCL metadata due to linking @@ -369,6 +371,7 @@ ; GCN-O2-NEXT: Assumption Cache Tracker ; GCN-O2-NEXT: Profile summary info ; GCN-O2-NEXT: ModulePass Manager +; GCN-O2-NEXT: Annotation2Metadata ; GCN-O2-NEXT: Force set function attributes ; GCN-O2-NEXT: Infer set function attributes ; GCN-O2-NEXT: Unify multiple OpenCL metadata due to linking @@ -727,6 +730,7 @@ ; GCN-O3-NEXT: Assumption Cache Tracker ; GCN-O3-NEXT: Profile summary info ; GCN-O3-NEXT: ModulePass Manager +; GCN-O3-NEXT: Annotation2Metadata ; GCN-O3-NEXT: Force set function attributes ; GCN-O3-NEXT: Infer set function attributes ; GCN-O3-NEXT: Unify multiple OpenCL metadata due to linking diff --git a/llvm/test/Other/new-pm-defaults.ll b/llvm/test/Other/new-pm-defaults.ll --- a/llvm/test/Other/new-pm-defaults.ll +++ b/llvm/test/Other/new-pm-defaults.ll @@ -92,6 +92,7 @@ ; CHECK-Oz: {{^}} ; CHECK-O: Starting llvm::Module pass manager run. +; CHECK-O-NEXT: Running pass: Annotation2Metadata ; CHECK-O-NEXT: Running pass: ForceFunctionAttrsPass ; CHECK-EP-PIPELINE-START-NEXT: Running pass: NoOpModulePass ; CHECK-O-NEXT: Running pass: InferFunctionAttrsPass diff --git a/llvm/test/Other/new-pm-lto-defaults.ll b/llvm/test/Other/new-pm-lto-defaults.ll --- a/llvm/test/Other/new-pm-lto-defaults.ll +++ b/llvm/test/Other/new-pm-lto-defaults.ll @@ -24,6 +24,7 @@ ; RUN: --check-prefix=CHECK-O3 --check-prefix=CHECK-EP-Peephole ; CHECK-O: Starting llvm::Module pass manager run. +; CHECK-O-NEXT: Running pass: Annotation2Metadata ; CHECK-O-NEXT: Running pass: GlobalDCEPass ; CHECK-O-NEXT: Running pass: ForceFunctionAttrsPass ; CHECK-O-NEXT: Running pass: InferFunctionAttrsPass diff --git a/llvm/test/Other/new-pm-thinlto-defaults.ll b/llvm/test/Other/new-pm-thinlto-defaults.ll --- a/llvm/test/Other/new-pm-thinlto-defaults.ll +++ b/llvm/test/Other/new-pm-thinlto-defaults.ll @@ -51,6 +51,7 @@ ; CHECK-NOEXT: {{^}} ; CHECK-O: Starting llvm::Module pass manager run. +; CHECK-O-NEXT: Running pass: Annotation2Metadata ; CHECK-O-NEXT: Running pass: ForceFunctionAttrsPass ; CHECK-EP-PIPELINE-START-NEXT: Running pass: NoOpModulePass ; CHECK-DIS-NEXT: Running analysis: InnerAnalysisManagerProxy diff --git a/llvm/test/Other/new-pm-thinlto-postlink-pgo-defaults.ll b/llvm/test/Other/new-pm-thinlto-postlink-pgo-defaults.ll --- a/llvm/test/Other/new-pm-thinlto-postlink-pgo-defaults.ll +++ b/llvm/test/Other/new-pm-thinlto-postlink-pgo-defaults.ll @@ -24,6 +24,7 @@ ; CHECK-NOEXT: {{^}} ; CHECK-O: Starting {{.*}}Module pass manager run. +; CHECK-O-NEXT: Running pass: Annotation2Metadata ; CHECK-O-NEXT: Running pass: ForceFunctionAttrsPass ; CHECK-EP-PIPELINE-START-NEXT: Running pass: NoOpModulePass ; CHECK-O-NEXT: Running pass: PGOIndirectCallPromotion diff --git a/llvm/test/Other/new-pm-thinlto-postlink-samplepgo-defaults.ll b/llvm/test/Other/new-pm-thinlto-postlink-samplepgo-defaults.ll --- a/llvm/test/Other/new-pm-thinlto-postlink-samplepgo-defaults.ll +++ b/llvm/test/Other/new-pm-thinlto-postlink-samplepgo-defaults.ll @@ -29,6 +29,7 @@ ; CHECK-NOEXT: {{^}} ; CHECK-O: Starting {{.*}}Module pass manager run. +; CHECK-O-NEXT: Running pass: Annotation2Metadata ; CHECK-O-NEXT: Running pass: ForceFunctionAttrsPass ; CHECK-EP-PIPELINE-START-NEXT: Running pass: NoOpModulePass ; CHECK-O-NEXT: Running pass: InferFunctionAttrsPass diff --git a/llvm/test/Other/new-pm-thinlto-prelink-pgo-defaults.ll b/llvm/test/Other/new-pm-thinlto-prelink-pgo-defaults.ll --- a/llvm/test/Other/new-pm-thinlto-prelink-pgo-defaults.ll +++ b/llvm/test/Other/new-pm-thinlto-prelink-pgo-defaults.ll @@ -28,6 +28,7 @@ ; RUN: | FileCheck %s --check-prefixes=CHECK-O,CHECK-O2,CHECK-O23SZ,CHECK-O123 ; ; CHECK-O: Starting {{.*}}Module pass manager run. +; CHECK-O-NEXT: Running pass: Annotation2Metadata ; CHECK-O-NEXT: Running pass: ForceFunctionAttrsPass ; CHECK-EP-PIPELINE-START-NEXT: Running pass: NoOpModulePass ; CHECK-O-NEXT: Running pass: InferFunctionAttrsPass diff --git a/llvm/test/Other/new-pm-thinlto-prelink-samplepgo-defaults.ll b/llvm/test/Other/new-pm-thinlto-prelink-samplepgo-defaults.ll --- a/llvm/test/Other/new-pm-thinlto-prelink-samplepgo-defaults.ll +++ b/llvm/test/Other/new-pm-thinlto-prelink-samplepgo-defaults.ll @@ -26,6 +26,7 @@ ; RUN: | FileCheck %s --check-prefixes=CHECK-O,CHECK-O2,CHECK-O23SZ ; ; CHECK-O: Starting {{.*}}Module pass manager run. +; CHECK-O-NEXT: Running pass: Annotation2Metadata ; CHECK-O-NEXT: Running pass: ForceFunctionAttrsPass ; CHECK-O-NEXT: Running analysis: InnerAnalysisManagerProxy ; CHECK-O-NEXT: Running pass: AddDiscriminatorsPass diff --git a/llvm/test/Other/opt-O0-pipeline.ll b/llvm/test/Other/opt-O0-pipeline.ll --- a/llvm/test/Other/opt-O0-pipeline.ll +++ b/llvm/test/Other/opt-O0-pipeline.ll @@ -18,6 +18,7 @@ ; CHECK: Assumption Cache Tracker ; CHECK-NEXT: Profile summary info ; CHECK-NEXT: ModulePass Manager +; CHECK-NEXT: Annotation2Metadata ; CHECK-NEXT: Force set function attributes ; CHECK-NEXT: CallGraph Construction ; CHECK-NEXT: Call Graph SCC Pass Manager diff --git a/llvm/test/Other/opt-O2-pipeline.ll b/llvm/test/Other/opt-O2-pipeline.ll --- a/llvm/test/Other/opt-O2-pipeline.ll +++ b/llvm/test/Other/opt-O2-pipeline.ll @@ -27,6 +27,7 @@ ; CHECK-NEXT: Assumption Cache Tracker ; CHECK-NEXT: Profile summary info ; CHECK-NEXT: ModulePass Manager +; CHECK-NEXT: Annotation2Metadata ; CHECK-NEXT: Force set function attributes ; CHECK-NEXT: Infer set function attributes ; CHECK-NEXT: Interprocedural Sparse Conditional Constant Propagation diff --git a/llvm/test/Other/opt-O3-pipeline-enable-matrix.ll b/llvm/test/Other/opt-O3-pipeline-enable-matrix.ll --- a/llvm/test/Other/opt-O3-pipeline-enable-matrix.ll +++ b/llvm/test/Other/opt-O3-pipeline-enable-matrix.ll @@ -27,6 +27,7 @@ ; CHECK-NEXT: Assumption Cache Tracker ; CHECK-NEXT: Profile summary info ; CHECK-NEXT: ModulePass Manager +; CHECK-NEXT: Annotation2Metadata ; CHECK-NEXT: Force set function attributes ; CHECK-NEXT: Infer set function attributes ; CHECK-NEXT: FunctionPass Manager diff --git a/llvm/test/Other/opt-O3-pipeline.ll b/llvm/test/Other/opt-O3-pipeline.ll --- a/llvm/test/Other/opt-O3-pipeline.ll +++ b/llvm/test/Other/opt-O3-pipeline.ll @@ -27,6 +27,7 @@ ; CHECK-NEXT: Assumption Cache Tracker ; CHECK-NEXT: Profile summary info ; CHECK-NEXT: ModulePass Manager +; CHECK-NEXT: Annotation2Metadata ; CHECK-NEXT: Force set function attributes ; CHECK-NEXT: Infer set function attributes ; CHECK-NEXT: FunctionPass Manager diff --git a/llvm/test/Other/opt-Os-pipeline.ll b/llvm/test/Other/opt-Os-pipeline.ll --- a/llvm/test/Other/opt-Os-pipeline.ll +++ b/llvm/test/Other/opt-Os-pipeline.ll @@ -27,6 +27,7 @@ ; CHECK-NEXT: Assumption Cache Tracker ; CHECK-NEXT: Profile summary info ; CHECK-NEXT: ModulePass Manager +; CHECK-NEXT: Annotation2Metadata ; CHECK-NEXT: Force set function attributes ; CHECK-NEXT: Infer set function attributes ; CHECK-NEXT: Interprocedural Sparse Conditional Constant Propagation diff --git a/llvm/test/Transforms/Util/annotation2metadata.ll b/llvm/test/Transforms/Util/annotation2metadata.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Transforms/Util/annotation2metadata.ll @@ -0,0 +1,61 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt -annotation2metadata -pass-remarks-analysis='annotation-remarks' -S %s | FileCheck %s +; RUN: opt -passes='annotation2metadata' -pass-remarks-analysis='annotation-remarks' -S %s | FileCheck %s + +@.str = private unnamed_addr constant [10 x i8] c"_remarks1\00", section "llvm.metadata" +@.str.1 = private unnamed_addr constant [6 x i8] c"ann.c\00", section "llvm.metadata" +@.str.2 = private unnamed_addr constant [10 x i8] c"_remarks2\00", section "llvm.metadata" +@llvm.global.annotations = appending global [8 x { i8*, i8*, i8*, i32 }] [ + { i8*, i8*, i8*, i32 } { i8* bitcast (void (float*)* @test1 to i8*), i8* getelementptr inbounds ([10 x i8], [10 x i8]* @.str, i32 0, i32 0), i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str.1, i32 0, i32 0), i32 2 }, + { i8*, i8*, i8*, i32 } { i8* bitcast (void (float*)* @test1 to i8*), i8* getelementptr inbounds ([10 x i8], [10 x i8]* @.str.2, i32 0, i32 0), i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str.1, i32 0, i32 0), i32 2 }, + { i8*, i8*, i8*, i32 } { i8* bitcast (void (float*)* @test3 to i8*), i8* getelementptr inbounds ([10 x i8], [10 x i8]* @.str, i32 0, i32 0), i8* undef, i32 4 }, ; Invalid entry, make sure we do not crash. + { i8*, i8*, i8*, i32 } { i8* bitcast (void (float*)* @test3 to i8*), i8* undef, i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str.1, i32 0, i32 0), i32 4 }, ; Invalid entry, make sure we do not crash. + { i8*, i8*, i8*, i32 } { i8* undef, i8* getelementptr inbounds ([10 x i8], [10 x i8]* @.str, i32 0, i32 0), i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str.1, i32 0, i32 0), i32 4 }, ; Invalid entry, make sure we do not crash. + { i8*, i8*, i8*, i32 } { i8* bitcast (void (float*)* undef to i8*), i8* undef, i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str.1, i32 0, i32 0), i32 4 }, ; Invalid entry, make sure we do not crash. + { i8*, i8*, i8*, i32 } { i8* undef, i8* undef, i8* undef, i32 300 }, ; Invalid entry, make sure we do not crash. + { i8*, i8*, i8*, i32 } { i8* bitcast (void (float*)* @test3 to i8*), i8* getelementptr inbounds ([10 x i8], [10 x i8]* @.str, i32 0, i32 0), i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str.1, i32 0, i32 0), i32 4 } + ], section "llvm.metadata" + + + +define void @test1(float* %a) { +; CHECK-LABEL: @test1( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[A_ADDR:%.*]] = alloca float*, align 8, !annotation [[GROUP1:!.+]] +; CHECK-NEXT: store float* [[A:%.*]], float** [[A_ADDR]], align 8, !annotation [[GROUP1]] +; CHECK-NEXT: ret void, !annotation [[GROUP1]] +; +entry: + %a.addr = alloca float*, align 8 + store float* %a, float** %a.addr, align 8 + ret void +} + +define void @test2(float* %a) { +; CHECK-LABEL: @test2( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[A_ADDR:%.*]] = alloca float*, align 8 +; CHECK-NEXT: store float* [[A:%.*]], float** [[A_ADDR]], align 8 +; CHECK-NEXT: ret void +; +entry: + %a.addr = alloca float*, align 8 + store float* %a, float** %a.addr, align 8 + ret void +} + +define void @test3(float* %a) { +; CHECK-LABEL: @test3( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[A_ADDR:%.*]] = alloca float*, align 8, !annotation [[GROUP2:!.+]] +; CHECK-NEXT: store float* [[A:%.*]], float** [[A_ADDR]], align 8, !annotation [[GROUP2]] +; CHECK-NEXT: ret void, !annotation [[GROUP2]] +; +entry: + %a.addr = alloca float*, align 8 + store float* %a, float** %a.addr, align 8 + ret void +} + +; CHECK: [[GROUP1]] = !{!"_remarks1", !"_remarks2"} +; CHECK-NEXT: [[GROUP2]] = !{!"_remarks1"}