If the DAG looks like this: a*b+c*d, it could be folded into fma(a, b, c*d) or fma(c, d, a*b). https://reviews.llvm.org/D11855 was posted to improve it that respects the uses of a*b or c*d to do the best choice.
But for a*b-c*d, it could be also folded into fma(a, b, -c*d) or fma(-c, d, a*b). This patch is trying to respect the uses of a*b and c*d to make the best choice.
And this is the motivated case:
define double @fsub1(double %a, double %b, double %c, double %d) { entry: %mul = fmul fast double %b, %a %mul1 = fmul fast double %d, %c %sub = fsub fast double %mul, %mul1 %mul3 = fmul fast double %mul, %sub ret double %mul3 }
define double @fsub1(double %a, double %b, double %c, double %d) { ; CHECK-LABEL: fsub1: ; CHECK: # %bb.0: # %entry -; CHECK-NEXT: xsmuldp 3, 4, 3 ; CHECK-NEXT: xsmuldp 0, 2, 1 -; CHECK-NEXT: xsmsubadp 3, 2, 1 -; CHECK-NEXT: xsmuldp 1, 0, 3 +; CHECK-NEXT: fmr 1, 0 +; CHECK-NEXT: xsnmsubadp 1, 4, 3 +; CHECK-NEXT: xsmuldp 1, 0, 1
I'm not sure why Aggressive && isContractableFMUL(N0) && isContractableFMUL(N1) check is here?
That is already checked in the lambdas.