llvm.org GIT mirror llvm / 0d362a2
[NewGVN] Fix the case where we have a phi-of-ops which goes away. Patch by Daniel Berlin, fixes PR33196 (and probably something else). git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@309988 91177308-0d34-0410-b5e6-96231b3b80d8 Davide Italiano 2 years ago
2 changed file(s) with 99 addition(s) and 6 deletion(s). Raw diff Collapse all Expand all
470470 DenseSet PHINodeUses;
471471 // Map a temporary instruction we created to a parent block.
472472 DenseMap TempToBlock;
473 // Map between the temporary phis we created and the real instructions they
474 // are known equivalent to.
473 // Map between the already in-program instructions and the temporary phis we
474 // created that they are known equivalent to.
475475 DenseMap RealToTemp;
476476 // In order to know when we should re-process instructions that have
477477 // phi-of-ops, we track the set of expressions that they needed as
485485 DenseMap>
486486 ExpressionToPhiOfOps;
487487 // Map from basic block to the temporary operations we created
488 DenseMapVector>> PHIOfOpsPHIs;
488 DenseMapPtrSet>> PHIOfOpsPHIs;
489489 // Map from temporary operation to MemoryAccess.
490490 DenseMap TempToMemory;
491491 // Set of all temporary instructions we created.
492 // Note: This will include instructions that were just created during value
493 // numbering. The way to test if something is using them is to check
494 // RealToTemp.
495
492496 DenseSet AllTempInstructions;
493497
494498 // Mapping from predicate info we used to the instructions we used it with.
633637 const Expression *makePossiblePhiOfOps(Instruction *,
634638 SmallPtrSetImpl &);
635639 void addPhiOfOps(PHINode *Op, BasicBlock *BB, Instruction *ExistingValue);
640 void removePhiOfOps(Instruction *I, PHINode *PHITemp);
636641
637642 // Value number an Instruction or MemoryPhi.
638643 void valueNumberMemoryPhi(MemoryPhi *);
24132418 }
24142419 }
24152420
2421 // Remove the PHI of Ops PHI for I
2422 void NewGVN::removePhiOfOps(Instruction *I, PHINode *PHITemp) {
2423 InstrDFS.erase(PHITemp);
2424 // It's still a temp instruction. We keep it in the array so it gets erased.
2425 // However, it's no longer used by I, or in the block/
2426 PHIOfOpsPHIs[getBlockForValue(PHITemp)].erase(PHITemp);
2427 TempToBlock.erase(PHITemp);
2428 RealToTemp.erase(I);
2429 }
2430
2431 // Add PHI Op in BB as a PHI of operations version of ExistingValue.
24162432 void NewGVN::addPhiOfOps(PHINode *Op, BasicBlock *BB,
24172433 Instruction *ExistingValue) {
24182434 InstrDFS[Op] = InstrToDFSNum(ExistingValue);
24192435 AllTempInstructions.insert(Op);
2420 PHIOfOpsPHIs[BB].push_back(Op);
2436 PHIOfOpsPHIs[BB].insert(Op);
24212437 TempToBlock[Op] = BB;
24222438 RealToTemp[ExistingValue] = Op;
24232439 }
27822798 if (Symbolized && !isa(Symbolized) &&
27832799 !isa(Symbolized) && PHINodeUses.count(I)) {
27842800 auto *PHIE = makePossiblePhiOfOps(I, Visited);
2785 if (PHIE)
2801 // If we created a phi of ops, use it.
2802 // If we couldn't create one, make sure we don't leave one lying around
2803 if (PHIE) {
27862804 Symbolized = PHIE;
2805 } else if (auto *Op = RealToTemp.lookup(I)) {
2806 removePhiOfOps(I, Op);
2807 }
27872808 }
27882809
27892810 } else {
36253646 CC->swap(MembersLeft);
36263647 } else {
36273648 // If this is a singleton, we can skip it.
3628 if (CC->size() != 1 || RealToTemp.lookup(Leader)) {
3649 if (CC->size() != 1 || RealToTemp.count(Leader)) {
36293650 // This is a stack because equality replacement/etc may place
36303651 // constants in the middle of the member list, and we want to use
36313652 // those constant values in preference to the current leader, over
0 ; RUN: opt -S -newgvn %s | FileCheck %s
1
2 ; CHECK: define i32 @main() {
3 ; CHECK-NEXT: entry:
4 ; CHECK-NEXT: %tmp = load i32, i32* @d, align 4
5 ; CHECK-NEXT: %tmp1 = load i32, i32* @c, align 4
6 ; CHECK-NEXT: %tobool = icmp eq i32 %tmp1, -1
7 ; CHECK-NEXT: br i1 %tobool, label %if.end, label %if.then
8 ; CHECK: if.then:
9 ; CHECK-NEXT: br label %L
10 ; CHECK: L:
11 ; CHECK-NEXT: %e.0 = phi i32 [ 0, %if.then ], [ %e.1, %if.then4 ]
12 ; CHECK-NEXT: br label %if.end
13 ; CHECK: if.end:
14 ; CHECK-NEXT: %e.1 = phi i32 [ %e.0, %L ], [ %tmp, %entry ]
15 ; CHECK-NEXT: store i32 %e.1, i32* @a, align 4
16 ; CHECK-NEXT: %tmp2 = load i32, i32* @b, align 4
17 ; CHECK-NEXT: store i32 0, i32* @b, align 4
18 ; CHECK-NEXT: %sext = shl i32 %tmp2, 16
19 ; CHECK-NEXT: %conv1 = ashr exact i32 %sext, 16
20 ; CHECK-NEXT: %add = add nsw i32 %conv1, %tmp1
21 ; CHECK-NEXT: %add2 = add nsw i32 %add, %e.1
22 ; CHECK-NEXT: store i32 %add2, i32* @a, align 4
23 ; CHECK-NEXT: %tobool3 = icmp eq i32 %add2, 0
24 ; CHECK-NEXT: br i1 %tobool3, label %if.end5, label %if.then4
25 ; CHECK: if.then4:
26 ; CHECK-NEXT: br label %L
27 ; CHECK: if.end5:
28 ; CHECK-NEXT: ret i32 0
29 ; CHECK-NEXT: }
30
31 @d = global i32 1, align 4
32 @c = common global i32 0, align 4
33 @a = common global i32 0, align 4
34 @b = common global i32 0, align 4
35
36 define i32 @main() {
37 entry:
38 %tmp = load i32, i32* @d, align 4
39 %tmp1 = load i32, i32* @c, align 4
40 %tobool = icmp eq i32 %tmp1, -1
41 br i1 %tobool, label %if.end, label %if.then
42
43 if.then: ; preds = %entry
44 br label %L
45
46 L: ; preds = %if.then4, %if.then
47 %e.0 = phi i32 [ 0, %if.then ], [ %e.1, %if.then4 ]
48 br label %if.end
49
50 if.end: ; preds = %L, %entry
51 %e.1 = phi i32 [ %e.0, %L ], [ %tmp, %entry ]
52 store i32 %e.1, i32* @a, align 4
53 %tmp2 = load i32, i32* @b, align 4
54 store i32 0, i32* @b, align 4
55 %sext = shl i32 %tmp2, 16
56 %conv1 = ashr exact i32 %sext, 16
57 %tmp3 = load i32, i32* @c, align 4
58 %add = add nsw i32 %conv1, %tmp3
59 %tmp4 = load i32, i32* @a, align 4
60 %and = and i32 %tmp4, %e.1
61 %add2 = add nsw i32 %add, %and
62 store i32 %add2, i32* @a, align 4
63 %tobool3 = icmp eq i32 %add2, 0
64 br i1 %tobool3, label %if.end5, label %if.then4
65
66 if.then4: ; preds = %if.end
67 br label %L
68
69 if.end5: ; preds = %if.end
70 ret i32 0
71 }