1; RUN: opt -scalarrepl -S < %s | FileCheck %s
2; Test promotion of allocas that have phis and select users.
3target 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"
4target triple = "x86_64-apple-darwin10.2"
5
6%struct.X = type { i32 }
7%PairTy = type {i32, i32}
8
9; CHECK-LABEL: @test1(
10; CHECK: %a.0 = alloca i32
11; CHECK: %b.0 = alloca i32
12define i32 @test1(i32 %x) nounwind readnone ssp {
13entry:
14  %a = alloca %struct.X, align 8                  ; <%struct.X*> [#uses=2]
15  %b = alloca %struct.X, align 8                  ; <%struct.X*> [#uses=2]
16  %0 = getelementptr inbounds %struct.X* %a, i64 0, i32 0 ; <i32*> [#uses=1]
17  store i32 1, i32* %0, align 8
18  %1 = getelementptr inbounds %struct.X* %b, i64 0, i32 0 ; <i32*> [#uses=1]
19  store i32 2, i32* %1, align 8
20  %2 = icmp eq i32 %x, 0                          ; <i1> [#uses=1]
21  %p.0 = select i1 %2, %struct.X* %b, %struct.X* %a ; <%struct.X*> [#uses=1]
22  %3 = getelementptr inbounds %struct.X* %p.0, i64 0, i32 0 ; <i32*> [#uses=1]
23  %4 = load i32* %3, align 8                      ; <i32> [#uses=1]
24  ret i32 %4
25}
26
27; CHECK-LABEL: @test2(
28; CHECK: %X.ld = phi i32 [ 1, %entry ], [ 2, %T ]
29; CHECK-NEXT: ret i32 %X.ld
30define i32 @test2(i1 %c) {
31entry:
32  %A = alloca {i32, i32}
33  %B = getelementptr {i32, i32}* %A, i32 0, i32 0
34  store i32 1, i32* %B
35  br i1 %c, label %T, label %F
36T:
37  %C = getelementptr {i32, i32}* %A, i32 0, i32 1
38  store i32 2, i32* %C
39  br label %F
40F:
41  %X = phi i32* [%B, %entry], [%C, %T]
42  %Q = load i32* %X
43  ret i32 %Q
44}
45
46; CHECK-LABEL: @test3(
47; CHECK-NEXT: %Q = select i1 %c, i32 1, i32 2
48; CHECK-NEXT: ret i32 %Q
49; rdar://8904039
50define i32 @test3(i1 %c) {
51  %A = alloca {i32, i32}
52  %B = getelementptr {i32, i32}* %A, i32 0, i32 0
53  store i32 1, i32* %B
54  %C = getelementptr {i32, i32}* %A, i32 0, i32 1
55  store i32 2, i32* %C
56
57  %X = select i1 %c, i32* %B, i32* %C
58  %Q = load i32* %X
59  ret i32 %Q
60}
61
62;; We can't scalarize this, a use of the select is not an element access.
63define i64 @test4(i1 %c) {
64entry:
65  %A = alloca %PairTy
66  ; CHECK-LABEL: @test4(
67  ; CHECK: %A = alloca %PairTy
68  %B = getelementptr %PairTy* %A, i32 0, i32 0
69  store i32 1, i32* %B
70  %C = getelementptr %PairTy* %A, i32 0, i32 1
71  store i32 2, i32* %B
72
73  %X = select i1 %c, i32* %B, i32* %C
74  %Y = bitcast i32* %X to i64*
75  %Q = load i64* %Y
76  ret i64 %Q
77}
78
79
80;;
81;; Tests for promoting allocas used by selects.
82;; rdar://7339113
83;;
84
85define i32 @test5(i32 *%P) nounwind readnone ssp {
86entry:
87  %b = alloca i32, align 8
88  store i32 2, i32* %b, align 8
89
90  ;; Select on constant condition should be folded.
91  %p.0 = select i1 false, i32* %b, i32* %P
92  store i32 123, i32* %p.0
93
94  %r = load i32* %b, align 8
95  ret i32 %r
96
97; CHECK-LABEL: @test5(
98; CHECK: store i32 123, i32* %P
99; CHECK: ret i32 2
100}
101
102define i32 @test6(i32 %x, i1 %c) nounwind readnone ssp {
103  %a = alloca i32, align 8
104  %b = alloca i32, align 8
105  store i32 1, i32* %a, align 8
106  store i32 2, i32* %b, align 8
107  %p.0 = select i1 %c, i32* %b, i32* %a
108  %r = load i32* %p.0, align 8
109  ret i32 %r
110; CHECK-LABEL: @test6(
111; CHECK-NEXT: %r = select i1 %c, i32 2, i32 1
112; CHECK-NEXT: ret i32 %r
113}
114
115; Verify that the loads happen where the loads are, not where the select is.
116define i32 @test7(i32 %x, i1 %c) nounwind readnone ssp {
117  %a = alloca i32, align 8
118  %b = alloca i32, align 8
119  store i32 1, i32* %a
120  store i32 2, i32* %b
121  %p.0 = select i1 %c, i32* %b, i32* %a
122
123  store i32 0, i32* %a
124
125  %r = load i32* %p.0, align 8
126  ret i32 %r
127; CHECK-LABEL: @test7(
128; CHECK-NOT: alloca i32
129; CHECK: %r = select i1 %c, i32 2, i32 0
130; CHECK: ret i32 %r
131}
132
133;; Promote allocs that are PHI'd together by moving the loads.
134define i32 @test8(i32 %x) nounwind readnone ssp {
135; CHECK-LABEL: @test8(
136; CHECK-NOT: load i32
137; CHECK-NOT: store i32
138; CHECK: %p.0.ld = phi i32 [ 2, %entry ], [ 1, %T ]
139; CHECK-NEXT: ret i32 %p.0.ld
140entry:
141  %a = alloca i32, align 8
142  %b = alloca i32, align 8
143  store i32 1, i32* %a, align 8
144  store i32 2, i32* %b, align 8
145  %c = icmp eq i32 %x, 0
146  br i1 %c, label %T, label %Cont
147T:
148  br label %Cont
149Cont:
150  %p.0 = phi i32* [%b, %entry],[%a, %T]
151  %r = load i32* %p.0, align 8
152  ret i32 %r
153}
154