1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -slsr -gvn -S | FileCheck %s
4 target datalayout = "e-i64:64-v16:16-v32:32-n16:32:64"
6 define void @shl(i32 %b, i32 %s) {
8 ; CHECK-NEXT: [[T1:%.*]] = add i32 [[B:%.*]], [[S:%.*]]
9 ; CHECK-NEXT: call void @foo(i32 [[T1]])
10 ; CHECK-NEXT: [[T2:%.*]] = add i32 [[T1]], [[S]]
11 ; CHECK-NEXT: call void @foo(i32 [[T2]])
12 ; CHECK-NEXT: ret void
15 call void @foo(i32 %t1)
18 call void @foo(i32 %t2)
22 define void @stride_is_2s(i32 %b, i32 %s) {
23 ; CHECK-LABEL: @stride_is_2s(
24 ; CHECK-NEXT: [[S2:%.*]] = shl i32 [[S:%.*]], 1
25 ; CHECK-NEXT: [[T1:%.*]] = add i32 [[B:%.*]], [[S2]]
26 ; CHECK-NEXT: call void @foo(i32 [[T1]])
27 ; CHECK-NEXT: [[T2:%.*]] = add i32 [[T1]], [[S2]]
28 ; CHECK-NEXT: call void @foo(i32 [[T2]])
29 ; CHECK-NEXT: [[T3:%.*]] = add i32 [[T2]], [[S2]]
30 ; CHECK-NEXT: call void @foo(i32 [[T3]])
31 ; CHECK-NEXT: ret void
35 call void @foo(i32 %t1)
38 call void @foo(i32 %t2)
41 call void @foo(i32 %t3)
45 define void @stride_is_3s(i32 %b, i32 %s) {
46 ; CHECK-LABEL: @stride_is_3s(
47 ; CHECK-NEXT: [[T1:%.*]] = add i32 [[S:%.*]], [[B:%.*]]
48 ; CHECK-NEXT: call void @foo(i32 [[T1]])
49 ; CHECK-NEXT: [[TMP1:%.*]] = mul i32 [[S]], 3
50 ; CHECK-NEXT: [[T2:%.*]] = add i32 [[T1]], [[TMP1]]
51 ; CHECK-NEXT: call void @foo(i32 [[T2]])
52 ; CHECK-NEXT: [[T3:%.*]] = add i32 [[T2]], [[TMP1]]
53 ; CHECK-NEXT: call void @foo(i32 [[T3]])
54 ; CHECK-NEXT: ret void
57 call void @foo(i32 %t1)
60 call void @foo(i32 %t2)
63 call void @foo(i32 %t3)
78 define void @stride_is_minus_2s(i32 %b, i32 %s) {
79 ; CHECK-LABEL: @stride_is_minus_2s(
80 ; CHECK-NEXT: [[S6:%.*]] = mul i32 [[S:%.*]], 6
81 ; CHECK-NEXT: [[T1:%.*]] = add i32 [[B:%.*]], [[S6]]
82 ; CHECK-NEXT: call void @foo(i32 [[T1]])
83 ; CHECK-NEXT: [[TMP1:%.*]] = shl i32 [[S]], 1
84 ; CHECK-NEXT: [[T2:%.*]] = sub i32 [[T1]], [[TMP1]]
85 ; CHECK-NEXT: call void @foo(i32 [[T2]])
86 ; CHECK-NEXT: [[T3:%.*]] = sub i32 [[T2]], [[TMP1]]
87 ; CHECK-NEXT: call void @foo(i32 [[T3]])
88 ; CHECK-NEXT: ret void
92 call void @foo(i32 %t1)
95 call void @foo(i32 %t2)
98 call void @foo(i32 %t3)
102 ; TODO: This pass is targeted at simple address-calcs, so it is artificially limited to
103 ; match scalar values. The code could be modified to handle vector types too.
105 define void @stride_is_minus_2s_vec(<2 x i32> %b, <2 x i32> %s) {
106 ; CHECK-LABEL: @stride_is_minus_2s_vec(
107 ; CHECK-NEXT: [[S6:%.*]] = mul <2 x i32> [[S:%.*]], <i32 6, i32 6>
108 ; CHECK-NEXT: [[T1:%.*]] = add <2 x i32> [[B:%.*]], [[S6]]
109 ; CHECK-NEXT: call void @voo(<2 x i32> [[T1]])
110 ; CHECK-NEXT: [[S4:%.*]] = shl <2 x i32> [[S]], <i32 2, i32 2>
111 ; CHECK-NEXT: [[T2:%.*]] = add <2 x i32> [[B]], [[S4]]
112 ; CHECK-NEXT: call void @voo(<2 x i32> [[T2]])
113 ; CHECK-NEXT: [[S2:%.*]] = shl <2 x i32> [[S]], <i32 1, i32 1>
114 ; CHECK-NEXT: [[T3:%.*]] = add <2 x i32> [[B]], [[S2]]
115 ; CHECK-NEXT: call void @voo(<2 x i32> [[T3]])
116 ; CHECK-NEXT: ret void
118 %s6 = mul <2 x i32> %s, <i32 6, i32 6>
119 %t1 = add <2 x i32> %b, %s6
120 call void @voo(<2 x i32> %t1)
121 %s4 = shl <2 x i32> %s, <i32 2, i32 2>
122 %t2 = add <2 x i32> %b, %s4
123 call void @voo(<2 x i32> %t2)
124 %s2 = shl <2 x i32> %s, <i32 1, i32 1>
125 %t3 = add <2 x i32> %b, %s2
126 call void @voo(<2 x i32> %t3)
134 ; do not rewrite b + s to t - 7 * s because the latter is more complicated.
135 define void @simple_enough(i32 %b, i32 %s) {
136 ; CHECK-LABEL: @simple_enough(
137 ; CHECK-NEXT: [[S8:%.*]] = shl i32 [[S:%.*]], 3
138 ; CHECK-NEXT: [[T1:%.*]] = add i32 [[B:%.*]], [[S8]]
139 ; CHECK-NEXT: call void @foo(i32 [[T1]])
140 ; CHECK-NEXT: [[T2:%.*]] = add i32 [[B]], [[S]]
141 ; CHECK-NEXT: call void @foo(i32 [[T2]])
142 ; CHECK-NEXT: ret void
145 %t1 = add i32 %b, %s8
146 call void @foo(i32 %t1)
148 call void @foo(i32 %t2)
152 define void @slsr_strided_add_128bit(i128 %b, i128 %s) {
153 ; CHECK-LABEL: @slsr_strided_add_128bit(
154 ; CHECK-NEXT: [[S125:%.*]] = shl i128 [[S:%.*]], 125
155 ; CHECK-NEXT: [[T1:%.*]] = add i128 [[B:%.*]], [[S125]]
156 ; CHECK-NEXT: call void @bar(i128 [[T1]])
157 ; CHECK-NEXT: [[T2:%.*]] = add i128 [[T1]], [[S125]]
158 ; CHECK-NEXT: call void @bar(i128 [[T2]])
159 ; CHECK-NEXT: ret void
161 %s125 = shl i128 %s, 125
162 %s126 = shl i128 %s, 126
163 %t1 = add i128 %b, %s125
164 call void @bar(i128 %t1)
165 %t2 = add i128 %b, %s126
166 call void @bar(i128 %t2)
170 declare void @foo(i32)
171 declare void @voo(<2 x i32>)
172 declare void @bar(i128)