From 24ba7d3f6c514c2feee65b15689e3a097c90686d Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Thu, 18 Aug 2016 17:34:01 +0000 Subject: [PATCH] Merging r278999: ------------------------------------------------------------------------ r278999 | hans | 2016-08-17 15:50:18 -0700 (Wed, 17 Aug 2016) | 3 lines SCEV: Don't assert about non-SCEV-able value in isSCEVExprNeverPoison() (PR28932) Differential Revision: https://reviews.llvm.org/D23594 ------------------------------------------------------------------------ git-svn-id: https://llvm.org/svn/llvm-project/llvm/branches/release_39@279093 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Analysis/ScalarEvolution.cpp | 4 ++ .../ScalarEvolution/flags-from-poison.ll | 49 +++++++++++++++++++ 2 files changed, 53 insertions(+) diff --git a/lib/Analysis/ScalarEvolution.cpp b/lib/Analysis/ScalarEvolution.cpp index 2abbf348035..e42a4b574d9 100644 --- a/lib/Analysis/ScalarEvolution.cpp +++ b/lib/Analysis/ScalarEvolution.cpp @@ -4822,6 +4822,10 @@ bool ScalarEvolution::isSCEVExprNeverPoison(const Instruction *I) { // from different loops, so that we know which loop to prove that I is // executed in. for (unsigned OpIndex = 0; OpIndex < I->getNumOperands(); ++OpIndex) { + // I could be an extractvalue from a call to an overflow intrinsic. + // TODO: We can do better here in some cases. + if (!isSCEVable(I->getOperand(OpIndex)->getType())) + return false; const SCEV *Op = getSCEV(I->getOperand(OpIndex)); if (auto *AddRec = dyn_cast(Op)) { bool AllOtherOpsLoopInvariant = true; diff --git a/test/Analysis/ScalarEvolution/flags-from-poison.ll b/test/Analysis/ScalarEvolution/flags-from-poison.ll index 2fcb4c038f2..8e73fe4fd54 100644 --- a/test/Analysis/ScalarEvolution/flags-from-poison.ll +++ b/test/Analysis/ScalarEvolution/flags-from-poison.ll @@ -688,3 +688,52 @@ outer.be: exit: ret void } + + +; PR28932: Don't assert on non-SCEV-able value %2. +%struct.anon = type { i8* } +@a = common global %struct.anon* null, align 8 +@b = common global i32 0, align 4 +declare { i32, i1 } @llvm.ssub.with.overflow.i32(i32, i32) +declare void @llvm.trap() +define i32 @pr28932() { +entry: + %.pre = load %struct.anon*, %struct.anon** @a, align 8 + %.pre7 = load i32, i32* @b, align 4 + br label %for.cond + +for.cond: ; preds = %cont6, %entry + %0 = phi i32 [ %3, %cont6 ], [ %.pre7, %entry ] + %1 = phi %struct.anon* [ %.ph, %cont6 ], [ %.pre, %entry ] + %tobool = icmp eq %struct.anon* %1, null + %2 = tail call { i32, i1 } @llvm.ssub.with.overflow.i32(i32 %0, i32 1) + %3 = extractvalue { i32, i1 } %2, 0 + %4 = extractvalue { i32, i1 } %2, 1 + %idxprom = sext i32 %3 to i64 + %5 = getelementptr inbounds %struct.anon, %struct.anon* %1, i64 0, i32 0 + %6 = load i8*, i8** %5, align 8 + %7 = getelementptr inbounds i8, i8* %6, i64 %idxprom + %8 = load i8, i8* %7, align 1 + br i1 %tobool, label %if.else, label %if.then + +if.then: ; preds = %for.cond + br i1 %4, label %trap, label %cont6 + +trap: ; preds = %if.else, %if.then + tail call void @llvm.trap() + unreachable + +if.else: ; preds = %for.cond + br i1 %4, label %trap, label %cont1 + +cont1: ; preds = %if.else + %conv5 = sext i8 %8 to i64 + %9 = inttoptr i64 %conv5 to %struct.anon* + store %struct.anon* %9, %struct.anon** @a, align 8 + br label %cont6 + +cont6: ; preds = %cont1, %if.then + %.ph = phi %struct.anon* [ %9, %cont1 ], [ %1, %if.then ] + store i32 %3, i32* @b, align 4 + br label %for.cond +} -- 2.49.0