| OLD | NEW |
| 1 ; This tests the optimization where producers and consumers of i1 (bool) | 1 ; This tests the optimization where producers and consumers of i1 (bool) |
| 2 ; variables are combined to implicitly use flags instead of explicitly using | 2 ; variables are combined to implicitly use flags instead of explicitly using |
| 3 ; stack or register variables. | 3 ; stack or register variables. |
| 4 | 4 |
| 5 ; RUN: %p2i -i %s --filetype=obj --disassemble --args -O2 \ | 5 ; RUN: %p2i -i %s --filetype=obj --disassemble --args -O2 \ |
| 6 ; RUN: -allow-externally-defined-symbols | FileCheck %s | 6 ; RUN: -allow-externally-defined-symbols | FileCheck %s |
| 7 | 7 |
| 8 ; RUN: %if --need=allow_dump --need=target_ARM32 --command %p2i --filetype=asm \ | 8 ; RUN: %if --need=allow_dump --need=target_ARM32 --command %p2i --filetype=asm \ |
| 9 ; RUN: --target arm32 -i %s --args -O2 --skip-unimplemented \ | 9 ; RUN: --target arm32 -i %s --args -O2 --skip-unimplemented \ |
| 10 ; RUN: -allow-externally-defined-symbols \ | 10 ; RUN: -allow-externally-defined-symbols \ |
| (...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 219 ; CHECK-LABEL: fold_cmp_select_multi | 219 ; CHECK-LABEL: fold_cmp_select_multi |
| 220 ; CHECK: cmp | 220 ; CHECK: cmp |
| 221 ; CHECK: cmovl | 221 ; CHECK: cmovl |
| 222 ; CHECK: cmp | 222 ; CHECK: cmp |
| 223 ; CHECK: cmovl | 223 ; CHECK: cmovl |
| 224 ; CHECK: cmp | 224 ; CHECK: cmp |
| 225 ; CHECK: cmovge | 225 ; CHECK: cmovge |
| 226 ; CHECK: add | 226 ; CHECK: add |
| 227 ; CHECK: add | 227 ; CHECK: add |
| 228 ; ARM32-LABEL: fold_cmp_select_multi | 228 ; ARM32-LABEL: fold_cmp_select_multi |
| 229 ; ARM32-DAG: mov [[T0:r[0-9]+]], #0 | 229 ; ARM32: mov [[T0:r[0-9]+]], #0 |
| 230 ; ARM32-DAG: cmp r0, r1 | 230 ; ARM32: cmp r0, r1 |
| 231 ; ARM32: movlt [[T0]], #1 | 231 ; ARM32: movlt [[T0]], #1 |
| 232 ; ARM32-DAG: mov [[T1:r[0-9]+]], r1 | 232 ; ARM32: uxtb [[T1:r[0-9]+]], [[T1]] |
| 233 ; ARM32-DAG: cmp [[T0]], #0 | 233 ; ARM32-NEXT: cmp [[T1]], #0 |
| 234 ; ARM32: [[T1]], r0 | 234 ; ARM32: movne [[T2:r[0-9]+]], r0 |
| 235 ; ARM32-DAG: mov [[T2:r[0-9]+]], r0 | 235 ; ARM32: uxtb [[T3:r[0-9]+]], [[T3]] |
| 236 ; ARM32-DAG: cmp [[T0]], #0 | 236 ; ARM32-NEXT: cmp [[T3]], #0 |
| 237 ; ARM32: [[T2]], r1 | 237 ; ARM32: movne [[T4:r[0-9]+]], r1 |
| 238 ; ARM32: cmp [[T0]], #0 | 238 ; ARM32: uxtb [[T5:r[0-9]+]], [[T5]] |
| 239 ; ARM32: movne | 239 ; ARM32-NEXT: cmp [[T5]], #0 |
| 240 ; ARM32: add | 240 ; ARM32: movne [[T6:r[0-9]+]], #123 |
| 241 ; ARM32: add | 241 ; ARM32: add [[T7:r[0-9]+]], [[T2]], [[T4]] |
| 242 ; ARM32: add {{r[0-9]+}}, [[T7]], [[T6]] |
| 242 ; ARM32: bx lr | 243 ; ARM32: bx lr |
| 243 | 244 |
| 244 | 245 |
| 245 ; Cmp/multi-select non-folding because of live-out. | 246 ; Cmp/multi-select non-folding because of live-out. |
| 246 define internal i32 @no_fold_cmp_select_multi_liveout(i32 %arg1, i32 %arg2) { | 247 define internal i32 @no_fold_cmp_select_multi_liveout(i32 %arg1, i32 %arg2) { |
| 247 entry: | 248 entry: |
| 248 %cmp1 = icmp slt i32 %arg1, %arg2 | 249 %cmp1 = icmp slt i32 %arg1, %arg2 |
| 249 %a = select i1 %cmp1, i32 %arg1, i32 %arg2 | 250 %a = select i1 %cmp1, i32 %arg1, i32 %arg2 |
| 250 %b = select i1 %cmp1, i32 %arg2, i32 %arg1 | 251 %b = select i1 %cmp1, i32 %arg2, i32 %arg1 |
| 251 br label %next | 252 br label %next |
| 252 next: | 253 next: |
| 253 %c = select i1 %cmp1, i32 123, i32 %arg1 | 254 %c = select i1 %cmp1, i32 123, i32 %arg1 |
| 254 %partial = add i32 %a, %b | 255 %partial = add i32 %a, %b |
| 255 %result = add i32 %partial, %c | 256 %result = add i32 %partial, %c |
| 256 ret i32 %result | 257 ret i32 %result |
| 257 } | 258 } |
| 258 | 259 |
| 259 ; CHECK-LABEL: no_fold_cmp_select_multi_liveout | 260 ; CHECK-LABEL: no_fold_cmp_select_multi_liveout |
| 260 ; CHECK: set | 261 ; CHECK: set |
| 261 ; CHECK: cmp | 262 ; CHECK: cmp |
| 262 ; CHECK: cmovne | 263 ; CHECK: cmovne |
| 263 ; CHECK: cmp | 264 ; CHECK: cmp |
| 264 ; CHECK: cmovne | 265 ; CHECK: cmovne |
| 265 ; CHECK: cmp | 266 ; CHECK: cmp |
| 266 ; CHECK: cmove | 267 ; CHECK: cmove |
| 267 ; CHECK: add | 268 ; CHECK: add |
| 268 ; CHECK: add | 269 ; CHECK: add |
| 269 ; ARM32-LABEL: no_fold_cmp_select_multi_liveout | 270 ; ARM32-LABEL: no_fold_cmp_select_multi_liveout |
| 270 ; ARM32-LABEL: fold_cmp_select_multi | 271 ; ARM32-LABEL: fold_cmp_select_multi |
| 271 ; ARM32-DAG: mov [[T0:r[0-9]+]], #0 | 272 ; ARM32: mov [[T0:r[0-9]+]], #0 |
| 272 ; ARM32-DAG: cmp r0, r1 | 273 ; ARM32: cmp r0, r1 |
| 273 ; ARM32: movlt [[T0]], #1 | 274 ; ARM32: movlt [[T0]], #1 |
| 274 ; ARM32-DAG: mov [[T1:r[0-9]+]], r1 | 275 ; ARM32: uxtb [[T2:r[0-9]+]], [[T2]] |
| 275 ; ARM32-DAG: cmp [[T0]], #0 | 276 ; ARM32-NEXT: cmp [[T2]], #0 |
| 276 ; ARM32: [[T1]], r0 | 277 ; ARM32: movne [[T1]], r0 |
| 277 ; ARM32-DAG: mov [[T2:r[0-9]+]], r0 | 278 ; ARM32: uxtb [[T4:r[0-9]+]], [[T4]] |
| 278 ; ARM32-DAG: cmp [[T0]], #0 | 279 ; ARM32-NEXT: cmp [[T4]], #0 |
| 279 ; ARM32: [[T2]], r1 | 280 ; ARM32: movne [[T3]], r1 |
| 280 ; ARM32: cmp [[T0]], #0 | 281 ; ARM32-LABEL: .Lno_fold_cmp_select_multi_liveout$next: |
| 281 ; ARM32: movne | 282 ; ARM32: uxtb [[T5:r[0-9]+]], [[T5]] |
| 282 ; ARM32: add | 283 ; ARM32: cmp [[T5]], #0 |
| 283 ; ARM32: add | 284 ; ARM32: movne [[T6:r[0-9]+]], #123 |
| 285 ; ARM32: add [[T7:r[0-9]+]], [[T2]], [[T4]] |
| 286 ; ARM32: add {{r[0-9]+}}, [[T7]], [[T6]] |
| 284 ; ARM32: bx lr | 287 ; ARM32: bx lr |
| 285 | 288 |
| 286 ; Cmp/multi-select non-folding because of extra non-whitelisted uses. | 289 ; Cmp/multi-select non-folding because of extra non-whitelisted uses. |
| 287 define internal i32 @no_fold_cmp_select_multi_non_whitelist(i32 %arg1, | 290 define internal i32 @no_fold_cmp_select_multi_non_whitelist(i32 %arg1, |
| 288 i32 %arg2) { | 291 i32 %arg2) { |
| 289 entry: | 292 entry: |
| 290 %cmp1 = icmp slt i32 %arg1, %arg2 | 293 %cmp1 = icmp slt i32 %arg1, %arg2 |
| 291 %a = select i1 %cmp1, i32 %arg1, i32 %arg2 | 294 %a = select i1 %cmp1, i32 %arg1, i32 %arg2 |
| 292 %b = select i1 %cmp1, i32 %arg2, i32 %arg1 | 295 %b = select i1 %cmp1, i32 %arg2, i32 %arg1 |
| 293 %c = select i1 %cmp1, i32 123, i32 %arg1 | 296 %c = select i1 %cmp1, i32 123, i32 %arg1 |
| (...skipping 10 matching lines...) Expand all Loading... |
| 304 ; CHECK: cmovne | 307 ; CHECK: cmovne |
| 305 ; CHECK: cmp | 308 ; CHECK: cmp |
| 306 ; CHECK: cmovne | 309 ; CHECK: cmovne |
| 307 ; CHECK: cmp | 310 ; CHECK: cmp |
| 308 ; CHECK: cmove | 311 ; CHECK: cmove |
| 309 ; CHECK: movzx | 312 ; CHECK: movzx |
| 310 ; CHECK: add | 313 ; CHECK: add |
| 311 ; CHECK: add | 314 ; CHECK: add |
| 312 ; CHECK: add | 315 ; CHECK: add |
| 313 ; ARM32-LABEL: no_fold_cmp_select_multi_non_whitelist | 316 ; ARM32-LABEL: no_fold_cmp_select_multi_non_whitelist |
| 314 ; ARM32-DAG: mov [[T0:r[0-9]+]], #0 | 317 ; ARM32: mov [[T0:r[0-9]+]], #0 |
| 315 ; ARM32-DAG: cmp r0, r1 | 318 ; ARM32: cmp r0, r1 |
| 316 ; ARM32: movlt [[T0]], #1 | 319 ; ARM32: movlt [[T0]], #1 |
| 317 ; ARM32-DAG: mov [[T1:r[0-9]+]], r1 | 320 ; ARM32: uxtb [[T1:r[0-9]+]], [[T1]] |
| 318 ; ARM32-DAG: cmp [[T0]], #0 | 321 ; ARM32-NEXT: cmp [[T1]], #0 |
| 319 ; ARM32: [[T1]], r0 | 322 ; ARM32: movne [[T2:r[0-9]+]], r0 |
| 320 ; ARM32-DAG: mov [[T2:r[0-9]+]], r0 | 323 ; ARM32: uxtb [[T3:r[0-9]+]], [[T3]] |
| 321 ; ARM32-DAG: cmp [[T0]], #0 | 324 ; ARM32-NEXT: cmp [[T3]], #0 |
| 322 ; ARM32: [[T2]], r1 | 325 ; ARM32: movne [[T4:r[0-9]+]], r1 |
| 323 ; ARM32: cmp [[T0]], #0 | 326 ; ARM32: uxtb [[T5:r[0-9]+]], [[T5]] |
| 324 ; ARM32: movne | 327 ; ARM32-NEXT: cmp [[T5]], #0 |
| 325 ; ARM32: and {{.*}}, [[T0]], #1 | 328 ; ARM32: movne [[T6:r[0-9]+]], #123 |
| 326 ; ARM32: add | 329 ; ARM32: and [[T7:r[0-9]+]], [[T0]], #1 |
| 327 ; ARM32: add | 330 ; ARM32: add [[T8:r[0-9]+]], [[T2]], [[T4]] |
| 328 ; ARM32: add | 331 ; ARM32: add {{r[0-9]+}}, [[T8]], [[T7]] |
| 329 ; ARM32: bx lr | 332 ; ARM32: bx lr |
| OLD | NEW |