mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-07 11:51:13 +00:00
[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. llvm-svn: 248690
This commit is contained in:
parent
c39648a72a
commit
a9895bca61
@ -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<BinaryOperator>(A) || isa<GetElementPtrInst>(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<SCEVUnknown>(A))
|
||||
if (const SCEVUnknown *BU = dyn_cast<SCEVUnknown>(B))
|
||||
if (const Instruction *AI = dyn_cast<Instruction>(AU->getValue()))
|
||||
if (const Instruction *BI = dyn_cast<Instruction>(BU->getValue()))
|
||||
if (AI->isIdenticalTo(BI) && !AI->mayReadFromMemory())
|
||||
if (ComputesEqualValues(AI, BI))
|
||||
return true;
|
||||
|
||||
// Otherwise assume they may have a different value.
|
||||
|
27
test/Transforms/IndVarSimplify/pr24952.ll
Normal file
27
test/Transforms/IndVarSimplify/pr24952.ll
Normal file
@ -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
|
||||
}
|
Loading…
Reference in New Issue
Block a user