mirror of
				https://github.com/c64scene-ar/llvm-6502.git
				synced 2025-10-31 08:16:47 +00:00 
			
		
		
		
	Fix ScalarEvolution's backedge-taken count computations to check for
overflow when computing a integer division to round up. Thanks to Nick Lewycky for noticing this! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@73862 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
		| @@ -332,6 +332,13 @@ namespace llvm { | |||||||
|                                           const SCEVHandle &SymName, |                                           const SCEVHandle &SymName, | ||||||
|                                           const SCEVHandle &NewVal); |                                           const SCEVHandle &NewVal); | ||||||
|  |  | ||||||
|  |     /// getBECount - Subtract the end and start values and divide by the step, | ||||||
|  |     /// rounding up, to get the number of times the backedge is executed. Return | ||||||
|  |     /// CouldNotCompute if an intermediate computation overflows. | ||||||
|  |     SCEVHandle getBECount(const SCEVHandle &Start, | ||||||
|  |                           const SCEVHandle &End, | ||||||
|  |                           const SCEVHandle &Step); | ||||||
|  |  | ||||||
|     /// getBackedgeTakenInfo - Return the BackedgeTakenInfo for the given |     /// getBackedgeTakenInfo - Return the BackedgeTakenInfo for the given | ||||||
|     /// loop, lazily computing new values if the loop hasn't been analyzed |     /// loop, lazily computing new values if the loop hasn't been analyzed | ||||||
|     /// yet. |     /// yet. | ||||||
|   | |||||||
| @@ -3788,6 +3788,33 @@ bool ScalarEvolution::isLoopGuardedByCond(const Loop *L, | |||||||
|   return false; |   return false; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | /// getBECount - Subtract the end and start values and divide by the step, | ||||||
|  | /// rounding up, to get the number of times the backedge is executed. Return | ||||||
|  | /// CouldNotCompute if an intermediate computation overflows. | ||||||
|  | SCEVHandle ScalarEvolution::getBECount(const SCEVHandle &Start, | ||||||
|  |                                        const SCEVHandle &End, | ||||||
|  |                                        const SCEVHandle &Step) { | ||||||
|  |   const Type *Ty = Start->getType(); | ||||||
|  |   SCEVHandle NegOne = getIntegerSCEV(-1, Ty); | ||||||
|  |   SCEVHandle Diff = getMinusSCEV(End, Start); | ||||||
|  |   SCEVHandle RoundUp = getAddExpr(Step, NegOne); | ||||||
|  |  | ||||||
|  |   // Add an adjustment to the difference between End and Start so that | ||||||
|  |   // the division will effectively round up. | ||||||
|  |   SCEVHandle Add = getAddExpr(Diff, RoundUp); | ||||||
|  |  | ||||||
|  |   // Check Add for unsigned overflow. | ||||||
|  |   // TODO: More sophisticated things could be done here. | ||||||
|  |   const Type *WideTy = IntegerType::get(getTypeSizeInBits(Ty) + 1); | ||||||
|  |   SCEVHandle OperandExtendedAdd = | ||||||
|  |     getAddExpr(getZeroExtendExpr(Diff, WideTy), | ||||||
|  |                getZeroExtendExpr(RoundUp, WideTy)); | ||||||
|  |   if (getZeroExtendExpr(Add, WideTy) != OperandExtendedAdd) | ||||||
|  |     return CouldNotCompute; | ||||||
|  |  | ||||||
|  |   return getUDivExpr(Add, Step); | ||||||
|  | } | ||||||
|  |  | ||||||
| /// HowManyLessThans - Return the number of times a backedge containing the | /// HowManyLessThans - Return the number of times a backedge containing the | ||||||
| /// specified less-than comparison will execute.  If not computable, return | /// specified less-than comparison will execute.  If not computable, return | ||||||
| /// CouldNotCompute. | /// CouldNotCompute. | ||||||
| @@ -3869,16 +3896,11 @@ HowManyLessThans(const SCEV *LHS, const SCEV *RHS, | |||||||
|  |  | ||||||
|     // Finally, we subtract these two values and divide, rounding up, to get |     // Finally, we subtract these two values and divide, rounding up, to get | ||||||
|     // the number of times the backedge is executed. |     // the number of times the backedge is executed. | ||||||
|     SCEVHandle BECount = getUDivExpr(getAddExpr(getMinusSCEV(End, Start), |     SCEVHandle BECount = getBECount(Start, End, Step); | ||||||
|                                                 getAddExpr(Step, NegOne)), |  | ||||||
|                                      Step); |  | ||||||
|  |  | ||||||
|     // The maximum backedge count is similar, except using the minimum start |     // The maximum backedge count is similar, except using the minimum start | ||||||
|     // value and the maximum end value. |     // value and the maximum end value. | ||||||
|     SCEVHandle MaxBECount = getUDivExpr(getAddExpr(getMinusSCEV(MaxEnd, |     SCEVHandle MaxBECount = getBECount(MinStart, MaxEnd, Step);; | ||||||
|                                                                 MinStart), |  | ||||||
|                                                    getAddExpr(Step, NegOne)), |  | ||||||
|                                         Step); |  | ||||||
|  |  | ||||||
|     return BackedgeTakenInfo(BECount, MaxBECount); |     return BackedgeTakenInfo(BECount, MaxBECount); | ||||||
|   } |   } | ||||||
|   | |||||||
| @@ -1,4 +1,9 @@ | |||||||
| ; RUN: llvm-as < %s | opt -analyze -scalar-evolution -disable-output |& grep {/u 3} | ; RUN: llvm-as < %s | opt -analyze -scalar-evolution -disable-output \ | ||||||
|  | ; RUN:  | grep {Loop bb: Unpredictable backedge-taken count\\.} | ||||||
|  |  | ||||||
|  | ; ScalarEvolution can't compute a trip count because it doesn't know if | ||||||
|  | ; dividing by the stride will have a remainder. This could theoretically | ||||||
|  | ; be teaching it how to use a more elaborate trip count computation. | ||||||
|  |  | ||||||
| define i32 @f(i32 %x) nounwind readnone { | define i32 @f(i32 %x) nounwind readnone { | ||||||
| entry: | entry: | ||||||
|   | |||||||
| @@ -1,5 +1,9 @@ | |||||||
| ; RUN: llvm-as < %s | opt -scalar-evolution -analyze -disable-output \ | ; RUN: llvm-as < %s | opt -scalar-evolution -analyze -disable-output \ | ||||||
| ; RUN:  | grep {backedge-taken count is ((64 + (-64 smax (-1 + (-1 \\* %0))) + %0) /u 64)} | ; RUN:  | grep {Loop bb3\\.i: Unpredictable backedge-taken count\\.} | ||||||
|  |  | ||||||
|  | ; ScalarEvolution can't compute a trip count because it doesn't know if | ||||||
|  | ; dividing by the stride will have a remainder. This could theoretically | ||||||
|  | ; be teaching it how to use a more elaborate trip count computation. | ||||||
|  |  | ||||||
| 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" | 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" | ||||||
| target triple = "x86_64-unknown-linux-gnu" | target triple = "x86_64-unknown-linux-gnu" | ||||||
|   | |||||||
| @@ -1,7 +1,9 @@ | |||||||
| ; RUN: llvm-as < %s | opt -indvars -loop-deletion | llvm-dis | grep phi | count 1 | ; RUN: llvm-as < %s | opt -indvars -loop-deletion | llvm-dis | grep phi | count 1 | ||||||
|  | ; XFAIL: * | ||||||
|  |  | ||||||
| ; Indvars should be able to evaluate this loop, allowing loop deletion | ; Indvars can't evaluate this loop, because ScalarEvolution can't compute | ||||||
| ; to delete it. | ; an exact trip count, because it doesn't know if dividing by the stride will | ||||||
|  | ; have a remainder. It could be done with more aggressive VRP though. | ||||||
|  |  | ||||||
| define i32 @test(i32 %x_offs) nounwind readnone { | define i32 @test(i32 %x_offs) nounwind readnone { | ||||||
| entry: | entry: | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user