blob: bd92780a036c783ef68861425420557f5e71ff7c [file] [log] [blame]
Jingyue Wuf1edf3e2015-04-21 19:56:18 +00001; RUN: opt < %s -slsr -gvn -S | FileCheck %s
Jingyue Wu177a8152015-03-26 16:49:24 +00002
3target datalayout = "e-i64:64-v16:16-v32:32-n16:32:64"
4
Jingyue Wub3ec8042015-04-15 17:14:03 +00005; foo(input[0]);
6; foo(input[s]);
7; foo(input[s * 2]);
8; =>
9; p0 = &input[0];
10; foo(*p);
11; p1 = p0 + s;
12; foo(*p1);
13; p2 = p1 + s;
14; foo(*p2);
15define void @slsr_gep(i32* %input, i64 %s) {
Jingyue Wu177a8152015-03-26 16:49:24 +000016; CHECK-LABEL: @slsr_gep(
17 ; v0 = input[0];
18 %p0 = getelementptr inbounds i32, i32* %input, i64 0
19 %v0 = load i32, i32* %p0
Jingyue Wub3ec8042015-04-15 17:14:03 +000020 call void @foo(i32 %v0)
Jingyue Wu177a8152015-03-26 16:49:24 +000021
22 ; v1 = input[s];
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
Jingyue Wub3ec8042015-04-15 17:14:03 +000026 call void @foo(i32 %v1)
Jingyue Wu177a8152015-03-26 16:49:24 +000027
28 ; v2 = input[s * 2];
Jingyue Wu96d74002015-04-06 17:15:48 +000029 %s2 = shl nsw i64 %s, 1
Jingyue Wu177a8152015-03-26 16:49:24 +000030 %p2 = getelementptr inbounds i32, i32* %input, i64 %s2
31; CHECK: %p2 = getelementptr inbounds i32, i32* %p1, i64 %s
32 %v2 = load i32, i32* %p2
Jingyue Wub3ec8042015-04-15 17:14:03 +000033 call void @foo(i32 %v2)
Jingyue Wu177a8152015-03-26 16:49:24 +000034
Jingyue Wub3ec8042015-04-15 17:14:03 +000035 ret void
Jingyue Wu177a8152015-03-26 16:49:24 +000036}
37
Jingyue Wub3ec8042015-04-15 17:14:03 +000038; foo(input[0]);
39; foo(input[(long)s]);
40; foo(input[(long)(s * 2)]);
41; =>
42; p0 = &input[0];
43; foo(*p);
44; p1 = p0 + (long)s;
45; foo(*p1);
46; p2 = p1 + (long)s;
47; foo(*p2);
48define void @slsr_gep_sext(i32* %input, i32 %s) {
Jingyue Wu177a8152015-03-26 16:49:24 +000049; CHECK-LABEL: @slsr_gep_sext(
50 ; v0 = input[0];
51 %p0 = getelementptr inbounds i32, i32* %input, i64 0
52 %v0 = load i32, i32* %p0
Jingyue Wub3ec8042015-04-15 17:14:03 +000053 call void @foo(i32 %v0)
Jingyue Wu177a8152015-03-26 16:49:24 +000054
Jingyue Wub3ec8042015-04-15 17:14:03 +000055 ; v1 = input[s];
Jingyue Wu177a8152015-03-26 16:49:24 +000056 %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
Jingyue Wub3ec8042015-04-15 17:14:03 +000060 call void @foo(i32 %v1)
Jingyue Wu177a8152015-03-26 16:49:24 +000061
Jingyue Wub3ec8042015-04-15 17:14:03 +000062 ; v2 = input[s * 2];
Jingyue Wu96d74002015-04-06 17:15:48 +000063 %s2 = shl nsw i32 %s, 1
Jingyue Wu177a8152015-03-26 16:49:24 +000064 %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
Jingyue Wub3ec8042015-04-15 17:14:03 +000068 call void @foo(i32 %v2)
Jingyue Wu177a8152015-03-26 16:49:24 +000069
Jingyue Wub3ec8042015-04-15 17:14:03 +000070 ret void
Jingyue Wu177a8152015-03-26 16:49:24 +000071}
72
Jingyue Wub3ec8042015-04-15 17:14:03 +000073; int input[10][5];
74; foo(input[s][t]);
75; foo(input[s * 2][t]);
76; foo(input[s * 3][t]);
77; =>
78; p0 = &input[s][t];
79; foo(*p0);
80; p1 = p0 + 5s;
81; foo(*p1);
82; p2 = p1 + 5s;
83; foo(*p2);
84define void @slsr_gep_2d([10 x [5 x i32]]* %input, i64 %s, i64 %t) {
Jingyue Wu177a8152015-03-26 16:49:24 +000085; CHECK-LABEL: @slsr_gep_2d(
86 ; v0 = input[s][t];
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
Jingyue Wub3ec8042015-04-15 17:14:03 +000089 call void @foo(i32 %v0)
Jingyue Wu177a8152015-03-26 16:49:24 +000090
91 ; v1 = input[s * 2][t];
Jingyue Wu96d74002015-04-06 17:15:48 +000092 %s2 = shl nsw i64 %s, 1
Jingyue Wu177a8152015-03-26 16:49:24 +000093; 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
Jingyue Wub3ec8042015-04-15 17:14:03 +000097 call void @foo(i32 %v1)
Jingyue Wu177a8152015-03-26 16:49:24 +000098
Jingyue Wub3ec8042015-04-15 17:14:03 +000099 ; v3 = input[s * 3][t];
Jingyue Wu177a8152015-03-26 16:49:24 +0000100 %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
Jingyue Wub3ec8042015-04-15 17:14:03 +0000104 call void @foo(i32 %v2)
Jingyue Wu177a8152015-03-26 16:49:24 +0000105
Jingyue Wub3ec8042015-04-15 17:14:03 +0000106 ret void
Jingyue Wu177a8152015-03-26 16:49:24 +0000107}
108
109%struct.S = type <{ i64, i32 }>
110
111; In this case, the bump
112; = (char *)&input[s * 2][t].f1 - (char *)&input[s][t].f1
113; = 60 * s
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
116; @slsr_gep_2d.
Jingyue Wub3ec8042015-04-15 17:14:03 +0000117define void @slsr_gep_uglygep([10 x [5 x %struct.S]]* %input, i64 %s, i64 %t) {
Jingyue Wu177a8152015-03-26 16:49:24 +0000118; 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
Jingyue Wub3ec8042015-04-15 17:14:03 +0000122 call void @bar(i64 %v0)
Jingyue Wu177a8152015-03-26 16:49:24 +0000123
124 ; v1 = input[s * 2][t].f1;
Jingyue Wu96d74002015-04-06 17:15:48 +0000125 %s2 = shl nsw i64 %s, 1
Jingyue Wu177a8152015-03-26 16:49:24 +0000126; 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
Jingyue Wub3ec8042015-04-15 17:14:03 +0000130 call void @bar(i64 %v1)
Jingyue Wu177a8152015-03-26 16:49:24 +0000131
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
Jingyue Wub3ec8042015-04-15 17:14:03 +0000137 call void @bar(i64 %v2)
Jingyue Wu177a8152015-03-26 16:49:24 +0000138
Jingyue Wub3ec8042015-04-15 17:14:03 +0000139 ret void
Jingyue Wu177a8152015-03-26 16:49:24 +0000140}
Jingyue Wu99a6bed2015-04-02 21:18:32 +0000141
Jingyue Wub3ec8042015-04-15 17:14:03 +0000142define void @slsr_out_of_bounds_gep(i32* %input, i32 %s) {
Jingyue Wu99a6bed2015-04-02 21:18:32 +0000143; CHECK-LABEL: @slsr_out_of_bounds_gep(
144 ; v0 = input[0];
145 %p0 = getelementptr i32, i32* %input, i64 0
146 %v0 = load i32, i32* %p0
Jingyue Wub3ec8042015-04-15 17:14:03 +0000147 call void @foo(i32 %v0)
Jingyue Wu99a6bed2015-04-02 21:18:32 +0000148
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
Jingyue Wub3ec8042015-04-15 17:14:03 +0000154 call void @foo(i32 %v1)
Jingyue Wu99a6bed2015-04-02 21:18:32 +0000155
156 ; v2 = input[(long)(s * 2)];
Jingyue Wu96d74002015-04-06 17:15:48 +0000157 %s2 = shl nsw i32 %s, 1
Jingyue Wu99a6bed2015-04-02 21:18:32 +0000158 %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
Jingyue Wub3ec8042015-04-15 17:14:03 +0000162 call void @foo(i32 %v2)
Jingyue Wu99a6bed2015-04-02 21:18:32 +0000163
Jingyue Wub3ec8042015-04-15 17:14:03 +0000164 ret void
Jingyue Wu99a6bed2015-04-02 21:18:32 +0000165}
Jingyue Wub3ec8042015-04-15 17:14:03 +0000166
167declare void @foo(i32)
168declare void @bar(i64)