1 ; RUN: opt < %s -slsr -gvn -S | FileCheck %s
3 target datalayout = "e-i64:64-v16:16-v32:32-n16:32:64"
15 define void @slsr_gep(i32* %input, i64 %s) {
16 ; CHECK-LABEL: @slsr_gep(
18 %p0 = getelementptr inbounds i32, i32* %input, i64 0
19 %v0 = load i32, i32* %p0
20 call void @foo(i32 %v0)
23 %p1 = getelementptr inbounds i32, i32* %input, i64 %s
24 ; CHECK: %p1 = getelementptr inbounds i32, i32* %input, i64 %s
25 %v1 = load i32, i32* %p1
26 call void @foo(i32 %v1)
29 %s2 = shl nsw i64 %s, 1
30 %p2 = getelementptr inbounds i32, i32* %input, i64 %s2
31 ; CHECK: %p2 = getelementptr inbounds i32, i32* %p1, i64 %s
32 %v2 = load i32, i32* %p2
33 call void @foo(i32 %v2)
39 ; foo(input[(long)s]);
40 ; foo(input[(long)(s * 2)]);
48 define void @slsr_gep_sext(i32* %input, i32 %s) {
49 ; CHECK-LABEL: @slsr_gep_sext(
51 %p0 = getelementptr inbounds i32, i32* %input, i64 0
52 %v0 = load i32, i32* %p0
53 call void @foo(i32 %v0)
56 %t = sext i32 %s to i64
57 %p1 = getelementptr inbounds i32, i32* %input, i64 %t
58 ; CHECK: %p1 = getelementptr inbounds i32, i32* %input, i64 %t
59 %v1 = load i32, i32* %p1
60 call void @foo(i32 %v1)
63 %s2 = shl nsw i32 %s, 1
64 %t2 = sext i32 %s2 to i64
65 %p2 = getelementptr inbounds i32, i32* %input, i64 %t2
66 ; CHECK: %p2 = getelementptr inbounds i32, i32* %p1, i64 %t
67 %v2 = load i32, i32* %p2
68 call void @foo(i32 %v2)
75 ; foo(input[s * 2][t]);
76 ; foo(input[s * 3][t]);
84 define void @slsr_gep_2d([10 x [5 x i32]]* %input, i64 %s, i64 %t) {
85 ; CHECK-LABEL: @slsr_gep_2d(
87 %p0 = getelementptr inbounds [10 x [5 x i32]], [10 x [5 x i32]]* %input, i64 0, i64 %s, i64 %t
88 %v0 = load i32, i32* %p0
89 call void @foo(i32 %v0)
91 ; v1 = input[s * 2][t];
92 %s2 = shl nsw i64 %s, 1
93 ; CHECK: [[BUMP:%[a-zA-Z0-9]+]] = mul i64 %s, 5
94 %p1 = getelementptr inbounds [10 x [5 x i32]], [10 x [5 x i32]]* %input, i64 0, i64 %s2, i64 %t
95 ; CHECK: %p1 = getelementptr inbounds i32, i32* %p0, i64 [[BUMP]]
96 %v1 = load i32, i32* %p1
97 call void @foo(i32 %v1)
99 ; v3 = input[s * 3][t];
100 %s3 = mul nsw i64 %s, 3
101 %p2 = getelementptr inbounds [10 x [5 x i32]], [10 x [5 x i32]]* %input, i64 0, i64 %s3, i64 %t
102 ; CHECK: %p2 = getelementptr inbounds i32, i32* %p1, i64 [[BUMP]]
103 %v2 = load i32, i32* %p2
104 call void @foo(i32 %v2)
109 %struct.S = type <{ i64, i32 }>
111 ; In this case, the bump
112 ; = (char *)&input[s * 2][t].f1 - (char *)&input[s][t].f1
114 ; which may not be divisible by typeof(input[s][t].f1) = 8. Therefore, we
115 ; rewrite the candidates using byte offset instead of index offset as in
117 define void @slsr_gep_uglygep([10 x [5 x %struct.S]]* %input, i64 %s, i64 %t) {
118 ; CHECK-LABEL: @slsr_gep_uglygep(
119 ; v0 = input[s][t].f1;
120 %p0 = getelementptr inbounds [10 x [5 x %struct.S]], [10 x [5 x %struct.S]]* %input, i64 0, i64 %s, i64 %t, i32 0
121 %v0 = load i64, i64* %p0
122 call void @bar(i64 %v0)
124 ; v1 = input[s * 2][t].f1;
125 %s2 = shl nsw i64 %s, 1
126 ; CHECK: [[BUMP:%[a-zA-Z0-9]+]] = mul i64 %s, 60
127 %p1 = getelementptr inbounds [10 x [5 x %struct.S]], [10 x [5 x %struct.S]]* %input, i64 0, i64 %s2, i64 %t, i32 0
128 ; CHECK: getelementptr inbounds i8, i8* %{{[0-9]+}}, i64 [[BUMP]]
129 %v1 = load i64, i64* %p1
130 call void @bar(i64 %v1)
132 ; v2 = input[s * 3][t].f1;
133 %s3 = mul nsw i64 %s, 3
134 %p2 = getelementptr inbounds [10 x [5 x %struct.S]], [10 x [5 x %struct.S]]* %input, i64 0, i64 %s3, i64 %t, i32 0
135 ; CHECK: getelementptr inbounds i8, i8* %{{[0-9]+}}, i64 [[BUMP]]
136 %v2 = load i64, i64* %p2
137 call void @bar(i64 %v2)
142 define void @slsr_out_of_bounds_gep(i32* %input, i32 %s) {
143 ; CHECK-LABEL: @slsr_out_of_bounds_gep(
145 %p0 = getelementptr i32, i32* %input, i64 0
146 %v0 = load i32, i32* %p0
147 call void @foo(i32 %v0)
149 ; v1 = input[(long)s];
150 %t = sext i32 %s to i64
151 %p1 = getelementptr i32, i32* %input, i64 %t
152 ; CHECK: %p1 = getelementptr i32, i32* %input, i64 %t
153 %v1 = load i32, i32* %p1
154 call void @foo(i32 %v1)
156 ; v2 = input[(long)(s * 2)];
157 %s2 = shl nsw i32 %s, 1
158 %t2 = sext i32 %s2 to i64
159 %p2 = getelementptr i32, i32* %input, i64 %t2
160 ; CHECK: %p2 = getelementptr i32, i32* %p1, i64 %t
161 %v2 = load i32, i32* %p2
162 call void @foo(i32 %v2)
167 declare void @foo(i32)
168 declare void @bar(i64)