llvm.org GIT mirror llvm / da1c0f6
[LFTR] Use SCEVExpander for the pointer limit case instead of manual IR gen As noted in the test change, this is not trivially NFC, but all of the changes in output are cases where the SCEVExpander form is more canonical/optimal than the hand generation. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@365075 91177308-0d34-0410-b5e6-96231b3b80d8 Philip Reames 2 months ago
6 changed file(s) with 20 addition(s) and 28 deletion(s). Raw diff Collapse all Expand all
23282328 // Expand the code for the iteration count.
23292329 assert(SE->isLoopInvariant(IVOffset, L) &&
23302330 "Computed iteration count is not loop invariant!");
2331 BranchInst *BI = cast(ExitingBB->getTerminator());
2332 Value *GEPOffset = Rewriter.expandCodeFor(IVOffset, OfsTy, BI);
2333
2334 Value *GEPBase = IndVar->getIncomingValueForBlock(L->getLoopPreheader());
2335 assert(AR->getStart() == SE->getSCEV(GEPBase) && "bad loop counter");
2331
23362332 // We could handle pointer IVs other than i8*, but we need to compensate for
23372333 // gep index scaling.
23382334 assert(SE->getSizeOfExpr(IntegerType::getInt64Ty(IndVar->getContext()),
2339 cast(GEPBase->getType())
2335 cast(IndVar->getType())
23402336 ->getElementType())->isOne() &&
23412337 "unit stride pointer IV must be i8*");
23422338
2343 IRBuilder<> Builder(L->getLoopPreheader()->getTerminator());
2344 return Builder.CreateGEP(GEPBase->getType()->getPointerElementType(),
2345 GEPBase, GEPOffset, "lftr.limit");
2339 const SCEV *IVLimit = SE->getAddExpr(IVInit, IVOffset);
2340 BranchInst *BI = cast(ExitingBB->getTerminator());
2341 return Rewriter.expandCodeFor(IVLimit, IndVar->getType(), BI);
23462342 } else {
23472343 // In any other case, convert both IVInit and ExitCount to integers before
23482344 // comparing. This may result in SCEV expansion of pointers, but in practice
23782374 IVLimit = SE->getAddExpr(IVLimit, SE->getOne(IVLimit->getType()));
23792375
23802376 // Expand the code for the iteration count.
2381 BranchInst *BI = cast(ExitingBB->getTerminator());
2382 IRBuilder<> Builder(BI);
23832377 assert(SE->isLoopInvariant(IVLimit, L) &&
23842378 "Computed iteration count is not loop invariant!");
23852379 // Ensure that we generate the same type as IndVar, or a smaller integer
23872381 // SCEV expression (IVInit) for a pointer type IV value (IndVar).
23882382 Type *LimitTy = ExitCount->getType()->isPointerTy() ?
23892383 IndVar->getType() : ExitCount->getType();
2384 BranchInst *BI = cast(ExitingBB->getTerminator());
23902385 return Rewriter.expandCodeFor(IVLimit, LimitTy, BI);
23912386 }
23922387 }
149149 ; PTR64-NEXT: [[TMP2:%.*]] = sub i32 [[TMP1]], [[BI]]
150150 ; PTR64-NEXT: [[TMP3:%.*]] = zext i32 [[TMP2]] to i64
151151 ; PTR64-NEXT: [[TMP4:%.*]] = add nuw nsw i64 [[TMP3]], 1
152 ; PTR64-NEXT: [[LFTR_LIMIT:%.*]] = getelementptr i8, i8* null, i64 [[TMP4]]
152 ; PTR64-NEXT: [[TMP5:%.*]] = inttoptr i64 [[TMP4]] to i8*
153153 ; PTR64-NEXT: br label [[LOOP:%.*]]
154154 ; PTR64: loop:
155155 ; PTR64-NEXT: [[P_01_US_US:%.*]] = phi i8* [ null, [[PREHEADER]] ], [ [[GEP:%.*]], [[LOOP]] ]
156156 ; PTR64-NEXT: [[GEP]] = getelementptr inbounds i8, i8* [[P_01_US_US]], i64 1
157157 ; PTR64-NEXT: [[SNEXT:%.*]] = load i8, i8* [[GEP]]
158 ; PTR64-NEXT: [[EXITCOND:%.*]] = icmp ne i8* [[GEP]], [[LFTR_LIMIT]]
158 ; PTR64-NEXT: [[EXITCOND:%.*]] = icmp ne i8* [[GEP]], [[TMP5]]
159159 ; PTR64-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
160160 ; PTR64: exit.loopexit:
161161 ; PTR64-NEXT: [[SNEXT_LCSSA:%.*]] = phi i8 [ [[SNEXT]], [[LOOP]] ]
170170 ; PTR32-NEXT: [[BI:%.*]] = ptrtoint i8* [[BUF:%.*]] to i32
171171 ; PTR32-NEXT: [[EI:%.*]] = ptrtoint i8* [[END:%.*]] to i32
172172 ; PTR32-NEXT: [[CNT:%.*]] = sub i32 [[EI]], [[BI]]
173 ; PTR32-NEXT: [[CNT1:%.*]] = inttoptr i32 [[CNT]] to i8*
173174 ; PTR32-NEXT: [[GUARD:%.*]] = icmp ult i32 0, [[CNT]]
174175 ; PTR32-NEXT: br i1 [[GUARD]], label [[PREHEADER:%.*]], label [[EXIT:%.*]]
175176 ; PTR32: preheader:
176 ; PTR32-NEXT: [[LFTR_LIMIT:%.*]] = getelementptr i8, i8* null, i32 [[CNT]]
177177 ; PTR32-NEXT: br label [[LOOP:%.*]]
178178 ; PTR32: loop:
179179 ; PTR32-NEXT: [[P_01_US_US:%.*]] = phi i8* [ null, [[PREHEADER]] ], [ [[GEP:%.*]], [[LOOP]] ]
180180 ; PTR32-NEXT: [[GEP]] = getelementptr inbounds i8, i8* [[P_01_US_US]], i64 1
181181 ; PTR32-NEXT: [[SNEXT:%.*]] = load i8, i8* [[GEP]]
182 ; PTR32-NEXT: [[EXITCOND:%.*]] = icmp ne i8* [[GEP]], [[LFTR_LIMIT]]
182 ; PTR32-NEXT: [[EXITCOND:%.*]] = icmp ne i8* [[GEP]], [[CNT1]]
183183 ; PTR32-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
184184 ; PTR32: exit.loopexit:
185185 ; PTR32-NEXT: [[SNEXT_LCSSA:%.*]] = phi i8 [ [[SNEXT]], [[LOOP]] ]
1010 ; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i8 addrspace(2)* [[BASE]], [[ADD_PTR]]
1111 ; CHECK-NEXT: br i1 [[CMP1]], label [[FOR_BODY_PREHEADER:%.*]], label [[FOR_END:%.*]]
1212 ; CHECK: for.body.preheader:
13 ; CHECK-NEXT: [[LFTR_LIMIT:%.*]] = getelementptr i8, i8 addrspace(2)* [[BASE]], i8 [[IDX_TRUNC]]
1413 ; CHECK-NEXT: br label [[FOR_BODY:%.*]]
1514 ; CHECK: for.body:
1615 ; CHECK-NEXT: [[P_02:%.*]] = phi i8 addrspace(2)* [ [[INCDEC_PTR:%.*]], [[FOR_BODY]] ], [ [[BASE]], [[FOR_BODY_PREHEADER]] ]
1918 ; CHECK-NEXT: [[SUB_PTR_SUB:%.*]] = sub i8 [[SUB_PTR_LHS_CAST]], [[SUB_PTR_RHS_CAST]]
2019 ; CHECK-NEXT: store i8 [[SUB_PTR_SUB]], i8 addrspace(2)* [[P_02]]
2120 ; CHECK-NEXT: [[INCDEC_PTR]] = getelementptr inbounds i8, i8 addrspace(2)* [[P_02]], i32 1
22 ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i8 addrspace(2)* [[INCDEC_PTR]], [[LFTR_LIMIT]]
21 ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i8 addrspace(2)* [[INCDEC_PTR]], [[ADD_PTR]]
2322 ; CHECK-NEXT: br i1 [[EXITCOND]], label [[FOR_BODY]], label [[FOR_END_LOOPEXIT:%.*]]
2423 ; CHECK: for.end.loopexit:
2524 ; CHECK-NEXT: br label [[FOR_END]]
5756 ; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i8 addrspace(3)* [[BASE]], [[ADD_PTR]]
5857 ; CHECK-NEXT: br i1 [[CMP1]], label [[FOR_BODY_PREHEADER:%.*]], label [[FOR_END:%.*]]
5958 ; CHECK: for.body.preheader:
60 ; CHECK-NEXT: [[LFTR_LIMIT:%.*]] = getelementptr i8, i8 addrspace(3)* [[BASE]], i16 [[IDX_TRUNC]]
6159 ; CHECK-NEXT: br label [[FOR_BODY:%.*]]
6260 ; CHECK: for.body:
6361 ; CHECK-NEXT: [[P_02:%.*]] = phi i8 addrspace(3)* [ [[INCDEC_PTR:%.*]], [[FOR_BODY]] ], [ [[BASE]], [[FOR_BODY_PREHEADER]] ]
6765 ; CHECK-NEXT: [[CONV:%.*]] = trunc i16 [[SUB_PTR_SUB]] to i8
6866 ; CHECK-NEXT: store i8 [[CONV]], i8 addrspace(3)* [[P_02]]
6967 ; CHECK-NEXT: [[INCDEC_PTR]] = getelementptr inbounds i8, i8 addrspace(3)* [[P_02]], i32 1
70 ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i8 addrspace(3)* [[INCDEC_PTR]], [[LFTR_LIMIT]]
68 ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i8 addrspace(3)* [[INCDEC_PTR]], [[ADD_PTR]]
7169 ; CHECK-NEXT: br i1 [[EXITCOND]], label [[FOR_BODY]], label [[FOR_END_LOOPEXIT:%.*]]
7270 ; CHECK: for.end.loopexit:
7371 ; CHECK-NEXT: br label [[FOR_END]]
111111 ; CHECK-NEXT: [[P_0:%.*]] = phi i8* [ getelementptr inbounds ([240 x i8], [240 x i8]* @data, i64 0, i64 0), [[ENTRY:%.*]] ], [ [[TMP3:%.*]], [[LOOP]] ]
112112 ; CHECK-NEXT: store volatile i8 0, i8* [[P_0]]
113113 ; CHECK-NEXT: [[TMP3]] = getelementptr inbounds i8, i8* [[P_0]], i64 1
114 ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i8* [[P_0]], getelementptr (i8, i8* getelementptr inbounds ([240 x i8], [240 x i8]* @data, i64 0, i64 0), i64 245)
114 ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i8* [[P_0]], getelementptr ([240 x i8], [240 x i8]* @data, i64 1, i64 5)
115115 ; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]]
116116 ; CHECK: exit:
117117 ; CHECK-NEXT: ret void
140140 ; CHECK-NEXT: [[P_0:%.*]] = phi i8* [ getelementptr inbounds ([240 x i8], [240 x i8]* @data, i64 0, i64 0), [[ENTRY:%.*]] ], [ [[TMP3:%.*]], [[LOOP]] ]
141141 ; CHECK-NEXT: [[TMP3]] = getelementptr inbounds i8, i8* [[P_0]], i64 1
142142 ; CHECK-NEXT: store volatile i8 0, i8* [[TMP3]]
143 ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i8* [[TMP3]], getelementptr (i8, i8* getelementptr inbounds ([240 x i8], [240 x i8]* @data, i64 0, i64 0), i64 246)
143 ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i8* [[TMP3]], getelementptr ([240 x i8], [240 x i8]* @data, i64 1, i64 6)
144144 ; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]]
145145 ; CHECK: exit:
146146 ; CHECK-NEXT: ret void
169169 ; CHECK-NEXT: [[P_0:%.*]] = phi i8* [ getelementptr inbounds ([240 x i8], [240 x i8]* @data, i64 0, i64 0), [[ENTRY:%.*]] ], [ [[TMP3:%.*]], [[LOOP]] ]
170170 ; CHECK-NEXT: [[TMP3]] = getelementptr inbounds i8, i8* [[P_0]], i64 1
171171 ; CHECK-NEXT: [[V:%.*]] = load i8, i8* [[TMP3]]
172 ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i8* [[TMP3]], getelementptr (i8, i8* getelementptr inbounds ([240 x i8], [240 x i8]* @data, i64 0, i64 0), i64 246)
172 ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i8* [[TMP3]], getelementptr ([240 x i8], [240 x i8]* @data, i64 1, i64 6)
173173 ; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]]
174174 ; CHECK: exit:
175175 ; CHECK-NEXT: [[V_LCSSA:%.*]] = phi i8 [ [[V]], [[LOOP]] ]
4444 ; CHECK-NEXT: [[TMP1:%.*]] = sub i3 -1, [[TMP0]]
4545 ; CHECK-NEXT: [[TMP2:%.*]] = zext i3 [[TMP1]] to i64
4646 ; CHECK-NEXT: [[TMP3:%.*]] = add nuw nsw i64 [[TMP2]], 1
47 ; CHECK-NEXT: [[LFTR_LIMIT:%.*]] = getelementptr i8, i8* getelementptr inbounds ([256 x i8], [256 x i8]* @data, i64 0, i64 0), i64 [[TMP3]]
47 ; CHECK-NEXT: [[SCEVGEP:%.*]] = getelementptr [256 x i8], [256 x i8]* @data, i64 0, i64 [[TMP3]]
4848 ; CHECK-NEXT: br label [[LOOP:%.*]]
4949 ; CHECK: loop:
5050 ; CHECK-NEXT: [[P:%.*]] = phi i8* [ getelementptr inbounds ([256 x i8], [256 x i8]* @data, i64 0, i64 0), [[ENTRY:%.*]] ], [ [[P_INC:%.*]], [[LOOP]] ]
5151 ; CHECK-NEXT: [[P_INC]] = getelementptr inbounds i8, i8* [[P]], i64 1
5252 ; CHECK-NEXT: store volatile i8 0, i8* [[P_INC]]
53 ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp eq i8* [[P_INC]], [[LFTR_LIMIT]]
53 ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp eq i8* [[P_INC]], [[SCEVGEP]]
5454 ; CHECK-NEXT: br i1 [[EXITCOND]], label [[END:%.*]], label [[LOOP]]
5555 ; CHECK: end:
5656 ; CHECK-NEXT: ret void
1919 ; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i8* [[BASE]], [[ADD_PTR]]
2020 ; CHECK-NEXT: br i1 [[CMP1]], label [[FOR_BODY_PREHEADER:%.*]], label [[FOR_END:%.*]]
2121 ; CHECK: for.body.preheader:
22 ; CHECK-NEXT: [[LFTR_LIMIT:%.*]] = getelementptr i8, i8* [[BASE]], i64 [[IDX_EXT]]
2322 ; CHECK-NEXT: br label [[FOR_BODY:%.*]]
2423 ; CHECK: for.body:
2524 ; CHECK-NEXT: [[P_02:%.*]] = phi i8* [ [[INCDEC_PTR:%.*]], [[FOR_BODY]] ], [ [[BASE]], [[FOR_BODY_PREHEADER]] ]
2928 ; CHECK-NEXT: [[CONV:%.*]] = trunc i64 [[SUB_PTR_SUB]] to i8
3029 ; CHECK-NEXT: store i8 [[CONV]], i8* [[P_02]]
3130 ; CHECK-NEXT: [[INCDEC_PTR]] = getelementptr inbounds i8, i8* [[P_02]], i32 1
32 ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i8* [[INCDEC_PTR]], [[LFTR_LIMIT]]
31 ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i8* [[INCDEC_PTR]], [[ADD_PTR]]
3332 ; CHECK-NEXT: br i1 [[EXITCOND]], label [[FOR_BODY]], label [[FOR_END_LOOPEXIT:%.*]]
3433 ; CHECK: for.end.loopexit:
3534 ; CHECK-NEXT: br label [[FOR_END]]
302301 ; CHECK-NEXT: br i1 [[CMP_PH]], label [[LOOP_PREHEADER:%.*]], label [[EXIT:%.*]]
303302 ; CHECK: loop.preheader:
304303 ; CHECK-NEXT: [[TMP0:%.*]] = sext i32 [[N]] to i64
305 ; CHECK-NEXT: [[LFTR_LIMIT:%.*]] = getelementptr i8, i8* [[IVSTART]], i64 [[TMP0]]
304 ; CHECK-NEXT: [[SCEVGEP:%.*]] = getelementptr [256 x i8], [256 x i8]* [[BASE]], i64 0, i64 [[TMP0]]
306305 ; CHECK-NEXT: br label [[LOOP:%.*]]
307306 ; CHECK: loop:
308307 ; CHECK-NEXT: [[APTR:%.*]] = phi i8* [ [[INCDEC_PTR:%.*]], [[LOOP]] ], [ [[IVSTART]], [[LOOP_PREHEADER]] ]
309308 ; CHECK-NEXT: [[INCDEC_PTR]] = getelementptr inbounds i8, i8* [[APTR]], i32 1
310309 ; CHECK-NEXT: store i8 3, i8* [[APTR]]
311 ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i8* [[INCDEC_PTR]], [[LFTR_LIMIT]]
310 ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i8* [[INCDEC_PTR]], [[SCEVGEP]]
312311 ; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
313312 ; CHECK: exit.loopexit:
314313 ; CHECK-NEXT: br label [[EXIT]]