llvm.org GIT mirror llvm / f5a309e
Use a sign-extend instead of a zero-extend when promoting a trip count value when the original loop iteration condition is signed and the canonical induction variable won't undergo signed overflow. This isn't required for correctness; it just preserves more information about original loop iteration values. Add a getTruncateOrSignExtend method to ScalarEvolution, following getTruncateOrZeroExtend. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@64918 91177308-0d34-0410-b5e6-96231b3b80d8 Dan Gohman 11 years ago
6 changed file(s) with 96 addition(s) and 19 deletion(s). Raw diff Collapse all Expand all
263263 /// extended, it is zero extended.
264264 SCEVHandle getTruncateOrZeroExtend(const SCEVHandle &V, const Type *Ty);
265265
266 /// getTruncateOrSignExtend - Return a SCEV corresponding to a conversion
267 /// of the input value to the specified type. If the type must be
268 /// extended, it is sign extended.
269 SCEVHandle getTruncateOrSignExtend(const SCEVHandle &V, const Type *Ty);
270
266271 /// getIntegerSCEV - Given an integer or FP type, create a constant for the
267272 /// specified signed integer value and return a SCEV for the constant.
268273 SCEVHandle getIntegerSCEV(int Val, const Type *Ty);
754754 return getZeroExtendExpr(V, Ty);
755755 }
756756
757 /// getTruncateOrSignExtend - Return a SCEV corresponding to a conversion
758 /// of the input value to the specified type. If the type must be
759 /// extended, it is sign extended.
760 SCEVHandle ScalarEvolution::getTruncateOrSignExtend(const SCEVHandle &V,
761 const Type *Ty) {
762 const Type *SrcTy = V->getType();
763 assert(SrcTy->isInteger() && Ty->isInteger() &&
764 "Cannot truncate or sign extend with non-integer arguments!");
765 if (SrcTy->getPrimitiveSizeInBits() == Ty->getPrimitiveSizeInBits())
766 return V; // No conversion
767 if (SrcTy->getPrimitiveSizeInBits() > Ty->getPrimitiveSizeInBits())
768 return getTruncateExpr(V, Ty);
769 return getSignExtendExpr(V, Ty);
770 }
771
757772 // get - Get a canonical add expression, or something simpler if possible.
758773 SCEVHandle ScalarEvolution::getAddExpr(std::vector &Ops) {
759774 assert(!Ops.empty() && "Cannot get empty add!");
9595 Value *IndVar,
9696 BasicBlock *ExitingBlock,
9797 BranchInst *BI,
98 SCEVExpander &Rewriter);
98 SCEVExpander &Rewriter,
99 bool SignExtendTripCount);
99100 void RewriteLoopExitValues(Loop *L, SCEV *IterationCount);
100101
101102 void DeleteTriviallyDeadInstructions(SmallPtrSet &Insts);
234235 Value *IndVar,
235236 BasicBlock *ExitingBlock,
236237 BranchInst *BI,
237 SCEVExpander &Rewriter) {
238 SCEVExpander &Rewriter,
239 bool SignExtendTripCount) {
238240 // If the exiting block is not the same as the backedge block, we must compare
239241 // against the preincremented value, otherwise we prefer to compare against
240242 // the post-incremented value.
252254 if ((isa(N) && !N->isZero()) ||
253255 SE->isLoopGuardedByCond(L, ICmpInst::ICMP_NE, N, Zero)) {
254256 // No overflow. Cast the sum.
255 IterationCount = SE->getTruncateOrZeroExtend(N, IndVar->getType());
257 if (SignExtendTripCount)
258 IterationCount = SE->getTruncateOrSignExtend(N, IndVar->getType());
259 else
260 IterationCount = SE->getTruncateOrZeroExtend(N, IndVar->getType());
256261 } else {
257262 // Potential overflow. Cast before doing the add.
258 IterationCount = SE->getTruncateOrZeroExtend(IterationCount,
259 IndVar->getType());
263 if (SignExtendTripCount)
264 IterationCount = SE->getTruncateOrSignExtend(IterationCount,
265 IndVar->getType());
266 else
267 IterationCount = SE->getTruncateOrZeroExtend(IterationCount,
268 IndVar->getType());
260269 IterationCount =
261270 SE->getAddExpr(IterationCount,
262271 SE->getIntegerSCEV(1, IndVar->getType()));
268277 CmpIndVar = L->getCanonicalInductionVariableIncrement();
269278 } else {
270279 // We have to use the preincremented value...
271 IterationCount = SE->getTruncateOrZeroExtend(IterationCount,
272 IndVar->getType());
280 if (SignExtendTripCount)
281 IterationCount = SE->getTruncateOrSignExtend(IterationCount,
282 IndVar->getType());
283 else
284 IterationCount = SE->getTruncateOrZeroExtend(IterationCount,
285 IndVar->getType());
273286 CmpIndVar = IndVar;
274287 }
275288
463476
464477 /// TestOrigIVForWrap - Analyze the original induction variable
465478 /// that controls the loop's iteration to determine whether it
466 /// would ever undergo signed or unsigned overflow.
479 /// would ever undergo signed or unsigned overflow. Also, check
480 /// whether an induction variable in the same type that starts
481 /// at 0 would undergo signed overflow.
467482 ///
468 /// In addition to setting the NoSignedWrap and NoUnsignedWrap
469 /// variables, return the PHI for this induction variable.
483 /// In addition to setting the NoSignedWrap, NoUnsignedWrap, and
484 /// SignExtendTripCount variables, return the PHI for this induction
485 /// variable.
470486 ///
471487 /// TODO: This duplicates a fair amount of ScalarEvolution logic.
472488 /// Perhaps this can be merged with ScalarEvolution::getIterationCount
476492 const BranchInst *BI,
477493 const Instruction *OrigCond,
478494 bool &NoSignedWrap,
479 bool &NoUnsignedWrap) {
495 bool &NoUnsignedWrap,
496 bool &SignExtendTripCount) {
480497 // Verify that the loop is sane and find the exit condition.
481498 const ICmpInst *Cmp = dyn_cast(OrigCond);
482499 if (!Cmp) return 0;
589606 // The original induction variable will start at some non-max value,
590607 // it counts up by one, and the loop iterates only while it remans
591608 // less than some value in the same type. As such, it will never wrap.
592 if (isSigned && !InitialVal->getValue().isMaxSignedValue())
609 if (isSigned && !InitialVal->getValue().isMaxSignedValue()) {
593610 NoSignedWrap = true;
594 else if (!isSigned && !InitialVal->getValue().isMaxValue())
611 // If the original induction variable starts at zero or greater,
612 // the trip count can be considered signed.
613 if (InitialVal->getValue().isNonNegative())
614 SignExtendTripCount = true;
615 } else if (!isSigned && !InitialVal->getValue().isMaxValue())
595616 NoUnsignedWrap = true;
596617 return PN;
597618 }
677698 // using it. We can currently only handle loops with a single exit.
678699 bool NoSignedWrap = false;
679700 bool NoUnsignedWrap = false;
701 bool SignExtendTripCount = false;
680702 const PHINode *OrigControllingPHI = 0;
681703 if (!isa(IterationCount) && ExitingBlock)
682704 // Can't rewrite non-branch yet.
685707 // Determine if the OrigIV will ever undergo overflow.
686708 OrigControllingPHI =
687709 TestOrigIVForWrap(L, BI, OrigCond,
688 NoSignedWrap, NoUnsignedWrap);
710 NoSignedWrap, NoUnsignedWrap,
711 SignExtendTripCount);
689712
690713 // We'll be replacing the original condition, so it'll be dead.
691714 DeadInsts.insert(OrigCond);
692715 }
693716
694717 LinearFunctionTestReplace(L, IterationCount, IndVar,
695 ExitingBlock, BI, Rewriter);
718 ExitingBlock, BI, Rewriter,
719 SignExtendTripCount);
696720 }
697721
698722 // Now that we have a canonical induction variable, we can rewrite any
0 ; RUN: llvm-as < %s | opt -indvars | llvm-dis > %t
1 ; RUN: grep sext %t | count 1
1 ; RUN: grep sext %t | count 2
2 ; RUN: grep { = sext i32 %n to i64} %t
23 ; RUN: grep phi %t | count 1
34 ; RUN: grep {phi i64} %t
45
None ; RUN: llvm-as < %s | opt -indvars | llvm-dis | not grep sext
1
2 target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128"
0 ; RUN: llvm-as < %s | opt -indvars | llvm-dis > %t
1 ; RUN: grep sext %t | count 2
2 ; RUN: grep { = sext i16 %N to i64} %t
3 ; RUN: grep { = sext i32 %count to i64} %t
34
45 define i64 @test(i64* nocapture %first, i32 %count) nounwind readonly {
56 entry:
0 ; RUN: llvm-as < %s | opt -indvars | llvm-dis > %t
1 ; RUN: grep { = sext i32 %n} %t
2 ; RUN: grep phi %t | count 1
3 ; RUN: not grep zext %t
4
5 define void @foo(i64* nocapture %x, i32 %n) nounwind {
6 entry:
7 %tmp102 = icmp sgt i32 %n, 0 ; [#uses=1]
8 br i1 %tmp102, label %bb.nph, label %return
9
10 bb.nph: ; preds = %entry
11 br label %bb
12
13 bb: ; preds = %bb7, %bb.nph
14 %i.01 = phi i32 [ %tmp6, %bb7 ], [ 0, %bb.nph ] ; [#uses=3]
15 %tmp1 = sext i32 %i.01 to i64 ; [#uses=1]
16 %tmp4 = getelementptr i64* %x, i32 %i.01 ; [#uses=1]
17 store i64 %tmp1, i64* %tmp4, align 8
18 %tmp6 = add i32 %i.01, 1 ; [#uses=2]
19 br label %bb7
20
21 bb7: ; preds = %bb
22 %tmp10 = icmp slt i32 %tmp6, %n ; [#uses=1]
23 br i1 %tmp10, label %bb, label %bb7.return_crit_edge
24
25 bb7.return_crit_edge: ; preds = %bb7
26 br label %return
27
28 return: ; preds = %bb7.return_crit_edge, %entry
29 ret void
30 }