1*cee313d2SEric Christopher; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2*cee313d2SEric Christopher;RUN: opt < %s -jump-threading -S | FileCheck %s
3*cee313d2SEric Christopher
4*cee313d2SEric Christopher
5*cee313d2SEric Christopherdeclare void @bar(...)
6*cee313d2SEric Christopherdeclare void @baz(...)
7*cee313d2SEric Christopher
8*cee313d2SEric Christopher; Make sure we thread the end of the bar block to the end of the function.
9*cee313d2SEric Christopherdefine void @test1(i32 %x) {
10*cee313d2SEric Christopher; CHECK-LABEL: @test1(
11*cee313d2SEric Christopher; CHECK-NEXT:  entry:
12*cee313d2SEric Christopher; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[X:%.*]], 9
13*cee313d2SEric Christopher; CHECK-NEXT:    br i1 [[CMP]], label [[IF_END_THREAD:%.*]], label [[IF_END:%.*]]
14*cee313d2SEric Christopher; CHECK:       if.end.thread:
15*cee313d2SEric Christopher; CHECK-NEXT:    call void (...) @bar()
16*cee313d2SEric Christopher; CHECK-NEXT:    br label [[IF_END4:%.*]]
17*cee313d2SEric Christopher; CHECK:       if.end:
18*cee313d2SEric Christopher; CHECK-NEXT:    [[X_OFF:%.*]] = add i32 [[X]], -3
19*cee313d2SEric Christopher; CHECK-NEXT:    [[TMP0:%.*]] = icmp ult i32 [[X_OFF]], 5
20*cee313d2SEric Christopher; CHECK-NEXT:    br i1 [[TMP0]], label [[IF_THEN3:%.*]], label [[IF_END4]]
21*cee313d2SEric Christopher; CHECK:       if.then3:
22*cee313d2SEric Christopher; CHECK-NEXT:    call void (...) @baz()
23*cee313d2SEric Christopher; CHECK-NEXT:    br label [[IF_END4]]
24*cee313d2SEric Christopher; CHECK:       if.end4:
25*cee313d2SEric Christopher; CHECK-NEXT:    ret void
26*cee313d2SEric Christopher;
27*cee313d2SEric Christopherentry:
28*cee313d2SEric Christopher  %cmp = icmp sgt i32 %x, 9
29*cee313d2SEric Christopher  br i1 %cmp, label %if.then, label %if.end
30*cee313d2SEric Christopher
31*cee313d2SEric Christopherif.then:                                          ; preds = %entry
32*cee313d2SEric Christopher  call void (...) @bar()
33*cee313d2SEric Christopher  br label %if.end
34*cee313d2SEric Christopher
35*cee313d2SEric Christopherif.end:                                           ; preds = %if.then, %entry
36*cee313d2SEric Christopher  %x.off = add i32 %x, -3
37*cee313d2SEric Christopher  %0 = icmp ult i32 %x.off, 5
38*cee313d2SEric Christopher  br i1 %0, label %if.then3, label %if.end4
39*cee313d2SEric Christopher
40*cee313d2SEric Christopherif.then3:                                         ; preds = %if.end
41*cee313d2SEric Christopher  call void (...) @baz()
42*cee313d2SEric Christopher  br label %if.end4
43*cee313d2SEric Christopher
44*cee313d2SEric Christopherif.end4:                                          ; preds = %if.then3, %if.end
45*cee313d2SEric Christopher  ret void
46*cee313d2SEric Christopher}
47*cee313d2SEric Christopher
48*cee313d2SEric Christopher; Make sure we thread the false side of the first if to the end of the function.
49*cee313d2SEric Christopherdefine void @test2(i32 %x) {
50*cee313d2SEric Christopher; CHECK-LABEL: @test2(
51*cee313d2SEric Christopher; CHECK-NEXT:  entry:
52*cee313d2SEric Christopher; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[X:%.*]], 9
53*cee313d2SEric Christopher; CHECK-NEXT:    br i1 [[CMP]], label [[IF_END:%.*]], label [[IF_END4:%.*]]
54*cee313d2SEric Christopher; CHECK:       if.end:
55*cee313d2SEric Christopher; CHECK-NEXT:    call void (...) @bar()
56*cee313d2SEric Christopher; CHECK-NEXT:    [[X_OFF:%.*]] = add i32 [[X]], -3
57*cee313d2SEric Christopher; CHECK-NEXT:    [[TMP0:%.*]] = icmp ult i32 [[X_OFF]], 5
58*cee313d2SEric Christopher; CHECK-NEXT:    br i1 [[TMP0]], label [[IF_THEN3:%.*]], label [[IF_END4]]
59*cee313d2SEric Christopher; CHECK:       if.then3:
60*cee313d2SEric Christopher; CHECK-NEXT:    call void (...) @baz()
61*cee313d2SEric Christopher; CHECK-NEXT:    br label [[IF_END4]]
62*cee313d2SEric Christopher; CHECK:       if.end4:
63*cee313d2SEric Christopher; CHECK-NEXT:    ret void
64*cee313d2SEric Christopher;
65*cee313d2SEric Christopherentry:
66*cee313d2SEric Christopher  %cmp = icmp slt i32 %x, 9
67*cee313d2SEric Christopher  br i1 %cmp, label %if.then, label %if.end
68*cee313d2SEric Christopher
69*cee313d2SEric Christopherif.then:                                          ; preds = %entry
70*cee313d2SEric Christopher  call void (...) @bar()
71*cee313d2SEric Christopher  br label %if.end
72*cee313d2SEric Christopher
73*cee313d2SEric Christopherif.end:                                           ; preds = %if.then, %entry
74*cee313d2SEric Christopher  %x.off = add i32 %x, -3
75*cee313d2SEric Christopher  %0 = icmp ult i32 %x.off, 5
76*cee313d2SEric Christopher  br i1 %0, label %if.then3, label %if.end4
77*cee313d2SEric Christopher
78*cee313d2SEric Christopherif.then3:                                         ; preds = %if.end
79*cee313d2SEric Christopher  call void (...) @baz()
80*cee313d2SEric Christopher  br label %if.end4
81*cee313d2SEric Christopher
82*cee313d2SEric Christopherif.end4:                                          ; preds = %if.then3, %if.end
83*cee313d2SEric Christopher  ret void
84*cee313d2SEric Christopher}
85*cee313d2SEric Christopher
86*cee313d2SEric Christopher; Negative test to make sure we don't thread when the ranges overlap.
87*cee313d2SEric Christopherdefine void @test3(i32 %x) {
88*cee313d2SEric Christopher; CHECK-LABEL: @test3(
89*cee313d2SEric Christopher; CHECK-NEXT:  entry:
90*cee313d2SEric Christopher; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[X:%.*]], 6
91*cee313d2SEric Christopher; CHECK-NEXT:    br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
92*cee313d2SEric Christopher; CHECK:       if.then:
93*cee313d2SEric Christopher; CHECK-NEXT:    call void (...) @bar()
94*cee313d2SEric Christopher; CHECK-NEXT:    br label [[IF_END]]
95*cee313d2SEric Christopher; CHECK:       if.end:
96*cee313d2SEric Christopher; CHECK-NEXT:    [[X_OFF:%.*]] = add i32 [[X]], -3
97*cee313d2SEric Christopher; CHECK-NEXT:    [[TMP0:%.*]] = icmp ult i32 [[X_OFF]], 5
98*cee313d2SEric Christopher; CHECK-NEXT:    br i1 [[TMP0]], label [[IF_THEN3:%.*]], label [[IF_END4:%.*]]
99*cee313d2SEric Christopher; CHECK:       if.then3:
100*cee313d2SEric Christopher; CHECK-NEXT:    call void (...) @baz()
101*cee313d2SEric Christopher; CHECK-NEXT:    br label [[IF_END4]]
102*cee313d2SEric Christopher; CHECK:       if.end4:
103*cee313d2SEric Christopher; CHECK-NEXT:    ret void
104*cee313d2SEric Christopher;
105*cee313d2SEric Christopherentry:
106*cee313d2SEric Christopher  %cmp = icmp sgt i32 %x, 6
107*cee313d2SEric Christopher  br i1 %cmp, label %if.then, label %if.end
108*cee313d2SEric Christopher
109*cee313d2SEric Christopherif.then:                                          ; preds = %entry
110*cee313d2SEric Christopher  call void (...) @bar()
111*cee313d2SEric Christopher  br label %if.end
112*cee313d2SEric Christopher
113*cee313d2SEric Christopherif.end:                                           ; preds = %if.then, %entry
114*cee313d2SEric Christopher  %x.off = add i32 %x, -3
115*cee313d2SEric Christopher  %0 = icmp ult i32 %x.off, 5
116*cee313d2SEric Christopher  br i1 %0, label %if.then3, label %if.end4
117*cee313d2SEric Christopher
118*cee313d2SEric Christopherif.then3:                                         ; preds = %if.end
119*cee313d2SEric Christopher  call void (...) @baz()
120*cee313d2SEric Christopher  br label %if.end4
121*cee313d2SEric Christopher
122*cee313d2SEric Christopherif.end4:                                          ; preds = %if.then3, %if.end
123*cee313d2SEric Christopher  ret void
124*cee313d2SEric Christopher}
125*cee313d2SEric Christopher
126