llvm.org GIT mirror llvm / f1b0fdf
[PM] port Rewrite Statepoints For GC to the new pass manager. Summary: The port is nearly straightforward. The only complication is related to the analyses handling, since one of the analyses used in this module pass is domtree, which is a function analysis. That requires asking for the results of each function and disallows a single interface for run-on-module pass action. Decided to copy-paste the main body of this pass. Most of its code is requesting analyses anyway, so not that much of a copy-paste. The rest of the code movement is to transform all the implementation helper functions like stripNonValidData into non-member statics. Extended all the related LLVM tests with new-pass-manager use. No failures. Reviewers: sanjoy, anna, reames Reviewed By: anna Subscribers: skatkov, llvm-commits Differential Revision: https://reviews.llvm.org/D41162 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@320796 91177308-0d34-0410-b5e6-96231b3b80d8 Fedor Sergeev 1 year, 9 months ago
50 changed file(s) with 195 addition(s) and 70 deletion(s). Raw diff Collapse all Expand all
320320 void initializeRenameIndependentSubregsPass(PassRegistry&);
321321 void initializeResetMachineFunctionPass(PassRegistry&);
322322 void initializeReversePostOrderFunctionAttrsLegacyPassPass(PassRegistry&);
323 void initializeRewriteStatepointsForGCPass(PassRegistry&);
323 void initializeRewriteStatepointsForGCLegacyPassPass(PassRegistry &);
324324 void initializeRewriteSymbolsLegacyPassPass(PassRegistry&);
325325 void initializeSafepointIRVerifierPass(PassRegistry&);
326326 void initializeSCCPLegacyPassPass(PassRegistry&);
0 //===- RewriteStatepointsForGC.h - ------------------------------*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file provides interface to "Rewrite Statepoints for GC" pass.
10 //
11 // This passe rewrites call/invoke instructions so as to make potential
12 // relocations performed by the garbage collector explicit in the IR.
13 //
14 //===----------------------------------------------------------------------===//
15
16 #ifndef LLVM_TRANSFORMS_SCALAR_REWRITE_STATEPOINTS_FOR_GC_H
17 #define LLVM_TRANSFORMS_SCALAR_REWRITE_STATEPOINTS_FOR_GC_H
18
19 #include "llvm/IR/PassManager.h"
20
21 namespace llvm {
22
23 class DominatorTree;
24 class Function;
25 class Module;
26 class TargetTransformInfo;
27 class TargetLibraryInfo;
28
29 struct RewriteStatepointsForGC : public PassInfoMixin {
30 PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
31
32 bool runOnFunction(Function &F, DominatorTree &, TargetTransformInfo &,
33 const TargetLibraryInfo &);
34 };
35
36 } // namespace llvm
37
38 #endif // LLVM_TRANSFORMS_SCALAR_REWRITE_STATEPOINTS_FOR_GC_H
520520 // RewriteStatepointsForGC - Rewrite any gc.statepoints which do not yet have
521521 // explicit relocations to include explicit relocations.
522522 //
523 ModulePass *createRewriteStatepointsForGCPass();
523 ModulePass *createRewriteStatepointsForGCLegacyPass();
524524
525525 //===----------------------------------------------------------------------===//
526526 //
125125 #include "llvm/Transforms/Scalar/NewGVN.h"
126126 #include "llvm/Transforms/Scalar/PartiallyInlineLibCalls.h"
127127 #include "llvm/Transforms/Scalar/Reassociate.h"
128 #include "llvm/Transforms/Scalar/RewriteStatepointsForGC.h"
128129 #include "llvm/Transforms/Scalar/SCCP.h"
129130 #include "llvm/Transforms/Scalar/SROA.h"
130131 #include "llvm/Transforms/Scalar/SimpleLoopUnswitch.h"
6767 MODULE_PASS("print", PrintModulePass(dbgs()))
6868 MODULE_PASS("print-lcg", LazyCallGraphPrinterPass(dbgs()))
6969 MODULE_PASS("print-lcg-dot", LazyCallGraphDOTPrinterPass(dbgs()))
70 MODULE_PASS("rewrite-statepoints-for-gc", RewriteStatepointsForGC())
7071 MODULE_PASS("rewrite-symbols", RewriteSymbolPass())
7172 MODULE_PASS("rpo-functionattrs", ReversePostOrderFunctionAttrsPass())
7273 MODULE_PASS("sample-profile", SampleProfileLoaderPass())
1010 // performed by the garbage collector explicit in the IR.
1111 //
1212 //===----------------------------------------------------------------------===//
13
14 #include "llvm/Transforms/Scalar/RewriteStatepointsForGC.h"
1315
1416 #include "llvm/ADT/ArrayRef.h"
1517 #include "llvm/ADT/DenseMap.h"
107109 AllowStatepointWithNoDeoptInfo("rs4gc-allow-statepoint-with-no-deopt-info",
108110 cl::Hidden, cl::init(true));
109111
112 /// The IR fed into RewriteStatepointsForGC may have had attributes and
113 /// metadata implying dereferenceability that are no longer valid/correct after
114 /// RewriteStatepointsForGC has run. This is because semantically, after
115 /// RewriteStatepointsForGC runs, all calls to gc.statepoint "free" the entire
116 /// heap. stripNonValidData (conservatively) restores
117 /// correctness by erasing all attributes in the module that externally imply
118 /// dereferenceability. Similar reasoning also applies to the noalias
119 /// attributes and metadata. gc.statepoint can touch the entire heap including
120 /// noalias objects.
121 /// Apart from attributes and metadata, we also remove instructions that imply
122 /// constant physical memory: llvm.invariant.start.
123 static void stripNonValidData(Module &M);
124
125 static bool shouldRewriteStatepointsIn(Function &F);
126
127 PreservedAnalyses RewriteStatepointsForGC::run(Module &M,
128 ModuleAnalysisManager &AM) {
129 bool Changed = false;
130 auto &FAM = AM.getResult(M).getManager();
131 for (Function &F : M) {
132 // Nothing to do for declarations.
133 if (F.isDeclaration() || F.empty())
134 continue;
135
136 // Policy choice says not to rewrite - the most common reason is that we're
137 // compiling code without a GCStrategy.
138 if (!shouldRewriteStatepointsIn(F))
139 continue;
140
141 auto &DT = FAM.getResult(F);
142 auto &TTI = FAM.getResult(F);
143 auto &TLI = FAM.getResult(F);
144 Changed |= runOnFunction(F, DT, TTI, TLI);
145 }
146 if (!Changed)
147 return PreservedAnalyses::all();
148
149 // stripNonValidData asserts that shouldRewriteStatepointsIn
150 // returns true for at least one function in the module. Since at least
151 // one function changed, we know that the precondition is satisfied.
152 stripNonValidData(M);
153
154 PreservedAnalyses PA;
155 PA.preserve();
156 PA.preserve();
157 return PA;
158 }
159
110160 namespace {
111161
112 struct RewriteStatepointsForGC : public ModulePass {
162 class RewriteStatepointsForGCLegacyPass : public ModulePass {
163 RewriteStatepointsForGC Impl;
164
165 public:
113166 static char ID; // Pass identification, replacement for typeid
114167
115 RewriteStatepointsForGC() : ModulePass(ID) {
116 initializeRewriteStatepointsForGCPass(*PassRegistry::getPassRegistry());
117 }
118
119 bool runOnFunction(Function &F);
168 RewriteStatepointsForGCLegacyPass() : ModulePass(ID), Impl() {
169 initializeRewriteStatepointsForGCLegacyPassPass(
170 *PassRegistry::getPassRegistry());
171 }
120172
121173 bool runOnModule(Module &M) override {
122174 bool Changed = false;
123 for (Function &F : M)
124 Changed |= runOnFunction(F);
125
126 if (Changed) {
127 // stripNonValidData asserts that shouldRewriteStatepointsIn
128 // returns true for at least one function in the module. Since at least
129 // one function changed, we know that the precondition is satisfied.
130 stripNonValidData(M);
131 }
132
133 return Changed;
175 const TargetLibraryInfo &TLI =
176 getAnalysis().getTLI();
177 for (Function &F : M) {
178 // Nothing to do for declarations.
179 if (F.isDeclaration() || F.empty())
180 continue;
181
182 // Policy choice says not to rewrite - the most common reason is that
183 // we're compiling code without a GCStrategy.
184 if (!shouldRewriteStatepointsIn(F))
185 continue;
186
187 TargetTransformInfo &TTI =
188 getAnalysis().getTTI(F);
189 auto &DT = getAnalysis(F).getDomTree();
190
191 Changed |= Impl.runOnFunction(F, DT, TTI, TLI);
192 }
193
194 if (!Changed)
195 return false;
196
197 // stripNonValidData asserts that shouldRewriteStatepointsIn
198 // returns true for at least one function in the module. Since at least
199 // one function changed, we know that the precondition is satisfied.
200 stripNonValidData(M);
201 return true;
134202 }
135203
136204 void getAnalysisUsage(AnalysisUsage &AU) const override {
140208 AU.addRequired();
141209 AU.addRequired();
142210 }
143
144 /// The IR fed into RewriteStatepointsForGC may have had attributes and
145 /// metadata implying dereferenceability that are no longer valid/correct after
146 /// RewriteStatepointsForGC has run. This is because semantically, after
147 /// RewriteStatepointsForGC runs, all calls to gc.statepoint "free" the entire
148 /// heap. stripNonValidData (conservatively) restores
149 /// correctness by erasing all attributes in the module that externally imply
150 /// dereferenceability. Similar reasoning also applies to the noalias
151 /// attributes and metadata. gc.statepoint can touch the entire heap including
152 /// noalias objects.
153 /// Apart from attributes and metadata, we also remove instructions that imply
154 /// constant physical memory: llvm.invariant.start.
155 void stripNonValidData(Module &M);
156
157 // Helpers for stripNonValidData
158 void stripNonValidDataFromBody(Function &F);
159 void stripNonValidAttributesFromPrototype(Function &F);
160
161 // Certain metadata on instructions are invalid after running RS4GC.
162 // Optimizations that run after RS4GC can incorrectly use this metadata to
163 // optimize functions. We drop such metadata on the instruction.
164 void stripInvalidMetadataFromInstruction(Instruction &I);
165211 };
166212
167213 } // end anonymous namespace
168214
169 char RewriteStatepointsForGC::ID = 0;
170
171 ModulePass *llvm::createRewriteStatepointsForGCPass() {
172 return new RewriteStatepointsForGC();
173 }
174
175 INITIALIZE_PASS_BEGIN(RewriteStatepointsForGC, "rewrite-statepoints-for-gc",
215 char RewriteStatepointsForGCLegacyPass::ID = 0;
216
217 ModulePass *llvm::createRewriteStatepointsForGCLegacyPass() {
218 return new RewriteStatepointsForGCLegacyPass();
219 }
220
221 INITIALIZE_PASS_BEGIN(RewriteStatepointsForGCLegacyPass,
222 "rewrite-statepoints-for-gc",
176223 "Make relocations explicit at statepoints", false, false)
177224 INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
178225 INITIALIZE_PASS_DEPENDENCY(TargetTransformInfoWrapperPass)
179 INITIALIZE_PASS_END(RewriteStatepointsForGC, "rewrite-statepoints-for-gc",
226 INITIALIZE_PASS_END(RewriteStatepointsForGCLegacyPass,
227 "rewrite-statepoints-for-gc",
180228 "Make relocations explicit at statepoints", false, false)
181229
182230 namespace {
23452393 AH.setAttributes(AH.getAttributes().removeAttributes(Ctx, Index, R));
23462394 }
23472395
2348 void
2349 RewriteStatepointsForGC::stripNonValidAttributesFromPrototype(Function &F) {
2396 static void stripNonValidAttributesFromPrototype(Function &F) {
23502397 LLVMContext &Ctx = F.getContext();
23512398
23522399 for (Argument &A : F.args())
23582405 RemoveNonValidAttrAtIndex(Ctx, F, AttributeList::ReturnIndex);
23592406 }
23602407
2361 void RewriteStatepointsForGC::stripInvalidMetadataFromInstruction(Instruction &I) {
2408 /// Certain metadata on instructions are invalid after running RS4GC.
2409 /// Optimizations that run after RS4GC can incorrectly use this metadata to
2410 /// optimize functions. We drop such metadata on the instruction.
2411 static void stripInvalidMetadataFromInstruction(Instruction &I) {
23622412 if (!isa(I) && !isa(I))
23632413 return;
23642414 // These are the attributes that are still valid on loads and stores after
23862436 I.dropUnknownNonDebugMetadata(ValidMetadataAfterRS4GC);
23872437 }
23882438
2389 void RewriteStatepointsForGC::stripNonValidDataFromBody(Function &F) {
2439 static void stripNonValidDataFromBody(Function &F) {
23902440 if (F.empty())
23912441 return;
23922442
24612511 return false;
24622512 }
24632513
2464 void RewriteStatepointsForGC::stripNonValidData(Module &M) {
2514 static void stripNonValidData(Module &M) {
24652515 #ifndef NDEBUG
24662516 assert(llvm::any_of(M, shouldRewriteStatepointsIn) && "precondition!");
24672517 #endif
24732523 stripNonValidDataFromBody(F);
24742524 }
24752525
2476 bool RewriteStatepointsForGC::runOnFunction(Function &F) {
2477 // Nothing to do for declarations.
2478 if (F.isDeclaration() || F.empty())
2479 return false;
2480
2481 // Policy choice says not to rewrite - the most common reason is that we're
2482 // compiling code without a GCStrategy.
2483 if (!shouldRewriteStatepointsIn(F))
2484 return false;
2485
2486 DominatorTree &DT = getAnalysis(F).getDomTree();
2487 TargetTransformInfo &TTI =
2488 getAnalysis().getTTI(F);
2489 const TargetLibraryInfo &TLI =
2490 getAnalysis().getTLI();
2526 bool RewriteStatepointsForGC::runOnFunction(Function &F, DominatorTree &DT,
2527 TargetTransformInfo &TTI,
2528 const TargetLibraryInfo &TLI) {
2529 assert(!F.isDeclaration() && !F.empty() &&
2530 "need function body to rewrite statepoints in");
2531 assert(shouldRewriteStatepointsIn(F) && "mismatch in rewrite decision");
24912532
24922533 auto NeedsRewrite = [&TLI](Instruction &I) {
24932534 if (ImmutableCallSite CS = ImmutableCallSite(&I))
8080 initializePartiallyInlineLibCallsLegacyPassPass(Registry);
8181 initializeReassociateLegacyPassPass(Registry);
8282 initializeRegToMemPass(Registry);
83 initializeRewriteStatepointsForGCPass(Registry);
83 initializeRewriteStatepointsForGCLegacyPassPass(Registry);
8484 initializeSCCPLegacyPassPass(Registry);
8585 initializeIPSCCPLegacyPassPass(Registry);
8686 initializeSROALegacyPassPass(Registry);
0 ; RUN: opt < %s -rewrite-statepoints-for-gc -spp-print-base-pointers -S 2>&1 | FileCheck %s
1 ; RUN: opt < %s -passes=rewrite-statepoints-for-gc -spp-print-base-pointers -S 2>&1 | FileCheck %s
12
23 ; CHECK: derived %merged_value base %merged_value.base
34
0 ; RUN: opt < %s -rewrite-statepoints-for-gc -spp-print-base-pointers -S 2>&1 | FileCheck %s
1 ; RUN: opt < %s -passes=rewrite-statepoints-for-gc -spp-print-base-pointers -S 2>&1 | FileCheck %s
12
23
34 declare i1 @runtime_value() "gc-leaf-function"
0 ; RUN: opt < %s -rewrite-statepoints-for-gc -spp-print-base-pointers -S 2>&1 | FileCheck %s
1 ; RUN: opt < %s -passes=rewrite-statepoints-for-gc -spp-print-base-pointers -S 2>&1 | FileCheck %s
12
23 ; CHECK: derived %next base %base_obj
34
0 ; RUN: opt < %s -rewrite-statepoints-for-gc -spp-print-base-pointers -S 2>&1 | FileCheck %s
1 ; RUN: opt < %s -passes=rewrite-statepoints-for-gc -spp-print-base-pointers -S 2>&1 | FileCheck %s
12
23 ; CHECK: derived %select base null
34
0 ; RUN: opt < %s -rewrite-statepoints-for-gc -spp-print-base-pointers -S 2>&1 | FileCheck %s
1 ; RUN: opt < %s -passes=rewrite-statepoints-for-gc -spp-print-base-pointers -S 2>&1 | FileCheck %s
12
23 ; CHECK: derived %derived base null
34
0 ; RUN: opt < %s -rewrite-statepoints-for-gc -spp-print-base-pointers -S 2>&1 | FileCheck %s
1 ; RUN: opt < %s -passes=rewrite-statepoints-for-gc -spp-print-base-pointers -S 2>&1 | FileCheck %s
12
23 ; CHECK: derived %merged_value base %base_obj
34
0 ; RUN: opt < %s -rewrite-statepoints-for-gc -spp-print-base-pointers -S 2>&1 | FileCheck %s
1 ; RUN: opt < %s -passes=rewrite-statepoints-for-gc -spp-print-base-pointers -S 2>&1 | FileCheck %s
12
23 ; CHECK: derived %next.i64 base %base_obj
34
0 ; RUN: opt < %s -rewrite-statepoints-for-gc -spp-print-base-pointers -S 2>&1 | FileCheck %s
1 ; RUN: opt < %s -passes=rewrite-statepoints-for-gc -spp-print-base-pointers -S 2>&1 | FileCheck %s
12
23 ; CHECK: derived %obj_to_consume base %obj_to_consume.base
34
0 ; RUN: opt < %s -rewrite-statepoints-for-gc -spp-print-base-pointers -S 2>&1 | FileCheck %s
1 ; RUN: opt < %s -passes=rewrite-statepoints-for-gc -spp-print-base-pointers -S 2>&1 | FileCheck %s
12
23 ; CHECK: derived %merged_value base %merged_value.base
34
0 ; RUN: opt < %s -rewrite-statepoints-for-gc -spp-print-base-pointers -S 2>&1 | FileCheck %s
1 ; RUN: opt < %s -passes=rewrite-statepoints-for-gc -spp-print-base-pointers -S 2>&1 | FileCheck %s
12
23 ; CHECK: derived %merged_value base %merged_value.base
34
0 ; RUN: opt < %s -rewrite-statepoints-for-gc -spp-print-base-pointers -S 2>&1 | FileCheck %s
1 ; RUN: opt < %s -passes=rewrite-statepoints-for-gc -spp-print-base-pointers -S 2>&1 | FileCheck %s
12
23 ; CHECK: derived %merged_value base %merged_value.base
34
0 ; RUN: opt < %s -rewrite-statepoints-for-gc -spp-print-base-pointers -S 2>&1 | FileCheck %s
1 ; RUN: opt < %s -passes=rewrite-statepoints-for-gc -spp-print-base-pointers -S 2>&1 | FileCheck %s
12
23 ; CHECK: derived %next_element_ptr base %array_obj
34
0 ; RUN: opt < %s -rewrite-statepoints-for-gc -spp-print-base-pointers -S 2>&1 | FileCheck %s
1 ; RUN: opt < %s -passes=rewrite-statepoints-for-gc -spp-print-base-pointers -S 2>&1 | FileCheck %s
12
23 ; CHECK: derived %next base %base_obj
34
0 ; RUN: opt < %s -rewrite-statepoints-for-gc -S 2>&1 | FileCheck %s
1 ; RUN: opt < %s -passes=rewrite-statepoints-for-gc -S 2>&1 | FileCheck %s
12
23 ; The rewriting needs to make %obj loop variant by inserting a phi
34 ; of the original value and it's relocation.
0 ; RUN: opt < %s -rewrite-statepoints-for-gc -S | FileCheck %s
1 ; RUN: opt < %s -passes=rewrite-statepoints-for-gc -S | FileCheck %s
12
23
34 define i64 addrspace(1)* @test(<2 x i64 addrspace(1)*> %vec, i32 %idx) gc "statepoint-example" {
0 ; RUN: opt -S -rewrite-statepoints-for-gc < %s | FileCheck %s
1 ; RUN: opt -S -passes=rewrite-statepoints-for-gc < %s | FileCheck %s
12
23 declare void @g()
34 declare i32 @h()
0 ; This is a collection of really basic tests for gc.statepoint rewriting.
11 ; RUN: opt < %s -rewrite-statepoints-for-gc -spp-rematerialization-threshold=0 -S | FileCheck %s
2 ; RUN: opt < %s -passes=rewrite-statepoints-for-gc -spp-rematerialization-threshold=0 -S | FileCheck %s
23
34 ; Trivial relocation over a single call
45
0 ;; RUN: opt < %s -rewrite-statepoints-for-gc -S | FileCheck %s
1 ;; RUN: opt < %s -passes=rewrite-statepoints-for-gc -S | FileCheck %s
12
23 ;; This test is to verify that gc_result from a call statepoint
34 ;; can have preceding phis in its parent basic block. Unlike
0 ; RUN: opt -rewrite-statepoints-for-gc -S < %s | FileCheck %s
1 ; RUN: opt -passes=rewrite-statepoints-for-gc -S < %s | FileCheck %s
12
23 ; A null test of a single value
34
0 ; RUN: opt -S -rewrite-statepoints-for-gc < %s | FileCheck %s
1 ; RUN: opt -S -passes=rewrite-statepoints-for-gc < %s | FileCheck %s
12
23 ; constants don't get relocated.
34 @G = addrspace(1) global i8 5
0 ; RUN: opt -rewrite-statepoints-for-gc -S < %s | FileCheck %s
1 ; RUN: opt -passes=rewrite-statepoints-for-gc -S < %s | FileCheck %s
12
23 target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
34 target triple = "x86_64-apple-macosx10.11.0"
0 ; RUN: opt -rewrite-statepoints-for-gc -S < %s | FileCheck %s
1 ; RUN: opt -passes=rewrite-statepoints-for-gc -S < %s | FileCheck %s
12
23 target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
34 target triple = "x86_64-apple-macosx10.11.0"
0 ; RUN: opt -rewrite-statepoints-for-gc -S < %s | FileCheck %s
1 ; RUN: opt -passes=rewrite-statepoints-for-gc -S < %s | FileCheck %s
12 ; Check that the "deopt-lowering" function attribute gets transcoded into
23 ; flags on the resulting statepoint
34
0 ; RUN: opt -S -rewrite-statepoints-for-gc < %s | FileCheck %s
1 ; RUN: opt -S -passes=rewrite-statepoints-for-gc < %s | FileCheck %s
12
23 ; CHECK: declare i8 addrspace(1)* @some_function_ret_deref()
34 ; CHECK: define i8 addrspace(1)* @test_deref_arg(i8 addrspace(1)* %a)
0 ; RUN: opt -S -rewrite-statepoints-for-gc < %s | FileCheck %s
1 ; RUN: opt -S -passes=rewrite-statepoints-for-gc < %s | FileCheck %s
12
23 ; This test checks that metadata that's invalid after RS4GC is dropped.
34 ; We can miscompile if optimizations scheduled after RS4GC uses the
0 ; RUN: opt < %s -rewrite-statepoints-for-gc -S | FileCheck %s
1 ; RUN: opt < %s -passes=rewrite-statepoints-for-gc -S | FileCheck %s
12
23 ; This test is to verify gc.relocate can handle pointer to vector of
34 ; pointers (<2 x i32 addrspace(1)*> addrspace(1)* in this case).
0 ; RUN: opt < %s -S -rewrite-statepoints-for-gc | FileCheck %s
1 ; RUN: opt < %s -S -passes=rewrite-statepoints-for-gc | FileCheck %s
12
23 declare i64 addrspace(1)* @some_call(i64 addrspace(1)*)
34 declare i32 @personality_function()
0 ; RUN: opt < %s -S -rewrite-statepoints-for-gc | FileCheck %s
1 ; RUN: opt < %s -S -passes=rewrite-statepoints-for-gc | FileCheck %s
12
23 declare void @foo() "gc-leaf-function"
34 declare void @bar()
11 ; This test verifies that calls to libcalls functions do not get converted to
22 ; statepoint calls.
33 ; RUN: opt -S -rewrite-statepoints-for-gc < %s | FileCheck %s
4 ; RUN: opt -S -passes=rewrite-statepoints-for-gc < %s | FileCheck %s
45
56 declare double @ldexp(double %x, i32 %n) nounwind readnone
67
0 ; Test that we can correctly handle vectors of pointers in statepoint
11 ; rewriting.
22 ; RUN: opt < %s -rewrite-statepoints-for-gc -S | FileCheck %s
3 ; RUN: opt < %s -passes=rewrite-statepoints-for-gc -S | FileCheck %s
34
45 ; A non-vector relocation for comparison
56 define i64 addrspace(1)* @test(i64 addrspace(1)* %obj) gc "statepoint-example" {
0 ; A collection of liveness test cases to ensure we're reporting the
11 ; correct live values at statepoints
22 ; RUN: opt -rewrite-statepoints-for-gc -spp-rematerialization-threshold=0 -S < %s | FileCheck %s
3 ; RUN: opt -passes=rewrite-statepoints-for-gc -spp-rematerialization-threshold=0 -S < %s | FileCheck %s
34
45 ; Tests to make sure we consider %obj live in both the taken and untaken
56 ; predeccessor of merge.
0 ; RUN: opt -S -rewrite-statepoints-for-gc < %s | FileCheck %s
1 ; RUN: opt -S -passes=rewrite-statepoints-for-gc < %s | FileCheck %s
12
23 declare void @f()
34 declare i32 @personality_function()
0 ; RUN: opt -rewrite-statepoints-for-gc -S < %s | FileCheck %s
1 ; RUN: opt -passes=rewrite-statepoints-for-gc -S < %s | FileCheck %s
12
23 ; Test to make sure we destroy LCSSA's single entry phi nodes before
34 ; running liveness
0
11 ;; RUN: opt -rewrite-statepoints-for-gc -verify -S < %s | FileCheck %s
2 ;; RUN: opt -passes=rewrite-statepoints-for-gc -verify -S < %s | FileCheck %s
23 ;; This test is to verify that RewriteStatepointsForGC correctly relocates values
34 ;; defined by invoke instruction results.
45
0 ; RUN: opt < %s -rewrite-statepoints-for-gc -spp-rematerialization-threshold=0 -S | FileCheck %s
1 ; RUN: opt < %s -passes=rewrite-statepoints-for-gc -spp-rematerialization-threshold=0 -S | FileCheck %s
12
23
34 declare void @foo()
0 ; RUN: opt < %s -rewrite-statepoints-for-gc -S | FileCheck %s
1 ; RUN: opt < %s -passes=rewrite-statepoints-for-gc -S | FileCheck %s
12
23
34 declare void @use_obj16(i16 addrspace(1)*) "gc-leaf-function"
0 ; RUN: opt -rewrite-statepoints-for-gc -verify -S < %s | FileCheck %s
1 ; RUN: opt -passes=rewrite-statepoints-for-gc -verify -S < %s | FileCheck %s
12
23 declare i8 addrspace(1)* @gc_call()
34
0 ; RUN: opt -S -rewrite-statepoints-for-gc < %s | FileCheck %s
1 ; RUN: opt -S -passes=rewrite-statepoints-for-gc < %s | FileCheck %s
12 ; Ensure statepoints copy (valid) attributes from callsites.
23
34 declare void @f(i8 addrspace(1)* %obj)
0 ; RUN: opt -rewrite-statepoints-for-gc -S < %s | FileCheck %s
1 ; RUN: opt -passes=rewrite-statepoints-for-gc -S < %s | FileCheck %s
12
23 ; Ensure that the gc.statepoint calls / invokes we generate carry over
34 ; the right calling conventions.
0 ; RUN: opt < %s -S -rewrite-statepoints-for-gc | FileCheck %s
1 ; RUN: opt < %s -S -passes=rewrite-statepoints-for-gc | FileCheck %s
12
23 ; Basic test to make sure that safepoints are placed
34 ; for CoreCLR GC
0 ; RUN: opt -rewrite-statepoints-for-gc -S < %s | FileCheck %s
1 ; RUN: opt -passes=rewrite-statepoints-for-gc -S < %s | FileCheck %s
12
23 ; Ensure that the gc.statepoint calls / invokes we generate have the
34 ; set of arguments we expect it to have.
0 ; RUN: opt < %s -rewrite-statepoints-for-gc -S | FileCheck %s
1 ; RUN: opt < %s -passes=rewrite-statepoints-for-gc -S | FileCheck %s
12
23 declare void @some_call(i64 addrspace(1)*)
34
0 ; RUN: opt -S -rewrite-statepoints-for-gc < %s | FileCheck %s
1 ; RUN: opt -S -passes=rewrite-statepoints-for-gc < %s | FileCheck %s
12 ;
23 ; A test to make sure that we can look through bitcasts of
34 ; vector types when a base pointer is contained in a vector.