llvm.org GIT mirror llvm / b75b647
[Reassociate] Prevent infinite loops when processing PHIs. Phi nodes can reside in live blocks but one of their incoming arguments can come from a dead block. Dead blocks and reassociate don't play nice together. In fact, reassociate performs an RPO as a first step to avoid processing dead blocks. The reason why Reassociate might not fixpoint when examining dead blocks is that the following: %xor0 = xor i16 %xor1, undef %xor1 = xor i16 %xor0, undef is perfectly valid LLVM IR (if it appears in a dead block), so the worklist algorithm keeps pushing the two instructions for reexamination. Note that this is not Reassociate fault, at least not entirely. It's llvm that has a weird definition of dominance. Fixes PR37390. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@332100 91177308-0d34-0410-b5e6-96231b3b80d8 Davide Italiano 1 year, 4 months ago
2 changed file(s) with 36 addition(s) and 1 deletion(s). Raw diff Collapse all Expand all
19041904 while (Op->hasOneUse() && Op->user_back()->getOpcode() == Opcode &&
19051905 Visited.insert(Op).second)
19061906 Op = Op->user_back();
1907 RedoInsts.insert(Op);
1907
1908 // The instruction we're going to push may be coming from a
1909 // dead block, and Reassociate skips the processing of unreachable
1910 // blocks because it's a waste of time and also because it can
1911 // lead to infinite loop due to LLVM's non-standard definition
1912 // of dominance.
1913 if (ValueRankMap.find(Op) != ValueRankMap.end())
1914 RedoInsts.insert(Op);
19081915 }
19091916
19101917 MadeChange = true;
0 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
1 ; RUN: opt -reassociate %s -S | FileCheck %s
2
3 target triple = "x86_64-unknown-linux-gnu"
4
5 define void @f() {
6 ; CHECK-LABEL: @f(
7 ; CHECK-NEXT: entry:
8 ; CHECK-NEXT: br label [[DONE:%.*]]
9 ; CHECK: dead:
10 ; CHECK-NEXT: [[XOR0:%.*]] = xor i16 [[XOR1:%.*]], undef
11 ; CHECK-NEXT: [[XOR1]] = xor i16 [[XOR0]], undef
12 ; CHECK-NEXT: br i1 undef, label [[DEAD:%.*]], label [[DONE]]
13 ; CHECK: done:
14 ; CHECK-NEXT: ret void
15 ;
16 entry:
17 br label %done
18
19 dead:
20 %xor0 = xor i16 %xor1, undef
21 %xor1 = xor i16 %xor0, undef
22 br i1 undef, label %dead, label %done
23
24 done:
25 %e = phi i16 [ %xor1, %dead ], [ 0, %entry ]
26 ret void
27 }