Skip to content

Commit a77c6f9

Browse files
Add an option to control whether partial results are allowed
1 parent 5da2cc9 commit a77c6f9

14 files changed

+158
-54
lines changed

llvm/include/llvm/Analysis/LoopAccessAnalysis.h

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -655,7 +655,8 @@ class RuntimePointerChecking {
655655
/// For memory dependences that cannot be determined at compile time, it
656656
/// generates run-time checks to prove independence. This is done by
657657
/// AccessAnalysis::canCheckPtrAtRT and the checks are maintained by the
658-
/// RuntimePointerCheck class.
658+
/// RuntimePointerCheck class. AllowPartial determines whether partial checks
659+
/// are generated when not all pointers could be analyzed.
659660
///
660661
/// If pointers can wrap or can't be expressed as affine AddRec expressions by
661662
/// ScalarEvolution, we will generate run-time checks by emitting a
@@ -668,7 +669,8 @@ class LoopAccessInfo {
668669
LLVM_ABI LoopAccessInfo(Loop *L, ScalarEvolution *SE,
669670
const TargetTransformInfo *TTI,
670671
const TargetLibraryInfo *TLI, AAResults *AA,
671-
DominatorTree *DT, LoopInfo *LI);
672+
DominatorTree *DT, LoopInfo *LI,
673+
bool AllowPartial = false);
672674

673675
/// Return true we can analyze the memory accesses in the loop and there are
674676
/// no memory dependence cycles. Note that for dependences between loads &
@@ -683,6 +685,11 @@ class LoopAccessInfo {
683685
/// not legal to insert them.
684686
bool hasConvergentOp() const { return HasConvergentOp; }
685687

688+
/// Return true if, when runtime pointer checking does not have complete
689+
/// results, it instead has partial results for those memory accesses that
690+
/// could be analyzed.
691+
bool hasAllowPartial() const { return AllowPartial; }
692+
686693
const RuntimePointerChecking *getRuntimePointerChecking() const {
687694
return PtrRtChecking.get();
688695
}
@@ -785,9 +792,9 @@ class LoopAccessInfo {
785792

786793
/// We need to check that all of the pointers in this list are disjoint
787794
/// at runtime. Using std::unique_ptr to make using move ctor simpler.
788-
/// This list may contain only partial information when we've failed to
789-
/// analyze all the memory accesses in the loop, in which case
790-
/// HasCompletePtrRtChecking will be false.
795+
/// If AllowPartial is true then this list may contain only partial
796+
/// information when we've failed to analyze all the memory accesses in the
797+
/// loop, in which case HasCompletePtrRtChecking will be false.
791798
std::unique_ptr<RuntimePointerChecking> PtrRtChecking;
792799

793800
/// The Memory Dependence Checker which can determine the
@@ -798,6 +805,8 @@ class LoopAccessInfo {
798805

799806
Loop *TheLoop;
800807

808+
bool AllowPartial;
809+
801810
unsigned NumLoads = 0;
802811
unsigned NumStores = 0;
803812

@@ -927,7 +936,7 @@ class LoopAccessInfoManager {
927936
const TargetLibraryInfo *TLI)
928937
: SE(SE), AA(AA), DT(DT), LI(LI), TTI(TTI), TLI(TLI) {}
929938

930-
LLVM_ABI const LoopAccessInfo &getInfo(Loop &L);
939+
LLVM_ABI const LoopAccessInfo &getInfo(Loop &L, bool AllowPartial = false);
931940

932941
LLVM_ABI void clear();
933942

llvm/include/llvm/Transforms/Scalar/LoopAccessAnalysisPrinter.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,11 @@ class raw_ostream;
2020
class LoopAccessInfoPrinterPass
2121
: public PassInfoMixin<LoopAccessInfoPrinterPass> {
2222
raw_ostream &OS;
23+
bool AllowPartial;
2324

2425
public:
25-
explicit LoopAccessInfoPrinterPass(raw_ostream &OS) : OS(OS) {}
26+
explicit LoopAccessInfoPrinterPass(raw_ostream &OS, bool AllowPartial)
27+
: OS(OS), AllowPartial(AllowPartial) {}
2628
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
2729
static bool isRequired() { return true; }
2830
};

llvm/lib/Analysis/LoopAccessAnalysis.cpp

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -700,7 +700,7 @@ class AccessAnalysis {
700700
/// loop, but we will have checks for those pointers we could analyze.
701701
bool canCheckPtrAtRT(RuntimePointerChecking &RtCheck, Loop *TheLoop,
702702
const DenseMap<Value *, const SCEV *> &Strides,
703-
Value *&UncomputablePtr);
703+
Value *&UncomputablePtr, bool AllowPartial);
704704

705705
/// Goes over all memory accesses, checks whether a RT check is needed
706706
/// and builds sets of dependent accesses.
@@ -1185,8 +1185,8 @@ bool AccessAnalysis::createCheckForAccess(
11851185

11861186
bool AccessAnalysis::canCheckPtrAtRT(
11871187
RuntimePointerChecking &RtCheck, Loop *TheLoop,
1188-
const DenseMap<Value *, const SCEV *> &StridesMap,
1189-
Value *&UncomputablePtr) {
1188+
const DenseMap<Value *, const SCEV *> &StridesMap, Value *&UncomputablePtr,
1189+
bool AllowPartial) {
11901190
// Find pointers with computable bounds. We are going to use this information
11911191
// to place a runtime bound check.
11921192
bool CanDoRT = true;
@@ -1279,6 +1279,8 @@ bool AccessAnalysis::canCheckPtrAtRT(
12791279
/*Assume=*/true)) {
12801280
CanDoAliasSetRT = false;
12811281
UncomputablePtr = Access.getPointer();
1282+
if (!AllowPartial)
1283+
break;
12821284
}
12831285
}
12841286
}
@@ -1318,7 +1320,7 @@ bool AccessAnalysis::canCheckPtrAtRT(
13181320
}
13191321
}
13201322

1321-
if (MayNeedRTCheck)
1323+
if (MayNeedRTCheck && (CanDoRT || AllowPartial))
13221324
RtCheck.generateChecks(DepCands, IsDepCheckNeeded);
13231325

13241326
LLVM_DEBUG(dbgs() << "LAA: We need to do " << RtCheck.getNumberOfChecks()
@@ -1331,6 +1333,8 @@ bool AccessAnalysis::canCheckPtrAtRT(
13311333
bool CanDoRTIfNeeded = !RtCheck.Need || CanDoRT;
13321334
assert(CanDoRTIfNeeded == (CanDoRT || !MayNeedRTCheck) &&
13331335
"CanDoRTIfNeeded depends on RtCheck.Need");
1336+
if (!CanDoRTIfNeeded && !AllowPartial)
1337+
RtCheck.reset();
13341338
return CanDoRTIfNeeded;
13351339
}
13361340

@@ -2600,7 +2604,7 @@ bool LoopAccessInfo::analyzeLoop(AAResults *AA, const LoopInfo *LI,
26002604
// to place a runtime bound check.
26012605
Value *UncomputablePtr = nullptr;
26022606
HasCompletePtrRtChecking = Accesses.canCheckPtrAtRT(
2603-
*PtrRtChecking, TheLoop, SymbolicStrides, UncomputablePtr);
2607+
*PtrRtChecking, TheLoop, SymbolicStrides, UncomputablePtr, AllowPartial);
26042608
if (!HasCompletePtrRtChecking) {
26052609
const auto *I = dyn_cast_or_null<Instruction>(UncomputablePtr);
26062610
recordAnalysis("CantIdentifyArrayBounds", I)
@@ -2629,8 +2633,9 @@ bool LoopAccessInfo::analyzeLoop(AAResults *AA, const LoopInfo *LI,
26292633
PtrRtChecking->Need = true;
26302634

26312635
UncomputablePtr = nullptr;
2632-
HasCompletePtrRtChecking = Accesses.canCheckPtrAtRT(
2633-
*PtrRtChecking, TheLoop, SymbolicStrides, UncomputablePtr);
2636+
HasCompletePtrRtChecking =
2637+
Accesses.canCheckPtrAtRT(*PtrRtChecking, TheLoop, SymbolicStrides,
2638+
UncomputablePtr, AllowPartial);
26342639

26352640
// Check that we found the bounds for the pointer.
26362641
if (!HasCompletePtrRtChecking) {
@@ -2908,9 +2913,10 @@ void LoopAccessInfo::collectStridedAccess(Value *MemAccess) {
29082913
LoopAccessInfo::LoopAccessInfo(Loop *L, ScalarEvolution *SE,
29092914
const TargetTransformInfo *TTI,
29102915
const TargetLibraryInfo *TLI, AAResults *AA,
2911-
DominatorTree *DT, LoopInfo *LI)
2916+
DominatorTree *DT, LoopInfo *LI,
2917+
bool AllowPartial)
29122918
: PSE(std::make_unique<PredicatedScalarEvolution>(*SE, *L)),
2913-
PtrRtChecking(nullptr), TheLoop(L) {
2919+
PtrRtChecking(nullptr), TheLoop(L), AllowPartial(AllowPartial) {
29142920
unsigned MaxTargetVectorWidthInBits = std::numeric_limits<unsigned>::max();
29152921
if (TTI && !TTI->enableScalableVectorization())
29162922
// Scale the vector width by 2 as rough estimate to also consider
@@ -2980,12 +2986,15 @@ void LoopAccessInfo::print(raw_ostream &OS, unsigned Depth) const {
29802986
PSE->print(OS, Depth);
29812987
}
29822988

2983-
const LoopAccessInfo &LoopAccessInfoManager::getInfo(Loop &L) {
2989+
const LoopAccessInfo &LoopAccessInfoManager::getInfo(Loop &L,
2990+
bool AllowPartial) {
29842991
const auto &[It, Inserted] = LoopAccessInfoMap.try_emplace(&L);
29852992

2986-
if (Inserted)
2987-
It->second =
2988-
std::make_unique<LoopAccessInfo>(&L, &SE, TTI, TLI, &AA, &DT, &LI);
2993+
// We need to create the LoopAccessInfo if either we don't already have one,
2994+
// or if it was created with a different value of AllowPartial.
2995+
if (Inserted || It->second->hasAllowPartial() != AllowPartial)
2996+
It->second = std::make_unique<LoopAccessInfo>(&L, &SE, TTI, TLI, &AA, &DT,
2997+
&LI, AllowPartial);
29892998

29902999
return *It->second;
29913000
}

llvm/lib/Passes/PassRegistry.def

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -441,7 +441,6 @@ FUNCTION_PASS("print-cfg-sccs", CFGSCCPrinterPass(errs()))
441441
FUNCTION_PASS("print-memderefs", MemDerefPrinterPass(errs()))
442442
FUNCTION_PASS("print-mustexecute", MustExecutePrinterPass(errs()))
443443
FUNCTION_PASS("print-predicateinfo", PredicateInfoPrinterPass(errs()))
444-
FUNCTION_PASS("print<access-info>", LoopAccessInfoPrinterPass(errs()))
445444
FUNCTION_PASS("print<assumptions>", AssumptionPrinterPass(errs()))
446445
FUNCTION_PASS("print<block-freq>", BlockFrequencyPrinterPass(errs()))
447446
FUNCTION_PASS("print<branch-prob>", BranchProbabilityPrinterPass(errs()))
@@ -583,6 +582,16 @@ FUNCTION_PASS_WITH_PARAMS(
583582
return MergedLoadStoreMotionPass(Opts);
584583
},
585584
parseMergedLoadStoreMotionOptions, "no-split-footer-bb;split-footer-bb")
585+
FUNCTION_PASS_WITH_PARAMS(
586+
"print<access-info>", "LoopAccessInfoPrinterPass",
587+
[](bool AllowPartial) {
588+
return LoopAccessInfoPrinterPass(errs(), AllowPartial);
589+
},
590+
[](StringRef Params) {
591+
return PassBuilder::parseSinglePassOption(Params, "allow-partial",
592+
"LoopAccessInfoPrinterPass");
593+
},
594+
"allow-partial")
586595
FUNCTION_PASS_WITH_PARAMS(
587596
"print<da>", "DependenceAnalysisPrinterPass",
588597
[](bool NormalizeResults) {

llvm/lib/Transforms/Scalar/LoopAccessAnalysisPrinter.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ PreservedAnalyses LoopAccessInfoPrinterPass::run(Function &F,
2828
while (!Worklist.empty()) {
2929
Loop *L = Worklist.pop_back_val();
3030
OS.indent(2) << L->getHeader()->getName() << ":\n";
31-
LAIs.getInfo(*L).print(OS, 4);
31+
LAIs.getInfo(*L, AllowPartial).print(OS, 4);
3232
}
3333
return PreservedAnalyses::all();
3434
}

llvm/lib/Transforms/Scalar/LoopVersioningLICM.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -368,7 +368,7 @@ bool LoopVersioningLICM::legalLoopInstructions() {
368368
IsReadOnlyLoop = true;
369369
using namespace ore;
370370
// Get LoopAccessInfo from current loop via the proxy.
371-
LAI = &LAIs.getInfo(*CurLoop);
371+
LAI = &LAIs.getInfo(*CurLoop, /*AllowPartial=*/true);
372372
// Check LoopAccessInfo for need of runtime check.
373373
if (LAI->getRuntimePointerChecking()->getChecks().empty()) {
374374
LLVM_DEBUG(dbgs() << " LAA: Runtime check not found !!\n");
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
; RUN: opt -disable-output -passes='print<access-info><allow-partial>,print<access-info>' %s 2>&1 | FileCheck %s --check-prefixes=ALLOW-BEFORE
2+
; RUN: opt -disable-output -passes='print<access-info>,print<access-info><allow-partial>' %s 2>&1 | FileCheck %s --check-prefixes=ALLOW-AFTER
3+
4+
; Check that we get the right results when loop access analysis is run twice,
5+
; once without partial results and once with.
6+
7+
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32"
8+
9+
define void @gep_loaded_offset(ptr %p, ptr %q, ptr %r, i32 %n) {
10+
; ALLOW-BEFORE-LABEL: 'gep_loaded_offset'
11+
; ALLOW-BEFORE-NEXT: while.body:
12+
; ALLOW-BEFORE-NEXT: Report: cannot identify array bounds
13+
; ALLOW-BEFORE-NEXT: Dependences:
14+
; ALLOW-BEFORE-NEXT: Run-time memory checks:
15+
; ALLOW-BEFORE-NEXT: Check 0:
16+
; ALLOW-BEFORE-NEXT: Comparing group GRP0:
17+
; ALLOW-BEFORE-NEXT: %p.addr = phi ptr [ %incdec.ptr, %while.body ], [ %p, %entry ]
18+
; ALLOW-BEFORE-NEXT: Against group GRP1:
19+
; ALLOW-BEFORE-NEXT: ptr %r
20+
; ALLOW-BEFORE-NEXT: Grouped accesses:
21+
; ALLOW-BEFORE-NEXT: Group GRP0:
22+
; ALLOW-BEFORE-NEXT: (Low: %p High: (4 + (4 * (zext i32 (-1 + %n)<nsw> to i64))<nuw><nsw> + %p))
23+
; ALLOW-BEFORE-NEXT: Member: {%p,+,4}<nuw><%while.body>
24+
; ALLOW-BEFORE-NEXT: Group GRP1:
25+
; ALLOW-BEFORE-NEXT: (Low: %r High: (8 + %r))
26+
; ALLOW-BEFORE-NEXT: Member: %r
27+
; ALLOW-BEFORE-NEXT: Generated run-time checks are incomplete
28+
; ALLOW-BEFORE-EMPTY:
29+
; ALLOW-BEFORE-NEXT: Non vectorizable stores to invariant address were not found in loop.
30+
; ALLOW-BEFORE-NEXT: SCEV assumptions:
31+
; ALLOW-BEFORE-EMPTY:
32+
; ALLOW-BEFORE-NEXT: Expressions re-written:
33+
;
34+
; ALLOW-BEFORE-LABEL: 'gep_loaded_offset'
35+
; ALLOW-BEFORE-NEXT: while.body:
36+
; ALLOW-BEFORE-NEXT: Report: cannot identify array bounds
37+
; ALLOW-BEFORE-NEXT: Dependences:
38+
; ALLOW-BEFORE-NEXT: Run-time memory checks:
39+
; ALLOW-BEFORE-NEXT: Grouped accesses:
40+
; ALLOW-BEFORE-EMPTY:
41+
; ALLOW-BEFORE-NEXT: Non vectorizable stores to invariant address were not found in loop.
42+
; ALLOW-BEFORE-NEXT: SCEV assumptions:
43+
; ALLOW-BEFORE-EMPTY:
44+
; ALLOW-BEFORE-NEXT: Expressions re-written:
45+
;
46+
; ALLOW-AFTER-LABEL: 'gep_loaded_offset'
47+
; ALLOW-AFTER-NEXT: while.body:
48+
; ALLOW-AFTER-NEXT: Report: cannot identify array bounds
49+
; ALLOW-AFTER-NEXT: Dependences:
50+
; ALLOW-AFTER-NEXT: Run-time memory checks:
51+
; ALLOW-AFTER-NEXT: Grouped accesses:
52+
; ALLOW-AFTER-EMPTY:
53+
; ALLOW-AFTER-NEXT: Non vectorizable stores to invariant address were not found in loop.
54+
; ALLOW-AFTER-NEXT: SCEV assumptions:
55+
; ALLOW-AFTER-EMPTY:
56+
; ALLOW-AFTER-NEXT: Expressions re-written:
57+
;
58+
; ALLOW-AFTER-LABEL: 'gep_loaded_offset'
59+
; ALLOW-AFTER-NEXT: while.body:
60+
; ALLOW-AFTER-NEXT: Report: cannot identify array bounds
61+
; ALLOW-AFTER-NEXT: Dependences:
62+
; ALLOW-AFTER-NEXT: Run-time memory checks:
63+
; ALLOW-AFTER-NEXT: Check 0:
64+
; ALLOW-AFTER-NEXT: Comparing group GRP0:
65+
; ALLOW-AFTER-NEXT: %p.addr = phi ptr [ %incdec.ptr, %while.body ], [ %p, %entry ]
66+
; ALLOW-AFTER-NEXT: Against group GRP1:
67+
; ALLOW-AFTER-NEXT: ptr %r
68+
; ALLOW-AFTER-NEXT: Grouped accesses:
69+
; ALLOW-AFTER-NEXT: Group GRP0:
70+
; ALLOW-AFTER-NEXT: (Low: %p High: (4 + (4 * (zext i32 (-1 + %n)<nsw> to i64))<nuw><nsw> + %p))
71+
; ALLOW-AFTER-NEXT: Member: {%p,+,4}<nuw><%while.body>
72+
; ALLOW-AFTER-NEXT: Group GRP1:
73+
; ALLOW-AFTER-NEXT: (Low: %r High: (8 + %r))
74+
; ALLOW-AFTER-NEXT: Member: %r
75+
; ALLOW-AFTER-NEXT: Generated run-time checks are incomplete
76+
; ALLOW-AFTER-EMPTY:
77+
; ALLOW-AFTER-NEXT: Non vectorizable stores to invariant address were not found in loop.
78+
; ALLOW-AFTER-NEXT: SCEV assumptions:
79+
; ALLOW-AFTER-EMPTY:
80+
; ALLOW-AFTER-NEXT: Expressions re-written:
81+
;
82+
entry:
83+
br label %while.body
84+
85+
while.body:
86+
%n.addr = phi i32 [ %dec, %while.body ], [ %n, %entry ]
87+
%p.addr = phi ptr [ %incdec.ptr, %while.body ], [ %p, %entry ]
88+
%dec = add nsw i32 %n.addr, -1
89+
%rval = load i64, ptr %r, align 4
90+
%arrayidx = getelementptr inbounds i32, ptr %q, i64 %rval
91+
%val = load i32, ptr %arrayidx, align 4
92+
%incdec.ptr = getelementptr inbounds nuw i8, ptr %p.addr, i64 4
93+
store i32 %val, ptr %p.addr, align 4
94+
%tobool.not = icmp eq i32 %dec, 0
95+
br i1 %tobool.not, label %while.end, label %while.body
96+
97+
while.end:
98+
ret void
99+
}

llvm/test/Analysis/LoopAccessAnalysis/forked-pointers.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --version 3
2-
; RUN: opt -disable-output -passes='print<access-info>' %s 2>&1 | FileCheck %s --check-prefixes=CHECK,FULLDEPTH
3-
; RUN: opt -disable-output -passes='print<access-info>' -max-forked-scev-depth=2 %s 2>&1 | FileCheck %s --check-prefixes=CHECK,DEPTH2
2+
; RUN: opt -disable-output -passes='print<access-info><allow-partial>' %s 2>&1 | FileCheck %s --check-prefixes=CHECK,FULLDEPTH
3+
; RUN: opt -disable-output -passes='print<access-info><allow-partial>' -max-forked-scev-depth=2 %s 2>&1 | FileCheck %s --check-prefixes=CHECK,DEPTH2
44

55
target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
66

llvm/test/Analysis/LoopAccessAnalysis/non-constant-strides-backward.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --version 4
2-
; RUN: opt -passes='print<access-info>' -disable-output %s 2>&1 | FileCheck %s
2+
; RUN: opt -passes='print<access-info><allow-partial>' -disable-output %s 2>&1 | FileCheck %s
33

44
target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128"
55

llvm/test/Analysis/LoopAccessAnalysis/non-constant-strides-forward.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --version 4
2-
; RUN: opt -passes='print<access-info>' -disable-output %s 2>&1 | FileCheck %s
2+
; RUN: opt -passes='print<access-info><allow-partial>' -disable-output %s 2>&1 | FileCheck %s
33

44
target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128"
55

llvm/test/Analysis/LoopAccessAnalysis/pointer-phis.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --version 3
2-
; RUN: opt -passes='print<access-info>' -disable-output < %s 2>&1 | FileCheck %s
2+
; RUN: opt -passes='print<access-info><allow-partial>' -disable-output < %s 2>&1 | FileCheck %s
33

44
%s1 = type { [32000 x double], [32000 x double], [32000 x double] }
55

llvm/test/Analysis/LoopAccessAnalysis/retry-runtime-checks-after-dependence-analysis-forked-pointers.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --version 5
2-
; RUN: opt -passes='print<access-info>' -disable-output %s 2>&1 | FileCheck %s
2+
; RUN: opt -passes='print<access-info><allow-partial>' -disable-output %s 2>&1 | FileCheck %s
33

44

55
define void @dependency_check_and_runtime_checks_needed_select_of_invariant_ptrs(ptr %a, ptr %b, ptr %c, i64 %offset, i64 %n) {

llvm/test/Analysis/LoopAccessAnalysis/underlying-object-loop-varying-phi.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --version 4
2-
; RUN: opt -passes='print<access-info>' -disable-output %s 2>&1 | FileCheck %s
2+
; RUN: opt -passes='print<access-info><allow-partial>' -disable-output %s 2>&1 | FileCheck %s
33

44
target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128"
55

0 commit comments

Comments
 (0)