diff --git a/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp b/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp --- a/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp +++ b/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp @@ -74,7 +74,6 @@ #include "llvm/Analysis/ScalarEvolutionExpressions.h" #include "llvm/Analysis/ScalarEvolutionNormalization.h" #include "llvm/Analysis/TargetTransformInfo.h" -#include "llvm/Transforms/Utils/Local.h" #include "llvm/Config/llvm-config.h" #include "llvm/IR/BasicBlock.h" #include "llvm/IR/Constant.h" @@ -99,6 +98,7 @@ #include "llvm/IR/ValueHandle.h" #include "llvm/Pass.h" #include "llvm/Support/Casting.h" +#include "llvm/Support/CheckedArithmetic.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/Debug.h" @@ -108,6 +108,7 @@ #include "llvm/Transforms/Scalar.h" #include "llvm/Transforms/Utils.h" #include "llvm/Transforms/Utils/BasicBlockUtils.h" +#include "llvm/Transforms/Utils/Local.h" #include #include #include @@ -115,8 +116,8 @@ #include #include #include -#include #include +#include #include using namespace llvm; @@ -4435,7 +4436,14 @@ I = F.BaseRegs.begin(), E = F.BaseRegs.end(); I != E; ++I) { if (const SCEVConstant *C = dyn_cast(*I)) { Formula NewF = F; - NewF.BaseOffset += C->getValue()->getSExtValue(); + + Optional MaybeResult = + checkedAdd(NewF.BaseOffset, C->getValue()->getSExtValue()); + // Skip simplification if addition overflows. + if (!MaybeResult) + continue; + + NewF.BaseOffset = *MaybeResult; NewF.BaseRegs.erase(NewF.BaseRegs.begin() + (I - F.BaseRegs.begin())); if (LU.HasFormulaWithSameRegs(NewF)) { diff --git a/llvm/test/Transforms/LoopStrengthReduce/X86/lsr-overflow.ll b/llvm/test/Transforms/LoopStrengthReduce/X86/lsr-overflow.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Transforms/LoopStrengthReduce/X86/lsr-overflow.ll @@ -0,0 +1,22 @@ +; RUN: opt -lsr-complexity-limit=50 -loop-reduce -S %s | FileCheck %s + +target triple = "x86_64-apple-macosx10.14.0" +target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128" + +; CHECK: overflow1 +define void @overflow1(i64 %a) { +bb: + br label %bb1 + +bb1: ; preds = %bb1, %bb + %tmp = phi i64 [ %a, %bb ], [ %tmp6, %bb1 ] + %tmp4 = icmp ne i64 %tmp, -9223372036854775808 + %tmp5 = and i1 %tmp4, 1 + %tmp6 = add i64 %tmp, 1 + br i1 %tmp5, label %bb1, label %bb7 + +bb7: ; preds = %bb1 + %tmp9 = and i64 %tmp, 1 + %tmp10 = icmp eq i64 %tmp9, 0 + unreachable +}