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