Skip to content

LAA: handle 0 return from getPtrStride correctly #124539

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jan 27, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions llvm/lib/Analysis/LoopAccessAnalysis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1448,7 +1448,7 @@ llvm::getPtrStride(PredicatedScalarEvolution &PSE, Type *AccessTy, Value *Ptr,
bool Assume, bool ShouldCheckWrap) {
const SCEV *PtrScev = replaceSymbolicStrideSCEV(PSE, StridesMap, Ptr);
if (PSE.getSE()->isLoopInvariant(PtrScev, Lp))
return {0};
return 0;

Type *Ty = Ptr->getType();
assert(Ty->isPointerTy() && "Unexpected non-ptr");
Expand Down Expand Up @@ -2602,7 +2602,7 @@ bool LoopAccessInfo::analyzeLoop(AAResults *AA, const LoopInfo *LI,
bool IsReadOnlyPtr = false;
Type *AccessTy = getLoadStoreType(LD);
if (Seen.insert({Ptr, AccessTy}).second ||
!getPtrStride(*PSE, LD->getType(), Ptr, TheLoop, SymbolicStrides).value_or(0)) {
!getPtrStride(*PSE, AccessTy, Ptr, TheLoop, SymbolicStrides)) {
++NumReads;
IsReadOnlyPtr = true;
}
Expand Down
8 changes: 0 additions & 8 deletions llvm/test/Analysis/LoopAccessAnalysis/pointer-phis.ll
Original file line number Diff line number Diff line change
Expand Up @@ -501,14 +501,6 @@ define void @phi_load_store_memdep_check(i1 %c, ptr %A, ptr %B, ptr %C) {
; CHECK-NEXT: %lv3 = load i16, ptr %c.sink, align 2 ->
; CHECK-NEXT: store i16 %add, ptr %c.sink, align 1
; CHECK-EMPTY:
; CHECK-NEXT: Unknown:
; CHECK-NEXT: %lv = load i16, ptr %A, align 1 ->
; CHECK-NEXT: store i16 %lv, ptr %A, align 1
; CHECK-EMPTY:
; CHECK-NEXT: Unknown:
; CHECK-NEXT: store i16 %lv, ptr %A, align 1 ->
; CHECK-NEXT: %lv2 = load i16, ptr %A, align 1
; CHECK-EMPTY:
; CHECK-NEXT: Run-time memory checks:
; CHECK-NEXT: Check 0:
; CHECK-NEXT: Comparing group ([[GRP10:0x[0-9a-f]+]]):
Expand Down
132 changes: 67 additions & 65 deletions llvm/test/Transforms/LoopDistribute/pointer-phi-in-loop.ll
Original file line number Diff line number Diff line change
Expand Up @@ -3,26 +3,73 @@

; Testcases inspired by PR50296, PR50288.

define void @phi_load_store_distribute(i1 %c, ptr %A, ptr %B, ptr %C) {
define void @phi_load_store_distribute(i1 %cond, ptr %A, ptr %B, ptr %C) {
; CHECK-LABEL: @phi_load_store_distribute(
; CHECK-NEXT: entry:
; CHECK-NEXT: br label [[FOR_BODY:%.*]]
; CHECK: for.body:
; CHECK-NEXT: [[IV:%.*]] = phi i16 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[IF_END:%.*]] ]
; CHECK-NEXT: [[LV:%.*]] = load i16, ptr [[A:%.*]], align 1
; CHECK: for.body.lver.check:
; CHECK-NEXT: [[SCEVGEP:%.*]] = getelementptr i8, ptr [[A:%.*]], i64 2
; CHECK-NEXT: [[SCEVGEP1:%.*]] = getelementptr i8, ptr [[C:%.*]], i64 2
; CHECK-NEXT: [[SCEVGEP2:%.*]] = getelementptr i8, ptr [[B:%.*]], i64 2
; CHECK-NEXT: [[BOUND0:%.*]] = icmp ult ptr [[A]], [[SCEVGEP1]]
; CHECK-NEXT: [[BOUND1:%.*]] = icmp ult ptr [[C]], [[SCEVGEP]]
; CHECK-NEXT: [[FOUND_CONFLICT:%.*]] = and i1 [[BOUND0]], [[BOUND1]]
; CHECK-NEXT: [[BOUND03:%.*]] = icmp ult ptr [[A]], [[SCEVGEP2]]
; CHECK-NEXT: [[BOUND14:%.*]] = icmp ult ptr [[B]], [[SCEVGEP]]
; CHECK-NEXT: [[FOUND_CONFLICT5:%.*]] = and i1 [[BOUND03]], [[BOUND14]]
; CHECK-NEXT: [[CONFLICT_RDX:%.*]] = or i1 [[FOUND_CONFLICT]], [[FOUND_CONFLICT5]]
; CHECK-NEXT: br i1 [[CONFLICT_RDX]], label [[ENTRY:%.*]], label [[FOR_BODY_PH_LDIST1:%.*]]
; CHECK: for.body.ph.lver.orig:
; CHECK-NEXT: br label [[FOR_BODY_LVER_ORIG:%.*]]
; CHECK: for.body.lver.orig:
; CHECK-NEXT: [[IV:%.*]] = phi i16 [ 0, [[ENTRY]] ], [ [[IV_NEXT:%.*]], [[IF_END:%.*]] ]
; CHECK-NEXT: [[LV:%.*]] = load i16, ptr [[A]], align 1
; CHECK-NEXT: store i16 [[LV]], ptr [[A]], align 1
; CHECK-NEXT: br i1 [[C:%.*]], label [[IF_THEN:%.*]], label [[IF_END]]
; CHECK: if.then:
; CHECK-NEXT: br i1 [[COND:%.*]], label [[IF_THEN:%.*]], label [[IF_END]]
; CHECK: if.then.lver.orig:
; CHECK-NEXT: [[LV2:%.*]] = load i16, ptr [[A]], align 1
; CHECK-NEXT: br label [[IF_END]]
; CHECK: if.end.lver.orig:
; CHECK-NEXT: [[C_SINK_LVER_ORIG:%.*]] = phi ptr [ [[B]], [[IF_THEN]] ], [ [[C]], [[FOR_BODY_LVER_ORIG]] ]
; CHECK-NEXT: [[LV3_LVER_ORIG:%.*]] = load i16, ptr [[C_SINK_LVER_ORIG]], align 2
; CHECK-NEXT: [[ADD_LVER_ORIG:%.*]] = add i16 [[LV3_LVER_ORIG]], 10
; CHECK-NEXT: store i16 [[ADD_LVER_ORIG]], ptr [[C_SINK_LVER_ORIG]], align 1
; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i16 [[IV]], 1
; CHECK-NEXT: [[TOBOOL_NOT_LVER_ORIG:%.*]] = icmp eq i16 [[IV_NEXT]], 1000
; CHECK-NEXT: br i1 [[TOBOOL_NOT_LVER_ORIG]], label [[FOR_END_LOOPEXIT_LOOPEXIT:%.*]], label [[FOR_BODY_LVER_ORIG]]
; CHECK: for.body.ph.ldist1:
; CHECK-NEXT: br label [[FOR_BODY_LDIST1:%.*]]
; CHECK: for.body.ldist1:
; CHECK-NEXT: [[IV_LDIST1:%.*]] = phi i16 [ 0, [[FOR_BODY_PH_LDIST1]] ], [ [[IV_NEXT_LDIST1:%.*]], [[IF_END_LDIST1:%.*]] ]
; CHECK-NEXT: [[LV_LDIST1:%.*]] = load i16, ptr [[A]], align 1, !alias.scope [[META0:![0-9]+]], !noalias [[META3:![0-9]+]]
; CHECK-NEXT: store i16 [[LV_LDIST1]], ptr [[A]], align 1, !alias.scope [[META0]], !noalias [[META3]]
; CHECK-NEXT: br i1 [[COND]], label [[IF_THEN_LDIST1:%.*]], label [[IF_END_LDIST1]]
; CHECK: if.then.ldist1:
; CHECK-NEXT: [[LV2_LDIST1:%.*]] = load i16, ptr [[A]], align 1, !alias.scope [[META0]], !noalias [[META3]]
; CHECK-NEXT: br label [[IF_END_LDIST1]]
; CHECK: if.end.ldist1:
; CHECK-NEXT: [[IV_NEXT_LDIST1]] = add nuw nsw i16 [[IV_LDIST1]], 1
; CHECK-NEXT: [[TOBOOL_NOT_LDIST1:%.*]] = icmp eq i16 [[IV_NEXT_LDIST1]], 1000
; CHECK-NEXT: br i1 [[TOBOOL_NOT_LDIST1]], label [[FOR_BODY_PH:%.*]], label [[FOR_BODY_LDIST1]]
; CHECK: for.body.ph:
; CHECK-NEXT: br label [[FOR_BODY1:%.*]]
; CHECK: for.body:
; CHECK-NEXT: [[IV1:%.*]] = phi i16 [ 0, [[FOR_BODY_PH]] ], [ [[IV_NEXT1:%.*]], [[IF_END1:%.*]] ]
; CHECK-NEXT: br i1 [[COND]], label [[IF_THEN1:%.*]], label [[IF_END1]]
; CHECK: if.then:
; CHECK-NEXT: br label [[IF_END1]]
; CHECK: if.end:
; CHECK-NEXT: [[C_SINK:%.*]] = phi ptr [ [[B:%.*]], [[IF_THEN]] ], [ [[C:%.*]], [[FOR_BODY]] ]
; CHECK-NEXT: [[C_SINK:%.*]] = phi ptr [ [[B]], [[IF_THEN1]] ], [ [[C]], [[FOR_BODY1]] ]
; CHECK-NEXT: [[LV3:%.*]] = load i16, ptr [[C_SINK]], align 2
; CHECK-NEXT: [[ADD:%.*]] = add i16 [[LV3]], 10
; CHECK-NEXT: store i16 [[ADD]], ptr [[C_SINK]], align 1
; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i16 [[IV]], 1
; CHECK-NEXT: [[TOBOOL_NOT:%.*]] = icmp eq i16 [[IV_NEXT]], 1000
; CHECK-NEXT: br i1 [[TOBOOL_NOT]], label [[FOR_END_LOOPEXIT:%.*]], label [[FOR_BODY]]
; CHECK-NEXT: [[IV_NEXT1]] = add nuw nsw i16 [[IV1]], 1
; CHECK-NEXT: [[TOBOOL_NOT:%.*]] = icmp eq i16 [[IV_NEXT1]], 1000
; CHECK-NEXT: br i1 [[TOBOOL_NOT]], label [[FOR_END_LOOPEXIT_LOOPEXIT6:%.*]], label [[FOR_BODY1]]
; CHECK: for.end.loopexit.loopexit:
; CHECK-NEXT: br label [[FOR_END_LOOPEXIT:%.*]]
; CHECK: for.end.loopexit.loopexit6:
; CHECK-NEXT: br label [[FOR_END_LOOPEXIT]]
; CHECK: for.end.loopexit:
; CHECK-NEXT: ret void
;
Expand All @@ -33,7 +80,7 @@ for.body: ; preds = %if.end, %entry
%iv = phi i16 [ 0, %entry ], [ %iv.next, %if.end ]
%lv = load i16, ptr %A, align 1
store i16 %lv, ptr %A, align 1
br i1 %c, label %if.then, label %if.end
br i1 %cond, label %if.then, label %if.end

if.then: ; preds = %for.body
%lv2 = load i16, ptr %A, align 1
Expand All @@ -55,66 +102,21 @@ for.end.loopexit: ; preds = %if.end
define void @phi_load_distribute(i1 %cond, ptr %A, ptr %B, ptr %C) {
; CHECK-LABEL: @phi_load_distribute(
; CHECK-NEXT: entry:
; CHECK-NEXT: br label [[FOR_BODY_LVER_CHECK:%.*]]
; CHECK: for.body.lver.check:
; CHECK-NEXT: [[SCEVGEP:%.*]] = getelementptr i8, ptr [[A:%.*]], i64 2
; CHECK-NEXT: [[SCEVGEP1:%.*]] = getelementptr i8, ptr [[C:%.*]], i64 2
; CHECK-NEXT: [[SCEVGEP2:%.*]] = getelementptr i8, ptr [[B:%.*]], i64 2
; CHECK-NEXT: [[BOUND0:%.*]] = icmp ult ptr [[A]], [[SCEVGEP1]]
; CHECK-NEXT: [[BOUND1:%.*]] = icmp ult ptr [[C]], [[SCEVGEP]]
; CHECK-NEXT: [[FOUND_CONFLICT:%.*]] = and i1 [[BOUND0]], [[BOUND1]]
; CHECK-NEXT: [[BOUND03:%.*]] = icmp ult ptr [[A]], [[SCEVGEP2]]
; CHECK-NEXT: [[BOUND14:%.*]] = icmp ult ptr [[B]], [[SCEVGEP]]
; CHECK-NEXT: [[FOUND_CONFLICT5:%.*]] = and i1 [[BOUND03]], [[BOUND14]]
; CHECK-NEXT: [[CONFLICT_RDX:%.*]] = or i1 [[FOUND_CONFLICT]], [[FOUND_CONFLICT5]]
; CHECK-NEXT: br i1 [[CONFLICT_RDX]], label [[FOR_BODY_PH_LVER_ORIG:%.*]], label [[FOR_BODY_PH_LDIST1:%.*]]
; CHECK: for.body.ph.lver.orig:
; CHECK-NEXT: br label [[FOR_BODY_LVER_ORIG:%.*]]
; CHECK: for.body.lver.orig:
; CHECK-NEXT: [[IV_LVER_ORIG:%.*]] = phi i16 [ 0, [[FOR_BODY_PH_LVER_ORIG]] ], [ [[IV_NEXT_LVER_ORIG:%.*]], [[IF_END_LVER_ORIG:%.*]] ]
; CHECK-NEXT: [[LV_LVER_ORIG:%.*]] = load i16, ptr [[A]], align 1
; CHECK: for.body:
; CHECK-NEXT: [[IV_LVER_ORIG:%.*]] = phi i16 [ 0, [[FOR_BODY_PH_LVER_ORIG:%.*]] ], [ [[IV_NEXT_LVER_ORIG:%.*]], [[IF_END_LVER_ORIG:%.*]] ]
; CHECK-NEXT: [[LV_LVER_ORIG:%.*]] = load i16, ptr [[A:%.*]], align 1
; CHECK-NEXT: store i16 [[LV_LVER_ORIG]], ptr [[A]], align 1
; CHECK-NEXT: br i1 [[COND:%.*]], label [[IF_THEN_LVER_ORIG:%.*]], label [[IF_END_LVER_ORIG]]
; CHECK: if.then.lver.orig:
; CHECK-NEXT: [[LV2_LVER_ORIG:%.*]] = load i16, ptr [[A]], align 1
; CHECK-NEXT: br label [[IF_END_LVER_ORIG]]
; CHECK: if.end.lver.orig:
; CHECK-NEXT: [[C_SINK_LVER_ORIG:%.*]] = phi ptr [ [[B]], [[IF_THEN_LVER_ORIG]] ], [ [[C]], [[FOR_BODY_LVER_ORIG]] ]
; CHECK-NEXT: [[LV3_LVER_ORIG:%.*]] = load i16, ptr [[C_SINK_LVER_ORIG]], align 2
; CHECK-NEXT: [[IV_NEXT_LVER_ORIG]] = add nuw nsw i16 [[IV_LVER_ORIG]], 1
; CHECK-NEXT: [[TOBOOL_NOT_LVER_ORIG:%.*]] = icmp eq i16 [[IV_NEXT_LVER_ORIG]], 1000
; CHECK-NEXT: br i1 [[TOBOOL_NOT_LVER_ORIG]], label [[FOR_END_LOOPEXIT_LOOPEXIT:%.*]], label [[FOR_BODY_LVER_ORIG]]
; CHECK: for.body.ph.ldist1:
; CHECK-NEXT: br label [[FOR_BODY_LDIST1:%.*]]
; CHECK: for.body.ldist1:
; CHECK-NEXT: [[IV_LDIST1:%.*]] = phi i16 [ 0, [[FOR_BODY_PH_LDIST1]] ], [ [[IV_NEXT_LDIST1:%.*]], [[IF_END_LDIST1:%.*]] ]
; CHECK-NEXT: [[LV_LDIST1:%.*]] = load i16, ptr [[A]], align 1, !alias.scope [[META0:![0-9]+]], !noalias [[META3:![0-9]+]]
; CHECK-NEXT: store i16 [[LV_LDIST1]], ptr [[A]], align 1, !alias.scope [[META0]], !noalias [[META3]]
; CHECK-NEXT: br i1 [[COND]], label [[IF_THEN_LDIST1:%.*]], label [[IF_END_LDIST1]]
; CHECK: if.then.ldist1:
; CHECK-NEXT: [[LV2_LDIST1:%.*]] = load i16, ptr [[A]], align 1, !alias.scope [[META0]], !noalias [[META3]]
; CHECK-NEXT: br label [[IF_END_LDIST1]]
; CHECK: if.end.ldist1:
; CHECK-NEXT: [[IV_NEXT_LDIST1]] = add nuw nsw i16 [[IV_LDIST1]], 1
; CHECK-NEXT: [[TOBOOL_NOT_LDIST1:%.*]] = icmp eq i16 [[IV_NEXT_LDIST1]], 1000
; CHECK-NEXT: br i1 [[TOBOOL_NOT_LDIST1]], label [[FOR_BODY_PH:%.*]], label [[FOR_BODY_LDIST1]]
; CHECK: for.body.ph:
; CHECK-NEXT: br label [[FOR_BODY:%.*]]
; CHECK: for.body:
; CHECK-NEXT: [[IV:%.*]] = phi i16 [ 0, [[FOR_BODY_PH]] ], [ [[IV_NEXT:%.*]], [[IF_END:%.*]] ]
; CHECK-NEXT: br i1 [[COND]], label [[IF_THEN:%.*]], label [[IF_END]]
; CHECK: if.then:
; CHECK-NEXT: br label [[IF_END]]
; CHECK-NEXT: [[LV2:%.*]] = load i16, ptr [[A]], align 1
; CHECK-NEXT: br label [[IF_END_LVER_ORIG]]
; CHECK: if.end:
; CHECK-NEXT: [[C_SINK:%.*]] = phi ptr [ [[B]], [[IF_THEN]] ], [ [[C]], [[FOR_BODY]] ]
; CHECK-NEXT: [[C_SINK:%.*]] = phi ptr [ [[B:%.*]], [[IF_THEN_LVER_ORIG]] ], [ [[C:%.*]], [[FOR_BODY_LVER_ORIG]] ]
; CHECK-NEXT: [[LV3:%.*]] = load i16, ptr [[C_SINK]], align 2
; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i16 [[IV]], 1
; CHECK-NEXT: [[TOBOOL_NOT:%.*]] = icmp eq i16 [[IV_NEXT]], 1000
; CHECK-NEXT: br i1 [[TOBOOL_NOT]], label [[FOR_END_LOOPEXIT_LOOPEXIT6:%.*]], label [[FOR_BODY]]
; CHECK: for.end.loopexit.loopexit:
; CHECK-NEXT: br label [[FOR_END_LOOPEXIT:%.*]]
; CHECK: for.end.loopexit.loopexit6:
; CHECK-NEXT: br label [[FOR_END_LOOPEXIT]]
; CHECK-NEXT: [[IV_NEXT_LVER_ORIG]] = add nuw nsw i16 [[IV_LVER_ORIG]], 1
; CHECK-NEXT: [[TOBOOL_NOT:%.*]] = icmp eq i16 [[IV_NEXT_LVER_ORIG]], 1000
; CHECK-NEXT: br i1 [[TOBOOL_NOT]], label [[FOR_END_LOOPEXIT:%.*]], label [[FOR_BODY_LVER_ORIG]]
; CHECK: for.end.loopexit:
; CHECK-NEXT: ret void
;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
; RUN: opt -passes=loop-distribute -enable-loop-distribute \
; RUN: -debug-only=loop-distribute -disable-output 2>&1 %s | FileCheck %s

define void @ldist(i1 %c, ptr %A, ptr %B, ptr %C) {
define void @ldist(i1 %cond, ptr %A, ptr %B, ptr %C) {
entry:
br label %for.body

for.body: ; preds = %if.end, %entry
%iv = phi i16 [ 0, %entry ], [ %iv.next, %if.end ]
%lv = load i16, ptr %A, align 1
store i16 %lv, ptr %A, align 1
br i1 %c, label %if.then, label %if.end
br i1 %cond, label %if.then, label %if.end

if.then: ; preds = %for.body
%lv2 = load i16, ptr %A, align 1
Expand All @@ -18,6 +18,8 @@ if.then: ; preds = %for.body
if.end: ; preds = %if.then, %for.body
%c.sink = phi ptr [ %B, %if.then ], [ %C, %for.body ]
%lv3 = load i16, ptr %c.sink
%add = add i16 %lv3, 10
store i16 %add, ptr %c.sink, align 1
%iv.next = add nuw nsw i16 %iv, 1
%tobool.not = icmp eq i16 %iv.next, 1000
br i1 %tobool.not, label %for.end.loopexit, label %for.body
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,51 +2,55 @@
; RUN: opt -passes=loop-distribute -enable-loop-distribute \
; RUN: -debug-only=loop-distribute -disable-output 2>&1 %s | FileCheck %s

define void @ldist(i1 %c, ptr %A, ptr %B, ptr %C) {
define void @ldist(i1 %cond, ptr %A, ptr %B, ptr %C) {
; CHECK-LABEL: 'ldist'
; CHECK-NEXT: LDist: Found a candidate loop: for.body
; CHECK-NEXT: LDist: Backward dependences:
; CHECK-NEXT: Unknown:
; CHECK-NEXT: %lv = load i16, ptr %A, align 1 ->
; CHECK-NEXT: store i16 %lv, ptr %A, align 1
; CHECK-NEXT: %lv3 = load i16, ptr %c.sink, align 2 ->
; CHECK-NEXT: store i16 %add, ptr %c.sink, align 1
; CHECK-NEXT: Unknown:
; CHECK-NEXT: store i16 %lv, ptr %A, align 1 ->
; CHECK-NEXT: %lv2 = load i16, ptr %A, align 1
; CHECK-NEXT: %lv3 = load i16, ptr %c.sink, align 2 ->
; CHECK-NEXT: store i16 %add, ptr %c.sink, align 1
; CHECK-NEXT: LDist: Seeded partitions:
; CHECK-NEXT: LDist: Partition 0: (cycle)
; CHECK-NEXT: LDist: Partition 0:
; CHECK-NEXT: for.body: %lv = load i16, ptr %A, align 1
; CHECK-NEXT: for.body: store i16 %lv, ptr %A, align 1
; CHECK-NEXT: if.then: %lv2 = load i16, ptr %A, align 1
; CHECK-NEXT: LDist: Partition 1:
; CHECK-NEXT: if.end: %lv3 = load i16, ptr %c.sink, align 2
; CHECK-NEXT: for.body: store i16 %lv, ptr %A, align 1
; CHECK-NEXT: LDist: Partition 2:
; CHECK-NEXT: if.then: %lv2 = load i16, ptr %A, align 1
; CHECK-NEXT: LDist: Partition 3: (cycle)
; CHECK-NEXT: if.end: %lv3 = load i16, ptr %c.sink, align 2
; CHECK-NEXT: if.end: store i16 %add, ptr %c.sink, align 1
; CHECK-NEXT: LDist: Merged partitions:
; CHECK-NEXT: LDist: Partition 0: (cycle)
; CHECK-NEXT: LDist: Partition 0:
; CHECK-NEXT: for.body: %lv = load i16, ptr %A, align 1
; CHECK-NEXT: for.body: store i16 %lv, ptr %A, align 1
; CHECK-NEXT: if.then: %lv2 = load i16, ptr %A, align 1
; CHECK-NEXT: LDist: Partition 1:
; CHECK-NEXT: LDist: Partition 1: (cycle)
; CHECK-NEXT: if.end: %lv3 = load i16, ptr %c.sink, align 2
; CHECK-NEXT: if.end: store i16 %add, ptr %c.sink, align 1
; CHECK-NEXT: LDist: Populated partitions:
; CHECK-NEXT: LDist: Partition 0: (cycle)
; CHECK-NEXT: LDist: Partition 0:
; CHECK-NEXT: for.body: %lv = load i16, ptr %A, align 1
; CHECK-NEXT: for.body: store i16 %lv, ptr %A, align 1
; CHECK-NEXT: if.then: %lv2 = load i16, ptr %A, align 1
; CHECK-NEXT: for.body: br i1 %c, label %if.then, label %if.end
; CHECK-NEXT: for.body: br i1 %cond, label %if.then, label %if.end
; CHECK-NEXT: if.then: br label %if.end
; CHECK-NEXT: if.end: br i1 %tobool.not, label %for.end.loopexit, label %for.body
; CHECK-NEXT: if.end: %tobool.not = icmp eq i16 %iv.next, 1000
; CHECK-NEXT: if.end: %iv.next = add nuw nsw i16 %iv, 1
; CHECK-NEXT: for.body: %iv = phi i16 [ 0, %entry ], [ %iv.next, %if.end ]
; CHECK-NEXT: LDist: Partition 1:
; CHECK-NEXT: LDist: Partition 1: (cycle)
; CHECK-NEXT: if.end: %lv3 = load i16, ptr %c.sink, align 2
; CHECK-NEXT: for.body: br i1 %c, label %if.then, label %if.end
; CHECK-NEXT: if.end: store i16 %add, ptr %c.sink, align 1
; CHECK-NEXT: for.body: br i1 %cond, label %if.then, label %if.end
; CHECK-NEXT: if.then: br label %if.end
; CHECK-NEXT: if.end: br i1 %tobool.not, label %for.end.loopexit, label %for.body
; CHECK-NEXT: if.end: %tobool.not = icmp eq i16 %iv.next, 1000
; CHECK-NEXT: if.end: %iv.next = add nuw nsw i16 %iv, 1
; CHECK-NEXT: for.body: %iv = phi i16 [ 0, %entry ], [ %iv.next, %if.end ]
; CHECK-NEXT: if.end: %add = add i16 %lv3, 10
; CHECK-NEXT: if.end: %c.sink = phi ptr [ %B, %if.then ], [ %C, %for.body ]
; CHECK-NEXT: LDist: Distributing loop: for.body
; CHECK-NEXT: LDist: Pointers:
Expand All @@ -56,19 +60,21 @@ define void @ldist(i1 %c, ptr %A, ptr %B, ptr %C) {
; CHECK-NEXT: ptr %A
; CHECK-NEXT: Against group ([[GRP2:0x[0-9a-f]+]]):
; CHECK-NEXT: ptr %C
; CHECK-NEXT: ptr %C
; CHECK-NEXT: Check 1:
; CHECK-NEXT: Comparing group ([[GRP1]]):
; CHECK-NEXT: ptr %A
; CHECK-NEXT: ptr %A
; CHECK-NEXT: Against group ([[GRP3:0x[0-9a-f]+]]):
; CHECK-NEXT: ptr %B
; CHECK-NEXT: ptr %B
; CHECK-NEXT: LDist: After removing unused Instrs:
; CHECK-NEXT: LDist: Partition 0:
; CHECK-NEXT: for.body.ldist1: ; preds = %if.end.ldist1, %for.body.ph.ldist1
; CHECK-NEXT: %iv.ldist1 = phi i16 [ 0, %for.body.ph.ldist1 ], [ %iv.next.ldist1, %if.end.ldist1 ]
; CHECK-NEXT: %lv.ldist1 = load i16, ptr %A, align 1, !alias.scope !0, !noalias !3
; CHECK-NEXT: store i16 %lv.ldist1, ptr %A, align 1, !alias.scope !0, !noalias !3
; CHECK-NEXT: br i1 %c, label %if.then.ldist1, label %if.end.ldist1
; CHECK-NEXT: br i1 %cond, label %if.then.ldist1, label %if.end.ldist1
; CHECK-EMPTY:
; CHECK-NEXT: if.then.ldist1: ; preds = %for.body.ldist1
; CHECK-NEXT: %lv2.ldist1 = load i16, ptr %A, align 1, !alias.scope !0, !noalias !3
Expand All @@ -81,14 +87,16 @@ define void @ldist(i1 %c, ptr %A, ptr %B, ptr %C) {
; CHECK-NEXT: LDist: Partition 1:
; CHECK-NEXT: for.body: ; preds = %if.end, %for.body.ph
; CHECK-NEXT: %iv = phi i16 [ 0, %for.body.ph ], [ %iv.next, %if.end ]
; CHECK-NEXT: br i1 %c, label %if.then, label %if.end
; CHECK-NEXT: br i1 %cond, label %if.then, label %if.end
; CHECK-EMPTY:
; CHECK-NEXT: if.then: ; preds = %for.body
; CHECK-NEXT: br label %if.end
; CHECK-EMPTY:
; CHECK-NEXT: if.end: ; preds = %if.then, %for.body
; CHECK-NEXT: %c.sink = phi ptr [ %B, %if.then ], [ %C, %for.body ]
; CHECK-NEXT: %lv3 = load i16, ptr %c.sink, align 2
; CHECK-NEXT: %add = add i16 %lv3, 10
; CHECK-NEXT: store i16 %add, ptr %c.sink, align 1
; CHECK-NEXT: %iv.next = add nuw nsw i16 %iv, 1
; CHECK-NEXT: %tobool.not = icmp eq i16 %iv.next, 1000
; CHECK-NEXT: br i1 %tobool.not, label %for.end.loopexit.loopexit6, label %for.body
Expand All @@ -100,7 +108,7 @@ for.body: ; preds = %if.end, %entry
%iv = phi i16 [ 0, %entry ], [ %iv.next, %if.end ]
%lv = load i16, ptr %A, align 1
store i16 %lv, ptr %A, align 1
br i1 %c, label %if.then, label %if.end
br i1 %cond, label %if.then, label %if.end

if.then: ; preds = %for.body
%lv2 = load i16, ptr %A, align 1
Expand All @@ -109,6 +117,8 @@ if.then: ; preds = %for.body
if.end: ; preds = %if.then, %for.body
%c.sink = phi ptr [ %B, %if.then ], [ %C, %for.body ]
%lv3 = load i16, ptr %c.sink
%add = add i16 %lv3, 10
store i16 %add, ptr %c.sink, align 1
%iv.next = add nuw nsw i16 %iv, 1
%tobool.not = icmp eq i16 %iv.next, 1000
br i1 %tobool.not, label %for.end.loopexit, label %for.body
Expand Down
Loading