|
1 | 1 | ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
2 | 2 | ; RUN: opt < %s -passes=instcombine -S | FileCheck %s
|
3 | 3 |
|
| 4 | +declare void @use(i32) |
| 5 | + |
4 | 6 | define i64 @match_unsigned(i64 %x) {
|
5 | 7 | ; CHECK-LABEL: @match_unsigned(
|
6 | 8 | ; CHECK-NEXT: [[UREM:%.*]] = urem i64 [[X:%.*]], 19136
|
@@ -127,3 +129,174 @@ define i32 @not_match_overflow(i32 %x) {
|
127 | 129 | %t4 = add i32 %t, %t3
|
128 | 130 | ret i32 %t4
|
129 | 131 | }
|
| 132 | + |
| 133 | +; Tests from PR76128. |
| 134 | +define i32 @fold_add_udiv_urem(i32 noundef %val) { |
| 135 | +; CHECK-LABEL: @fold_add_udiv_urem( |
| 136 | +; CHECK-NEXT: entry: |
| 137 | +; CHECK-NEXT: [[DIV:%.*]] = udiv i32 [[VAL:%.*]], 10 |
| 138 | +; CHECK-NEXT: [[SHL:%.*]] = shl i32 [[DIV]], 4 |
| 139 | +; CHECK-NEXT: [[REM:%.*]] = urem i32 [[VAL]], 10 |
| 140 | +; CHECK-NEXT: [[ADD:%.*]] = or disjoint i32 [[SHL]], [[REM]] |
| 141 | +; CHECK-NEXT: ret i32 [[ADD]] |
| 142 | +; |
| 143 | +entry: |
| 144 | + %div = udiv i32 %val, 10 |
| 145 | + %shl = shl i32 %div, 4 |
| 146 | + %rem = urem i32 %val, 10 |
| 147 | + %add = add i32 %shl, %rem |
| 148 | + ret i32 %add |
| 149 | +} |
| 150 | +define i32 @fold_add_sdiv_srem(i32 noundef %val) { |
| 151 | +; CHECK-LABEL: @fold_add_sdiv_srem( |
| 152 | +; CHECK-NEXT: entry: |
| 153 | +; CHECK-NEXT: [[DIV:%.*]] = sdiv i32 [[VAL:%.*]], 10 |
| 154 | +; CHECK-NEXT: [[SHL:%.*]] = shl i32 [[DIV]], 4 |
| 155 | +; CHECK-NEXT: [[REM:%.*]] = srem i32 [[VAL]], 10 |
| 156 | +; CHECK-NEXT: [[ADD:%.*]] = add i32 [[SHL]], [[REM]] |
| 157 | +; CHECK-NEXT: ret i32 [[ADD]] |
| 158 | +; |
| 159 | +entry: |
| 160 | + %div = sdiv i32 %val, 10 |
| 161 | + %shl = shl i32 %div, 4 |
| 162 | + %rem = srem i32 %val, 10 |
| 163 | + %add = add i32 %shl, %rem |
| 164 | + ret i32 %add |
| 165 | +} |
| 166 | +define i32 @fold_add_udiv_urem_to_mul(i32 noundef %val) { |
| 167 | +; CHECK-LABEL: @fold_add_udiv_urem_to_mul( |
| 168 | +; CHECK-NEXT: entry: |
| 169 | +; CHECK-NEXT: [[DIV:%.*]] = udiv i32 [[VAL:%.*]], 7 |
| 170 | +; CHECK-NEXT: [[MUL1:%.*]] = mul i32 [[DIV]], 21 |
| 171 | +; CHECK-NEXT: [[REM:%.*]] = urem i32 [[VAL]], 7 |
| 172 | +; CHECK-NEXT: [[MUL2:%.*]] = mul nuw nsw i32 [[REM]], 3 |
| 173 | +; CHECK-NEXT: [[ADD:%.*]] = add i32 [[MUL1]], [[MUL2]] |
| 174 | +; CHECK-NEXT: ret i32 [[ADD]] |
| 175 | +; |
| 176 | +entry: |
| 177 | + %div = udiv i32 %val, 7 |
| 178 | + %mul1 = mul i32 %div, 21 |
| 179 | + %rem = urem i32 %val, 7 |
| 180 | + %mul2 = mul i32 %rem, 3 |
| 181 | + %add = add i32 %mul1, %mul2 |
| 182 | + ret i32 %add |
| 183 | +} |
| 184 | +define i32 @fold_add_udiv_urem_to_mul_multiuse(i32 noundef %val) { |
| 185 | +; CHECK-LABEL: @fold_add_udiv_urem_to_mul_multiuse( |
| 186 | +; CHECK-NEXT: entry: |
| 187 | +; CHECK-NEXT: [[DIV:%.*]] = udiv i32 [[VAL:%.*]], 7 |
| 188 | +; CHECK-NEXT: [[MUL1:%.*]] = mul i32 [[DIV]], 21 |
| 189 | +; CHECK-NEXT: [[REM:%.*]] = urem i32 [[VAL]], 7 |
| 190 | +; CHECK-NEXT: call void @use(i32 [[REM]]) |
| 191 | +; CHECK-NEXT: [[MUL2:%.*]] = mul nuw nsw i32 [[REM]], 3 |
| 192 | +; CHECK-NEXT: [[ADD:%.*]] = add i32 [[MUL1]], [[MUL2]] |
| 193 | +; CHECK-NEXT: ret i32 [[ADD]] |
| 194 | +; |
| 195 | +entry: |
| 196 | + %div = udiv i32 %val, 7 |
| 197 | + %mul1 = mul i32 %div, 21 |
| 198 | + %rem = urem i32 %val, 7 |
| 199 | + call void @use(i32 %rem) |
| 200 | + %mul2 = mul i32 %rem, 3 |
| 201 | + %add = add i32 %mul1, %mul2 |
| 202 | + ret i32 %add |
| 203 | +} |
| 204 | +define i32 @fold_add_udiv_urem_commuted(i32 noundef %val) { |
| 205 | +; CHECK-LABEL: @fold_add_udiv_urem_commuted( |
| 206 | +; CHECK-NEXT: entry: |
| 207 | +; CHECK-NEXT: [[DIV:%.*]] = udiv i32 [[VAL:%.*]], 10 |
| 208 | +; CHECK-NEXT: [[SHL:%.*]] = shl i32 [[DIV]], 4 |
| 209 | +; CHECK-NEXT: [[REM:%.*]] = urem i32 [[VAL]], 10 |
| 210 | +; CHECK-NEXT: [[ADD:%.*]] = or disjoint i32 [[REM]], [[SHL]] |
| 211 | +; CHECK-NEXT: ret i32 [[ADD]] |
| 212 | +; |
| 213 | +entry: |
| 214 | + %div = udiv i32 %val, 10 |
| 215 | + %shl = shl i32 %div, 4 |
| 216 | + %rem = urem i32 %val, 10 |
| 217 | + %add = add i32 %rem, %shl |
| 218 | + ret i32 %add |
| 219 | +} |
| 220 | +define i32 @fold_add_udiv_urem_or_disjoint(i32 noundef %val) { |
| 221 | +; CHECK-LABEL: @fold_add_udiv_urem_or_disjoint( |
| 222 | +; CHECK-NEXT: entry: |
| 223 | +; CHECK-NEXT: [[DIV:%.*]] = udiv i32 [[VAL:%.*]], 10 |
| 224 | +; CHECK-NEXT: [[SHL:%.*]] = shl i32 [[DIV]], 4 |
| 225 | +; CHECK-NEXT: [[REM:%.*]] = urem i32 [[VAL]], 10 |
| 226 | +; CHECK-NEXT: [[ADD:%.*]] = or disjoint i32 [[SHL]], [[REM]] |
| 227 | +; CHECK-NEXT: ret i32 [[ADD]] |
| 228 | +; |
| 229 | +entry: |
| 230 | + %div = udiv i32 %val, 10 |
| 231 | + %shl = shl i32 %div, 4 |
| 232 | + %rem = urem i32 %val, 10 |
| 233 | + %add = or disjoint i32 %shl, %rem |
| 234 | + ret i32 %add |
| 235 | +} |
| 236 | +; Negative tests |
| 237 | +define i32 @fold_add_udiv_urem_without_noundef(i32 %val) { |
| 238 | +; CHECK-LABEL: @fold_add_udiv_urem_without_noundef( |
| 239 | +; CHECK-NEXT: entry: |
| 240 | +; CHECK-NEXT: [[DIV:%.*]] = udiv i32 [[VAL:%.*]], 10 |
| 241 | +; CHECK-NEXT: [[SHL:%.*]] = shl i32 [[DIV]], 4 |
| 242 | +; CHECK-NEXT: [[REM:%.*]] = urem i32 [[VAL]], 10 |
| 243 | +; CHECK-NEXT: [[ADD:%.*]] = or disjoint i32 [[SHL]], [[REM]] |
| 244 | +; CHECK-NEXT: ret i32 [[ADD]] |
| 245 | +; |
| 246 | +entry: |
| 247 | + %div = udiv i32 %val, 10 |
| 248 | + %shl = shl i32 %div, 4 |
| 249 | + %rem = urem i32 %val, 10 |
| 250 | + %add = add i32 %shl, %rem |
| 251 | + ret i32 %add |
| 252 | +} |
| 253 | +define i32 @fold_add_udiv_urem_multiuse_mul(i32 noundef %val) { |
| 254 | +; CHECK-LABEL: @fold_add_udiv_urem_multiuse_mul( |
| 255 | +; CHECK-NEXT: entry: |
| 256 | +; CHECK-NEXT: [[DIV:%.*]] = udiv i32 [[VAL:%.*]], 10 |
| 257 | +; CHECK-NEXT: [[SHL:%.*]] = shl i32 [[DIV]], 4 |
| 258 | +; CHECK-NEXT: call void @use(i32 [[SHL]]) |
| 259 | +; CHECK-NEXT: [[REM:%.*]] = urem i32 [[VAL]], 10 |
| 260 | +; CHECK-NEXT: [[ADD:%.*]] = or disjoint i32 [[SHL]], [[REM]] |
| 261 | +; CHECK-NEXT: ret i32 [[ADD]] |
| 262 | +; |
| 263 | +entry: |
| 264 | + %div = udiv i32 %val, 10 |
| 265 | + %shl = shl i32 %div, 4 |
| 266 | + call void @use(i32 %shl) |
| 267 | + %rem = urem i32 %val, 10 |
| 268 | + %add = add i32 %shl, %rem |
| 269 | + ret i32 %add |
| 270 | +} |
| 271 | +define i32 @fold_add_udiv_srem(i32 noundef %val) { |
| 272 | +; CHECK-LABEL: @fold_add_udiv_srem( |
| 273 | +; CHECK-NEXT: entry: |
| 274 | +; CHECK-NEXT: [[DIV:%.*]] = udiv i32 [[VAL:%.*]], 10 |
| 275 | +; CHECK-NEXT: [[SHL:%.*]] = shl i32 [[DIV]], 4 |
| 276 | +; CHECK-NEXT: [[REM:%.*]] = srem i32 [[VAL]], 10 |
| 277 | +; CHECK-NEXT: [[ADD:%.*]] = add i32 [[SHL]], [[REM]] |
| 278 | +; CHECK-NEXT: ret i32 [[ADD]] |
| 279 | +; |
| 280 | +entry: |
| 281 | + %div = udiv i32 %val, 10 |
| 282 | + %shl = shl i32 %div, 4 |
| 283 | + %rem = srem i32 %val, 10 |
| 284 | + %add = add i32 %shl, %rem |
| 285 | + ret i32 %add |
| 286 | +} |
| 287 | +define i32 @fold_add_udiv_urem_non_constant(i32 noundef %val, i32 noundef %c) { |
| 288 | +; CHECK-LABEL: @fold_add_udiv_urem_non_constant( |
| 289 | +; CHECK-NEXT: entry: |
| 290 | +; CHECK-NEXT: [[DIV:%.*]] = udiv i32 [[VAL:%.*]], [[C:%.*]] |
| 291 | +; CHECK-NEXT: [[SHL:%.*]] = shl i32 [[DIV]], 4 |
| 292 | +; CHECK-NEXT: [[REM:%.*]] = urem i32 [[VAL]], [[C]] |
| 293 | +; CHECK-NEXT: [[ADD:%.*]] = add i32 [[SHL]], [[REM]] |
| 294 | +; CHECK-NEXT: ret i32 [[ADD]] |
| 295 | +; |
| 296 | +entry: |
| 297 | + %div = udiv i32 %val, %c |
| 298 | + %shl = shl i32 %div, 4 |
| 299 | + %rem = urem i32 %val, %c |
| 300 | + %add = add i32 %shl, %rem |
| 301 | + ret i32 %add |
| 302 | +} |
0 commit comments