aboutsummaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorMark Seaborn <mseaborn@chromium.org>2013-03-29 17:42:10 -0700
committerMark Seaborn <mseaborn@chromium.org>2013-03-29 17:42:10 -0700
commitcd93e1afec966dba60433f8df5f78f10ef217f93 (patch)
tree97c1b68239f23dedd72f5283e37a4957af9d10a1 /test
parent946417b9fe7da9334c76182f28020ff4f46e11f8 (diff)
PNaCl: Fix ExpandTls to handle a couple of corner cases involving PHI nodes
ExpandTls's use of replaceUsesOfWith() didn't work for PHI nodes containing the same Constant twice (which needs to work for same or differing incoming BasicBlocks). The same applies to ExpandTlsConstantExpr. I noticed this while implementing ExpandConstantExpr. Fix this and factor out some common code that all three passes can use. BUG=https://code.google.com/p/nativeclient/issues/detail?id=2837 TEST=test/Transforms/NaCl/*.ll Review URL: https://codereview.chromium.org/13128002
Diffstat (limited to 'test')
-rw-r--r--test/Transforms/NaCl/expand-tls-constexpr.ll36
-rw-r--r--test/Transforms/NaCl/expand-tls-phi.ll37
2 files changed, 73 insertions, 0 deletions
diff --git a/test/Transforms/NaCl/expand-tls-constexpr.ll b/test/Transforms/NaCl/expand-tls-constexpr.ll
index 06bb8ed830..b7ab253692 100644
--- a/test/Transforms/NaCl/expand-tls-constexpr.ll
+++ b/test/Transforms/NaCl/expand-tls-constexpr.ll
@@ -114,3 +114,39 @@ return:
; CHECK: %expanded = getelementptr inbounds i32* @tvar, i32 1
; CHECK: return:
; CHECK: %result = phi i32* [ %expanded, %entry ], [ null, %else ]
+
+
+; This tests that ExpandTlsConstantExpr correctly handles a PHI node
+; that contains the same ConstantExpr twice. Using
+; replaceAllUsesWith() is not correct on a PHI node when the new
+; instruction has to be added to an incoming block.
+define i32 @test_converting_phi_twice(i1 %arg) {
+ br i1 %arg, label %iftrue, label %iffalse
+iftrue:
+ br label %exit
+iffalse:
+ br label %exit
+exit:
+ %result = phi i32 [ ptrtoint (i32* @tvar to i32), %iftrue ],
+ [ ptrtoint (i32* @tvar to i32), %iffalse ]
+ ret i32 %result
+}
+; CHECK: define i32 @test_converting_phi_twice(i1 %arg)
+; CHECK: iftrue:
+; CHECK: %expanded{{.*}} = ptrtoint i32* @tvar to i32
+; CHECK: iffalse:
+; CHECK: %expanded{{.*}} = ptrtoint i32* @tvar to i32
+; CHECK: exit:
+; CHECK: %result = phi i32 [ %expanded1, %iftrue ], [ %expanded, %iffalse ]
+
+
+define i32 @test_converting_phi_multiple_entry(i1 %arg) {
+entry:
+ br i1 %arg, label %done, label %done
+done:
+ %result = phi i32 [ ptrtoint (i32* @tvar to i32), %entry ],
+ [ ptrtoint (i32* @tvar to i32), %entry ]
+ ret i32 %result
+}
+; CHECK: define i32 @test_converting_phi_multiple_entry(i1 %arg)
+; CHECK: %result = phi i32 [ %expanded, %entry ], [ %expanded, %entry ]
diff --git a/test/Transforms/NaCl/expand-tls-phi.ll b/test/Transforms/NaCl/expand-tls-phi.ll
index 0292a1d633..4aa0a7a32c 100644
--- a/test/Transforms/NaCl/expand-tls-phi.ll
+++ b/test/Transforms/NaCl/expand-tls-phi.ll
@@ -16,8 +16,45 @@ return:
}
; The TLS access gets pushed back into the PHI node's incoming block,
; which might be suboptimal but works in all cases.
+; CHECK: define i32* @get_tvar(i1 %cmp) {
; CHECK: entry:
; CHECK: %field = getelementptr %tls_struct* %tls_struct, i32 -1, i32 0, i32 0
; CHECK: else:
; CHECK: return:
; CHECK: %result = phi i32* [ %field, %entry ], [ null, %else ]
+
+
+; This tests that ExpandTls correctly handles a PHI node that contains
+; the same TLS variable twice. Using replaceAllUsesWith() is not
+; correct on a PHI node when the new instruction has to be added to an
+; incoming block.
+define i32* @tls_phi_twice(i1 %arg) {
+ br i1 %arg, label %iftrue, label %iffalse
+iftrue:
+ br label %exit
+iffalse:
+ br label %exit
+exit:
+ %result = phi i32* [ @tvar, %iftrue ], [ @tvar, %iffalse ]
+ ret i32* %result
+}
+; CHECK: define i32* @tls_phi_twice(i1 %arg) {
+; CHECK: iftrue:
+; CHECK: %field{{.*}} = getelementptr %tls_struct* %tls_struct{{.*}}, i32 -1, i32 0, i32 0
+; CHECK: iffalse:
+; CHECK: %field{{.*}} = getelementptr %tls_struct* %tls_struct{{.*}}, i32 -1, i32 0, i32 0
+; CHECK: exit:
+; CHECK: %result = phi i32* [ %field{{.*}}, %iftrue ], [ %field{{.*}}, %iffalse ]
+
+
+; In this corner case, ExpandTls must expand out @tvar only once,
+; otherwise it will produce invalid IR.
+define i32* @tls_phi_multiple_entry(i1 %arg) {
+entry:
+ br i1 %arg, label %done, label %done
+done:
+ %result = phi i32* [ @tvar, %entry ], [ @tvar, %entry ]
+ ret i32* %result
+}
+; CHECK: define i32* @tls_phi_multiple_entry(i1 %arg) {
+; CHECK: %result = phi i32* [ %field, %entry ], [ %field, %entry ]