llvm.org GIT mirror llvm / 2ab4f52
[InstCombine] canonicalize fdiv after fmul if reassociation is allowed (X / Y) * Z --> (X * Z) / Y This can allow other optimizations/reassociations as shown in the test diffs. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@358404 91177308-0d34-0410-b5e6-96231b3b80d8 Sanjay Patel 5 months ago
4 changed file(s) with 30 addition(s) and 23 deletion(s). Raw diff Collapse all Expand all
429429 }
430430 }
431431
432 Value *Z;
433 if (match(&I, m_c_FMul(m_OneUse(m_FDiv(m_Value(X), m_Value(Y))),
434 m_Value(Z)))) {
435 // Sink division: (X / Y) * Z --> (X * Z) / Y
436 Value *NewFMul = Builder.CreateFMulFMF(X, Z, &I);
437 return BinaryOperator::CreateFDivFMF(NewFMul, Y, &I);
438 }
439
432440 // sqrt(X) * sqrt(Y) -> sqrt(X * Y)
433441 // nnan disallows the possibility of returning a number if both operands are
434442 // negative (in that case, we should return NaN).
598598 ;
599599 define float @fdiv3(float %x) {
600600 ; CHECK-LABEL: @fdiv3(
601 ; CHECK-NEXT: [[DIV:%.*]] = fdiv float [[X:%.*]], 0x47EFFFFFE0000000
602 ; CHECK-NEXT: [[DIV1:%.*]] = fmul fast float [[DIV]], 0x3FDBD37A80000000
601 ; CHECK-NEXT: [[TMP1:%.*]] = fmul fast float [[X:%.*]], 0x3FDBD37A80000000
602 ; CHECK-NEXT: [[DIV1:%.*]] = fdiv fast float [[TMP1]], 0x47EFFFFFE0000000
603603 ; CHECK-NEXT: ret float [[DIV1]]
604604 ;
605605 %div = fdiv float %x, 0x47EFFFFFE0000000
2626
2727 define double @pow_ab_a_reassoc_commute(double %a, double %b) {
2828 ; CHECK-LABEL: @pow_ab_a_reassoc_commute(
29 ; CHECK-NEXT: [[TMP1:%.*]] = fdiv double 1.000000e+00, [[A:%.*]]
30 ; CHECK-NEXT: [[TMP2:%.*]] = call double @llvm.pow.f64(double [[A]], double [[B:%.*]])
31 ; CHECK-NEXT: [[MUL:%.*]] = fmul reassoc double [[TMP1]], [[TMP2]]
29 ; CHECK-NEXT: [[TMP1:%.*]] = call double @llvm.pow.f64(double [[A:%.*]], double [[B:%.*]])
30 ; CHECK-NEXT: [[MUL:%.*]] = fdiv reassoc double [[TMP1]], [[A]]
3231 ; CHECK-NEXT: ret double [[MUL]]
3332 ;
3433 %1 = fdiv double 1.0, %a
382382
383383 define float @log2half_commute(float %x1, float %y) {
384384 ; CHECK-LABEL: @log2half_commute(
385 ; CHECK-NEXT: [[X:%.*]] = fdiv float [[X1:%.*]], 7.000000e+00
386385 ; CHECK-NEXT: [[LOG2:%.*]] = call fast float @llvm.log2.f32(float [[Y:%.*]])
387 ; CHECK-NEXT: [[TMP1:%.*]] = fmul fast float [[LOG2]], [[X]]
388 ; CHECK-NEXT: [[MUL:%.*]] = fsub fast float [[TMP1]], [[X]]
386 ; CHECK-NEXT: [[TMP1:%.*]] = fmul fast float [[LOG2]], [[X1:%.*]]
387 ; CHECK-NEXT: [[TMP2:%.*]] = fsub fast float [[TMP1]], [[X1]]
388 ; CHECK-NEXT: [[MUL:%.*]] = fmul fast float [[TMP2]], 0x3FC24924A0000000
389389 ; CHECK-NEXT: ret float [[MUL]]
390390 ;
391391 %x = fdiv float %x1, 7.0 ; thwart complexity-based canonicalization
474474 ret float %r
475475 }
476476
477 ; Rule "X/C1 * C2 => X * (C2/C1) is not applicable if C2/C1 is abnormal
477 ; Canonicalization "X/C1 * C2 => X * (C2/C1)" still applies if C2/C1 is denormal
478 ; (otherwise, we should not have allowed the reassociation in the previous test).
478479 ; 0x3810000000000000 == FLT_MIN
479480
480481 define float @fdiv_constant_denominator_fmul_denorm(float %x) {
481482 ; CHECK-LABEL: @fdiv_constant_denominator_fmul_denorm(
482 ; CHECK-NEXT: [[T1:%.*]] = fdiv float [[X:%.*]], 2.000000e+03
483 ; CHECK-NEXT: [[T3:%.*]] = fmul fast float [[T1]], 0x3810000000000000
483 ; CHECK-NEXT: [[T3:%.*]] = fmul fast float [[X:%.*]], 0x3760620000000000
484484 ; CHECK-NEXT: ret float [[T3]]
485485 ;
486486 %t1 = fdiv float %x, 2.0e+3
706706
707707 define double @fmul_fdivs_factor_common_denominator(double %x, double %y, double %z) {
708708 ; CHECK-LABEL: @fmul_fdivs_factor_common_denominator(
709 ; CHECK-NEXT: [[DIV1:%.*]] = fdiv double [[X:%.*]], [[Z:%.*]]
710 ; CHECK-NEXT: [[DIV2:%.*]] = fdiv double [[Y:%.*]], [[Z]]
711 ; CHECK-NEXT: [[MUL:%.*]] = fmul fast double [[DIV1]], [[DIV2]]
709 ; CHECK-NEXT: [[TMP1:%.*]] = fmul fast double [[Y:%.*]], [[X:%.*]]
710 ; CHECK-NEXT: [[TMP2:%.*]] = fmul fast double [[Z:%.*]], [[Z]]
711 ; CHECK-NEXT: [[MUL:%.*]] = fdiv fast double [[TMP1]], [[TMP2]]
712712 ; CHECK-NEXT: ret double [[MUL]]
713713 ;
714714 %div1 = fdiv double %x, %z
719719
720720 define double @fmul_fdivs_factor(double %x, double %y, double %z, double %w) {
721721 ; CHECK-LABEL: @fmul_fdivs_factor(
722 ; CHECK-NEXT: [[DIV1:%.*]] = fdiv double [[X:%.*]], [[Y:%.*]]
723 ; CHECK-NEXT: [[DIV2:%.*]] = fdiv double [[Z:%.*]], [[W:%.*]]
724 ; CHECK-NEXT: [[MUL:%.*]] = fmul reassoc double [[DIV1]], [[DIV2]]
722 ; CHECK-NEXT: [[TMP1:%.*]] = fmul reassoc double [[Z:%.*]], [[X:%.*]]
723 ; CHECK-NEXT: [[TMP2:%.*]] = fdiv reassoc double [[TMP1]], [[W:%.*]]
724 ; CHECK-NEXT: [[MUL:%.*]] = fdiv reassoc double [[TMP2]], [[Y:%.*]]
725725 ; CHECK-NEXT: ret double [[MUL]]
726726 ;
727727 %div1 = fdiv double %x, %y
732732
733733 define double @fmul_fdiv_factor(double %x, double %y, double %z) {
734734 ; CHECK-LABEL: @fmul_fdiv_factor(
735 ; CHECK-NEXT: [[DIV:%.*]] = fdiv double [[X:%.*]], [[Y:%.*]]
736 ; CHECK-NEXT: [[MUL:%.*]] = fmul reassoc double [[DIV]], [[Z:%.*]]
735 ; CHECK-NEXT: [[TMP1:%.*]] = fmul reassoc double [[X:%.*]], [[Z:%.*]]
736 ; CHECK-NEXT: [[MUL:%.*]] = fdiv reassoc double [[TMP1]], [[Y:%.*]]
737737 ; CHECK-NEXT: ret double [[MUL]]
738738 ;
739739 %div = fdiv double %x, %y
743743
744744 define double @fmul_fdiv_factor_constant1(double %x, double %y) {
745745 ; CHECK-LABEL: @fmul_fdiv_factor_constant1(
746 ; CHECK-NEXT: [[DIV:%.*]] = fdiv double [[X:%.*]], [[Y:%.*]]
747 ; CHECK-NEXT: [[MUL:%.*]] = fmul reassoc double [[DIV]], 4.200000e+01
746 ; CHECK-NEXT: [[TMP1:%.*]] = fmul reassoc double [[X:%.*]], 4.200000e+01
747 ; CHECK-NEXT: [[MUL:%.*]] = fdiv reassoc double [[TMP1]], [[Y:%.*]]
748748 ; CHECK-NEXT: ret double [[MUL]]
749749 ;
750750 %div = fdiv double %x, %y
754754
755755 define <2 x float> @fmul_fdiv_factor_constant2(<2 x float> %x, <2 x float> %y) {
756756 ; CHECK-LABEL: @fmul_fdiv_factor_constant2(
757 ; CHECK-NEXT: [[DIV:%.*]] = fdiv <2 x float> [[X:%.*]],
758 ; CHECK-NEXT: [[MUL:%.*]] = fmul reassoc <2 x float> [[DIV]], [[Y:%.*]]
757 ; CHECK-NEXT: [[TMP1:%.*]] = fmul reassoc <2 x float> [[X:%.*]], [[Y:%.*]]
758 ; CHECK-NEXT: [[MUL:%.*]] = fdiv reassoc <2 x float> [[TMP1]],
759759 ; CHECK-NEXT: ret <2 x float> [[MUL]]
760760 ;
761761 %div = fdiv <2 x float> %x,