summaryrefslogtreecommitdiffstats
path: root/test/Transforms/JumpThreading
diff options
context:
space:
mode:
Diffstat (limited to 'test/Transforms/JumpThreading')
-rw-r--r--test/Transforms/JumpThreading/2010-08-26-and.ll2
-rw-r--r--test/Transforms/JumpThreading/and-and-cond.ll10
-rw-r--r--test/Transforms/JumpThreading/and-cond.ll9
-rw-r--r--test/Transforms/JumpThreading/basic.ll2
-rw-r--r--test/Transforms/JumpThreading/crash.ll27
-rw-r--r--test/Transforms/JumpThreading/degenerate-phi.ll24
-rw-r--r--test/Transforms/JumpThreading/indirectbr.ll94
-rw-r--r--test/Transforms/JumpThreading/lvi-load.ll2
-rw-r--r--test/Transforms/JumpThreading/select.ll123
-rw-r--r--test/Transforms/JumpThreading/thread-loads.ll9
10 files changed, 292 insertions, 10 deletions
diff --git a/test/Transforms/JumpThreading/2010-08-26-and.ll b/test/Transforms/JumpThreading/2010-08-26-and.ll
index 17a0aba..2d6caf75 100644
--- a/test/Transforms/JumpThreading/2010-08-26-and.ll
+++ b/test/Transforms/JumpThreading/2010-08-26-and.ll
@@ -1,4 +1,4 @@
-; RUN: opt -jump-threading -enable-jump-threading-lvi -S < %s | FileCheck %s
+; RUN: opt -jump-threading -S < %s | FileCheck %s
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-n8:16:32:64"
target triple = "x86_64-apple-darwin10.0.0"
diff --git a/test/Transforms/JumpThreading/and-and-cond.ll b/test/Transforms/JumpThreading/and-and-cond.ll
index e6db9ee..765d940 100644
--- a/test/Transforms/JumpThreading/and-and-cond.ll
+++ b/test/Transforms/JumpThreading/and-and-cond.ll
@@ -1,14 +1,14 @@
-; RUN: opt < %s -jump-threading -mem2reg -instcombine -simplifycfg -S | grep {ret i32 %v1}
-; There should be no uncond branches left.
-; RUN: opt < %s -jump-threading -mem2reg -instcombine -simplifycfg -S | not grep {br label}
+; RUN: opt < %s -jump-threading -mem2reg -instcombine -simplifycfg -S | FileCheck %s
declare i32 @f1()
declare i32 @f2()
declare void @f3()
define i32 @test(i1 %cond, i1 %cond2, i1 %cond3) {
+; CHECK: test
br i1 %cond, label %T1, label %F1
+; CHECK-NOT: T1:
T1:
%v1 = call i32 @f1()
br label %Merge
@@ -18,6 +18,10 @@ F1:
br label %Merge
Merge:
+; CHECK: Merge:
+; CHECK: %v1 = call i32 @f1()
+; CHECK-NEXT: %D = and i1 %cond2, %cond3
+; CHECK-NEXT: br i1 %D
%A = phi i1 [true, %T1], [false, %F1]
%B = phi i32 [%v1, %T1], [%v2, %F1]
%C = and i1 %A, %cond2
diff --git a/test/Transforms/JumpThreading/and-cond.ll b/test/Transforms/JumpThreading/and-cond.ll
index 58dbec7..0159bb3 100644
--- a/test/Transforms/JumpThreading/and-cond.ll
+++ b/test/Transforms/JumpThreading/and-cond.ll
@@ -1,14 +1,14 @@
-; RUN: opt < %s -jump-threading -mem2reg -instcombine -simplifycfg -S | grep {ret i32 %v1}
-; There should be no uncond branches left.
-; RUN: opt < %s -jump-threading -mem2reg -instcombine -simplifycfg -S | not grep {br label}
+; RUN: opt < %s -jump-threading -mem2reg -instcombine -simplifycfg -S | FileCheck %s
declare i32 @f1()
declare i32 @f2()
declare void @f3()
define i32 @test(i1 %cond, i1 %cond2) {
+; CHECK: test
br i1 %cond, label %T1, label %F1
+; CHECK-NOT: T1
T1:
%v1 = call i32 @f1()
br label %Merge
@@ -18,6 +18,9 @@ F1:
br label %Merge
Merge:
+; CHECK: Merge:
+; CHECK: %v1 = call i32 @f1()
+; CHECK-NEXT: br i1 %cond2
%A = phi i1 [true, %T1], [false, %F1]
%B = phi i32 [%v1, %T1], [%v2, %F1]
%C = and i1 %A, %cond2
diff --git a/test/Transforms/JumpThreading/basic.ll b/test/Transforms/JumpThreading/basic.ll
index cd274e7..46271379 100644
--- a/test/Transforms/JumpThreading/basic.ll
+++ b/test/Transforms/JumpThreading/basic.ll
@@ -1,4 +1,4 @@
-; RUN: opt %s -jump-threading -S -enable-jump-threading-lvi | FileCheck %s
+; RUN: opt %s -jump-threading -S | FileCheck %s
declare i32 @f1()
declare i32 @f2()
diff --git a/test/Transforms/JumpThreading/crash.ll b/test/Transforms/JumpThreading/crash.ll
index 751bc65..aed51a1 100644
--- a/test/Transforms/JumpThreading/crash.ll
+++ b/test/Transforms/JumpThreading/crash.ll
@@ -484,3 +484,30 @@ bb269.us.us:
bb288.bb289.loopexit_crit_edge:
unreachable
}
+
+; PR 8247
+%struct.S1 = type { i8, i8 }
+@func_89.l_245 = internal constant %struct.S1 { i8 33, i8 6 }, align 1
+define void @func_89(i16 zeroext %p_90, %struct.S1* nocapture %p_91, i32* nocapture %p_92) nounwind ssp {
+entry:
+ store i32 0, i32* %p_92, align 4
+ br i1 false, label %lbl_260, label %if.else
+
+if.else: ; preds = %entry
+ br label %for.cond
+
+for.cond: ; preds = %lbl_260, %if.else
+ %l_245.0 = phi i16 [ %l_245.1, %lbl_260 ], [ 33, %if.else ]
+ %l_261.0 = phi i32 [ %and, %lbl_260 ], [ 255, %if.else ]
+ %tobool21 = icmp ult i16 %l_245.0, 256
+ br i1 %tobool21, label %if.end, label %lbl_260
+
+lbl_260: ; preds = %for.cond, %entry
+ %l_245.1 = phi i16 [ 1569, %entry ], [ %l_245.0, %for.cond ]
+ %l_261.1 = phi i32 [ 255, %entry ], [ %l_261.0, %for.cond ]
+ %and = and i32 %l_261.1, 1
+ br label %for.cond
+
+if.end: ; preds = %for.cond
+ ret void
+}
diff --git a/test/Transforms/JumpThreading/degenerate-phi.ll b/test/Transforms/JumpThreading/degenerate-phi.ll
new file mode 100644
index 0000000..35d9fde
--- /dev/null
+++ b/test/Transforms/JumpThreading/degenerate-phi.ll
@@ -0,0 +1,24 @@
+; RUN: opt -jump-threading -disable-output %s
+; PR9112
+
+; This is actually a test for value tracking. Jump threading produces
+; "%phi = phi i16" when it removes all edges leading to %unreachable.
+; The .ll parser won't let us write that directly since it's invalid code.
+
+define void @func() nounwind {
+entry:
+ br label %bb
+
+bb:
+ br label %bb
+
+unreachable:
+ %phi = phi i16 [ %add, %unreachable ], [ 0, %next ]
+ %add = add i16 0, %phi
+ %cmp = icmp slt i16 %phi, 0
+ br i1 %cmp, label %unreachable, label %next
+
+next:
+ br label %unreachable
+}
+
diff --git a/test/Transforms/JumpThreading/indirectbr.ll b/test/Transforms/JumpThreading/indirectbr.ll
new file mode 100644
index 0000000..141277f
--- /dev/null
+++ b/test/Transforms/JumpThreading/indirectbr.ll
@@ -0,0 +1,94 @@
+; RUN: opt -S < %s -jump-threading | FileCheck %s
+
+; Keep block addresses alive.
+@addresses = constant [4 x i8*] [
+ i8* blockaddress(@test1, %L1), i8* blockaddress(@test1, %L2),
+ i8* blockaddress(@test2, %L1), i8* blockaddress(@test2, %L2)
+]
+
+declare void @bar()
+declare void @baz()
+
+
+
+; Check basic jump threading for indirectbr instructions.
+
+; CHECK: void @test1
+; CHECK: br i1 %tobool, label %L1, label %indirectgoto
+; CHECK-NOT: if.else:
+; CHECK: L1:
+; CHECK: indirectbr i8* %address, [label %L1, label %L2]
+define void @test1(i32 %i, i8* %address) nounwind {
+entry:
+ %rem = srem i32 %i, 2
+ %tobool = icmp ne i32 %rem, 0
+ br i1 %tobool, label %indirectgoto, label %if.else
+
+if.else: ; preds = %entry
+ br label %indirectgoto
+
+L1: ; preds = %indirectgoto
+ call void @bar()
+ ret void
+
+L2: ; preds = %indirectgoto
+ call void @baz()
+ ret void
+
+indirectgoto: ; preds = %if.else, %entry
+ %indirect.goto.dest = phi i8* [ %address, %if.else ], [ blockaddress(@test1, %L1), %entry ]
+ indirectbr i8* %indirect.goto.dest, [label %L1, label %L2]
+}
+
+
+; Check constant folding of indirectbr
+
+; CHECK: void @test2
+; CHECK: entry:
+; CHECK-NEXT: br label %L1
+; CHECK: L1:
+; CHECK-NEXT: call void @bar
+; CHECK-NEXT: ret void
+define void @test2() nounwind {
+entry:
+ indirectbr i8* blockaddress(@test2, %L1), [label %L1, label %L2]
+
+L1: ; preds = %indirectgoto
+ call void @bar()
+ ret void
+
+L2: ; preds = %indirectgoto
+ call void @baz()
+ ret void
+}
+
+
+; PR4151
+; Don't merge address-taken blocks.
+@.str = private unnamed_addr constant [4 x i8] c"%p\0A\00"
+
+; CHECK: @test3
+; CHECK: __here:
+; CHECK: blockaddress(@test3, %__here)
+; CHECK: __here1:
+; CHECK: blockaddress(@test3, %__here1)
+; CHECK: __here3:
+; CHECK: blockaddress(@test3, %__here3)
+define void @test3() nounwind ssp noredzone {
+entry:
+ br label %__here
+
+__here: ; preds = %entry
+ %call = call i32 (...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i64 0, i64 0), i64 ptrtoint (i8* blockaddress(@test3, %__here) to i64)) nounwind noredzone
+ br label %__here1
+
+__here1: ; preds = %__here
+ %call2 = call i32 (...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i64 0, i64 0), i64 ptrtoint (i8* blockaddress(@test3, %__here1) to i64)) nounwind noredzone
+ br label %__here3
+
+__here3: ; preds = %__here1
+ %call4 = call i32 (...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i64 0, i64 0), i64 ptrtoint (i8* blockaddress(@test3, %__here3) to i64)) nounwind noredzone
+ ret void
+}
+
+declare i32 @printf(...) noredzone
diff --git a/test/Transforms/JumpThreading/lvi-load.ll b/test/Transforms/JumpThreading/lvi-load.ll
index 0bf4187..2a4cf92 100644
--- a/test/Transforms/JumpThreading/lvi-load.ll
+++ b/test/Transforms/JumpThreading/lvi-load.ll
@@ -1,4 +1,4 @@
-; RUN: opt -S -jump-threading -enable-jump-threading-lvi -dce < %s | FileCheck %s
+; RUN: opt -S -jump-threading -dce < %s | FileCheck %s
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-n8:16:32:64"
target triple = "x86_64-apple-darwin10.4"
diff --git a/test/Transforms/JumpThreading/select.ll b/test/Transforms/JumpThreading/select.ll
new file mode 100644
index 0000000..8a81857
--- /dev/null
+++ b/test/Transforms/JumpThreading/select.ll
@@ -0,0 +1,123 @@
+; RUN: opt -S -jump-threading < %s | FileCheck %s
+
+declare void @foo()
+declare void @bar()
+declare void @baz()
+declare void @quux()
+
+
+; Jump threading of branch with select as condition.
+; Mostly theoretical since instruction combining simplifies all selects of
+; booleans where at least one operand is true/false/undef.
+
+; CHECK: @test_br
+; CHECK-NEXT: entry:
+; CHECK-NEXT: br i1 %cond, label %L1,
+define void @test_br(i1 %cond, i1 %value) nounwind {
+entry:
+ br i1 %cond, label %L0, label %L3
+L0:
+ %expr = select i1 %cond, i1 true, i1 %value
+ br i1 %expr, label %L1, label %L2
+
+L1:
+ call void @foo()
+ ret void
+L2:
+ call void @bar()
+ ret void
+L3:
+ call void @baz()
+ br label %L0
+}
+
+
+; Jump threading of switch with select as condition.
+
+; CHECK: @test_switch
+; CHECK-NEXT: entry:
+; CHECK-NEXT: br i1 %cond, label %L1,
+define void @test_switch(i1 %cond, i8 %value) nounwind {
+entry:
+ br i1 %cond, label %L0, label %L4
+L0:
+ %expr = select i1 %cond, i8 1, i8 %value
+ switch i8 %expr, label %L3 [i8 1, label %L1 i8 2, label %L2]
+
+L1:
+ call void @foo()
+ ret void
+L2:
+ call void @bar()
+ ret void
+L3:
+ call void @baz()
+ ret void
+L4:
+ call void @quux()
+ br label %L0
+}
+
+; Make sure the blocks in the indirectbr test aren't trivially removable as
+; successors by taking their addresses.
+@anchor = constant [3 x i8*] [
+ i8* blockaddress(@test_indirectbr, %L1),
+ i8* blockaddress(@test_indirectbr, %L2),
+ i8* blockaddress(@test_indirectbr, %L3)
+]
+
+
+; Jump threading of indirectbr with select as address.
+
+; CHECK: @test_indirectbr
+; CHECK-NEXT: entry:
+; CHECK-NEXT: br i1 %cond, label %L1, label %L3
+define void @test_indirectbr(i1 %cond, i8* %address) nounwind {
+entry:
+ br i1 %cond, label %L0, label %L3
+L0:
+ %indirect.goto.dest = select i1 %cond, i8* blockaddress(@test_indirectbr, %L1), i8* %address
+ indirectbr i8* %indirect.goto.dest, [label %L1, label %L2, label %L3]
+
+L1:
+ call void @foo()
+ ret void
+L2:
+ call void @bar()
+ ret void
+L3:
+ call void @baz()
+ ret void
+}
+
+
+; A more complicated case: the condition is a select based on a comparison.
+
+; CHECK: @test_switch_cmp
+; CHECK-NEXT: entry:
+; CHECK-NEXT: br i1 %cond, label %L0, label %[[THREADED:[A-Za-z.0-9]+]]
+; CHECK: [[THREADED]]:
+; CHECK-NEXT: call void @quux
+; CHECK-NEXT: br label %L1
+define void @test_switch_cmp(i1 %cond, i32 %val, i8 %value) nounwind {
+entry:
+ br i1 %cond, label %L0, label %L4
+L0:
+ %val.phi = phi i32 [%val, %entry], [-1, %L4]
+ %cmp = icmp slt i32 %val.phi, 0
+ %expr = select i1 %cmp, i8 1, i8 %value
+ switch i8 %expr, label %L3 [i8 1, label %L1 i8 2, label %L2]
+
+L1:
+ call void @foo()
+ ret void
+L2:
+ call void @bar()
+ ret void
+L3:
+ call void @baz()
+ ret void
+L4:
+ call void @quux()
+ br label %L0
+}
diff --git a/test/Transforms/JumpThreading/thread-loads.ll b/test/Transforms/JumpThreading/thread-loads.ll
index 96ba701..cce23ea 100644
--- a/test/Transforms/JumpThreading/thread-loads.ll
+++ b/test/Transforms/JumpThreading/thread-loads.ll
@@ -1,4 +1,4 @@
-; RUN: opt < %s -jump-threading -simplifycfg -S | grep {ret i32 1}
+; RUN: opt < %s -jump-threading -S | FileCheck %s
; rdar://6402033
; Test that we can thread through the block with the partially redundant load (%2).
@@ -6,12 +6,16 @@ target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f3
target triple = "i386-apple-darwin7"
define i32 @foo(i32* %P) nounwind {
+; CHECK: foo
entry:
%0 = tail call i32 (...)* @f1() nounwind ; <i32> [#uses=1]
%1 = icmp eq i32 %0, 0 ; <i1> [#uses=1]
br i1 %1, label %bb1, label %bb
bb: ; preds = %entry
+; CHECK: bb1.thread:
+; CHECK: store
+; CHECK: br label %bb3
store i32 42, i32* %P, align 4
br label %bb1
@@ -26,6 +30,9 @@ bb2: ; preds = %bb1
ret i32 %res.0
bb3: ; preds = %bb1
+; CHECK: bb3:
+; CHECK: %res.01 = phi i32 [ 1, %bb1.thread ], [ 0, %bb1 ]
+; CHECK: ret i32 %res.01
ret i32 %res.0
}
OpenPOWER on IntegriCloud