diff --git a/llvm/include/llvm/IR/Instruction.h b/llvm/include/llvm/IR/Instruction.h --- a/llvm/include/llvm/IR/Instruction.h +++ b/llvm/include/llvm/IR/Instruction.h @@ -340,6 +340,8 @@ } /// @} + void addAnnotationMetadata(StringRef Name); + /// Sets the metadata on this instruction from the AAMDNodes structure. void setAAMetadata(const AAMDNodes &N); 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,28 @@ +//===- SCCP.h - Sparse Conditional Constant Propagation ---------*- 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 +// +//===----------------------------------------------------------------------===// +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_TRANSFORMS_IPO_ANNOTATION2METADATA_H +#define LLVM_TRANSFORMS_IPO_ANNOTATION2METADATA_H + +#include "llvm/IR/PassManager.h" + +namespace llvm { + +class Module; + +/// Pass to perform interprocedural constant propagation. +class Annotation2MetadataPass : public PassInfoMixin { +public: + PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM); +}; + +} // end namespace llvm + +#endif // LLVM_TRANSFORMS_IPO_SCCP_H diff --git a/llvm/lib/IR/Instruction.cpp b/llvm/lib/IR/Instruction.cpp --- a/llvm/lib/IR/Instruction.cpp +++ b/llvm/lib/IR/Instruction.cpp @@ -116,6 +116,27 @@ return Order < Other->Order; } +void Instruction::addAnnotationMetadata(StringRef Name) { + MDBuilder MDB(getContext()); + + auto *Existing = getMetadata("annotation"); + SmallVector Names; + bool AppendName = true; + if (Existing) { + auto *Tuple = cast(Existing); + for (auto &N : Tuple->operands()) { + if (cast(N.get())->getString() == Name) + AppendName = false; + Names.push_back(N.get()); + } + } + if (AppendName) + Names.push_back(MDB.createString(Name)); + + MDNode *MD = MDTuple::get(getContext(), Names); + setMetadata("annotation", MD); +} + void Instruction::setHasNoUnsignedWrap(bool b) { cast(this)->setHasNoUnsignedWrap(b); } 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" @@ -1318,6 +1319,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()); @@ -1351,6 +1355,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 @@ -1455,6 +1465,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,95 @@ +//===-- 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/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/Support/Debug.h" +#include "llvm/Transforms/IPO.h" + +using namespace llvm; + +#define DEBUG_TYPE "annotation2metadata" + +static bool convertAnnotation2Metadata(Module &M) { + 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()) { + auto *OpC = dyn_cast(&Op); + if (!OpC) + 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 *Fn = + dyn_cast(cast(OpC->getOperand(0))->getOperand(0)); + if (!Fn) + continue; + 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,57 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt -annotation2metadata -S %s | FileCheck %s +; RUN: opt -passes='annotation2metadata' -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 [4 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* getelementptr inbounds ([6 x i8], [6 x i8]* @.str.1, i32 0, i32 0), i32 4 }, + { i8*, i8*, i8*, i32 } { i8* undef, i8* undef, i8* undef, i32 300 } ; Invalid entry, make sure we do not crash. + ], 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"}