300 lines · plain
1# RUN: llc -mtriple=aarch64-linux-gnu -run-pass machine-combiner -verify-machineinstrs -o - %s | FileCheck %s2 3# The test cases in this file check following transformation if the right form4# can reduce latency.5# A - (B + C) ==> (A - B) - C6 7---8# 32 bit.9 10# CHECK-LABEL: name: test111# CHECK: [[TMP:%[0-9]+]]:gpr32 = SUBWrr killed %3, %412# CHECK-NEXT: %7:gpr32 = SUBWrr killed [[TMP]], %513 14name: test115registers:16 - { id: 0, class: gpr32common }17 - { id: 1, class: gpr32 }18 - { id: 2, class: gpr32 }19 - { id: 3, class: gpr32common }20 - { id: 4, class: gpr32common }21 - { id: 5, class: gpr32 }22 - { id: 6, class: gpr32 }23 - { id: 7, class: gpr32 }24 - { id: 8, class: gpr32 }25body: |26 bb.0:27 %2:gpr32 = COPY $w228 %1:gpr32 = COPY $w129 %0:gpr32common = COPY $w030 %3:gpr32common = ORRWri %2:gpr32, 160031 %4:gpr32common = ADDWri %0:gpr32common, 100, 032 %5:gpr32 = EORWrs %1:gpr32, %4:gpr32common, 833 %6:gpr32 = ADDWrr %5:gpr32, %4:gpr32common34 %7:gpr32 = SUBWrr killed %3:gpr32common, killed %6:gpr3235 %8:gpr32 = EORWrs killed %7:gpr32, %5:gpr32, 14136 $w0 = COPY %8:gpr3237 RET_ReallyLR implicit $w038 39...40---41# 64 bit.42 43# CHECK-LABEL: name: test244# CHECK: [[TMP:%[0-9]+]]:gpr64 = SUBXrr killed %3, %445# CHECK-NEXT: %7:gpr64 = SUBXrr killed [[TMP]], %546 47name: test248registers:49 - { id: 0, class: gpr64common }50 - { id: 1, class: gpr64 }51 - { id: 2, class: gpr64 }52 - { id: 3, class: gpr64common }53 - { id: 4, class: gpr64common }54 - { id: 5, class: gpr64 }55 - { id: 6, class: gpr64 }56 - { id: 7, class: gpr64 }57 - { id: 8, class: gpr64 }58body: |59 bb.0:60 %2:gpr64 = COPY $x261 %1:gpr64 = COPY $x162 %0:gpr64common = COPY $x063 %3:gpr64common = ORRXri %2:gpr64, 160064 %4:gpr64common = ADDXri %0:gpr64common, 100, 065 %5:gpr64 = EORXrs %1:gpr64, %4:gpr64common, 866 %6:gpr64 = ADDXrr %5:gpr64, %4:gpr64common67 %7:gpr64 = SUBXrr killed %3:gpr64common, killed %6:gpr6468 %8:gpr64 = EORXrs killed %7:gpr64, %5:gpr64, 14169 $x0 = COPY %8:gpr6470 RET_ReallyLR implicit $x071 72...73---74# Negative test. The right form can't reduce latency.75 76# CHECK-LABEL: name: test377# CHECK: %6:gpr32 = ADDWrr killed %3, %478# CHECK-NEXT: %7:gpr32 = SUBWrr %5, killed %679 80name: test381registers:82 - { id: 0, class: gpr32common }83 - { id: 1, class: gpr32 }84 - { id: 2, class: gpr32 }85 - { id: 3, class: gpr32common }86 - { id: 4, class: gpr32common }87 - { id: 5, class: gpr32 }88 - { id: 6, class: gpr32 }89 - { id: 7, class: gpr32 }90 - { id: 8, class: gpr32 }91body: |92 bb.0:93 %2:gpr32 = COPY $w294 %1:gpr32 = COPY $w195 %0:gpr32common = COPY $w096 %3:gpr32common = ORRWri %2:gpr32, 160097 %4:gpr32common = ADDWri %0:gpr32common, 100, 098 %5:gpr32 = EORWrs %1:gpr32, %4:gpr32common, 899 %6:gpr32 = ADDWrr killed %3:gpr32common, %4:gpr32common100 %7:gpr32 = SUBWrr %5:gpr32, killed %6:gpr32101 %8:gpr32 = EORWrs killed %7:gpr32, %5:gpr32, 141102 $w0 = COPY %8:gpr32103 RET_ReallyLR implicit $w0104 105...106---107# Dead define of flag registers should not block transformation.108 109# CHECK-LABEL: name: test4110# CHECK: [[TMP:%[0-9]+]]:gpr64 = SUBXrr killed %3, %4111# CHECK-NEXT: %7:gpr64 = SUBXrr killed [[TMP]], %5112 113name: test4114registers:115 - { id: 0, class: gpr64common }116 - { id: 1, class: gpr64 }117 - { id: 2, class: gpr64 }118 - { id: 3, class: gpr64common }119 - { id: 4, class: gpr64common }120 - { id: 5, class: gpr64 }121 - { id: 6, class: gpr64 }122 - { id: 7, class: gpr64 }123 - { id: 8, class: gpr64 }124body: |125 bb.0:126 %2:gpr64 = COPY $x2127 %1:gpr64 = COPY $x1128 %0:gpr64common = COPY $x0129 %3:gpr64common = ORRXri %2:gpr64, 1600130 %4:gpr64common = ADDXri %0:gpr64common, 100, 0131 %5:gpr64 = EORXrs %1:gpr64, %4:gpr64common, 8132 %6:gpr64 = ADDSXrr %5:gpr64, %4:gpr64common, implicit-def dead $nzcv133 %7:gpr64 = SUBSXrr killed %3:gpr64common, killed %6:gpr64, implicit-def dead $nzcv134 %8:gpr64 = EORXrs killed %7:gpr64, %5:gpr64, 141135 $x0 = COPY %8:gpr64136 RET_ReallyLR implicit $x0137 138...139---140# Non dead define of flag register in SUB can block the transformation.141 142# CHECK-LABEL: name: test5143# CHECK: %6:gpr32 = ADDWrr %5, %4144# CHECK-NEXT: %7:gpr32 = SUBSWrr killed %3, killed %6, implicit-def $nzcv145 146name: test5147registers:148 - { id: 0, class: gpr32common }149 - { id: 1, class: gpr32 }150 - { id: 2, class: gpr32 }151 - { id: 3, class: gpr32common }152 - { id: 4, class: gpr32common }153 - { id: 5, class: gpr32 }154 - { id: 6, class: gpr32 }155 - { id: 7, class: gpr32 }156 - { id: 8, class: gpr32 }157body: |158 bb.0:159 %2:gpr32 = COPY $w2160 %1:gpr32 = COPY $w1161 %0:gpr32common = COPY $w0162 %3:gpr32common = ORRWri %2:gpr32, 1600163 %4:gpr32common = ADDWri %0:gpr32common, 100, 0164 %5:gpr32 = EORWrs %1:gpr32, %4:gpr32common, 8165 %6:gpr32 = ADDWrr %5:gpr32, %4:gpr32common166 %7:gpr32 = SUBSWrr killed %3:gpr32common, killed %6:gpr32, implicit-def $nzcv167 %8:gpr32 = EORWrs killed %7:gpr32, %5:gpr32, 141168 $w0 = COPY %8:gpr32169 RET_ReallyLR implicit $w0170 171...172---173# Non dead define of flag register in ADD can block the transformation.174 175# CHECK-LABEL: name: test6176# CHECK: %6:gpr64 = ADDSXrr %5, %4, implicit-def $nzcv177# CHECK-NEXT: %7:gpr64 = SUBXrr killed %3, killed %6178 179name: test6180registers:181 - { id: 0, class: gpr64common }182 - { id: 1, class: gpr64 }183 - { id: 2, class: gpr64 }184 - { id: 3, class: gpr64common }185 - { id: 4, class: gpr64common }186 - { id: 5, class: gpr64 }187 - { id: 6, class: gpr64 }188 - { id: 7, class: gpr64 }189 - { id: 8, class: gpr64 }190body: |191 bb.0:192 %2:gpr64 = COPY $x2193 %1:gpr64 = COPY $x1194 %0:gpr64common = COPY $x0195 %3:gpr64common = ORRXri %2:gpr64, 1600196 %4:gpr64common = ADDXri %0:gpr64common, 100, 0197 %5:gpr64 = EORXrs %1:gpr64, %4:gpr64common, 8198 %6:gpr64 = ADDSXrr %5:gpr64, %4:gpr64common, implicit-def $nzcv199 %7:gpr64 = SUBXrr killed %3:gpr64common, killed %6:gpr64200 %8:gpr64 = EORXrs killed %7:gpr64, %5:gpr64, 141201 $x0 = COPY %8:gpr64202 RET_ReallyLR implicit $x0203 204...205---206# ADD has multiple uses, so it is always required, we should not transform it.207 208# CHECK-LABEL: name: test7209# CHECK: %6:gpr32 = ADDWrr %5, %4210# CHECK-NEXT: %7:gpr32 = SUBWrr killed %3, %6211 212name: test7213registers:214 - { id: 0, class: gpr32common }215 - { id: 1, class: gpr32 }216 - { id: 2, class: gpr32 }217 - { id: 3, class: gpr32common }218 - { id: 4, class: gpr32common }219 - { id: 5, class: gpr32 }220 - { id: 6, class: gpr32 }221 - { id: 7, class: gpr32 }222 - { id: 8, class: gpr32 }223 - { id: 9, class: gpr32 }224body: |225 bb.0:226 %2:gpr32 = COPY $w2227 %1:gpr32 = COPY $w1228 %0:gpr32common = COPY $w0229 %3:gpr32common = ORRWri %2:gpr32, 1600230 %4:gpr32common = ADDWri %0:gpr32common, 100, 0231 %5:gpr32 = EORWrs %1:gpr32, %4:gpr32common, 8232 %6:gpr32 = ADDWrr %5:gpr32, %4:gpr32common233 %7:gpr32 = SUBWrr killed %3:gpr32common, %6:gpr32234 %8:gpr32 = EORWrs killed %7:gpr32, %5:gpr32, 141235 %9:gpr32 = ADDWrr %8:gpr32, %6:gpr32236 $w0 = COPY %9:gpr32237 RET_ReallyLR implicit $w0238 239...240---241# Drop nowrap flags in SUB242 243# CHECK-LABEL: name: test8244# CHECK: [[SUBXrr:%[0-9]+]]:gpr64 = SUBXrr %1, %0245# CHECK-NEXT: %4:gpr64common = SUBXrr killed [[SUBXrr]], killed %2246 247name: test8248registers:249 - { id: 0, class: gpr64 }250 - { id: 1, class: gpr64 }251 - { id: 2, class: gpr64common }252 - { id: 3, class: gpr64 }253 - { id: 4, class: gpr64common }254 - { id: 5, class: gpr64 }255body: |256 bb.0:257 %1:gpr64 = COPY $x1258 %0:gpr64 = COPY $x0259 %2:gpr64common = ORRXri %0:gpr64, 4096260 %3:gpr64 = ADDXrr killed %2:gpr64common, %0:gpr64261 %4:gpr64common = nsw SUBSXrr %1:gpr64, killed %3:gpr64, implicit-def dead $nzcv262 %5:gpr64 = SUBSXri %4:gpr64common, 0, 0, implicit-def $nzcv263 $x0 = COPY %5:gpr64264 RET_ReallyLR implicit $x0265 266...267---268# WZR use269 270# CHECK-LABEL: name: wzr271# CHECK: [[TMP:%[0-9]+]]:gpr32 = SUBWrr killed $wzr, %4272# CHECK-NEXT: %7:gpr32 = SUBWrr killed [[TMP]], %5273 274name: wzr275registers:276 - { id: 0, class: gpr32common }277 - { id: 1, class: gpr32 }278 - { id: 2, class: gpr32 }279 - { id: 3, class: gpr32common }280 - { id: 4, class: gpr32common }281 - { id: 5, class: gpr32 }282 - { id: 6, class: gpr32 }283 - { id: 7, class: gpr32 }284 - { id: 8, class: gpr32 }285body: |286 bb.0:287 %2:gpr32 = COPY $w2288 %1:gpr32 = COPY $w1289 %0:gpr32common = COPY $w0290 %3:gpr32common = ORRWri %2:gpr32, 1600291 %4:gpr32common = ADDWri %0:gpr32common, 100, 0292 %5:gpr32 = EORWrs %1:gpr32, %4:gpr32common, 8293 %6:gpr32 = ADDWrr %5:gpr32, %4:gpr32common294 %7:gpr32 = SUBWrr killed $wzr, killed %6:gpr32295 %8:gpr32 = EORWrs killed %7:gpr32, %5:gpr32, 141296 $w0 = COPY %8:gpr32297 RET_ReallyLR implicit $w0298 299...300