summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHeejin Ahn <aheejin@gmail.com>2019-08-26 21:51:35 +0000
committerHeejin Ahn <aheejin@gmail.com>2019-08-26 21:51:35 +0000
commit173a3a54bba06ffbf2b680cf52f1f8a257c33b15 (patch)
tree07ba56303aca951130917b03c347b92c891a1561
parented4fefb0df94799d902fadeabef4161f729ff8ca (diff)
downloadbcm5719-llvm-173a3a54bba06ffbf2b680cf52f1f8a257c33b15.tar.gz
bcm5719-llvm-173a3a54bba06ffbf2b680cf52f1f8a257c33b15.zip
[WebAssembly] Fix SSA rebuilding in SjLj transformation
Summary: Previously we skipped uses within the same BB as a def when rebuilding SSA after SjLj transformation. For example, before transformation, ``` for.cond: %0 = phi i32 [ %var, %for.inc ] ... %var = ... br label %for.inc for.inc: ; preds = %for.cond call i32 @setjmp(...) br %for.cond ``` In this BB, %var should be defined in all paths from %for.inc to make %0 valid. In the input it was true; %for.inc's only predecessor was %for.cond. But after SjLj transformation, it is possible that %for.inc has other predecessors that are reachable without reaching %for.cond. ``` entry.split: ... br i1 %a, label %bb.1, label %for.inc for.cond: %0 = phi i32 [ %var, %for.inc ] ... ; Not valid! %var = ... br label %for.inc for.inc: ; preds = %for.cond, %entry.split call i32 @setjmp(...) ... br %for.cond ``` In this case, we can't use %var in the `phi` instruction in %for.cond, because %var is not defined in all paths through %for.inc (If the control flow is %entry -> %entry.split -> %for.inc -> %for.cond, %var has not been defined until we reach the `phi`). But the previous code excluded users within the same BB, skipping instructions within the same BB so they are not rewritten properly. User instructions within the same BB also should be candidates for rewriting if they are _before_ the original definition. Fixes PR43097. Reviewers: dschuff Subscribers: sbc100, jgravelle-google, hiraditya, sunfish, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D66729 llvm-svn: 369978
-rw-r--r--llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp7
-rw-r--r--llvm/test/CodeGen/WebAssembly/lower-em-sjlj.ll20
2 files changed, 22 insertions, 5 deletions
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp
index 568382bac15..d70e197cbcb 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp
@@ -636,15 +636,12 @@ void WebAssemblyLowerEmscriptenEHSjLj::rebuildSSA(Function &F) {
SSAUpdater SSA;
for (BasicBlock &BB : F) {
for (Instruction &I : BB) {
+ SSA.Initialize(I.getType(), I.getName());
+ SSA.AddAvailableValue(&BB, &I);
for (auto UI = I.use_begin(), UE = I.use_end(); UI != UE;) {
Use &U = *UI;
++UI;
- SSA.Initialize(I.getType(), I.getName());
- SSA.AddAvailableValue(&BB, &I);
auto *User = cast<Instruction>(U.getUser());
- if (User->getParent() == &BB)
- continue;
-
if (auto *UserPN = dyn_cast<PHINode>(User))
if (UserPN->getIncomingBlock(U) == &BB)
continue;
diff --git a/llvm/test/CodeGen/WebAssembly/lower-em-sjlj.ll b/llvm/test/CodeGen/WebAssembly/lower-em-sjlj.ll
index 5dfdd440fbc..540b13bdbd8 100644
--- a/llvm/test/CodeGen/WebAssembly/lower-em-sjlj.ll
+++ b/llvm/test/CodeGen/WebAssembly/lower-em-sjlj.ll
@@ -226,6 +226,26 @@ entry:
unreachable
}
+; Tests if SSA rewrite works when a use and its def are within the same BB.
+define void @ssa_rewite_in_same_bb() {
+entry:
+ call void @foo()
+ br label %for.cond
+
+for.cond: ; preds = %for.inc, %entry
+ ; CHECK: %{{.*}} = phi i32 [ %var[[VARNO:.*]], %for.inc.split ]
+ %0 = phi i32 [ %var, %for.inc ], [ undef, %entry ]
+ %var = add i32 0, 0
+ br label %for.inc
+
+for.inc: ; preds = %for.cond
+ %call5 = call i32 @setjmp(%struct.__jmp_buf_tag* undef) #0
+ br label %for.cond
+
+; CHECK: for.inc.split:
+ ; CHECK: %var[[VARNO]] = phi i32 [ %var, %for.inc ]
+}
+
declare void @foo()
; Function Attrs: returns_twice
declare i32 @setjmp(%struct.__jmp_buf_tag*) #0
OpenPOWER on IntegriCloud