1# RUN: llc -run-pass=machine-combiner -o - -simplify-mir -mtriple=arm64-apple-iphoneos %s | FileCheck %s 2 3# Can create FMADD, because both the fmul and fadd have all fast-math flags. 4# 5# CHECK-LABEL: name: scalar_fmadd_fast 6# CHECK: [[C:%.*]]:fpr32 = COPY $s2 7# CHECK-NEXT: [[B:%.*]]:fpr32 = COPY $s1 8# CHECK-NEXT: [[A:%.*]]:fpr32 = COPY $s0 9# CHECK-NEXT: :fpr32 = FMADDSrrr [[B]], [[A]], [[C]] 10--- 11name: scalar_fmadd_fast 12alignment: 4 13tracksRegLiveness: true 14registers: 15 - { id: 0, class: fpr32 } 16 - { id: 1, class: fpr32 } 17 - { id: 2, class: fpr32 } 18 - { id: 3, class: fpr32 } 19 - { id: 4, class: fpr32 } 20liveins: 21 - { reg: '$s0', virtual-reg: '%0' } 22 - { reg: '$s1', virtual-reg: '%1' } 23 - { reg: '$s2', virtual-reg: '%2' } 24frameInfo: 25 maxAlignment: 1 26 maxCallFrameSize: 0 27machineFunctionInfo: {} 28body: | 29 bb.0.entry: 30 liveins: $s0, $s1, $s2 31 32 %2:fpr32 = COPY $s2 33 %1:fpr32 = COPY $s1 34 %0:fpr32 = COPY $s0 35 %3:fpr32 = nnan ninf nsz arcp contract afn reassoc FMULSrr %1, %0 36 %4:fpr32 = nnan ninf nsz arcp contract afn reassoc FADDSrr killed %3, %2 37 $s0 = COPY %4 38 RET_ReallyLR implicit $s0 39 40... 41 42# Can create FMADD, because both the fmul and fadd have the contract fast-math flag. 43# 44# CHECK-LABEL: name: scalar_fmadd_contract 45# CHECK: [[C:%.*]]:fpr32 = COPY $s2 46# CHECK-NEXT: [[B:%.*]]:fpr32 = COPY $s1 47# CHECK-NEXT: [[A:%.*]]:fpr32 = COPY $s0 48# CHECK-NEXT: :fpr32 = FMADDSrrr [[B]], [[A]], [[C]] 49 50--- 51name: scalar_fmadd_contract 52alignment: 4 53tracksRegLiveness: true 54registers: 55 - { id: 0, class: fpr32 } 56 - { id: 1, class: fpr32 } 57 - { id: 2, class: fpr32 } 58 - { id: 3, class: fpr32 } 59 - { id: 4, class: fpr32 } 60liveins: 61 - { reg: '$s0', virtual-reg: '%0' } 62 - { reg: '$s1', virtual-reg: '%1' } 63 - { reg: '$s2', virtual-reg: '%2' } 64frameInfo: 65 maxAlignment: 1 66 maxCallFrameSize: 0 67machineFunctionInfo: {} 68body: | 69 bb.0.entry: 70 liveins: $s0, $s1, $s2 71 72 %2:fpr32 = COPY $s2 73 %1:fpr32 = COPY $s1 74 %0:fpr32 = COPY $s0 75 %3:fpr32 = contract FMULSrr %1, %0 76 %4:fpr32 = contract FADDSrr killed %3, %2 77 $s0 = COPY %4 78 RET_ReallyLR implicit $s0 79 80... 81 82# Do not create FMADD, because we don't have the contract flag on the FADD. 83 84# CHECK-LABEL: name: scalar_fmadd_contract_op0 85# CHECK: [[C:%.*]]:fpr32 = COPY $s2 86# CHECK-NEXT: [[B:%.*]]:fpr32 = COPY $s1 87# CHECK-NEXT: [[A:%.*]]:fpr32 = COPY $s0 88# CHECK-NEXT: [[MUL:%.*]]:fpr32 = contract FMULSrr [[B]], [[A]] 89# CHECK-NEXT: fpr32 = FADDSrr killed [[MUL]], [[C]] 90--- 91name: scalar_fmadd_contract_op0 92alignment: 4 93tracksRegLiveness: true 94registers: 95 - { id: 0, class: fpr32 } 96 - { id: 1, class: fpr32 } 97 - { id: 2, class: fpr32 } 98 - { id: 3, class: fpr32 } 99 - { id: 4, class: fpr32 } 100liveins: 101 - { reg: '$s0', virtual-reg: '%0' } 102 - { reg: '$s1', virtual-reg: '%1' } 103 - { reg: '$s2', virtual-reg: '%2' } 104frameInfo: 105 maxAlignment: 1 106 maxCallFrameSize: 0 107machineFunctionInfo: {} 108body: | 109 bb.0.entry: 110 liveins: $s0, $s1, $s2 111 112 %2:fpr32 = COPY $s2 113 %1:fpr32 = COPY $s1 114 %0:fpr32 = COPY $s0 115 %3:fpr32 = contract FMULSrr %1, %0 116 %4:fpr32 = FADDSrr killed %3, %2 117 $s0 = COPY %4 118 RET_ReallyLR implicit $s0 119 120... 121 122# Do create FMADD, because we have the contract flag on the FADD. 123# 124# CHECK-LABEL: name: scalar_fmadd_contract_op1 125# CHECK: [[C:%.*]]:fpr32 = COPY $s2 126# CHECK-NEXT: [[B:%.*]]:fpr32 = COPY $s1 127# CHECK-NEXT: [[A:%.*]]:fpr32 = COPY $s0 128# CHECK-NEXT: :fpr32 = FMADDSrrr [[B]], [[A]], [[C]] 129 130--- 131name: scalar_fmadd_contract_op1 132alignment: 4 133tracksRegLiveness: true 134registers: 135 - { id: 0, class: fpr32 } 136 - { id: 1, class: fpr32 } 137 - { id: 2, class: fpr32 } 138 - { id: 3, class: fpr32 } 139 - { id: 4, class: fpr32 } 140liveins: 141 - { reg: '$s0', virtual-reg: '%0' } 142 - { reg: '$s1', virtual-reg: '%1' } 143 - { reg: '$s2', virtual-reg: '%2' } 144frameInfo: 145 maxAlignment: 1 146 maxCallFrameSize: 0 147machineFunctionInfo: {} 148body: | 149 bb.0.entry: 150 liveins: $s0, $s1, $s2 151 152 %2:fpr32 = COPY $s2 153 %1:fpr32 = COPY $s1 154 %0:fpr32 = COPY $s0 155 %3:fpr32 = FMULSrr %1, %0 156 %4:fpr32 = contract FADDSrr killed %3, %2 157 $s0 = COPY %4 158 RET_ReallyLR implicit $s0 159 160... 161 162# Do not create FMADD, as nsz flag does not allow it. 163# 164# CHECK-LABEL: name: scalar_fmadd_nsz 165# CHECK: [[C:%.*]]:fpr32 = COPY $s2 166# CHECK-NEXT: [[B:%.*]]:fpr32 = COPY $s1 167# CHECK-NEXT: [[A:%.*]]:fpr32 = COPY $s0 168# CHECK-NEXT: [[MUL:%.*]]:fpr32 = nsz FMULSrr [[B]], [[A]] 169# CHECK-NEXT: fpr32 = nsz FADDSrr killed [[MUL]], [[C]] 170 171--- 172name: scalar_fmadd_nsz 173alignment: 4 174tracksRegLiveness: true 175registers: 176 - { id: 0, class: fpr32 } 177 - { id: 1, class: fpr32 } 178 - { id: 2, class: fpr32 } 179 - { id: 3, class: fpr32 } 180 - { id: 4, class: fpr32 } 181liveins: 182 - { reg: '$s0', virtual-reg: '%0' } 183 - { reg: '$s1', virtual-reg: '%1' } 184 - { reg: '$s2', virtual-reg: '%2' } 185frameInfo: 186 maxAlignment: 1 187 maxCallFrameSize: 0 188machineFunctionInfo: {} 189body: | 190 bb.0.entry: 191 liveins: $s0, $s1, $s2 192 193 %2:fpr32 = COPY $s2 194 %1:fpr32 = COPY $s1 195 %0:fpr32 = COPY $s0 196 %3:fpr32 = nsz FMULSrr %1, %0 197 %4:fpr32 = nsz FADDSrr killed %3, %2 198 $s0 = COPY %4 199 RET_ReallyLR implicit $s0 200 201... 202 203# Can create FMLA, because both the fmul and fadd have all fast-math flags. 204# 205# CHECK-LABEL: name: vector_fmadd_fast 206# CHECK: [[C:%.*]]:fpr128 = COPY $q2 207# CHECK-NEXT: [[B:%.*]]:fpr128 = COPY $q1 208# CHECK-NEXT: [[A:%.*]]:fpr128 = COPY $q0 209# CHECK-NEXT: fpr128 = FMLAv2f64 [[C]], [[B]], [[A]] 210--- 211name: vector_fmadd_fast 212alignment: 4 213tracksRegLiveness: true 214registers: 215 - { id: 0, class: fpr128 } 216 - { id: 1, class: fpr128 } 217 - { id: 2, class: fpr128 } 218 - { id: 3, class: fpr128 } 219 - { id: 4, class: fpr128 } 220liveins: 221 - { reg: '$q0', virtual-reg: '%0' } 222 - { reg: '$q1', virtual-reg: '%1' } 223 - { reg: '$q2', virtual-reg: '%2' } 224frameInfo: 225 maxAlignment: 1 226 maxCallFrameSize: 0 227machineFunctionInfo: {} 228body: | 229 bb.0.entry: 230 liveins: $q0, $q1, $q2 231 232 %2:fpr128 = COPY $q2 233 %1:fpr128 = COPY $q1 234 %0:fpr128 = COPY $q0 235 %3:fpr128 = nnan ninf nsz arcp contract afn reassoc FMULv2f64 %1, %0 236 %4:fpr128 = nnan ninf nsz arcp contract afn reassoc FADDv2f64 killed %3, %2 237 $q0 = COPY %4 238 RET_ReallyLR implicit $q0 239 240... 241 242# Can create FMLA, because both the fmul and fadd have the contract fast-math flag. 243# 244# CHECK-LABEL: name: vector_fmadd_contract 245# CHECK: [[C:%.*]]:fpr128 = COPY $q2 246# CHECK-NEXT: [[B:%.*]]:fpr128 = COPY $q1 247# CHECK-NEXT: [[A:%.*]]:fpr128 = COPY $q0 248# CHECK-NEXT: fpr128 = FMLAv2f64 [[C]], [[B]], [[A]] 249--- 250name: vector_fmadd_contract 251alignment: 4 252tracksRegLiveness: true 253registers: 254 - { id: 0, class: fpr128 } 255 - { id: 1, class: fpr128 } 256 - { id: 2, class: fpr128 } 257 - { id: 3, class: fpr128 } 258 - { id: 4, class: fpr128 } 259liveins: 260 - { reg: '$q0', virtual-reg: '%0' } 261 - { reg: '$q1', virtual-reg: '%1' } 262 - { reg: '$q2', virtual-reg: '%2' } 263frameInfo: 264 maxAlignment: 1 265 maxCallFrameSize: 0 266machineFunctionInfo: {} 267body: | 268 bb.0.entry: 269 liveins: $q0, $q1, $q2 270 271 %2:fpr128 = COPY $q2 272 %1:fpr128 = COPY $q1 273 %0:fpr128 = COPY $q0 274 %3:fpr128 = contract FMULv2f64 %1, %0 275 %4:fpr128 = contract FADDv2f64 killed %3, %2 276 $q0 = COPY %4 277 RET_ReallyLR implicit $q0 278 279... 280 281# Do not create FMLA, because we don't have the contract flag on the FADD. 282# 283# CHECK-LABEL: name: vector_fmadd_contract_op0 284# CHECK: [[C:%.*]]:fpr128 = COPY $q2 285# CHECK-NEXT: [[B:%.*]]:fpr128 = COPY $q1 286# CHECK-NEXT: [[A:%.*]]:fpr128 = COPY $q0 287# CHECK-NEXT: [[MUL:%.*]]:fpr128 = contract FMULv2f64 [[B]], [[A]] 288# CHECK-NEXT: fpr128 = FADDv2f64 killed [[MUL]], [[C]] 289--- 290name: vector_fmadd_contract_op0 291alignment: 4 292tracksRegLiveness: true 293registers: 294 - { id: 0, class: fpr128 } 295 - { id: 1, class: fpr128 } 296 - { id: 2, class: fpr128 } 297 - { id: 3, class: fpr128 } 298 - { id: 4, class: fpr128 } 299liveins: 300 - { reg: '$q0', virtual-reg: '%0' } 301 - { reg: '$q1', virtual-reg: '%1' } 302 - { reg: '$q2', virtual-reg: '%2' } 303frameInfo: 304 maxAlignment: 1 305 maxCallFrameSize: 0 306machineFunctionInfo: {} 307body: | 308 bb.0.entry: 309 liveins: $q0, $q1, $q2 310 311 %2:fpr128 = COPY $q2 312 %1:fpr128 = COPY $q1 313 %0:fpr128 = COPY $q0 314 %3:fpr128 = contract FMULv2f64 %1, %0 315 %4:fpr128 = FADDv2f64 killed %3, %2 316 $q0 = COPY %4 317 RET_ReallyLR implicit $q0 318 319... 320 321# Do create FMLA, because we have the contract flag on the FADD. 322# 323# CHECK-LABEL: name: vector_fmadd_contract_op1 324# CHECK: [[C:%.*]]:fpr128 = COPY $q2 325# CHECK-NEXT: [[B:%.*]]:fpr128 = COPY $q1 326# CHECK-NEXT: [[A:%.*]]:fpr128 = COPY $q0 327# CHECK-NEXT: fpr128 = FMLAv2f64 [[C]], [[B]], [[A]] 328 329--- 330name: vector_fmadd_contract_op1 331alignment: 4 332tracksRegLiveness: true 333registers: 334 - { id: 0, class: fpr128 } 335 - { id: 1, class: fpr128 } 336 - { id: 2, class: fpr128 } 337 - { id: 3, class: fpr128 } 338 - { id: 4, class: fpr128 } 339liveins: 340 - { reg: '$q0', virtual-reg: '%0' } 341 - { reg: '$q1', virtual-reg: '%1' } 342 - { reg: '$q2', virtual-reg: '%2' } 343frameInfo: 344 maxAlignment: 1 345 maxCallFrameSize: 0 346machineFunctionInfo: {} 347body: | 348 bb.0.entry: 349 liveins: $q0, $q1, $q2 350 351 %2:fpr128 = COPY $q2 352 %1:fpr128 = COPY $q1 353 %0:fpr128 = COPY $q0 354 %3:fpr128 = FMULv2f64 %1, %0 355 %4:fpr128 = contract FADDv2f64 killed %3, %2 356 $q0 = COPY %4 357 RET_ReallyLR implicit $q0 358 359... 360 361# Do not create FMLA, as nsz flag does not allow it. 362# 363# CHECK-LABEL: name: vector_fmadd_nsz 364# CHECK: [[C:%.*]]:fpr128 = COPY $q2 365# CHECK-NEXT: [[B:%.*]]:fpr128 = COPY $q1 366# CHECK-NEXT: [[A:%.*]]:fpr128 = COPY $q0 367# CHECK-NEXT: [[MUL:%.*]]:fpr128 = nsz FMULv2f64 [[B]], [[A]] 368# CHECK-NEXT: fpr128 = nsz FADDv2f64 killed [[MUL]], [[C]] 369--- 370name: vector_fmadd_nsz 371alignment: 4 372tracksRegLiveness: true 373registers: 374 - { id: 0, class: fpr128 } 375 - { id: 1, class: fpr128 } 376 - { id: 2, class: fpr128 } 377 - { id: 3, class: fpr128 } 378 - { id: 4, class: fpr128 } 379liveins: 380 - { reg: '$q0', virtual-reg: '%0' } 381 - { reg: '$q1', virtual-reg: '%1' } 382 - { reg: '$q2', virtual-reg: '%2' } 383frameInfo: 384 maxAlignment: 1 385 maxCallFrameSize: 0 386machineFunctionInfo: {} 387body: | 388 bb.0.entry: 389 liveins: $q0, $q1, $q2 390 391 %2:fpr128 = COPY $q2 392 %1:fpr128 = COPY $q1 393 %0:fpr128 = COPY $q0 394 %3:fpr128 = nsz FMULv2f64 %1, %0 395 %4:fpr128 = nsz FADDv2f64 killed %3, %2 396 $q0 = COPY %4 397 RET_ReallyLR implicit $q0 398 399... 400