llvm.org GIT mirror llvm / d38cdb0
fix PR6414, a nondeterminism issue in IPSCCP which was because of a subtle interation in a loop operating in densemap order. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@97288 91177308-0d34-0410-b5e6-96231b3b80d8 Chris Lattner 9 years ago
2 changed file(s) with 47 addition(s) and 1 deletion(s). Raw diff Collapse all Expand all
19171917 // all call uses with the inferred value. This means we don't need to bother
19181918 // actually returning anything from the function. Replace all return
19191919 // instructions with return undef.
1920 //
1921 // Do this in two stages: first identify the functions we should process, then
1922 // actually zap their returns. This is important because we can only do this
1923 // the address of the function isn't taken. In cases where a return is the
1924 // last use of a function, the order of processing functions would affect
1925 // whether we other functions are optimizable.
1926 SmallVector ReturnsToZap;
1927
19201928 // TODO: Process multiple value ret instructions also.
19211929 const DenseMap &RV = Solver.getTrackedRetVals();
19221930 for (DenseMap::const_iterator I = RV.begin(),
19321940 for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB)
19331941 if (ReturnInst *RI = dyn_cast(BB->getTerminator()))
19341942 if (!isa(RI->getOperand(0)))
1935 RI->setOperand(0, UndefValue::get(F->getReturnType()));
1943 ReturnsToZap.push_back(RI);
1944 }
1945
1946 // Zap all returns which we've identified as zap to change.
1947 for (unsigned i = 0, e = ReturnsToZap.size(); i != e; ++i) {
1948 Function *F = ReturnsToZap[i]->getParent()->getParent();
1949 ReturnsToZap[i]->setOperand(0, UndefValue::get(F->getReturnType()));
19361950 }
19371951
19381952 // If we infered constant or undef values for globals variables, we can delete
0 ; RUN: opt -ipsccp -S %s | FileCheck %s
1 ; PR6414
2 target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128"
3 target triple = "x86_64-unknown-linux-gnu"
4
5 define internal i32 ()* @f() {
6 ret i32 ()* @g
7 }
8
9 define internal i32 @g() {
10 ret i32 8
11 }
12
13 ; CHECK: internal i32 @g()
14 ; CHECK-NEXT: ret i32 8
15
16 define internal void @outer_mod() {
17 %1 = call i32 ()* ()* @f() ; [#uses=1]
18 %2 = call i32 %1() ; [#uses=0]
19 ret void
20 }
21
22 define internal void @module_init() {
23 call void @register_outer_mod(void ()* @outer_mod)
24 ret void
25 }
26
27 declare void @register_outer_mod(void ()*)
28
29 define i32 @main() {
30 ret i32 0
31 }