llvm.org GIT mirror llvm / 0dace14
[EarlyCSE] add tests for commuted min/max; NFC See PR35642: https://bugs.llvm.org/show_bug.cgi?id=35642 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@320530 91177308-0d34-0410-b5e6-96231b3b80d8 Sanjay Patel 1 year, 9 months ago
1 changed file(s) with 173 addition(s) and 25 deletion(s). Raw diff Collapse all Expand all
0 ; RUN: opt < %s -S -early-cse | FileCheck %s
11 ; RUN: opt < %s -S -basicaa -early-cse-memssa | FileCheck %s
22
3 define void @test1(float %A, float %B, float* %PA, float* %PB) {
34 ; CHECK-LABEL: @test1(
4 define void @test1(float %A, float %B, float* %PA, float* %PB) {
5 ; CHECK-NEXT: fadd
6 ; CHECK-NEXT: store
7 ; CHECK-NEXT: store
8 ; CHECK-NEXT: ret
5 ; CHECK-NEXT: [[C:%.*]] = fadd float %A, %B
6 ; CHECK-NEXT: store float [[C]], float* %PA
7 ; CHECK-NEXT: store float [[C]], float* %PB
8 ; CHECK-NEXT: ret void
9 ;
910 %C = fadd float %A, %B
1011 store float %C, float* %PA
1112 %D = fadd float %B, %A
1314 ret void
1415 }
1516
17 define void @test2(float %A, float %B, i1* %PA, i1* %PB) {
1618 ; CHECK-LABEL: @test2(
17 define void @test2(float %A, float %B, i1* %PA, i1* %PB) {
18 ; CHECK-NEXT: fcmp
19 ; CHECK-NEXT: store
20 ; CHECK-NEXT: store
21 ; CHECK-NEXT: ret
19 ; CHECK-NEXT: [[C:%.*]] = fcmp oeq float %A, %B
20 ; CHECK-NEXT: store i1 [[C]], i1* %PA
21 ; CHECK-NEXT: store i1 [[C]], i1* %PB
22 ; CHECK-NEXT: ret void
23 ;
2224 %C = fcmp oeq float %A, %B
2325 store i1 %C, i1* %PA
2426 %D = fcmp oeq float %B, %A
2628 ret void
2729 }
2830
31 define void @test3(float %A, float %B, i1* %PA, i1* %PB) {
2932 ; CHECK-LABEL: @test3(
30 define void @test3(float %A, float %B, i1* %PA, i1* %PB) {
31 ; CHECK-NEXT: fcmp
32 ; CHECK-NEXT: store
33 ; CHECK-NEXT: store
34 ; CHECK-NEXT: ret
33 ; CHECK-NEXT: [[C:%.*]] = fcmp uge float %A, %B
34 ; CHECK-NEXT: store i1 [[C]], i1* %PA
35 ; CHECK-NEXT: store i1 [[C]], i1* %PB
36 ; CHECK-NEXT: ret void
37 ;
3538 %C = fcmp uge float %A, %B
3639 store i1 %C, i1* %PA
3740 %D = fcmp ule float %B, %A
3942 ret void
4043 }
4144
45 define void @test4(i32 %A, i32 %B, i1* %PA, i1* %PB) {
4246 ; CHECK-LABEL: @test4(
43 define void @test4(i32 %A, i32 %B, i1* %PA, i1* %PB) {
44 ; CHECK-NEXT: icmp
45 ; CHECK-NEXT: store
46 ; CHECK-NEXT: store
47 ; CHECK-NEXT: ret
47 ; CHECK-NEXT: [[C:%.*]] = icmp eq i32 %A, %B
48 ; CHECK-NEXT: store i1 [[C]], i1* %PA
49 ; CHECK-NEXT: store i1 [[C]], i1* %PB
50 ; CHECK-NEXT: ret void
51 ;
4852 %C = icmp eq i32 %A, %B
4953 store i1 %C, i1* %PA
5054 %D = icmp eq i32 %B, %A
5256 ret void
5357 }
5458
59 define void @test5(i32 %A, i32 %B, i1* %PA, i1* %PB) {
5560 ; CHECK-LABEL: @test5(
56 define void @test5(i32 %A, i32 %B, i1* %PA, i1* %PB) {
57 ; CHECK-NEXT: icmp
58 ; CHECK-NEXT: store
59 ; CHECK-NEXT: store
60 ; CHECK-NEXT: ret
61 ; CHECK-NEXT: [[C:%.*]] = icmp sgt i32 %A, %B
62 ; CHECK-NEXT: store i1 [[C]], i1* %PA
63 ; CHECK-NEXT: store i1 [[C]], i1* %PB
64 ; CHECK-NEXT: ret void
65 ;
6166 %C = icmp sgt i32 %A, %B
6267 store i1 %C, i1* %PA
6368 %D = icmp slt i32 %B, %A
6469 store i1 %D, i1* %PB
6570 ret void
6671 }
72
73 ; Min/max operands may be commuted in the compare and select.
74
75 define i8 @smin_commute(i8 %a, i8 %b) {
76 ; CHECK-LABEL: @smin_commute(
77 ; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i8 %a, %b
78 ; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i8 %b, %a
79 ; CHECK-NEXT: [[M1:%.*]] = select i1 [[CMP1]], i8 %a, i8 %b
80 ; CHECK-NEXT: [[M2:%.*]] = select i1 [[CMP2]], i8 %b, i8 %a
81 ; CHECK-NEXT: [[R:%.*]] = mul i8 [[M1]], [[M2]]
82 ; CHECK-NEXT: ret i8 [[R]]
83 ;
84 %cmp1 = icmp slt i8 %a, %b
85 %cmp2 = icmp slt i8 %b, %a
86 %m1 = select i1 %cmp1, i8 %a, i8 %b
87 %m2 = select i1 %cmp2, i8 %b, i8 %a
88 %r = mul i8 %m1, %m2
89 ret i8 %r
90 }
91
92 ; Min/max can also have a swapped predicate and select operands.
93
94 define i1 @smin_swapped(i8 %a, i8 %b) {
95 ; CHECK-LABEL: @smin_swapped(
96 ; CHECK-NEXT: [[CMP1:%.*]] = icmp sgt i8 %a, %b
97 ; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i8 %a, %b
98 ; CHECK-NEXT: [[M1:%.*]] = select i1 [[CMP1]], i8 %b, i8 %a
99 ; CHECK-NEXT: [[M2:%.*]] = select i1 [[CMP2]], i8 %a, i8 %b
100 ; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[M2]], [[M1]]
101 ; CHECK-NEXT: ret i1 [[R]]
102 ;
103 %cmp1 = icmp sgt i8 %a, %b
104 %cmp2 = icmp slt i8 %a, %b
105 %m1 = select i1 %cmp1, i8 %b, i8 %a
106 %m2 = select i1 %cmp2, i8 %a, i8 %b
107 %r = icmp eq i8 %m2, %m1
108 ret i1 %r
109 }
110
111 define i8 @smax_commute(i8 %a, i8 %b) {
112 ; CHECK-LABEL: @smax_commute(
113 ; CHECK-NEXT: [[CMP1:%.*]] = icmp sgt i8 %a, %b
114 ; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i8 %b, %a
115 ; CHECK-NEXT: [[M1:%.*]] = select i1 [[CMP1]], i8 %a, i8 %b
116 ; CHECK-NEXT: [[M2:%.*]] = select i1 [[CMP2]], i8 %b, i8 %a
117 ; CHECK-NEXT: [[R:%.*]] = urem i8 [[M2]], [[M1]]
118 ; CHECK-NEXT: ret i8 [[R]]
119 ;
120 %cmp1 = icmp sgt i8 %a, %b
121 %cmp2 = icmp sgt i8 %b, %a
122 %m1 = select i1 %cmp1, i8 %a, i8 %b
123 %m2 = select i1 %cmp2, i8 %b, i8 %a
124 %r = urem i8 %m2, %m1
125 ret i8 %r
126 }
127
128 define i8 @smax_swapped(i8 %a, i8 %b) {
129 ; CHECK-LABEL: @smax_swapped(
130 ; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i8 %a, %b
131 ; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i8 %a, %b
132 ; CHECK-NEXT: [[M1:%.*]] = select i1 [[CMP1]], i8 %b, i8 %a
133 ; CHECK-NEXT: [[M2:%.*]] = select i1 [[CMP2]], i8 %a, i8 %b
134 ; CHECK-NEXT: [[R:%.*]] = sdiv i8 [[M1]], [[M2]]
135 ; CHECK-NEXT: ret i8 [[R]]
136 ;
137 %cmp1 = icmp slt i8 %a, %b
138 %cmp2 = icmp sgt i8 %a, %b
139 %m1 = select i1 %cmp1, i8 %b, i8 %a
140 %m2 = select i1 %cmp2, i8 %a, i8 %b
141 %r = sdiv i8 %m1, %m2
142 ret i8 %r
143 }
144
145 define i8 @umin_commute(i8 %a, i8 %b) {
146 ; CHECK-LABEL: @umin_commute(
147 ; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i8 %a, %b
148 ; CHECK-NEXT: [[CMP2:%.*]] = icmp ult i8 %b, %a
149 ; CHECK-NEXT: [[M1:%.*]] = select i1 [[CMP1]], i8 %a, i8 %b
150 ; CHECK-NEXT: [[M2:%.*]] = select i1 [[CMP2]], i8 %b, i8 %a
151 ; CHECK-NEXT: [[R:%.*]] = sub i8 [[M2]], [[M1]]
152 ; CHECK-NEXT: ret i8 [[R]]
153 ;
154 %cmp1 = icmp ult i8 %a, %b
155 %cmp2 = icmp ult i8 %b, %a
156 %m1 = select i1 %cmp1, i8 %a, i8 %b
157 %m2 = select i1 %cmp2, i8 %b, i8 %a
158 %r = sub i8 %m2, %m1
159 ret i8 %r
160 }
161
162 ; Choose a vector type just to show that works.
163
164 define <2 x i8> @umin_swapped(<2 x i8> %a, <2 x i8> %b) {
165 ; CHECK-LABEL: @umin_swapped(
166 ; CHECK-NEXT: [[CMP1:%.*]] = icmp ugt <2 x i8> %a, %b
167 ; CHECK-NEXT: [[CMP2:%.*]] = icmp ult <2 x i8> %a, %b
168 ; CHECK-NEXT: [[M1:%.*]] = select <2 x i1> [[CMP1]], <2 x i8> %b, <2 x i8> %a
169 ; CHECK-NEXT: [[M2:%.*]] = select <2 x i1> [[CMP2]], <2 x i8> %a, <2 x i8> %b
170 ; CHECK-NEXT: [[R:%.*]] = sub <2 x i8> [[M2]], [[M1]]
171 ; CHECK-NEXT: ret <2 x i8> [[R]]
172 ;
173 %cmp1 = icmp ugt <2 x i8> %a, %b
174 %cmp2 = icmp ult <2 x i8> %a, %b
175 %m1 = select <2 x i1> %cmp1, <2 x i8> %b, <2 x i8> %a
176 %m2 = select <2 x i1> %cmp2, <2 x i8> %a, <2 x i8> %b
177 %r = sub <2 x i8> %m2, %m1
178 ret <2 x i8> %r
179 }
180
181 define i8 @umax_commute(i8 %a, i8 %b) {
182 ; CHECK-LABEL: @umax_commute(
183 ; CHECK-NEXT: [[CMP1:%.*]] = icmp ugt i8 %a, %b
184 ; CHECK-NEXT: [[CMP2:%.*]] = icmp ugt i8 %b, %a
185 ; CHECK-NEXT: [[M1:%.*]] = select i1 [[CMP1]], i8 %a, i8 %b
186 ; CHECK-NEXT: [[M2:%.*]] = select i1 [[CMP2]], i8 %b, i8 %a
187 ; CHECK-NEXT: [[R:%.*]] = udiv i8 [[M1]], [[M2]]
188 ; CHECK-NEXT: ret i8 [[R]]
189 ;
190 %cmp1 = icmp ugt i8 %a, %b
191 %cmp2 = icmp ugt i8 %b, %a
192 %m1 = select i1 %cmp1, i8 %a, i8 %b
193 %m2 = select i1 %cmp2, i8 %b, i8 %a
194 %r = udiv i8 %m1, %m2
195 ret i8 %r
196 }
197
198 define i8 @umax_swapped(i8 %a, i8 %b) {
199 ; CHECK-LABEL: @umax_swapped(
200 ; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i8 %a, %b
201 ; CHECK-NEXT: [[CMP2:%.*]] = icmp ugt i8 %a, %b
202 ; CHECK-NEXT: [[M1:%.*]] = select i1 [[CMP1]], i8 %b, i8 %a
203 ; CHECK-NEXT: [[M2:%.*]] = select i1 [[CMP2]], i8 %a, i8 %b
204 ; CHECK-NEXT: [[R:%.*]] = add i8 [[M2]], [[M1]]
205 ; CHECK-NEXT: ret i8 [[R]]
206 ;
207 %cmp1 = icmp ult i8 %a, %b
208 %cmp2 = icmp ugt i8 %a, %b
209 %m1 = select i1 %cmp1, i8 %b, i8 %a
210 %m2 = select i1 %cmp2, i8 %a, i8 %b
211 %r = add i8 %m2, %m1
212 ret i8 %r
213 }
214