Index: lib/CodeGen/LoopGenerators.cpp =================================================================== --- lib/CodeGen/LoopGenerators.cpp +++ lib/CodeGen/LoopGenerators.cpp @@ -17,17 +17,32 @@ #include "llvm/IR/DataLayout.h" #include "llvm/IR/Dominators.h" #include "llvm/IR/Module.h" +#include "llvm/IR/PatternMatch.h" #include "llvm/Support/CommandLine.h" #include "llvm/Transforms/Utils/BasicBlockUtils.h" using namespace llvm; using namespace polly; +using namespace PatternMatch; static cl::opt PollyNumThreads("polly-num-threads", cl::desc("Number of threads to use (0 = auto)"), cl::Hidden, cl::init(0)); +static bool mayOverflowOnIV(Value *UB, Value *Stride, IntegerType *LoopIVType) { + auto UBSMax = APInt::getSignedMaxValue(LoopIVType->getBitWidth()); + const APInt *UBInt, *StrideInt; + + if (!match(UB, m_APInt(UBInt))) + return true; + + if (!match(Stride, m_APInt(StrideInt))) + return true; + + return !UBInt->slt(UBSMax - *StrideInt); +} + // We generate a loop of either of the following structures: // // BeforeBB BeforeBB @@ -123,10 +138,12 @@ IV->addIncoming(LB, PreHeaderBB); Stride = Builder.CreateZExtOrBitCast(Stride, LoopIVType); Value *IncrementedIV = Builder.CreateNSWAdd(IV, Stride, "polly.indvar_next"); - Value *LoopCondition; - UB = Builder.CreateSub(UB, Stride, "polly.adjust_ub"); - LoopCondition = Builder.CreateICmp(Predicate, IV, UB); - LoopCondition->setName("polly.loop_cond"); + bool MayOverflow = mayOverflowOnIV(UB, Stride, LoopIVType); + auto *CmpIV = MayOverflow ? IV : IncrementedIV; + auto *AdjustedUB = + MayOverflow ? Builder.CreateSub(UB, Stride, "polly.adjust_ub") : UB; + Value *LoopCondition = + Builder.CreateICmp(Predicate, CmpIV, AdjustedUB, "polly.loop_cond"); // Create the loop latch and annotate it as such. BranchInst *B = Builder.CreateCondBr(LoopCondition, HeaderBB, ExitBB); Index: test/Isl/CodeGen/LoopParallelMD/loop_nest_param_parallel.ll =================================================================== --- test/Isl/CodeGen/LoopParallelMD/loop_nest_param_parallel.ll +++ test/Isl/CodeGen/LoopParallelMD/loop_nest_param_parallel.ll @@ -2,10 +2,10 @@ ; ; Check that we mark multiple parallel loops correctly including the memory instructions. ; -; CHECK-DAG: %polly.loop_cond[[COuter:[0-9]*]] = icmp sle i64 %polly.indvar{{[0-9]*}}, 1022 +; CHECK-DAG: %polly.loop_cond[[COuter:[0-9]*]] = icmp sle i64 %polly.indvar_next{{[0-9]*}}, 1023 ; CHECK-DAG: br i1 %polly.loop_cond[[COuter]], label %polly.loop_header{{[0-9]*}}, label %polly.loop_exit{{[0-9]*}}, !llvm.loop ![[IDOuter:[0-9]*]] ; -; CHECK-DAG: %polly.loop_cond[[CInner:[0-9]*]] = icmp sle i64 %polly.indvar{{[0-9]*}}, 510 +; CHECK-DAG: %polly.loop_cond[[CInner:[0-9]*]] = icmp sle i64 %polly.indvar_next{{[0-9]*}}, 511 ; CHECK-DAG: br i1 %polly.loop_cond[[CInner]], label %polly.loop_header{{[0-9]*}}, label %polly.loop_exit{{[0-9]*}}, !llvm.loop ![[IDInner:[0-9]*]] ; ; CHECK-DAG: store i32 %{{[a-z_0-9]*}}, i32* %{{[a-z_0-9]*}}, {{[ ._!,a-zA-Z0-9]*}}, !llvm.mem.parallel_loop_access !4 Index: test/Isl/CodeGen/MemAccess/generate-all.ll =================================================================== --- test/Isl/CodeGen/MemAccess/generate-all.ll +++ test/Isl/CodeGen/MemAccess/generate-all.ll @@ -15,7 +15,7 @@ ; SCEV-NEXT: %p_tmp5 = fadd float %tmp4_p_scalar_, 1.000000e+01 ; SCEV-NEXT: store float %p_tmp5, float* %p_tmp3, align 4, !alias.scope !0, !noalias !2 ; SCEV-NEXT: %polly.indvar_next = add nsw i64 %polly.indvar, 1 -; SCEV-NEXT: %polly.loop_cond = icmp sle i64 %polly.indvar, 98 +; SCEV-NEXT: %polly.loop_cond = icmp sle i64 %polly.indvar_next, 99 ; SCEV-NEXT: br i1 %polly.loop_cond, label %polly.loop_header, label %polly.loop_exit ; ASTEXPR: polly.stmt.bb2: ; preds = %polly.loop_header @@ -27,7 +27,7 @@ ; ASTEXPR-NEXT: %polly.access.A2 = getelementptr float, float* %A, i64 %pexp.pdiv_r1 ; ASTEXPR-NEXT: store float %p_tmp5, float* %polly.access.A2, align 4, !alias.scope !0, !noalias !2 ; ASTEXPR-NEXT: %polly.indvar_next = add nsw i64 %polly.indvar, 1 -; ASTEXPR-NEXT: %polly.loop_cond = icmp sle i64 %polly.indvar, 98 +; ASTEXPR-NEXT: %polly.loop_cond = icmp sle i64 %polly.indvar_next, 99 ; ASTEXPR-NEXT: br i1 %polly.loop_cond, label %polly.loop_header, label %polly.loop_exit target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" Index: test/Isl/CodeGen/non_affine_float_compare.ll =================================================================== --- test/Isl/CodeGen/non_affine_float_compare.ll +++ test/Isl/CodeGen/non_affine_float_compare.ll @@ -34,7 +34,7 @@ ; CHECK: %p_tmp11b = fadd float %tmp10b_p_scalar_, 1.000000e+00 ; CHECK: store float %p_tmp11b, float* %scevgep[[R4]], align 4, !alias.scope !0, !noalias !2 ; CHECK: %polly.indvar_next = add nsw i64 %polly.indvar, 1 -; CHECK: %polly.loop_cond = icmp sle i64 %polly.indvar, 1022 +; CHECK: %polly.loop_cond = icmp sle i64 %polly.indvar_next, 1023 ; CHECK: br i1 %polly.loop_cond, label %polly.loop_header, label %polly.loop_exit target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"