[llvm] r339518 - [InstCombine] move/add tests for fadd/fsub factorization; NFC

Sanjay Patel via llvm-commits llvm-commits at lists.llvm.org
Sun Aug 12 08:06:15 PDT 2018


Author: spatel
Date: Sun Aug 12 08:06:15 2018
New Revision: 339518

URL: http://llvm.org/viewvc/llvm-project?rev=339518&view=rev
Log:
[InstCombine] move/add tests for fadd/fsub factorization; NFC

Added:
    llvm/trunk/test/Transforms/InstCombine/fadd-fsub-factor.ll
Modified:
    llvm/trunk/test/Transforms/InstCombine/fast-math.ll

Added: llvm/trunk/test/Transforms/InstCombine/fadd-fsub-factor.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/fadd-fsub-factor.ll?rev=339518&view=auto
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/fadd-fsub-factor.ll (added)
+++ llvm/trunk/test/Transforms/InstCombine/fadd-fsub-factor.ll Sun Aug 12 08:06:15 2018
@@ -0,0 +1,497 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt < %s -instcombine -S | FileCheck %s
+
+; =========================================================================
+;
+;   Test FP factorization with patterns:
+;   X * Z + Y * Z --> (X + Y) * Z (including all 4 commuted variants)
+;   X * Z - Y * Z --> (X - Y) * Z (including all 4 commuted variants)
+;   X / Z + Y / Z --> (X + Y) / Z
+;   X / Z - Y / Z --> (X - Y) / Z
+;
+; =========================================================================
+
+; Minimum FMF - the final result requires/propagates FMF.
+
+define float @fmul_fadd(float %x, float %y, float %z) {
+; CHECK-LABEL: @fmul_fadd(
+; CHECK-NEXT:    [[TMP1:%.*]] = fadd reassoc nsz float [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    [[TMP2:%.*]] = fmul reassoc nsz float [[TMP1]], [[Z:%.*]]
+; CHECK-NEXT:    ret float [[TMP2]]
+;
+  %t1 = fmul float %x, %z
+  %t2 = fmul float %y, %z
+  %r = fadd reassoc nsz float %t1, %t2
+  ret float %r
+}
+
+; FIXME:
+; Verify vector types and commuted operands.
+
+define <2 x float> @fmul_fadd_commute1_vec(<2 x float> %x, <2 x float> %y, <2 x float> %z) {
+; CHECK-LABEL: @fmul_fadd_commute1_vec(
+; CHECK-NEXT:    [[T1:%.*]] = fmul <2 x float> [[Z:%.*]], [[X:%.*]]
+; CHECK-NEXT:    [[T2:%.*]] = fmul <2 x float> [[Z]], [[Y:%.*]]
+; CHECK-NEXT:    [[R:%.*]] = fadd reassoc nsz <2 x float> [[T1]], [[T2]]
+; CHECK-NEXT:    ret <2 x float> [[R]]
+;
+  %t1 = fmul <2 x float> %z, %x
+  %t2 = fmul <2 x float> %z, %y
+  %r = fadd reassoc nsz <2 x float> %t1, %t2
+  ret <2 x float> %r
+}
+
+; FIXME:
+; Verify vector types, commuted operands, FMF propagation.
+
+define <2 x float> @fmul_fadd_commute2_vec(<2 x float> %x, <2 x float> %y, <2 x float> %z) {
+; CHECK-LABEL: @fmul_fadd_commute2_vec(
+; CHECK-NEXT:    [[T1:%.*]] = fmul fast <2 x float> [[X:%.*]], [[Z:%.*]]
+; CHECK-NEXT:    [[T2:%.*]] = fmul nnan <2 x float> [[Z]], [[Y:%.*]]
+; CHECK-NEXT:    [[R:%.*]] = fadd reassoc ninf nsz <2 x float> [[T1]], [[T2]]
+; CHECK-NEXT:    ret <2 x float> [[R]]
+;
+  %t1 = fmul fast <2 x float> %x, %z
+  %t2 = fmul nnan <2 x float> %z, %y
+  %r = fadd reassoc nsz ninf <2 x float> %t1, %t2
+  ret <2 x float> %r
+}
+
+; Verify different scalar type, commuted operands, FMF propagation.
+
+define double @fmul_fadd_commute3(double %x, double %y, double %z) {
+; CHECK-LABEL: @fmul_fadd_commute3(
+; CHECK-NEXT:    [[TMP1:%.*]] = fadd reassoc nnan nsz double [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    [[TMP2:%.*]] = fmul reassoc nnan nsz double [[TMP1]], [[Z:%.*]]
+; CHECK-NEXT:    ret double [[TMP2]]
+;
+  %t1 = fmul double %z, %x
+  %t2 = fmul fast double %y, %z
+  %r = fadd reassoc nsz nnan double %t1, %t2
+  ret double %r
+}
+
+; Negative test - verify the fold is not done with only 'reassoc' ('nsz' is required).
+
+define float @fmul_fadd_not_enough_FMF(float %x, float %y, float %z) {
+; CHECK-LABEL: @fmul_fadd_not_enough_FMF(
+; CHECK-NEXT:    [[T1:%.*]] = fmul fast float [[X:%.*]], [[Z:%.*]]
+; CHECK-NEXT:    [[T2:%.*]] = fmul fast float [[Y:%.*]], [[Z]]
+; CHECK-NEXT:    [[R:%.*]] = fadd reassoc float [[T1]], [[T2]]
+; CHECK-NEXT:    ret float [[R]]
+;
+  %t1 = fmul fast float %x, %z
+  %t2 = fmul fast float %y, %z
+  %r = fadd reassoc float %t1, %t2
+  ret float %r
+}
+
+declare void @use(float)
+
+; FIXME:
+; Negative test - extra uses should disable the fold.
+
+define float @fmul_fadd_uses1(float %x, float %y, float %z) {
+; CHECK-LABEL: @fmul_fadd_uses1(
+; CHECK-NEXT:    [[T1:%.*]] = fmul float [[Z:%.*]], [[X:%.*]]
+; CHECK-NEXT:    [[TMP1:%.*]] = fadd reassoc nsz float [[X]], [[Y:%.*]]
+; CHECK-NEXT:    [[TMP2:%.*]] = fmul reassoc nsz float [[TMP1]], [[Z]]
+; CHECK-NEXT:    call void @use(float [[T1]])
+; CHECK-NEXT:    ret float [[TMP2]]
+;
+  %t1 = fmul float %z, %x
+  %t2 = fmul float %y, %z
+  %r = fadd reassoc nsz float %t1, %t2
+  call void @use(float %t1)
+  ret float %r
+}
+
+; FIXME:
+; Negative test - extra uses should disable the fold.
+
+define float @fmul_fadd_uses2(float %x, float %y, float %z) {
+; CHECK-LABEL: @fmul_fadd_uses2(
+; CHECK-NEXT:    [[T2:%.*]] = fmul float [[Z:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    [[TMP1:%.*]] = fadd reassoc nsz float [[X:%.*]], [[Y]]
+; CHECK-NEXT:    [[TMP2:%.*]] = fmul reassoc nsz float [[TMP1]], [[Z]]
+; CHECK-NEXT:    call void @use(float [[T2]])
+; CHECK-NEXT:    ret float [[TMP2]]
+;
+  %t1 = fmul float %z, %x
+  %t2 = fmul float %z, %y
+  %r = fadd reassoc nsz float %t1, %t2
+  call void @use(float %t2)
+  ret float %r
+}
+
+; FIXME:
+; Negative test - extra uses should disable the fold.
+
+define float @fmul_fadd_uses3(float %x, float %y, float %z) {
+; CHECK-LABEL: @fmul_fadd_uses3(
+; CHECK-NEXT:    [[T1:%.*]] = fmul float [[X:%.*]], [[Z:%.*]]
+; CHECK-NEXT:    [[T2:%.*]] = fmul float [[Z]], [[Y:%.*]]
+; CHECK-NEXT:    [[TMP1:%.*]] = fadd reassoc nsz float [[X]], [[Y]]
+; CHECK-NEXT:    [[TMP2:%.*]] = fmul reassoc nsz float [[TMP1]], [[Z]]
+; CHECK-NEXT:    call void @use(float [[T1]])
+; CHECK-NEXT:    call void @use(float [[T2]])
+; CHECK-NEXT:    ret float [[TMP2]]
+;
+  %t1 = fmul float %x, %z
+  %t2 = fmul float %z, %y
+  %r = fadd reassoc nsz float %t1, %t2
+  call void @use(float %t1)
+  call void @use(float %t2)
+  ret float %r
+}
+
+; Minimum FMF - the final result requires/propagates FMF.
+
+define half @fmul_fsub(half %x, half %y, half %z) {
+; CHECK-LABEL: @fmul_fsub(
+; CHECK-NEXT:    [[TMP1:%.*]] = fsub reassoc nsz half [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    [[TMP2:%.*]] = fmul reassoc nsz half [[TMP1]], [[Z:%.*]]
+; CHECK-NEXT:    ret half [[TMP2]]
+;
+  %t1 = fmul half %x, %z
+  %t2 = fmul half %y, %z
+  %r = fsub reassoc nsz half %t1, %t2
+  ret half %r
+}
+
+; FIXME:
+; Verify vector types and commuted operands.
+
+define <2 x float> @fmul_fsub_commute1_vec(<2 x float> %x, <2 x float> %y, <2 x float> %z) {
+; CHECK-LABEL: @fmul_fsub_commute1_vec(
+; CHECK-NEXT:    [[T1:%.*]] = fmul <2 x float> [[Z:%.*]], [[X:%.*]]
+; CHECK-NEXT:    [[T2:%.*]] = fmul <2 x float> [[Y:%.*]], [[Z]]
+; CHECK-NEXT:    [[R:%.*]] = fsub reassoc nsz <2 x float> [[T1]], [[T2]]
+; CHECK-NEXT:    ret <2 x float> [[R]]
+;
+  %t1 = fmul <2 x float> %z, %x
+  %t2 = fmul <2 x float> %y, %z
+  %r = fsub reassoc nsz <2 x float> %t1, %t2
+  ret <2 x float> %r
+}
+
+; FIXME:
+; Verify vector types, commuted operands, FMF propagation.
+
+define <2 x float> @fmul_fsub_commute2_vec(<2 x float> %x, <2 x float> %y, <2 x float> %z) {
+; CHECK-LABEL: @fmul_fsub_commute2_vec(
+; CHECK-NEXT:    [[T1:%.*]] = fmul fast <2 x float> [[X:%.*]], [[Z:%.*]]
+; CHECK-NEXT:    [[T2:%.*]] = fmul nnan <2 x float> [[Z]], [[Y:%.*]]
+; CHECK-NEXT:    [[R:%.*]] = fsub reassoc ninf nsz <2 x float> [[T1]], [[T2]]
+; CHECK-NEXT:    ret <2 x float> [[R]]
+;
+  %t1 = fmul fast <2 x float> %x, %z
+  %t2 = fmul nnan <2 x float> %z, %y
+  %r = fsub reassoc nsz ninf <2 x float> %t1, %t2
+  ret <2 x float> %r
+}
+
+; Verify different scalar type, commuted operands, FMF propagation.
+
+define double @fmul_fsub_commute3(double %x, double %y, double %z) {
+; CHECK-LABEL: @fmul_fsub_commute3(
+; CHECK-NEXT:    [[TMP1:%.*]] = fsub reassoc nnan nsz double [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    [[TMP2:%.*]] = fmul reassoc nnan nsz double [[TMP1]], [[Z:%.*]]
+; CHECK-NEXT:    ret double [[TMP2]]
+;
+  %t1 = fmul double %z, %x
+  %t2 = fmul fast double %z, %y
+  %r = fsub reassoc nsz nnan double %t1, %t2
+  ret double %r
+}
+
+; Negative test - verify the fold is not done with only 'nsz' ('reassoc' is required).
+
+define float @fmul_fsub_not_enough_FMF(float %x, float %y, float %z) {
+; CHECK-LABEL: @fmul_fsub_not_enough_FMF(
+; CHECK-NEXT:    [[T1:%.*]] = fmul fast float [[Z:%.*]], [[X:%.*]]
+; CHECK-NEXT:    [[T2:%.*]] = fmul fast float [[Y:%.*]], [[Z]]
+; CHECK-NEXT:    [[R:%.*]] = fsub nsz float [[T1]], [[T2]]
+; CHECK-NEXT:    ret float [[R]]
+;
+  %t1 = fmul fast float %z, %x
+  %t2 = fmul fast float %y, %z
+  %r = fsub nsz float %t1, %t2
+  ret float %r
+}
+
+; FIXME:
+; Negative test - extra uses should disable the fold.
+
+define float @fmul_fsub_uses1(float %x, float %y, float %z) {
+; CHECK-LABEL: @fmul_fsub_uses1(
+; CHECK-NEXT:    [[T1:%.*]] = fmul float [[X:%.*]], [[Z:%.*]]
+; CHECK-NEXT:    [[TMP1:%.*]] = fsub reassoc nsz float [[X]], [[Y:%.*]]
+; CHECK-NEXT:    [[TMP2:%.*]] = fmul reassoc nsz float [[TMP1]], [[Z]]
+; CHECK-NEXT:    call void @use(float [[T1]])
+; CHECK-NEXT:    ret float [[TMP2]]
+;
+  %t1 = fmul float %x, %z
+  %t2 = fmul float %y, %z
+  %r = fsub reassoc nsz float %t1, %t2
+  call void @use(float %t1)
+  ret float %r
+}
+
+; FIXME:
+; Negative test - extra uses should disable the fold.
+
+define float @fmul_fsub_uses2(float %x, float %y, float %z) {
+; CHECK-LABEL: @fmul_fsub_uses2(
+; CHECK-NEXT:    [[T2:%.*]] = fmul float [[Z:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    [[TMP1:%.*]] = fsub reassoc nsz float [[X:%.*]], [[Y]]
+; CHECK-NEXT:    [[TMP2:%.*]] = fmul reassoc nsz float [[TMP1]], [[Z]]
+; CHECK-NEXT:    call void @use(float [[T2]])
+; CHECK-NEXT:    ret float [[TMP2]]
+;
+  %t1 = fmul float %z, %x
+  %t2 = fmul float %z, %y
+  %r = fsub reassoc nsz float %t1, %t2
+  call void @use(float %t2)
+  ret float %r
+}
+
+; FIXME:
+; Negative test - extra uses should disable the fold.
+
+define float @fmul_fsub_uses3(float %x, float %y, float %z) {
+; CHECK-LABEL: @fmul_fsub_uses3(
+; CHECK-NEXT:    [[T1:%.*]] = fmul float [[X:%.*]], [[Z:%.*]]
+; CHECK-NEXT:    [[T2:%.*]] = fmul float [[Y:%.*]], [[Z]]
+; CHECK-NEXT:    [[TMP1:%.*]] = fsub reassoc nsz float [[X]], [[Y]]
+; CHECK-NEXT:    [[TMP2:%.*]] = fmul reassoc nsz float [[TMP1]], [[Z]]
+; CHECK-NEXT:    call void @use(float [[T1]])
+; CHECK-NEXT:    call void @use(float [[T2]])
+; CHECK-NEXT:    ret float [[TMP2]]
+;
+  %t1 = fmul float %x, %z
+  %t2 = fmul float %y, %z
+  %r = fsub reassoc nsz float %t1, %t2
+  call void @use(float %t1)
+  call void @use(float %t2)
+  ret float %r
+}
+
+; Common divisor
+
+define double @fdiv_fadd(double %x, double %y, double %z) {
+; CHECK-LABEL: @fdiv_fadd(
+; CHECK-NEXT:    [[TMP1:%.*]] = fadd reassoc nsz double [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    [[TMP2:%.*]] = fdiv reassoc nsz double [[TMP1]], [[Z:%.*]]
+; CHECK-NEXT:    ret double [[TMP2]]
+;
+  %t1 = fdiv double %x, %z
+  %t2 = fdiv double %y, %z
+  %r = fadd reassoc nsz double %t1, %t2
+  ret double %r
+}
+
+define float @fdiv_fsub(float %x, float %y, float %z) {
+; CHECK-LABEL: @fdiv_fsub(
+; CHECK-NEXT:    [[TMP1:%.*]] = fsub reassoc nsz float [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    [[TMP2:%.*]] = fdiv reassoc nsz float [[TMP1]], [[Z:%.*]]
+; CHECK-NEXT:    ret float [[TMP2]]
+;
+  %t1 = fdiv fast float %x, %z
+  %t2 = fdiv nnan float %y, %z
+  %r = fsub reassoc nsz float %t1, %t2
+  ret float %r
+}
+
+; FIXME:
+; Verify vector types.
+
+define <2 x double> @fdiv_fadd_vec(<2 x double> %x, <2 x double> %y, <2 x double> %z) {
+; CHECK-LABEL: @fdiv_fadd_vec(
+; CHECK-NEXT:    [[T1:%.*]] = fdiv fast <2 x double> [[X:%.*]], [[Z:%.*]]
+; CHECK-NEXT:    [[T2:%.*]] = fdiv <2 x double> [[Y:%.*]], [[Z]]
+; CHECK-NEXT:    [[R:%.*]] = fadd reassoc nsz <2 x double> [[T1]], [[T2]]
+; CHECK-NEXT:    ret <2 x double> [[R]]
+;
+  %t1 = fdiv fast <2 x double> %x, %z
+  %t2 = fdiv <2 x double> %y, %z
+  %r = fadd reassoc nsz <2 x double> %t1, %t2
+  ret <2 x double> %r
+}
+
+; FIXME:
+; Verify vector types.
+
+define <2 x float> @fdiv_fsub_vec(<2 x float> %x, <2 x float> %y, <2 x float> %z) {
+; CHECK-LABEL: @fdiv_fsub_vec(
+; CHECK-NEXT:    [[T1:%.*]] = fdiv <2 x float> [[X:%.*]], [[Z:%.*]]
+; CHECK-NEXT:    [[T2:%.*]] = fdiv nnan <2 x float> [[Y:%.*]], [[Z]]
+; CHECK-NEXT:    [[R:%.*]] = fsub reassoc nsz <2 x float> [[T1]], [[T2]]
+; CHECK-NEXT:    ret <2 x float> [[R]]
+;
+  %t1 = fdiv <2 x float> %x, %z
+  %t2 = fdiv nnan <2 x float> %y, %z
+  %r = fsub reassoc nsz <2 x float> %t1, %t2
+  ret <2 x float> %r
+}
+
+; Negative test - common operand is not divisor.
+
+define float @fdiv_fadd_commute1(float %x, float %y, float %z) {
+; CHECK-LABEL: @fdiv_fadd_commute1(
+; CHECK-NEXT:    [[T1:%.*]] = fdiv fast float [[Z:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    [[T2:%.*]] = fdiv fast float [[Z]], [[X:%.*]]
+; CHECK-NEXT:    [[R:%.*]] = fadd fast float [[T1]], [[T2]]
+; CHECK-NEXT:    ret float [[R]]
+;
+  %t1 = fdiv fast float %z, %y
+  %t2 = fdiv fast float %z, %x
+  %r = fadd fast float %t1, %t2
+  ret float %r
+}
+
+; Negative test - common operand is not divisor.
+
+define float @fdiv_fsub_commute2(float %x, float %y, float %z) {
+; CHECK-LABEL: @fdiv_fsub_commute2(
+; CHECK-NEXT:    [[T1:%.*]] = fdiv fast float [[Z:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    [[T2:%.*]] = fdiv fast float [[X:%.*]], [[Z]]
+; CHECK-NEXT:    [[R:%.*]] = fsub fast float [[T1]], [[T2]]
+; CHECK-NEXT:    ret float [[R]]
+;
+  %t1 = fdiv fast float %z, %y
+  %t2 = fdiv fast float %x, %z
+  %r = fsub fast float %t1, %t2
+  ret float %r
+}
+
+; Negative test - verify the fold is not done with only 'nsz' ('reassoc' is required).
+
+define float @fdiv_fadd_not_enough_FMF(float %x, float %y, float %z) {
+; CHECK-LABEL: @fdiv_fadd_not_enough_FMF(
+; CHECK-NEXT:    [[T1:%.*]] = fdiv fast float [[Y:%.*]], [[X:%.*]]
+; CHECK-NEXT:    [[T2:%.*]] = fdiv fast float [[Z:%.*]], [[X]]
+; CHECK-NEXT:    [[T3:%.*]] = fadd nsz float [[T1]], [[T2]]
+; CHECK-NEXT:    ret float [[T3]]
+;
+  %t1 = fdiv fast float %y, %x
+  %t2 = fdiv fast float %z, %x
+  %t3 = fadd nsz float %t1, %t2
+  ret float %t3
+}
+
+; Negative test - verify the fold is not done with only 'reassoc' ('nsz' is required).
+
+define float @fdiv_fsub_not_enough_FMF(float %x, float %y, float %z) {
+; CHECK-LABEL: @fdiv_fsub_not_enough_FMF(
+; CHECK-NEXT:    [[T1:%.*]] = fdiv fast float [[Y:%.*]], [[X:%.*]]
+; CHECK-NEXT:    [[T2:%.*]] = fdiv fast float [[Z:%.*]], [[X]]
+; CHECK-NEXT:    [[T3:%.*]] = fsub reassoc float [[T1]], [[T2]]
+; CHECK-NEXT:    ret float [[T3]]
+;
+  %t1 = fdiv fast float %y, %x
+  %t2 = fdiv fast float %z, %x
+  %t3 = fsub reassoc float %t1, %t2
+  ret float %t3
+}
+
+; FIXME:
+; Negative test - extra uses should disable the fold.
+
+define float @fdiv_fadd_uses1(float %x, float %y, float %z) {
+; CHECK-LABEL: @fdiv_fadd_uses1(
+; CHECK-NEXT:    [[T1:%.*]] = fdiv fast float [[X:%.*]], [[Z:%.*]]
+; CHECK-NEXT:    [[TMP1:%.*]] = fadd fast float [[X]], [[Y:%.*]]
+; CHECK-NEXT:    [[TMP2:%.*]] = fdiv fast float [[TMP1]], [[Z]]
+; CHECK-NEXT:    call void @use(float [[T1]])
+; CHECK-NEXT:    ret float [[TMP2]]
+;
+  %t1 = fdiv fast float %x, %z
+  %t2 = fdiv fast float %y, %z
+  %r = fadd fast float %t1, %t2
+  call void @use(float %t1)
+  ret float %r
+}
+
+; FIXME:
+; Negative test - extra uses should disable the fold.
+
+define float @fdiv_fsub_uses2(float %x, float %y, float %z) {
+; CHECK-LABEL: @fdiv_fsub_uses2(
+; CHECK-NEXT:    [[T2:%.*]] = fdiv fast float [[Y:%.*]], [[Z:%.*]]
+; CHECK-NEXT:    [[TMP1:%.*]] = fsub fast float [[X:%.*]], [[Y]]
+; CHECK-NEXT:    [[TMP2:%.*]] = fdiv fast float [[TMP1]], [[Z]]
+; CHECK-NEXT:    call void @use(float [[T2]])
+; CHECK-NEXT:    ret float [[TMP2]]
+;
+  %t1 = fdiv fast float %x, %z
+  %t2 = fdiv fast float %y, %z
+  %r = fsub fast float %t1, %t2
+  call void @use(float %t2)
+  ret float %r
+}
+
+; FIXME:
+; Negative test - extra uses should disable the fold.
+
+define float @fdiv_fsub_uses3(float %x, float %y, float %z) {
+; CHECK-LABEL: @fdiv_fsub_uses3(
+; CHECK-NEXT:    [[T1:%.*]] = fdiv fast float [[X:%.*]], [[Z:%.*]]
+; CHECK-NEXT:    [[T2:%.*]] = fdiv fast float [[Y:%.*]], [[Z]]
+; CHECK-NEXT:    [[TMP1:%.*]] = fsub fast float [[X]], [[Y]]
+; CHECK-NEXT:    [[TMP2:%.*]] = fdiv fast float [[TMP1]], [[Z]]
+; CHECK-NEXT:    call void @use(float [[T1]])
+; CHECK-NEXT:    call void @use(float [[T2]])
+; CHECK-NEXT:    ret float [[TMP2]]
+;
+  %t1 = fdiv fast float %x, %z
+  %t2 = fdiv fast float %y, %z
+  %r = fsub fast float %t1, %t2
+  call void @use(float %t1)
+  call void @use(float %t2)
+  ret float %r
+}
+
+; Constants are fine to combine if they are not denorms.
+
+define float @fdiv_fadd_not_denorm(float %x) {
+; CHECK-LABEL: @fdiv_fadd_not_denorm(
+; CHECK-NEXT:    [[TMP1:%.*]] = fdiv fast float 0x3818000000000000, [[X:%.*]]
+; CHECK-NEXT:    ret float [[TMP1]]
+;
+  %t1 = fdiv fast float 0x3810000000000000, %x
+  %t2 = fdiv fast float 0x3800000000000000, %x
+  %r = fadd fast float %t1, %t2
+  ret float %r
+}
+
+; Negative test - disabled if x+y is denormal.
+
+define float @fdiv_fadd_denorm(float %x) {
+; CHECK-LABEL: @fdiv_fadd_denorm(
+; CHECK-NEXT:    [[T1:%.*]] = fdiv fast float 0xB810000000000000, [[X:%.*]]
+; CHECK-NEXT:    [[T2:%.*]] = fdiv fast float 0x3800000000000000, [[X]]
+; CHECK-NEXT:    [[R:%.*]] = fadd fast float [[T1]], [[T2]]
+; CHECK-NEXT:    ret float [[R]]
+;
+  %t1 = fdiv fast float 0xB810000000000000, %x
+  %t2 = fdiv fast float 0x3800000000000000, %x
+  %r = fadd fast float %t1, %t2
+  ret float %r
+}
+
+; Negative test - disabled if x-y is denormal.
+
+define float @fdiv_fsub_denorm(float %x) {
+; CHECK-LABEL: @fdiv_fsub_denorm(
+; CHECK-NEXT:    [[T1:%.*]] = fdiv fast float 0x3810000000000000, [[X:%.*]]
+; CHECK-NEXT:    [[T2:%.*]] = fdiv fast float 0x3800000000000000, [[X]]
+; CHECK-NEXT:    [[R:%.*]] = fsub fast float [[T1]], [[T2]]
+; CHECK-NEXT:    ret float [[R]]
+;
+  %t1 = fdiv fast float 0x3810000000000000, %x
+  %t2 = fdiv fast float 0x3800000000000000, %x
+  %r = fsub fast float %t1, %t2
+  ret float %r
+}
+

Modified: llvm/trunk/test/Transforms/InstCombine/fast-math.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/fast-math.ll?rev=339518&r1=339517&r2=339518&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/fast-math.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/fast-math.ll Sun Aug 12 08:06:15 2018
@@ -622,379 +622,6 @@ define float @fdiv4(float %x) {
 
 ; =========================================================================
 ;
-;   Testing-cases about factorization
-;
-; =========================================================================
-; x*z + y*z => (x+y) * z
-define float @fact_mul1(float %x, float %y, float %z) {
-; CHECK-LABEL: @fact_mul1(
-; CHECK-NEXT:    [[TMP1:%.*]] = fadd fast float [[X:%.*]], [[Y:%.*]]
-; CHECK-NEXT:    [[TMP2:%.*]] = fmul fast float [[TMP1]], [[Z:%.*]]
-; CHECK-NEXT:    ret float [[TMP2]]
-;
-  %t1 = fmul fast float %x, %z
-  %t2 = fmul fast float %y, %z
-  %t3 = fadd fast float %t1, %t2
-  ret float %t3
-}
-
-; Check again using the minimal subset of FMF.
-define float @fact_mul1_reassoc_nsz(float %x, float %y, float %z) {
-; CHECK-LABEL: @fact_mul1_reassoc_nsz(
-; CHECK-NEXT:    [[TMP1:%.*]] = fadd reassoc nsz float [[X:%.*]], [[Y:%.*]]
-; CHECK-NEXT:    [[TMP2:%.*]] = fmul reassoc nsz float [[TMP1]], [[Z:%.*]]
-; CHECK-NEXT:    ret float [[TMP2]]
-;
-  %t1 = fmul reassoc nsz float %x, %z
-  %t2 = fmul reassoc nsz float %y, %z
-  %t3 = fadd reassoc nsz float %t1, %t2
-  ret float %t3
-}
-
-; Verify the fold is not done with only 'reassoc' ('nsz' is required).
-define float @fact_mul1_reassoc(float %x, float %y, float %z) {
-; CHECK-LABEL: @fact_mul1_reassoc(
-; CHECK-NEXT:    [[T1:%.*]] = fmul reassoc float [[X:%.*]], [[Z:%.*]]
-; CHECK-NEXT:    [[T2:%.*]] = fmul reassoc float [[Y:%.*]], [[Z]]
-; CHECK-NEXT:    [[T3:%.*]] = fadd reassoc float [[T1]], [[T2]]
-; CHECK-NEXT:    ret float [[T3]]
-;
-  %t1 = fmul reassoc float %x, %z
-  %t2 = fmul reassoc float %y, %z
-  %t3 = fadd reassoc float %t1, %t2
-  ret float %t3
-}
-
-; z*x + y*z => (x+y) * z
-define float @fact_mul2(float %x, float %y, float %z) {
-; CHECK-LABEL: @fact_mul2(
-; CHECK-NEXT:    [[TMP1:%.*]] = fsub fast float [[X:%.*]], [[Y:%.*]]
-; CHECK-NEXT:    [[TMP2:%.*]] = fmul fast float [[TMP1]], [[Z:%.*]]
-; CHECK-NEXT:    ret float [[TMP2]]
-;
-  %t1 = fmul fast float %z, %x
-  %t2 = fmul fast float %y, %z
-  %t3 = fsub fast float %t1, %t2
-  ret float %t3
-}
-
-; Check again using the minimal subset of FMF.
-define float @fact_mul2_reassoc_nsz(float %x, float %y, float %z) {
-; CHECK-LABEL: @fact_mul2_reassoc_nsz(
-; CHECK-NEXT:    [[TMP1:%.*]] = fsub reassoc nsz float [[X:%.*]], [[Y:%.*]]
-; CHECK-NEXT:    [[TMP2:%.*]] = fmul reassoc nsz float [[TMP1]], [[Z:%.*]]
-; CHECK-NEXT:    ret float [[TMP2]]
-;
-  %t1 = fmul reassoc nsz float %z, %x
-  %t2 = fmul reassoc nsz float %y, %z
-  %t3 = fsub reassoc nsz float %t1, %t2
-  ret float %t3
-}
-
-; Verify the fold is not done with only 'reassoc' ('nsz' is required).
-define float @fact_mul2_reassoc(float %x, float %y, float %z) {
-; CHECK-LABEL: @fact_mul2_reassoc(
-; CHECK-NEXT:    [[T1:%.*]] = fmul reassoc float [[Z:%.*]], [[X:%.*]]
-; CHECK-NEXT:    [[T2:%.*]] = fmul reassoc float [[Y:%.*]], [[Z]]
-; CHECK-NEXT:    [[T3:%.*]] = fsub reassoc float [[T1]], [[T2]]
-; CHECK-NEXT:    ret float [[T3]]
-;
-  %t1 = fmul reassoc float %z, %x
-  %t2 = fmul reassoc float %y, %z
-  %t3 = fsub reassoc float %t1, %t2
-  ret float %t3
-}
-
-; z*x - z*y => (x-y) * z
-define float @fact_mul3(float %x, float %y, float %z) {
-; CHECK-LABEL: @fact_mul3(
-; CHECK-NEXT:    [[TMP1:%.*]] = fsub fast float [[X:%.*]], [[Y:%.*]]
-; CHECK-NEXT:    [[TMP2:%.*]] = fmul fast float [[TMP1]], [[Z:%.*]]
-; CHECK-NEXT:    ret float [[TMP2]]
-;
-  %t2 = fmul fast float %z, %y
-  %t1 = fmul fast float %z, %x
-  %t3 = fsub fast float %t1, %t2
-  ret float %t3
-}
-
-; Check again using the minimal subset of FMF.
-define float @fact_mul3_reassoc_nsz(float %x, float %y, float %z) {
-; CHECK-LABEL: @fact_mul3_reassoc_nsz(
-; CHECK-NEXT:    [[TMP1:%.*]] = fsub reassoc nsz float [[X:%.*]], [[Y:%.*]]
-; CHECK-NEXT:    [[TMP2:%.*]] = fmul reassoc nsz float [[TMP1]], [[Z:%.*]]
-; CHECK-NEXT:    ret float [[TMP2]]
-;
-  %t2 = fmul reassoc nsz float %z, %y
-  %t1 = fmul reassoc nsz float %z, %x
-  %t3 = fsub reassoc nsz float %t1, %t2
-  ret float %t3
-}
-
-; Verify the fold is not done with only 'reassoc' ('nsz' is required).
-define float @fact_mul3_reassoc(float %x, float %y, float %z) {
-; CHECK-LABEL: @fact_mul3_reassoc(
-; CHECK-NEXT:    [[T2:%.*]] = fmul reassoc float [[Z:%.*]], [[Y:%.*]]
-; CHECK-NEXT:    [[T1:%.*]] = fmul reassoc float [[Z]], [[X:%.*]]
-; CHECK-NEXT:    [[T3:%.*]] = fsub reassoc float [[T1]], [[T2]]
-; CHECK-NEXT:    ret float [[T3]]
-;
-  %t2 = fmul reassoc float %z, %y
-  %t1 = fmul reassoc float %z, %x
-  %t3 = fsub reassoc float %t1, %t2
-  ret float %t3
-}
-
-; x*z - z*y => (x-y) * z
-define float @fact_mul4(float %x, float %y, float %z) {
-; CHECK-LABEL: @fact_mul4(
-; CHECK-NEXT:    [[TMP1:%.*]] = fsub reassoc nsz float [[X:%.*]], [[Y:%.*]]
-; CHECK-NEXT:    [[TMP2:%.*]] = fmul reassoc nsz float [[TMP1]], [[Z:%.*]]
-; CHECK-NEXT:    ret float [[TMP2]]
-;
-  %t1 = fmul float %x, %z
-  %t2 = fmul float %z, %y
-  %t3 = fsub reassoc nsz float %t1, %t2
-  ret float %t3
-}
-
-define float @fact_mul4_commute1(float %x, float %y, float %z) {
-; CHECK-LABEL: @fact_mul4_commute1(
-; CHECK-NEXT:    [[TMP1:%.*]] = fsub reassoc nsz float [[X:%.*]], [[Y:%.*]]
-; CHECK-NEXT:    [[TMP2:%.*]] = fmul reassoc nsz float [[TMP1]], [[Z:%.*]]
-; CHECK-NEXT:    ret float [[TMP2]]
-;
-  %t1 = fmul float %x, %z
-  %t2 = fmul float %y, %z
-  %t3 = fsub reassoc nsz float %t1, %t2
-  ret float %t3
-}
-
-define float @fact_mul4_commute2(float %x, float %y, float %z) {
-; CHECK-LABEL: @fact_mul4_commute2(
-; CHECK-NEXT:    [[TMP1:%.*]] = fsub reassoc nsz float [[X:%.*]], [[Y:%.*]]
-; CHECK-NEXT:    [[TMP2:%.*]] = fmul reassoc nsz float [[TMP1]], [[Z:%.*]]
-; CHECK-NEXT:    ret float [[TMP2]]
-;
-  %t1 = fmul float %z, %x
-  %t2 = fmul float %y, %z
-  %t3 = fsub reassoc nsz float %t1, %t2
-  ret float %t3
-}
-
-define <2 x float> @fact_mul4_commute3_vec(<2 x float> %x, <2 x float> %y, <2 x float> %z) {
-; CHECK-LABEL: @fact_mul4_commute3_vec(
-; CHECK-NEXT:    [[T1:%.*]] = fmul <2 x float> [[Z:%.*]], [[X:%.*]]
-; CHECK-NEXT:    [[T2:%.*]] = fmul <2 x float> [[Z]], [[Y:%.*]]
-; CHECK-NEXT:    [[T3:%.*]] = fsub reassoc nsz <2 x float> [[T1]], [[T2]]
-; CHECK-NEXT:    ret <2 x float> [[T3]]
-;
-  %t1 = fmul <2 x float> %z, %x
-  %t2 = fmul <2 x float> %z, %y
-  %t3 = fsub reassoc nsz <2 x float> %t1, %t2
-  ret <2 x float> %t3
-}
-
-declare void @use(float)
-
-define float @fact_mul4_uses1(float %x, float %y, float %z) {
-; CHECK-LABEL: @fact_mul4_uses1(
-; CHECK-NEXT:    [[T1:%.*]] = fmul float [[Z:%.*]], [[X:%.*]]
-; CHECK-NEXT:    call void @use(float [[T1]])
-; CHECK-NEXT:    [[TMP1:%.*]] = fsub reassoc nsz float [[X]], [[Y:%.*]]
-; CHECK-NEXT:    [[TMP2:%.*]] = fmul reassoc nsz float [[TMP1]], [[Z]]
-; CHECK-NEXT:    ret float [[TMP2]]
-;
-  %t1 = fmul float %z, %x
-  call void @use(float %t1)
-  %t2 = fmul float %y, %z
-  %t3 = fsub reassoc nsz float %t1, %t2
-  ret float %t3
-}
-
-define float @fact_mul4_uses2(float %x, float %y, float %z) {
-; CHECK-LABEL: @fact_mul4_uses2(
-; CHECK-NEXT:    [[T2:%.*]] = fmul float [[Y:%.*]], [[Z:%.*]]
-; CHECK-NEXT:    call void @use(float [[T2]])
-; CHECK-NEXT:    [[TMP1:%.*]] = fsub reassoc nsz float [[X:%.*]], [[Y]]
-; CHECK-NEXT:    [[TMP2:%.*]] = fmul reassoc nsz float [[TMP1]], [[Z]]
-; CHECK-NEXT:    ret float [[TMP2]]
-;
-  %t1 = fmul float %x, %z
-  %t2 = fmul float %y, %z
-  call void @use(float %t2)
-  %t3 = fsub reassoc nsz float %t1, %t2
-  ret float %t3
-}
-
-define float @fact_mul4_uses3(float %x, float %y, float %z) {
-; CHECK-LABEL: @fact_mul4_uses3(
-; CHECK-NEXT:    [[T1:%.*]] = fmul float [[Z:%.*]], [[X:%.*]]
-; CHECK-NEXT:    call void @use(float [[T1]])
-; CHECK-NEXT:    [[T2:%.*]] = fmul float [[Z]], [[Y:%.*]]
-; CHECK-NEXT:    call void @use(float [[T2]])
-; CHECK-NEXT:    [[TMP1:%.*]] = fsub reassoc nsz float [[X]], [[Y]]
-; CHECK-NEXT:    [[TMP2:%.*]] = fmul reassoc nsz float [[TMP1]], [[Z]]
-; CHECK-NEXT:    ret float [[TMP2]]
-;
-  %t1 = fmul float %z, %x
-  call void @use(float %t1)
-  %t2 = fmul float %z, %y
-  call void @use(float %t2)
-  %t3 = fsub reassoc nsz float %t1, %t2
-  ret float %t3
-}
-
-; Verify the fold is not done with only 'reassoc' ('nsz' is required).
-define float @fact_mul4_reassoc(float %x, float %y, float %z) {
-; CHECK-LABEL: @fact_mul4_reassoc(
-; CHECK-NEXT:    [[T1:%.*]] = fmul reassoc float [[X:%.*]], [[Z:%.*]]
-; CHECK-NEXT:    [[T2:%.*]] = fmul reassoc float [[Z]], [[Y:%.*]]
-; CHECK-NEXT:    [[T3:%.*]] = fsub reassoc float [[T1]], [[T2]]
-; CHECK-NEXT:    ret float [[T3]]
-;
-  %t1 = fmul reassoc float %x, %z
-  %t2 = fmul reassoc float %z, %y
-  %t3 = fsub reassoc float %t1, %t2
-  ret float %t3
-}
-
-; x/y + x/z, no xform
-define float @fact_div1(float %x, float %y, float %z) {
-; CHECK-LABEL: @fact_div1(
-; CHECK-NEXT:    [[T1:%.*]] = fdiv fast float [[X:%.*]], [[Y:%.*]]
-; CHECK-NEXT:    [[T2:%.*]] = fdiv fast float [[X]], [[Z:%.*]]
-; CHECK-NEXT:    [[T3:%.*]] = fadd fast float [[T1]], [[T2]]
-; CHECK-NEXT:    ret float [[T3]]
-;
-  %t1 = fdiv fast float %x, %y
-  %t2 = fdiv fast float %x, %z
-  %t3 = fadd fast float %t1, %t2
-  ret float %t3
-}
-
-; x/y + z/x; no xform
-define float @fact_div2(float %x, float %y, float %z) {
-; CHECK-LABEL: @fact_div2(
-; CHECK-NEXT:    [[T1:%.*]] = fdiv fast float [[X:%.*]], [[Y:%.*]]
-; CHECK-NEXT:    [[T2:%.*]] = fdiv fast float [[Z:%.*]], [[X]]
-; CHECK-NEXT:    [[T3:%.*]] = fadd fast float [[T1]], [[T2]]
-; CHECK-NEXT:    ret float [[T3]]
-;
-  %t1 = fdiv fast float %x, %y
-  %t2 = fdiv fast float %z, %x
-  %t3 = fadd fast float %t1, %t2
-  ret float %t3
-}
-
-; y/x + z/x => (y+z)/x
-define float @fact_div3(float %x, float %y, float %z) {
-; CHECK-LABEL: @fact_div3(
-; CHECK-NEXT:    [[TMP1:%.*]] = fadd fast float [[Y:%.*]], [[Z:%.*]]
-; CHECK-NEXT:    [[TMP2:%.*]] = fdiv fast float [[TMP1]], [[X:%.*]]
-; CHECK-NEXT:    ret float [[TMP2]]
-;
-  %t1 = fdiv fast float %y, %x
-  %t2 = fdiv fast float %z, %x
-  %t3 = fadd fast float %t1, %t2
-  ret float %t3
-}
-
-; Check again using the minimal subset of FMF.
-define float @fact_div3_reassoc_nsz(float %x, float %y, float %z) {
-; CHECK-LABEL: @fact_div3_reassoc_nsz(
-; CHECK-NEXT:    [[TMP1:%.*]] = fadd reassoc nsz float [[Y:%.*]], [[Z:%.*]]
-; CHECK-NEXT:    [[TMP2:%.*]] = fdiv reassoc nsz float [[TMP1]], [[X:%.*]]
-; CHECK-NEXT:    ret float [[TMP2]]
-;
-  %t1 = fdiv reassoc nsz float %y, %x
-  %t2 = fdiv reassoc nsz float %z, %x
-  %t3 = fadd reassoc nsz float %t1, %t2
-  ret float %t3
-}
-
-; Verify the fold is not done with only 'reassoc' ('nsz' is required).
-define float @fact_div3_reassoc(float %x, float %y, float %z) {
-; CHECK-LABEL: @fact_div3_reassoc(
-; CHECK-NEXT:    [[T1:%.*]] = fdiv reassoc float [[Y:%.*]], [[X:%.*]]
-; CHECK-NEXT:    [[T2:%.*]] = fdiv reassoc float [[Z:%.*]], [[X]]
-; CHECK-NEXT:    [[T3:%.*]] = fadd reassoc float [[T1]], [[T2]]
-; CHECK-NEXT:    ret float [[T3]]
-;
-  %t1 = fdiv reassoc float %y, %x
-  %t2 = fdiv reassoc float %z, %x
-  %t3 = fadd reassoc float %t1, %t2
-  ret float %t3
-}
-
-; y/x - z/x => (y-z)/x
-define float @fact_div4(float %x, float %y, float %z) {
-; CHECK-LABEL: @fact_div4(
-; CHECK-NEXT:    [[TMP1:%.*]] = fsub fast float [[Y:%.*]], [[Z:%.*]]
-; CHECK-NEXT:    [[TMP2:%.*]] = fdiv fast float [[TMP1]], [[X:%.*]]
-; CHECK-NEXT:    ret float [[TMP2]]
-;
-  %t1 = fdiv fast float %y, %x
-  %t2 = fdiv fast float %z, %x
-  %t3 = fsub fast float %t1, %t2
-  ret float %t3
-}
-
-; Check again using the minimal subset of FMF.
-define float @fact_div4_reassoc_nsz(float %x, float %y, float %z) {
-; CHECK-LABEL: @fact_div4_reassoc_nsz(
-; CHECK-NEXT:    [[TMP1:%.*]] = fsub reassoc nsz float [[Y:%.*]], [[Z:%.*]]
-; CHECK-NEXT:    [[TMP2:%.*]] = fdiv reassoc nsz float [[TMP1]], [[X:%.*]]
-; CHECK-NEXT:    ret float [[TMP2]]
-;
-  %t1 = fdiv reassoc nsz float %y, %x
-  %t2 = fdiv reassoc nsz float %z, %x
-  %t3 = fsub reassoc nsz float %t1, %t2
-  ret float %t3
-}
-
-; Verify the fold is not done with only 'reassoc' ('nsz' is required).
-define float @fact_div4_reassoc(float %x, float %y, float %z) {
-; CHECK-LABEL: @fact_div4_reassoc(
-; CHECK-NEXT:    [[T1:%.*]] = fdiv reassoc float [[Y:%.*]], [[X:%.*]]
-; CHECK-NEXT:    [[T2:%.*]] = fdiv reassoc float [[Z:%.*]], [[X]]
-; CHECK-NEXT:    [[T3:%.*]] = fsub reassoc float [[T1]], [[T2]]
-; CHECK-NEXT:    ret float [[T3]]
-;
-  %t1 = fdiv reassoc float %y, %x
-  %t2 = fdiv reassoc float %z, %x
-  %t3 = fsub reassoc float %t1, %t2
-  ret float %t3
-}
-
-; y/x - z/x => (y-z)/x is disabled if y-z is denormal.
-define float @fact_div5(float %x) {
-; CHECK-LABEL: @fact_div5(
-; CHECK-NEXT:    [[TMP1:%.*]] = fdiv fast float 0x3818000000000000, [[X:%.*]]
-; CHECK-NEXT:    ret float [[TMP1]]
-;
-  %t1 = fdiv fast float 0x3810000000000000, %x
-  %t2 = fdiv fast float 0x3800000000000000, %x
-  %t3 = fadd fast float %t1, %t2
-  ret float %t3
-}
-
-; y/x - z/x => (y-z)/x is disabled if y-z is denormal.
-define float @fact_div6(float %x) {
-; CHECK-LABEL: @fact_div6(
-; CHECK-NEXT:    [[T1:%.*]] = fdiv fast float 0x3810000000000000, [[X:%.*]]
-; CHECK-NEXT:    [[T2:%.*]] = fdiv fast float 0x3800000000000000, [[X]]
-; CHECK-NEXT:    [[T3:%.*]] = fsub fast float [[T1]], [[T2]]
-; CHECK-NEXT:    ret float [[T3]]
-;
-  %t1 = fdiv fast float 0x3810000000000000, %x
-  %t2 = fdiv fast float 0x3800000000000000, %x
-  %t3 = fsub fast float %t1, %t2
-  ret float %t3
-}
-
-; =========================================================================
-;
 ;   Test-cases for square root
 ;
 ; =========================================================================




More information about the llvm-commits mailing list