LegalizeDAG: allow libcalls for max/min atomic operations
[oota-llvm.git] / test / CodeGen / ARM / atomic-op.ll
1 ; RUN: llc < %s -mtriple=armv7-apple-ios -verify-machineinstrs | FileCheck %s
2 ; RUN: llc < %s -mtriple=thumbv7-apple-ios -verify-machineinstrs | FileCheck %s
3 ; RUN: llc < %s -mtriple=thumbv6-apple-ios -verify-machineinstrs | FileCheck %s --check-prefix=CHECK-T1
4
5 define void @func(i32 %argc, i8** %argv) nounwind {
6 entry:
7         %argc.addr = alloca i32         ; <i32*> [#uses=1]
8         %argv.addr = alloca i8**                ; <i8***> [#uses=1]
9         %val1 = alloca i32              ; <i32*> [#uses=2]
10         %val2 = alloca i32              ; <i32*> [#uses=15]
11         %andt = alloca i32              ; <i32*> [#uses=2]
12         %ort = alloca i32               ; <i32*> [#uses=2]
13         %xort = alloca i32              ; <i32*> [#uses=2]
14         %old = alloca i32               ; <i32*> [#uses=18]
15         %temp = alloca i32              ; <i32*> [#uses=2]
16         store i32 %argc, i32* %argc.addr
17         store i8** %argv, i8*** %argv.addr
18         store i32 0, i32* %val1
19         store i32 31, i32* %val2
20         store i32 3855, i32* %andt
21         store i32 3855, i32* %ort
22         store i32 3855, i32* %xort
23         store i32 4, i32* %temp
24         %tmp = load i32* %temp
25   ; CHECK: ldrex
26   ; CHECK: add
27   ; CHECK: strex
28   ; CHECK-T1: blx ___sync_fetch_and_add_4
29   %0 = atomicrmw add i32* %val1, i32 %tmp monotonic
30         store i32 %0, i32* %old
31   ; CHECK: ldrex
32   ; CHECK: sub
33   ; CHECK: strex
34   ; CHECK-T1: blx ___sync_fetch_and_sub_4
35   %1 = atomicrmw sub i32* %val2, i32 30 monotonic
36         store i32 %1, i32* %old
37   ; CHECK: ldrex
38   ; CHECK: add
39   ; CHECK: strex
40   ; CHECK-T1: blx ___sync_fetch_and_add_4
41   %2 = atomicrmw add i32* %val2, i32 1 monotonic
42         store i32 %2, i32* %old
43   ; CHECK: ldrex
44   ; CHECK: sub
45   ; CHECK: strex
46   ; CHECK-T1: blx ___sync_fetch_and_sub_4
47   %3 = atomicrmw sub i32* %val2, i32 1 monotonic
48         store i32 %3, i32* %old
49   ; CHECK: ldrex
50   ; CHECK: and
51   ; CHECK: strex
52   ; CHECK-T1: blx ___sync_fetch_and_and_4
53   %4 = atomicrmw and i32* %andt, i32 4080 monotonic
54         store i32 %4, i32* %old
55   ; CHECK: ldrex
56   ; CHECK: or
57   ; CHECK: strex
58   ; CHECK-T1: blx ___sync_fetch_and_or_4
59   %5 = atomicrmw or i32* %ort, i32 4080 monotonic
60         store i32 %5, i32* %old
61   ; CHECK: ldrex
62   ; CHECK: eor
63   ; CHECK: strex
64   ; CHECK-T1: blx ___sync_fetch_and_xor_4
65   %6 = atomicrmw xor i32* %xort, i32 4080 monotonic
66         store i32 %6, i32* %old
67   ; CHECK: ldrex
68   ; CHECK: cmp
69   ; CHECK: strex
70   ; CHECK-T1: blx ___sync_fetch_and_min_4
71   %7 = atomicrmw min i32* %val2, i32 16 monotonic
72         store i32 %7, i32* %old
73         %neg = sub i32 0, 1
74   ; CHECK: ldrex
75   ; CHECK: cmp
76   ; CHECK: strex
77   ; CHECK-T1: blx ___sync_fetch_and_min_4
78   %8 = atomicrmw min i32* %val2, i32 %neg monotonic
79         store i32 %8, i32* %old
80   ; CHECK: ldrex
81   ; CHECK: cmp
82   ; CHECK: strex
83   ; CHECK-T1: blx ___sync_fetch_and_max_4
84   %9 = atomicrmw max i32* %val2, i32 1 monotonic
85         store i32 %9, i32* %old
86   ; CHECK: ldrex
87   ; CHECK: cmp
88   ; CHECK: strex
89   ; CHECK-T1: blx ___sync_fetch_and_max_4
90   %10 = atomicrmw max i32* %val2, i32 0 monotonic
91         store i32 %10, i32* %old
92   ; CHECK: ldrex
93   ; CHECK: cmp
94   ; CHECK: strex
95   ; CHECK-T1: blx ___sync_fetch_and_umin_4
96   %11 = atomicrmw umin i32* %val2, i32 16 monotonic
97         store i32 %11, i32* %old
98         %uneg = sub i32 0, 1
99   ; CHECK: ldrex
100   ; CHECK: cmp
101   ; CHECK: strex
102   ; CHECK-T1: blx ___sync_fetch_and_umin_4
103   %12 = atomicrmw umin i32* %val2, i32 %uneg monotonic
104         store i32 %12, i32* %old
105   ; CHECK: ldrex
106   ; CHECK: cmp
107   ; CHECK: strex
108   ; CHECK-T1: blx ___sync_fetch_and_umax_4
109   %13 = atomicrmw umax i32* %val2, i32 1 monotonic
110         store i32 %13, i32* %old
111   ; CHECK: ldrex
112   ; CHECK: cmp
113   ; CHECK: strex
114   ; CHECK-T1: blx ___sync_fetch_and_umax_4
115   %14 = atomicrmw umax i32* %val2, i32 0 monotonic
116         store i32 %14, i32* %old
117
118   ret void
119 }
120
121 define void @func2() nounwind {
122 entry:
123   %val = alloca i16
124   %old = alloca i16
125   store i16 31, i16* %val
126   ; CHECK: ldrex
127   ; CHECK: cmp
128   ; CHECK: strex
129   ; CHECK-T1: blx ___sync_fetch_and_umin_2
130   %0 = atomicrmw umin i16* %val, i16 16 monotonic
131   store i16 %0, i16* %old
132   %uneg = sub i16 0, 1
133   ; CHECK: ldrex
134   ; CHECK: cmp
135   ; CHECK: strex
136   ; CHECK-T1: blx ___sync_fetch_and_umin_2
137   %1 = atomicrmw umin i16* %val, i16 %uneg monotonic
138   store i16 %1, i16* %old
139   ; CHECK: ldrex
140   ; CHECK: cmp
141   ; CHECK: strex
142   ; CHECK-T1: blx ___sync_fetch_and_umax_2
143   %2 = atomicrmw umax i16* %val, i16 1 monotonic
144   store i16 %2, i16* %old
145   ; CHECK: ldrex
146   ; CHECK: cmp
147   ; CHECK: strex
148   ; CHECK-T1: blx ___sync_fetch_and_umax_2
149   %3 = atomicrmw umax i16* %val, i16 0 monotonic
150   store i16 %3, i16* %old
151   ret void
152 }
153
154 define void @func3() nounwind {
155 entry:
156   %val = alloca i8
157   %old = alloca i8
158   store i8 31, i8* %val
159   ; CHECK: ldrex
160   ; CHECK: cmp
161   ; CHECK: strex
162   ; CHECK-T1: blx ___sync_fetch_and_umin_1
163   %0 = atomicrmw umin i8* %val, i8 16 monotonic
164   store i8 %0, i8* %old
165   ; CHECK: ldrex
166   ; CHECK: cmp
167   ; CHECK: strex
168   ; CHECK-T1: blx ___sync_fetch_and_umin_1
169   %uneg = sub i8 0, 1
170   %1 = atomicrmw umin i8* %val, i8 %uneg monotonic
171   store i8 %1, i8* %old
172   ; CHECK: ldrex
173   ; CHECK: cmp
174   ; CHECK: strex
175   ; CHECK-T1: blx ___sync_fetch_and_umax_1
176   %2 = atomicrmw umax i8* %val, i8 1 monotonic
177   store i8 %2, i8* %old
178   ; CHECK: ldrex
179   ; CHECK: cmp
180   ; CHECK: strex
181   ; CHECK-T1: blx ___sync_fetch_and_umax_1
182   %3 = atomicrmw umax i8* %val, i8 0 monotonic
183   store i8 %3, i8* %old
184   ret void
185 }
186
187 ; CHECK: func4
188 ; This function should not need to use callee-saved registers.
189 ; rdar://problem/12203728
190 ; CHECK-NOT: r4
191 define i32 @func4(i32* %p) nounwind optsize ssp {
192 entry:
193   %0 = atomicrmw add i32* %p, i32 1 monotonic
194   ret i32 %0
195 }