239 lines
7 KiB
YAML
239 lines
7 KiB
YAML
# RUN: llc -mtriple=aarch64-linux-gnu -run-pass machine-combiner -o - %s | FileCheck %s
|
|
|
|
# The test cases in this file check following transformation if the right form
|
|
# can reduce latency.
|
|
# A - (B + C) ==> (A - B) - C
|
|
|
|
---
|
|
# 32 bit.
|
|
|
|
# CHECK-LABEL: name: test1
|
|
# CHECK: [[TMP:%[0-9]+]]:gpr32common = SUBWrr killed %3, %4
|
|
# CHECK-NEXT: %7:gpr32 = SUBWrr killed [[TMP]], %5
|
|
|
|
name: test1
|
|
registers:
|
|
- { id: 0, class: gpr32common }
|
|
- { id: 1, class: gpr32 }
|
|
- { id: 2, class: gpr32 }
|
|
- { id: 3, class: gpr32common }
|
|
- { id: 4, class: gpr32common }
|
|
- { id: 5, class: gpr32 }
|
|
- { id: 6, class: gpr32 }
|
|
- { id: 7, class: gpr32 }
|
|
- { id: 8, class: gpr32 }
|
|
body: |
|
|
bb.0:
|
|
%2:gpr32 = COPY $w2
|
|
%1:gpr32 = COPY $w1
|
|
%0:gpr32common = COPY $w0
|
|
%3:gpr32common = ORRWri %2:gpr32, 1600
|
|
%4:gpr32common = ADDWri %0:gpr32common, 100, 0
|
|
%5:gpr32 = EORWrs %1:gpr32, %4:gpr32common, 8
|
|
%6:gpr32 = ADDWrr %5:gpr32, %4:gpr32common
|
|
%7:gpr32 = SUBWrr killed %3:gpr32common, killed %6:gpr32
|
|
%8:gpr32 = EORWrs killed %7:gpr32, %5:gpr32, 141
|
|
$w0 = COPY %8:gpr32
|
|
RET_ReallyLR implicit $w0
|
|
|
|
...
|
|
---
|
|
# 64 bit.
|
|
|
|
# CHECK-LABEL: name: test2
|
|
# CHECK: [[TMP:%[0-9]+]]:gpr64common = SUBXrr killed %3, %4
|
|
# CHECK-NEXT: %7:gpr64 = SUBXrr killed [[TMP]], %5
|
|
|
|
name: test2
|
|
registers:
|
|
- { id: 0, class: gpr64common }
|
|
- { id: 1, class: gpr64 }
|
|
- { id: 2, class: gpr64 }
|
|
- { id: 3, class: gpr64common }
|
|
- { id: 4, class: gpr64common }
|
|
- { id: 5, class: gpr64 }
|
|
- { id: 6, class: gpr64 }
|
|
- { id: 7, class: gpr64 }
|
|
- { id: 8, class: gpr64 }
|
|
body: |
|
|
bb.0:
|
|
%2:gpr64 = COPY $x2
|
|
%1:gpr64 = COPY $x1
|
|
%0:gpr64common = COPY $x0
|
|
%3:gpr64common = ORRXri %2:gpr64, 1600
|
|
%4:gpr64common = ADDXri %0:gpr64common, 100, 0
|
|
%5:gpr64 = EORXrs %1:gpr64, %4:gpr64common, 8
|
|
%6:gpr64 = ADDXrr %5:gpr64, %4:gpr64common
|
|
%7:gpr64 = SUBXrr killed %3:gpr64common, killed %6:gpr64
|
|
%8:gpr64 = EORXrs killed %7:gpr64, %5:gpr64, 141
|
|
$x0 = COPY %8:gpr64
|
|
RET_ReallyLR implicit $x0
|
|
|
|
...
|
|
---
|
|
# Negative test. The right form can't reduce latency.
|
|
|
|
# CHECK-LABEL: name: test3
|
|
# CHECK: %6:gpr32 = ADDWrr killed %3, %4
|
|
# CHECK-NEXT: %7:gpr32 = SUBWrr %5, killed %6
|
|
|
|
name: test3
|
|
registers:
|
|
- { id: 0, class: gpr32common }
|
|
- { id: 1, class: gpr32 }
|
|
- { id: 2, class: gpr32 }
|
|
- { id: 3, class: gpr32common }
|
|
- { id: 4, class: gpr32common }
|
|
- { id: 5, class: gpr32 }
|
|
- { id: 6, class: gpr32 }
|
|
- { id: 7, class: gpr32 }
|
|
- { id: 8, class: gpr32 }
|
|
body: |
|
|
bb.0:
|
|
%2:gpr32 = COPY $w2
|
|
%1:gpr32 = COPY $w1
|
|
%0:gpr32common = COPY $w0
|
|
%3:gpr32common = ORRWri %2:gpr32, 1600
|
|
%4:gpr32common = ADDWri %0:gpr32common, 100, 0
|
|
%5:gpr32 = EORWrs %1:gpr32, %4:gpr32common, 8
|
|
%6:gpr32 = ADDWrr killed %3:gpr32common, %4:gpr32common
|
|
%7:gpr32 = SUBWrr %5:gpr32, killed %6:gpr32
|
|
%8:gpr32 = EORWrs killed %7:gpr32, %5:gpr32, 141
|
|
$w0 = COPY %8:gpr32
|
|
RET_ReallyLR implicit $w0
|
|
|
|
...
|
|
---
|
|
# Dead define of flag registers should not block transformation.
|
|
|
|
# CHECK-LABEL: name: test4
|
|
# CHECK: [[TMP:%[0-9]+]]:gpr64common = SUBXrr killed %3, %4
|
|
# CHECK-NEXT: %7:gpr64 = SUBXrr killed [[TMP]], %5
|
|
|
|
name: test4
|
|
registers:
|
|
- { id: 0, class: gpr64common }
|
|
- { id: 1, class: gpr64 }
|
|
- { id: 2, class: gpr64 }
|
|
- { id: 3, class: gpr64common }
|
|
- { id: 4, class: gpr64common }
|
|
- { id: 5, class: gpr64 }
|
|
- { id: 6, class: gpr64 }
|
|
- { id: 7, class: gpr64 }
|
|
- { id: 8, class: gpr64 }
|
|
body: |
|
|
bb.0:
|
|
%2:gpr64 = COPY $x2
|
|
%1:gpr64 = COPY $x1
|
|
%0:gpr64common = COPY $x0
|
|
%3:gpr64common = ORRXri %2:gpr64, 1600
|
|
%4:gpr64common = ADDXri %0:gpr64common, 100, 0
|
|
%5:gpr64 = EORXrs %1:gpr64, %4:gpr64common, 8
|
|
%6:gpr64 = ADDSXrr %5:gpr64, %4:gpr64common, implicit-def dead $nzcv
|
|
%7:gpr64 = SUBSXrr killed %3:gpr64common, killed %6:gpr64, implicit-def dead $nzcv
|
|
%8:gpr64 = EORXrs killed %7:gpr64, %5:gpr64, 141
|
|
$x0 = COPY %8:gpr64
|
|
RET_ReallyLR implicit $x0
|
|
|
|
...
|
|
---
|
|
# Non dead define of flag register in SUB can block the transformation.
|
|
|
|
# CHECK-LABEL: name: test5
|
|
# CHECK: %6:gpr32 = ADDWrr %5, %4
|
|
# CHECK-NEXT: %7:gpr32 = SUBSWrr killed %3, killed %6, implicit-def $nzcv
|
|
|
|
name: test5
|
|
registers:
|
|
- { id: 0, class: gpr32common }
|
|
- { id: 1, class: gpr32 }
|
|
- { id: 2, class: gpr32 }
|
|
- { id: 3, class: gpr32common }
|
|
- { id: 4, class: gpr32common }
|
|
- { id: 5, class: gpr32 }
|
|
- { id: 6, class: gpr32 }
|
|
- { id: 7, class: gpr32 }
|
|
- { id: 8, class: gpr32 }
|
|
body: |
|
|
bb.0:
|
|
%2:gpr32 = COPY $w2
|
|
%1:gpr32 = COPY $w1
|
|
%0:gpr32common = COPY $w0
|
|
%3:gpr32common = ORRWri %2:gpr32, 1600
|
|
%4:gpr32common = ADDWri %0:gpr32common, 100, 0
|
|
%5:gpr32 = EORWrs %1:gpr32, %4:gpr32common, 8
|
|
%6:gpr32 = ADDWrr %5:gpr32, %4:gpr32common
|
|
%7:gpr32 = SUBSWrr killed %3:gpr32common, killed %6:gpr32, implicit-def $nzcv
|
|
%8:gpr32 = EORWrs killed %7:gpr32, %5:gpr32, 141
|
|
$w0 = COPY %8:gpr32
|
|
RET_ReallyLR implicit $w0
|
|
|
|
...
|
|
---
|
|
# Non dead define of flag register in ADD can block the transformation.
|
|
|
|
# CHECK-LABEL: name: test6
|
|
# CHECK: %6:gpr64 = ADDSXrr %5, %4, implicit-def $nzcv
|
|
# CHECK-NEXT: %7:gpr64 = SUBXrr killed %3, killed %6
|
|
|
|
name: test6
|
|
registers:
|
|
- { id: 0, class: gpr64common }
|
|
- { id: 1, class: gpr64 }
|
|
- { id: 2, class: gpr64 }
|
|
- { id: 3, class: gpr64common }
|
|
- { id: 4, class: gpr64common }
|
|
- { id: 5, class: gpr64 }
|
|
- { id: 6, class: gpr64 }
|
|
- { id: 7, class: gpr64 }
|
|
- { id: 8, class: gpr64 }
|
|
body: |
|
|
bb.0:
|
|
%2:gpr64 = COPY $x2
|
|
%1:gpr64 = COPY $x1
|
|
%0:gpr64common = COPY $x0
|
|
%3:gpr64common = ORRXri %2:gpr64, 1600
|
|
%4:gpr64common = ADDXri %0:gpr64common, 100, 0
|
|
%5:gpr64 = EORXrs %1:gpr64, %4:gpr64common, 8
|
|
%6:gpr64 = ADDSXrr %5:gpr64, %4:gpr64common, implicit-def $nzcv
|
|
%7:gpr64 = SUBXrr killed %3:gpr64common, killed %6:gpr64
|
|
%8:gpr64 = EORXrs killed %7:gpr64, %5:gpr64, 141
|
|
$x0 = COPY %8:gpr64
|
|
RET_ReallyLR implicit $x0
|
|
|
|
...
|
|
---
|
|
# ADD has multiple uses, so it is always required, we should not transform it.
|
|
|
|
# CHECK-LABEL: name: test7
|
|
# CHECK: %6:gpr32 = ADDWrr %5, %4
|
|
# CHECK-NEXT: %7:gpr32 = SUBWrr killed %3, %6
|
|
|
|
name: test7
|
|
registers:
|
|
- { id: 0, class: gpr32common }
|
|
- { id: 1, class: gpr32 }
|
|
- { id: 2, class: gpr32 }
|
|
- { id: 3, class: gpr32common }
|
|
- { id: 4, class: gpr32common }
|
|
- { id: 5, class: gpr32 }
|
|
- { id: 6, class: gpr32 }
|
|
- { id: 7, class: gpr32 }
|
|
- { id: 8, class: gpr32 }
|
|
- { id: 9, class: gpr32 }
|
|
body: |
|
|
bb.0:
|
|
%2:gpr32 = COPY $w2
|
|
%1:gpr32 = COPY $w1
|
|
%0:gpr32common = COPY $w0
|
|
%3:gpr32common = ORRWri %2:gpr32, 1600
|
|
%4:gpr32common = ADDWri %0:gpr32common, 100, 0
|
|
%5:gpr32 = EORWrs %1:gpr32, %4:gpr32common, 8
|
|
%6:gpr32 = ADDWrr %5:gpr32, %4:gpr32common
|
|
%7:gpr32 = SUBWrr killed %3:gpr32common, %6:gpr32
|
|
%8:gpr32 = EORWrs killed %7:gpr32, %5:gpr32, 141
|
|
%9:gpr32 = ADDWrr %8:gpr32, %6:gpr32
|
|
$w0 = COPY %9:gpr32
|
|
RET_ReallyLR implicit $w0
|
|
|
|
...
|