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