From: Sanjoy Das Date: Sun, 27 Sep 2015 21:09:48 +0000 (+0000) Subject: [SCEV] identical instructions don't compute equal values X-Git-Url: http://plrg.eecs.uci.edu/git/?p=oota-llvm.git;a=commitdiff_plain;h=d8387ead1eab56e32b0a89c3dfe72d489eec4f34 [SCEV] identical instructions don't compute equal values Before this change `HasSameValue` would return true for distinct `alloca` instructions if they happened to be allocating the same type (`alloca` instructions are not specified as reading memory). This change adds an explicit whitelist of instruction types for which "identical" instructions compute the same value. Fixes PR24952. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@248690 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Analysis/ScalarEvolution.cpp b/lib/Analysis/ScalarEvolution.cpp index 32d3d36c739..57caa9d368a 100644 --- a/lib/Analysis/ScalarEvolution.cpp +++ b/lib/Analysis/ScalarEvolution.cpp @@ -6412,13 +6412,20 @@ static bool HasSameValue(const SCEV *A, const SCEV *B) { // Quick check to see if they are the same SCEV. if (A == B) return true; + auto ComputesEqualValues = [](const Instruction *A, const Instruction *B) { + // Not all instructions that are "identical" compute the same value. For + // instance, two distinct alloca instructions allocating the same type are + // identical and do not read memory; but compute distinct values. + return A->isIdenticalTo(B) && (isa(A) || isa(A)); + }; + // Otherwise, if they're both SCEVUnknown, it's possible that they hold // two different instructions with the same value. Check for this case. if (const SCEVUnknown *AU = dyn_cast(A)) if (const SCEVUnknown *BU = dyn_cast(B)) if (const Instruction *AI = dyn_cast(AU->getValue())) if (const Instruction *BI = dyn_cast(BU->getValue())) - if (AI->isIdenticalTo(BI) && !AI->mayReadFromMemory()) + if (ComputesEqualValues(AI, BI)) return true; // Otherwise assume they may have a different value. diff --git a/test/Transforms/IndVarSimplify/pr24952.ll b/test/Transforms/IndVarSimplify/pr24952.ll new file mode 100644 index 00000000000..c430cae98f5 --- /dev/null +++ b/test/Transforms/IndVarSimplify/pr24952.ll @@ -0,0 +1,27 @@ +; RUN: opt -indvars -S < %s | FileCheck %s + +declare void @use(i1) + +define void @f() { +; CHECK-LABEL: @f( + entry: + %x = alloca i32 + %y = alloca i32 + br label %loop + + loop: + %iv = phi i32 [ 0, %entry ], [ %iv.inc, %loop ] + %iv.inc = add i32 %iv, 1 + + %x.gep = getelementptr i32, i32* %x, i32 %iv + %eql = icmp eq i32* %x.gep, %y +; CHECK-NOT: @use(i1 true) + call void @use(i1 %eql) + + ; %be.cond deliberately 'false' -- we want want the trip count to be 0. + %be.cond = icmp ult i32 %iv, 0 + br i1 %be.cond, label %loop, label %leave + + leave: + ret void +}