diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp --- a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp +++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp @@ -4976,6 +4976,15 @@ case AArch64::FMULXv2f32: case AArch64::FMULXv4f32: case AArch64::FMULXv2f64: + // -- SVE instructions -- + // Opcodes FMULX_ZZZ_? don't exist because there is no unpredicated FMULX + // in the SVE instruction set (though there are predicated ones). + case AArch64::FADD_ZZZ_H: + case AArch64::FADD_ZZZ_S: + case AArch64::FADD_ZZZ_D: + case AArch64::FMUL_ZZZ_H: + case AArch64::FMUL_ZZZ_S: + case AArch64::FMUL_ZZZ_D: return Inst.getParent()->getParent()->getTarget().Options.UnsafeFPMath || (Inst.getFlag(MachineInstr::MIFlag::FmReassoc) && Inst.getFlag(MachineInstr::MIFlag::FmNsz)); diff --git a/llvm/test/CodeGen/AArch64/machine-combiner.ll b/llvm/test/CodeGen/AArch64/machine-combiner.ll --- a/llvm/test/CodeGen/AArch64/machine-combiner.ll +++ b/llvm/test/CodeGen/AArch64/machine-combiner.ll @@ -601,6 +601,68 @@ ret <4 x i32> %t2 } +; Verify that scalable vector FP arithmetic operations are reassociated. + +define @reassociate_adds_nxv4f16( %x0, %x1, %x2, %x3) { +; CHECK-STD-LABEL: reassociate_adds_nxv4f16: +; CHECK-STD: // %bb.0: +; CHECK-STD-NEXT: fadd z0.h, z0.h, z1.h +; CHECK-STD-NEXT: fadd z0.h, z2.h, z0.h +; CHECK-STD-NEXT: fadd z0.h, z3.h, z0.h +; CHECK-STD-NEXT: ret +; +; CHECK-UNSAFE-LABEL: reassociate_adds_nxv4f16: +; CHECK-UNSAFE: // %bb.0: +; CHECK-UNSAFE-NEXT: fadd z0.h, z0.h, z1.h +; CHECK-UNSAFE-NEXT: fadd z1.h, z3.h, z2.h +; CHECK-UNSAFE-NEXT: fadd z0.h, z1.h, z0.h +; CHECK-UNSAFE-NEXT: ret + %t0 = fadd reassoc %x0, %x1 + %t1 = fadd reassoc %x2, %t0 + %t2 = fadd reassoc %x3, %t1 + ret %t2 +} + +define @reassociate_adds_nxv4f32( %x0, %x1, %x2, %x3) { +; CHECK-STD-LABEL: reassociate_adds_nxv4f32: +; CHECK-STD: // %bb.0: +; CHECK-STD-NEXT: fadd z0.s, z0.s, z1.s +; CHECK-STD-NEXT: fadd z0.s, z2.s, z0.s +; CHECK-STD-NEXT: fadd z0.s, z3.s, z0.s +; CHECK-STD-NEXT: ret +; +; CHECK-UNSAFE-LABEL: reassociate_adds_nxv4f32: +; CHECK-UNSAFE: // %bb.0: +; CHECK-UNSAFE-NEXT: fadd z0.s, z0.s, z1.s +; CHECK-UNSAFE-NEXT: fadd z1.s, z3.s, z2.s +; CHECK-UNSAFE-NEXT: fadd z0.s, z1.s, z0.s +; CHECK-UNSAFE-NEXT: ret + %t0 = fadd reassoc %x0, %x1 + %t1 = fadd reassoc %x2, %t0 + %t2 = fadd reassoc %x3, %t1 + ret %t2 +} + +define @reassociate_muls_nxv2f64( %x0, %x1, %x2, %x3) { +; CHECK-STD-LABEL: reassociate_muls_nxv2f64: +; CHECK-STD: // %bb.0: +; CHECK-STD-NEXT: fmul z0.d, z0.d, z1.d +; CHECK-STD-NEXT: fmul z0.d, z2.d, z0.d +; CHECK-STD-NEXT: fmul z0.d, z3.d, z0.d +; CHECK-STD-NEXT: ret +; +; CHECK-UNSAFE-LABEL: reassociate_muls_nxv2f64: +; CHECK-UNSAFE: // %bb.0: +; CHECK-UNSAFE-NEXT: fmul z0.d, z0.d, z1.d +; CHECK-UNSAFE-NEXT: fmul z1.d, z3.d, z2.d +; CHECK-UNSAFE-NEXT: fmul z0.d, z1.d, z0.d +; CHECK-UNSAFE-NEXT: ret + %t0 = fmul reassoc %x0, %x1 + %t1 = fmul reassoc %x2, %t0 + %t2 = fmul reassoc %x3, %t1 + ret %t2 +} + ; PR25016: https://llvm.org/bugs/show_bug.cgi?id=25016 ; Verify that reassociation is not happening needlessly or wrongly.