This patch follows is a follow up to r178171, which uses the register
[oota-llvm.git] / test / CodeGen / X86 / atom-call-reg-indirect-foldedreload32.ll
1 ; RUN: llc < %s -mtriple=i386-linux-gnu -mcpu=atom 2>&1 | \
2 ; RUN:     grep "calll" | not grep "("
3 ; RUN: llc < %s -mtriple=i386-linux-gnu -mcpu=core2 2>&1 | \
4 ; RUN:     grep "calll" | grep "4-byte Folded Reload"
5
6 %struct.targettype = type {i32}
7 %struct.op_ptr1 = type opaque
8 %struct.op_ptr2 = type opaque
9 %union.anon = type { [8 x i32], [48 x i8] }
10 %struct.const1 = type { [64 x i16], i8 }
11 %struct.const2 = type { [17 x i8], [256 x i8], i8 }
12
13 %struct.ref1 = type { void (%struct.ref2*)*, i32 (%struct.ref2*)*, void (%struct.ref2*)*, i32 (%struct.ref2*, i8***)*, %struct.op_ptr2** }
14 %struct.ref2 = type { %struct.localref13*, %struct.localref15*, %struct.localref12*, i8*, i8, i32, %struct.localref11*, i32, i32, i32, i32, i32, i32, i32, double, i8, i8, i32, i8, i8, i8, i32, i8, i32, i8, i8, i8, i32, i32, i32, i32, i32, i32, i8**, i32, i32, i32, i32, i32, [64 x i32]*, [4 x %struct.const1*], [4 x %struct.const2*], [4 x %struct.const2*], i32, %struct.ref3*, i8, i8, [16 x i8], [16 x i8], [16 x i8], i32, i8, i8, i8, i8, i16, i16, i8, i8, i8, %struct.localref10*, i32, i32, i32, i32, i8*, i32, [4 x %struct.ref3*], i32, i32, i32, [10 x i32], i32, i32, i32, i32, i32, %struct.localref8*, %struct.localref9*, %struct.ref1*, %struct.localref7*, %struct.localref6*, %struct.localref5*, %struct.localref1*, %struct.ref4*, %struct.localref2*, %struct.localref3*, %struct.localref4* }
15 %struct.ref3 = type { i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i8, i32, i32, i32, i32, i32, i32, %struct.const1*, i8* }
16 %struct.ref4 = type { void (%struct.ref2*)*, [5 x void (%struct.ref2*, %struct.ref3*, i16*, i8**, i32)*] }
17
18 %struct.localref1 = type { void (%struct.ref2*)*, i8 (%struct.ref2*, [64 x i16]**)*, i8 }
19 %struct.localref2 = type { void (%struct.ref2*)*, void (%struct.ref2*, i8***, i32*, i32, i8**, i32*, i32)*, i8 }
20 %struct.localref3 = type { void (%struct.ref2*)*, void (%struct.ref2*, i8***, i32, i8**, i32)* }
21 %struct.localref4 = type { {}*, void (%struct.ref2*, i8**, i8**, i32)*, void (%struct.ref2*)*, void (%struct.ref2*)* }
22 %struct.localref5 = type { void (%struct.ref2*)*, i32 (%struct.ref2*)*, i8 (%struct.ref2*)*, i8, i8, i32, i32 }
23 %struct.localref6 = type { i32 (%struct.ref2*)*, void (%struct.ref2*)*, void (%struct.ref2*)*, void (%struct.ref2*)*, i8, i8 }
24 %struct.localref7 = type { void (%struct.ref2*, i32)*, void (%struct.ref2*, i8***, i32*, i32, i8**, i32*, i32)* }
25 %struct.localref8 = type { void (%struct.ref2*)*, void (%struct.ref2*)*, i8 }
26 %struct.localref9 = type { void (%struct.ref2*, i32)*, void (%struct.ref2*, i8**, i32*, i32)* }
27 %struct.localref10 = type { %struct.localref10*, i8, i32, i32, i8* }
28 %struct.localref11 = type { i8*, %struct.targettype, void (%struct.ref2*)*, i8 (%struct.ref2*)*, void (%struct.ref2*, %struct.targettype)*, i8 (%struct.ref2*, i32)*, void (%struct.ref2*)* }
29 %struct.localref12 = type { {}*, %struct.targettype, %struct.targettype, i32, i32 }
30 %struct.localref13 = type { void (%struct.localref14*)*, void (%struct.localref14*, i32)*, void (%struct.localref14*)*, void (%struct.localref14*, i8*)*, void (%struct.localref14*)*, i32, %union.anon, i32, %struct.targettype, i8**, i32, i8**, i32, i32 }
31 %struct.localref14 = type { %struct.localref13*, %struct.localref15*, %struct.localref12*, i8*, i8, i32 }
32 %struct.localref15 = type { i8* (%struct.localref14*, i32, %struct.targettype)*, i8* (%struct.localref14*, i32, %struct.targettype)*, i8** (%struct.localref14*, i32, i32, i32)*, [64 x i16]** (%struct.localref14*, i32, i32, i32)*, %struct.op_ptr1* (%struct.localref14*, i32, i8, i32, i32, i32)*, %struct.op_ptr2* (%struct.localref14*, i32, i8, i32, i32, i32)*, {}*, i8** (%struct.localref14*, %struct.op_ptr1*, i32, i32, i8)*, [64 x i16]** (%struct.localref14*, %struct.op_ptr2*, i32, i32, i8)*, void (%struct.localref14*, i32)*, {}*, %struct.targettype, %struct.targettype}
33
34 define internal i32 @foldedreload(%struct.ref2* %cinfo, i8*** nocapture %output1) {
35   %1 = getelementptr inbounds %struct.ref2* %cinfo, i32 0, i32 79
36   %2 = load %struct.ref1** %1, align 4
37   %3 = getelementptr inbounds %struct.ref2* %cinfo, i32 0, i32 68
38   %4 = load i32* %3, align 4
39   %5 = add i32 %4, -1
40   %6 = getelementptr inbounds %struct.ref2* %cinfo, i32 0, i32 64
41   %7 = load i32* %6, align 4
42   %8 = add i32 %7, -1
43   %9 = getelementptr inbounds %struct.ref1* %2, i32 1, i32 1
44   %10 = bitcast i32 (%struct.ref2*)** %9 to i32*
45   %11 = load i32* %10, align 4
46   %12 = getelementptr inbounds %struct.ref1* %2, i32 1, i32 2
47   %13 = bitcast void (%struct.ref2*)** %12 to i32*
48   %14 = load i32* %13, align 4
49   %15 = icmp slt i32 %11, %14
50   br i1 %15, label %.lr.ph18, label %._crit_edge19
51
52 .lr.ph18:
53   %16 = getelementptr inbounds %struct.ref1* %2, i32 1
54   %17 = bitcast %struct.ref1* %16 to i32*
55   %18 = getelementptr inbounds %struct.ref1* %16, i32 0, i32 0
56   %19 = getelementptr inbounds %struct.ref2* %cinfo, i32 0, i32 66
57   %20 = getelementptr inbounds %struct.ref2* %cinfo, i32 0, i32 84
58   %21 = getelementptr inbounds %struct.ref2* %cinfo, i32 0, i32 36
59   %22 = getelementptr inbounds %struct.ref1* %2, i32 1, i32 3
60   %23 = bitcast i32 (%struct.ref2*, i8***)** %22 to [10 x [64 x i16]*]*
61   %.pre = load i32* %17, align 4
62   br label %24
63
64 ; <label>:24
65   %25 = phi i32 [ %14, %.lr.ph18 ], [ %89, %88 ]
66   %26 = phi i32 [ %.pre, %.lr.ph18 ], [ 0, %88 ]
67   %var1.015 = phi i32 [ %11, %.lr.ph18 ], [ %90, %88 ]
68   %27 = icmp ugt i32 %26, %5
69   br i1 %27, label %88, label %.preheader7.lr.ph
70
71 .preheader7.lr.ph:
72   %.pre24 = load i32* %19, align 4
73   br label %.preheader7
74
75 .preheader7:
76   %28 = phi i32 [ %.pre24, %.preheader7.lr.ph ], [ %85, %._crit_edge11 ]
77   %var2.012 = phi i32 [ %26, %.preheader7.lr.ph ], [ %86, %._crit_edge11 ]
78   %29 = icmp sgt i32 %28, 0
79   br i1 %29, label %.lr.ph10, label %._crit_edge11
80
81 .lr.ph10:
82   %30 = phi i32 [ %28, %.preheader7 ], [ %82, %81 ]
83   %var4.09 = phi i32 [ 0, %.preheader7 ], [ %var4.1.lcssa, %81 ]
84   %ci.08 = phi i32 [ 0, %.preheader7 ], [ %83, %81 ]
85   %31 = getelementptr inbounds %struct.ref2* %cinfo, i32 0, i32 67, i32 %ci.08
86   %32 = load %struct.ref3** %31, align 4
87   %33 = getelementptr inbounds %struct.ref3* %32, i32 0, i32 1
88   %34 = load i32* %33, align 4
89   %35 = load %struct.ref4** %20, align 4
90   %36 = getelementptr inbounds %struct.ref4* %35, i32 0, i32 1, i32 %34
91   %37 = load void (%struct.ref2*, %struct.ref3*, i16*, i8**, i32)** %36, align 4
92   %38 = getelementptr inbounds %struct.ref3* %32, i32 0, i32 17
93   %39 = load i32* %38, align 4
94   %40 = getelementptr inbounds %struct.ref3* %32, i32 0, i32 9
95   %41 = load i32* %40, align 4
96   %42 = getelementptr inbounds %struct.ref3* %32, i32 0, i32 16
97   %43 = load i32* %42, align 4
98   %44 = mul i32 %43, %var2.012
99   %45 = getelementptr inbounds %struct.ref3* %32, i32 0, i32 14
100   %46 = load i32* %45, align 4
101   %47 = icmp sgt i32 %46, 0
102   br i1 %47, label %.lr.ph6, label %81
103
104 .lr.ph6:
105   %48 = getelementptr inbounds i8*** %output1, i32 %34
106   %49 = mul nsw i32 %41, %var1.015
107   %50 = load i8*** %48, align 4
108   %51 = getelementptr inbounds i8** %50, i32 %49
109   %52 = getelementptr inbounds %struct.ref3* %32, i32 0, i32 13
110   %53 = getelementptr inbounds %struct.ref3* %32, i32 0, i32 18
111   %54 = icmp sgt i32 %39, 0
112   br i1 %54, label %.lr.ph6.split.us, label %.lr.ph6..lr.ph6.split_crit_edge
113
114 .lr.ph6..lr.ph6.split_crit_edge:
115   br label %._crit_edge26
116
117 .lr.ph6.split.us:
118   %55 = phi i32 [ %63, %._crit_edge28 ], [ %46, %.lr.ph6 ]
119   %56 = phi i32 [ %64, %._crit_edge28 ], [ %41, %.lr.ph6 ]
120   %var4.15.us = phi i32 [ %66, %._crit_edge28 ], [ %var4.09, %.lr.ph6 ]
121   %output2.04.us = phi i8** [ %69, %._crit_edge28 ], [ %51, %.lr.ph6 ]
122   %var5.03.us = phi i32 [ %67, %._crit_edge28 ], [ 0, %.lr.ph6 ]
123   %57 = load i32* %21, align 4
124   %58 = icmp ult i32 %57, %8
125   br i1 %58, label %.lr.ph.us, label %59
126
127 ; <label>:59
128   %60 = add nsw i32 %var5.03.us, %var1.015
129   %61 = load i32* %53, align 4
130   %62 = icmp slt i32 %60, %61
131   br i1 %62, label %.lr.ph.us, label %._crit_edge27
132
133 ._crit_edge27:
134   %63 = phi i32 [ %.pre23.pre, %.loopexit.us ], [ %55, %59 ]
135   %64 = phi i32 [ %74, %.loopexit.us ], [ %56, %59 ]
136   %65 = load i32* %52, align 4
137   %66 = add nsw i32 %65, %var4.15.us
138   %67 = add nsw i32 %var5.03.us, 1
139   %68 = icmp slt i32 %67, %63
140   br i1 %68, label %._crit_edge28, label %._crit_edge
141
142 ._crit_edge28:
143   %69 = getelementptr inbounds i8** %output2.04.us, i32 %64
144   br label %.lr.ph6.split.us
145
146 .lr.ph.us:
147   %var3.02.us = phi i32 [ %75, %.lr.ph.us ], [ %44, %.lr.ph6.split.us ], [ %44, %59 ]
148   %xindex.01.us = phi i32 [ %76, %.lr.ph.us ], [ 0, %.lr.ph6.split.us ], [ 0, %59 ]
149   %70 = add nsw i32 %xindex.01.us, %var4.15.us
150   %71 = getelementptr inbounds [10 x [64 x i16]*]* %23, i32 0, i32 %70
151   %72 = load [64 x i16]** %71, align 4
152   %73 = getelementptr inbounds [64 x i16]* %72, i32 0, i32 0
153   tail call void %37(%struct.ref2* %cinfo, %struct.ref3* %32, i16* %73, i8** %output2.04.us, i32 %var3.02.us) nounwind
154   %74 = load i32* %40, align 4
155   %75 = add i32 %74, %var3.02.us
156   %76 = add nsw i32 %xindex.01.us, 1
157   %exitcond = icmp eq i32 %76, %39
158   br i1 %exitcond, label %.loopexit.us, label %.lr.ph.us
159
160 .loopexit.us:
161   %.pre23.pre = load i32* %45, align 4
162   br label %._crit_edge27
163
164 ._crit_edge26:
165   %var4.15 = phi i32 [ %var4.09, %.lr.ph6..lr.ph6.split_crit_edge ], [ %78, %._crit_edge26 ]
166   %var5.03 = phi i32 [ 0, %.lr.ph6..lr.ph6.split_crit_edge ], [ %79, %._crit_edge26 ]
167   %77 = load i32* %52, align 4
168   %78 = add nsw i32 %77, %var4.15
169   %79 = add nsw i32 %var5.03, 1
170   %80 = icmp slt i32 %79, %46
171   br i1 %80, label %._crit_edge26, label %._crit_edge
172
173 ._crit_edge:
174   %split = phi i32 [ %66, %._crit_edge27 ], [ %78, %._crit_edge26 ]
175   %.pre25 = load i32* %19, align 4
176   br label %81
177
178 ; <label>:81
179   %82 = phi i32 [ %.pre25, %._crit_edge ], [ %30, %.lr.ph10 ]
180   %var4.1.lcssa = phi i32 [ %split, %._crit_edge ], [ %var4.09, %.lr.ph10 ]
181   %83 = add nsw i32 %ci.08, 1
182   %84 = icmp slt i32 %83, %82
183   br i1 %84, label %.lr.ph10, label %._crit_edge11
184
185 ._crit_edge11:
186   %85 = phi i32 [ %28, %.preheader7 ], [ %82, %81 ]
187   %86 = add i32 %var2.012, 1
188   %87 = icmp ugt i32 %86, %5
189   br i1 %87, label %._crit_edge14, label %.preheader7
190
191 ._crit_edge14:
192   %.pre21 = load i32* %13, align 4
193   br label %88
194
195 ; <label>:88
196   %89 = phi i32 [ %.pre21, %._crit_edge14 ], [ %25, %24 ]
197   store void (%struct.ref2*)* null, void (%struct.ref2*)** %18, align 4
198   %90 = add nsw i32 %var1.015, 1
199   %91 = icmp slt i32 %90, %89
200   br i1 %91, label %24, label %._crit_edge19
201
202 ._crit_edge19:
203   ret i32 3
204 }