Skip to content

Commit 8ade3d4

Browse files
Revert "[LoopInterchange] Remove a limitation in LoopInterchange legality"
This reverts commit 15702ff while I investigate a ppc build bot failure at https://lab.llvm.org/buildbot#builders/36/builds/16051.
1 parent 3988a06 commit 8ade3d4

File tree

4 files changed

+86
-21
lines changed

4 files changed

+86
-21
lines changed

llvm/lib/Transforms/Scalar/LoopInterchange.cpp

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -887,6 +887,78 @@ bool LoopInterchangeLegality::currentLimitations() {
887887
return true;
888888
}
889889

890+
// TODO: Current limitation: Since we split the inner loop latch at the point
891+
// were induction variable is incremented (induction.next); We cannot have
892+
// more than 1 user of induction.next since it would result in broken code
893+
// after split.
894+
// e.g.
895+
// for(i=0;i<N;i++) {
896+
// for(j = 0;j<M;j++) {
897+
// A[j+1][i+2] = A[j][i]+k;
898+
// }
899+
// }
900+
Instruction *InnerIndexVarInc = nullptr;
901+
if (InnerInductionVar->getIncomingBlock(0) == InnerLoopPreHeader)
902+
InnerIndexVarInc =
903+
dyn_cast<Instruction>(InnerInductionVar->getIncomingValue(1));
904+
else
905+
InnerIndexVarInc =
906+
dyn_cast<Instruction>(InnerInductionVar->getIncomingValue(0));
907+
908+
if (!InnerIndexVarInc) {
909+
LLVM_DEBUG(
910+
dbgs() << "Did not find an instruction to increment the induction "
911+
<< "variable.\n");
912+
ORE->emit([&]() {
913+
return OptimizationRemarkMissed(DEBUG_TYPE, "NoIncrementInInner",
914+
InnerLoop->getStartLoc(),
915+
InnerLoop->getHeader())
916+
<< "The inner loop does not increment the induction variable.";
917+
});
918+
return true;
919+
}
920+
921+
// Since we split the inner loop latch on this induction variable. Make sure
922+
// we do not have any instruction between the induction variable and branch
923+
// instruction.
924+
925+
bool FoundInduction = false;
926+
for (const Instruction &I :
927+
llvm::reverse(InnerLoopLatch->instructionsWithoutDebug())) {
928+
if (isa<BranchInst>(I) || isa<CmpInst>(I) || isa<TruncInst>(I) ||
929+
isa<ZExtInst>(I))
930+
continue;
931+
932+
// We found an instruction. If this is not induction variable then it is not
933+
// safe to split this loop latch.
934+
if (!I.isIdenticalTo(InnerIndexVarInc)) {
935+
LLVM_DEBUG(dbgs() << "Found unsupported instructions between induction "
936+
<< "variable increment and branch.\n");
937+
ORE->emit([&]() {
938+
return OptimizationRemarkMissed(
939+
DEBUG_TYPE, "UnsupportedInsBetweenInduction",
940+
InnerLoop->getStartLoc(), InnerLoop->getHeader())
941+
<< "Found unsupported instruction between induction variable "
942+
"increment and branch.";
943+
});
944+
return true;
945+
}
946+
947+
FoundInduction = true;
948+
break;
949+
}
950+
// The loop latch ended and we didn't find the induction variable return as
951+
// current limitation.
952+
if (!FoundInduction) {
953+
LLVM_DEBUG(dbgs() << "Did not find the induction variable.\n");
954+
ORE->emit([&]() {
955+
return OptimizationRemarkMissed(DEBUG_TYPE, "NoIndutionVariable",
956+
InnerLoop->getStartLoc(),
957+
InnerLoop->getHeader())
958+
<< "Did not find the induction variable.";
959+
});
960+
return true;
961+
}
890962
return false;
891963
}
892964

llvm/test/Transforms/LoopInterchange/currentLimitation.ll

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,19 @@ target triple = "x86_64-unknown-linux-gnu"
1515
@C = common global [100 x [100 x i64]] zeroinitializer
1616

1717
;;--------------------------------------Test case 01------------------------------------
18-
;; This loop can be interchanged with -da-disable-delinearization-checks, otherwise it cannot
19-
;; be interchanged due to dependence.
18+
;; [FIXME] This loop though valid is currently not interchanged due to the limitation that we cannot split the inner loop latch due to multiple use of inner induction
19+
;; variable.(used to increment the loop counter and to access A[j+1][i+1]
2020
;; for(int i=0;i<N-1;i++)
2121
;; for(int j=1;j<N-1;j++)
2222
;; A[j+1][i+1] = A[j+1][i+1] + k;
2323

24+
; IR-LABEL: @interchange_01
25+
; IR-NOT: split
26+
2427
; CHECK: Name: Dependence
2528
; CHECK-NEXT: Function: interchange_01
2629

27-
; DELIN: Name: Interchanged
30+
; DELIN: Name: UnsupportedInsBetweenInduction
2831
; DELIN-NEXT: Function: interchange_01
2932
define void @interchange_01(i32 %k, i32 %N) {
3033
entry:

llvm/test/Transforms/LoopInterchange/interchangeable.ll

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -146,33 +146,23 @@ for.end11:
146146
define void @interchange_10() {
147147
; CHECK-LABEL: @interchange_10(
148148
; CHECK-NEXT: entry:
149-
; CHECK-NEXT: br label [[FOR2_PREHEADER:%.*]]
150-
; CHECK: for1.header.preheader:
151149
; CHECK-NEXT: br label [[FOR1_HEADER:%.*]]
152150
; CHECK: for1.header:
153-
; CHECK-NEXT: [[J23:%.*]] = phi i64 [ [[J_NEXT24:%.*]], [[FOR1_INC10:%.*]] ], [ 1, [[FOR1_HEADER_PREHEADER:%.*]] ]
151+
; CHECK-NEXT: [[J23:%.*]] = phi i64 [ 1, [[ENTRY:%.*]] ], [ [[J_NEXT24:%.*]], [[FOR1_INC10:%.*]] ]
154152
; CHECK-NEXT: [[J_NEXT24]] = add nuw nsw i64 [[J23]], 1
155-
; CHECK-NEXT: br label [[FOR2_SPLIT1:%.*]]
156-
; CHECK: for2.preheader:
157153
; CHECK-NEXT: br label [[FOR2:%.*]]
158154
; CHECK: for2:
159-
; CHECK-NEXT: [[J:%.*]] = phi i64 [ [[TMP0:%.*]], [[FOR2_SPLIT:%.*]] ], [ 1, [[FOR2_PREHEADER]] ]
160-
; CHECK-NEXT: br label [[FOR1_HEADER_PREHEADER]]
161-
; CHECK: for2.split1:
162-
; CHECK-NEXT: [[J_NEXT:%.*]] = add nuw nsw i64 [[J]], 1
155+
; CHECK-NEXT: [[J:%.*]] = phi i64 [ [[J_NEXT:%.*]], [[FOR2]] ], [ 1, [[FOR1_HEADER]] ]
156+
; CHECK-NEXT: [[J_NEXT]] = add nuw nsw i64 [[J]], 1
163157
; CHECK-NEXT: [[ARRAYIDX5:%.*]] = getelementptr inbounds [100 x [100 x i64]], [100 x [100 x i64]]* @A, i64 0, i64 [[J]], i64 [[J23]]
164158
; CHECK-NEXT: store i64 [[J]], i64* [[ARRAYIDX5]]
165159
; CHECK-NEXT: [[ARRAYIDX10:%.*]] = getelementptr inbounds [100 x [100 x i64]], [100 x [100 x i64]]* @A, i64 0, i64 [[J]], i64 [[J_NEXT24]]
166160
; CHECK-NEXT: store i64 [[J23]], i64* [[ARRAYIDX10]]
167161
; CHECK-NEXT: [[EXITCOND:%.*]] = icmp eq i64 [[J]], 99
168-
; CHECK-NEXT: br label [[FOR1_INC10]]
169-
; CHECK: for2.split:
170-
; CHECK-NEXT: [[TMP0]] = add nuw nsw i64 [[J]], 1
171-
; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i64 [[J]], 99
172-
; CHECK-NEXT: br i1 [[TMP1]], label [[FOR_END12:%.*]], label [[FOR2]]
162+
; CHECK-NEXT: br i1 [[EXITCOND]], label [[FOR1_INC10]], label [[FOR2]]
173163
; CHECK: for1.inc10:
174164
; CHECK-NEXT: [[EXITCOND26:%.*]] = icmp eq i64 [[J23]], 98
175-
; CHECK-NEXT: br i1 [[EXITCOND26]], label [[FOR2_SPLIT]], label [[FOR1_HEADER]]
165+
; CHECK-NEXT: br i1 [[EXITCOND26]], label [[FOR_END12:%.*]], label [[FOR1_HEADER]]
176166
; CHECK: for.end12:
177167
; CHECK-NEXT: ret void
178168
;

llvm/test/Transforms/LoopInterchange/loop-interchange-optimization-remarks.ll

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -130,12 +130,12 @@ define void @test02(i32 %k, i32 %N) {
130130
; CHECK-NEXT: - String: Cannot interchange loops due to dependences.
131131
; CHECK-NEXT: ...
132132

133-
; DELIN: --- !Passed
133+
; DELIN: --- !Missed
134134
; DELIN-NEXT: Pass: loop-interchange
135-
; DELIN-NEXT: Name: Interchanged
135+
; DELIN-NEXT: Name: UnsupportedInsBetweenInduction
136136
; DELIN-NEXT: Function: test02
137137
; DELIN-NEXT: Args:
138-
; DELIN-NEXT: - String: Loop interchanged with enclosing loop.
138+
; DELIN-NEXT: - String: Found unsupported instruction between induction variable increment and branch.
139139
; DELIN-NEXT: ...
140140

141141
;;-----------------------------------Test case 03-------------------------------

0 commit comments

Comments
 (0)