[DAGCombine] Fix a bug in MergeConsecutiveStores.
[oota-llvm.git] / test / CodeGen / SystemZ / cond-store-07.ll
1 ; Test STOCs that are presented as selects.
2 ;
3 ; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z196 | FileCheck %s
4
5 declare void @foo(i32 *)
6
7 ; Test the simple case, with the loaded value first.
8 define void @f1(i32 *%ptr, i32 %alt, i32 %limit) {
9 ; CHECK-LABEL: f1:
10 ; CHECK: clfi %r4, 42
11 ; CHECK: stoche %r3, 0(%r2)
12 ; CHECK: br %r14
13   %cond = icmp ult i32 %limit, 42
14   %orig = load i32 , i32 *%ptr
15   %res = select i1 %cond, i32 %orig, i32 %alt
16   store i32 %res, i32 *%ptr
17   ret void
18 }
19
20 ; ...and with the loaded value second
21 define void @f2(i32 *%ptr, i32 %alt, i32 %limit) {
22 ; CHECK-LABEL: f2:
23 ; CHECK: clfi %r4, 42
24 ; CHECK: stocl %r3, 0(%r2)
25 ; CHECK: br %r14
26   %cond = icmp ult i32 %limit, 42
27   %orig = load i32 , i32 *%ptr
28   %res = select i1 %cond, i32 %alt, i32 %orig
29   store i32 %res, i32 *%ptr
30   ret void
31 }
32
33 ; Test cases where the value is explicitly sign-extended to 64 bits, with the
34 ; loaded value first.
35 define void @f3(i32 *%ptr, i64 %alt, i32 %limit) {
36 ; CHECK-LABEL: f3:
37 ; CHECK: clfi %r4, 42
38 ; CHECK: stoche %r3, 0(%r2)
39 ; CHECK: br %r14
40   %cond = icmp ult i32 %limit, 42
41   %orig = load i32 , i32 *%ptr
42   %ext = sext i32 %orig to i64
43   %res = select i1 %cond, i64 %ext, i64 %alt
44   %trunc = trunc i64 %res to i32
45   store i32 %trunc, i32 *%ptr
46   ret void
47 }
48
49 ; ...and with the loaded value second
50 define void @f4(i32 *%ptr, i64 %alt, i32 %limit) {
51 ; CHECK-LABEL: f4:
52 ; CHECK: clfi %r4, 42
53 ; CHECK: stocl %r3, 0(%r2)
54 ; CHECK: br %r14
55   %cond = icmp ult i32 %limit, 42
56   %orig = load i32 , i32 *%ptr
57   %ext = sext i32 %orig to i64
58   %res = select i1 %cond, i64 %alt, i64 %ext
59   %trunc = trunc i64 %res to i32
60   store i32 %trunc, i32 *%ptr
61   ret void
62 }
63
64 ; Test cases where the value is explicitly zero-extended to 32 bits, with the
65 ; loaded value first.
66 define void @f5(i32 *%ptr, i64 %alt, i32 %limit) {
67 ; CHECK-LABEL: f5:
68 ; CHECK: clfi %r4, 42
69 ; CHECK: stoche %r3, 0(%r2)
70 ; CHECK: br %r14
71   %cond = icmp ult i32 %limit, 42
72   %orig = load i32 , i32 *%ptr
73   %ext = zext i32 %orig to i64
74   %res = select i1 %cond, i64 %ext, i64 %alt
75   %trunc = trunc i64 %res to i32
76   store i32 %trunc, i32 *%ptr
77   ret void
78 }
79
80 ; ...and with the loaded value second
81 define void @f6(i32 *%ptr, i64 %alt, i32 %limit) {
82 ; CHECK-LABEL: f6:
83 ; CHECK: clfi %r4, 42
84 ; CHECK: stocl %r3, 0(%r2)
85 ; CHECK: br %r14
86   %cond = icmp ult i32 %limit, 42
87   %orig = load i32 , i32 *%ptr
88   %ext = zext i32 %orig to i64
89   %res = select i1 %cond, i64 %alt, i64 %ext
90   %trunc = trunc i64 %res to i32
91   store i32 %trunc, i32 *%ptr
92   ret void
93 }
94
95 ; Check the high end of the aligned STOC range.
96 define void @f7(i32 *%base, i32 %alt, i32 %limit) {
97 ; CHECK-LABEL: f7:
98 ; CHECK: clfi %r4, 42
99 ; CHECK: stoche %r3, 524284(%r2)
100 ; CHECK: br %r14
101   %ptr = getelementptr i32, i32 *%base, i64 131071
102   %cond = icmp ult i32 %limit, 42
103   %orig = load i32 , i32 *%ptr
104   %res = select i1 %cond, i32 %orig, i32 %alt
105   store i32 %res, i32 *%ptr
106   ret void
107 }
108
109 ; Check the next word up.  Other sequences besides this one would be OK.
110 define void @f8(i32 *%base, i32 %alt, i32 %limit) {
111 ; CHECK-LABEL: f8:
112 ; CHECK: agfi %r2, 524288
113 ; CHECK: clfi %r4, 42
114 ; CHECK: stoche %r3, 0(%r2)
115 ; CHECK: br %r14
116   %ptr = getelementptr i32, i32 *%base, i64 131072
117   %cond = icmp ult i32 %limit, 42
118   %orig = load i32 , i32 *%ptr
119   %res = select i1 %cond, i32 %orig, i32 %alt
120   store i32 %res, i32 *%ptr
121   ret void
122 }
123
124 ; Check the low end of the STOC range.
125 define void @f9(i32 *%base, i32 %alt, i32 %limit) {
126 ; CHECK-LABEL: f9:
127 ; CHECK: clfi %r4, 42
128 ; CHECK: stoche %r3, -524288(%r2)
129 ; CHECK: br %r14
130   %ptr = getelementptr i32, i32 *%base, i64 -131072
131   %cond = icmp ult i32 %limit, 42
132   %orig = load i32 , i32 *%ptr
133   %res = select i1 %cond, i32 %orig, i32 %alt
134   store i32 %res, i32 *%ptr
135   ret void
136 }
137
138 ; Check the next word down, with the same comments as f8.
139 define void @f10(i32 *%base, i32 %alt, i32 %limit) {
140 ; CHECK-LABEL: f10:
141 ; CHECK: agfi %r2, -524292
142 ; CHECK: clfi %r4, 42
143 ; CHECK: stoche %r3, 0(%r2)
144 ; CHECK: br %r14
145   %ptr = getelementptr i32, i32 *%base, i64 -131073
146   %cond = icmp ult i32 %limit, 42
147   %orig = load i32 , i32 *%ptr
148   %res = select i1 %cond, i32 %orig, i32 %alt
149   store i32 %res, i32 *%ptr
150   ret void
151 }
152
153 ; Try a frame index base.
154 define void @f11(i32 %alt, i32 %limit) {
155 ; CHECK-LABEL: f11:
156 ; CHECK: brasl %r14, foo@PLT
157 ; CHECK: stoche {{%r[0-9]+}}, {{[0-9]+}}(%r15)
158 ; CHECK: brasl %r14, foo@PLT
159 ; CHECK: br %r14
160   %ptr = alloca i32
161   call void @foo(i32 *%ptr)
162   %cond = icmp ult i32 %limit, 42
163   %orig = load i32 , i32 *%ptr
164   %res = select i1 %cond, i32 %orig, i32 %alt
165   store i32 %res, i32 *%ptr
166   call void @foo(i32 *%ptr)
167   ret void
168 }
169
170 ; Test that conditionally-executed stores do not use STOC, since STOC
171 ; is allowed to trap even when the condition is false.
172 define void @f12(i32 %a, i32 %b, i32 *%dest) {
173 ; CHECK-LABEL: f12:
174 ; CHECK-NOT: stoc
175 ; CHECK: br %r14
176 entry:
177   %cmp = icmp ule i32 %a, %b
178   br i1 %cmp, label %store, label %exit
179
180 store:
181   store i32 %b, i32 *%dest
182   br label %exit
183
184 exit:
185   ret void
186 }