diff options
| author | Sanjay Patel <spatel@rotateright.com> | 2018-03-12 23:10:08 +0000 |
|---|---|---|
| committer | Sanjay Patel <spatel@rotateright.com> | 2018-03-12 23:10:08 +0000 |
| commit | a71f95404f2dffdb488a1782317dfaff7e67ec82 (patch) | |
| tree | 8e54041794846008739c9d57b4aea3a34ee41841 | |
| parent | 8febe3dcf4e8b5be5e1c1401b5a38375ce7aecf0 (diff) | |
| download | bcm5719-llvm-a71f95404f2dffdb488a1782317dfaff7e67ec82.tar.gz bcm5719-llvm-a71f95404f2dffdb488a1782317dfaff7e67ec82.zip | |
[InstCombine] add test to show fmul transform creates extra fdiv; NFC
Also, move fmul reassociation tests to the same file as other fmul transforms.
llvm-svn: 327342
| -rw-r--r-- | llvm/test/Transforms/InstCombine/fast-math.ll | 88 | ||||
| -rw-r--r-- | llvm/test/Transforms/InstCombine/fmul.ll | 107 |
2 files changed, 107 insertions, 88 deletions
diff --git a/llvm/test/Transforms/InstCombine/fast-math.ll b/llvm/test/Transforms/InstCombine/fast-math.ll index 6c251c355cf..96d70dbdfc4 100644 --- a/llvm/test/Transforms/InstCombine/fast-math.ll +++ b/llvm/test/Transforms/InstCombine/fast-math.ll @@ -273,94 +273,6 @@ define float @fmul_distribute4(float %f1) { ret float %t3 } -; C1/X * C2 => (C1*C2) / X -define float @fmul2(float %f1) { -; CHECK-LABEL: @fmul2( -; CHECK-NEXT: [[TMP1:%.*]] = fdiv fast float 1.200000e+07, [[F1:%.*]] -; CHECK-NEXT: ret float [[TMP1]] -; - %t1 = fdiv float 2.0e+3, %f1 - %t3 = fmul fast float %t1, 6.0e+3 - ret float %t3 -} - -; X/C1 * C2 => X * (C2/C1) is disabled if X/C1 has multiple uses -@fmul2_external = external global float -define float @fmul2_disable(float %f1) { -; CHECK-LABEL: @fmul2_disable( -; CHECK-NEXT: [[DIV:%.*]] = fdiv fast float 1.000000e+00, [[F1:%.*]] -; CHECK-NEXT: store float [[DIV]], float* @fmul2_external, align 4 -; CHECK-NEXT: [[MUL:%.*]] = fmul fast float [[DIV]], 2.000000e+00 -; CHECK-NEXT: ret float [[MUL]] -; - %div = fdiv fast float 1.000000e+00, %f1 - store float %div, float* @fmul2_external - %mul = fmul fast float %div, 2.000000e+00 - ret float %mul -} - -; X/C1 * C2 => X * (C2/C1) (if C2/C1 is normal Fp) -define float @fmul3(float %f1, float %f2) { -; CHECK-LABEL: @fmul3( -; CHECK-NEXT: [[TMP1:%.*]] = fmul fast float [[F1:%.*]], 3.000000e+00 -; CHECK-NEXT: ret float [[TMP1]] -; - %t1 = fdiv float %f1, 2.0e+3 - %t3 = fmul fast float %t1, 6.0e+3 - ret float %t3 -} - -define <4 x float> @fmul3_vec(<4 x float> %f1, <4 x float> %f2) { -; CHECK-LABEL: @fmul3_vec( -; CHECK-NEXT: [[TMP1:%.*]] = fmul fast <4 x float> [[F1:%.*]], <float 3.000000e+00, float 2.000000e+00, float 1.000000e+00, float 1.000000e+00> -; CHECK-NEXT: ret <4 x float> [[TMP1]] -; - %t1 = fdiv <4 x float> %f1, <float 2.0e+3, float 3.0e+3, float 2.0e+3, float 1.0e+3> - %t3 = fmul fast <4 x float> %t1, <float 6.0e+3, float 6.0e+3, float 2.0e+3, float 1.0e+3> - ret <4 x float> %t3 -} - -; Make sure fmul with constant expression doesn't assert. -define <4 x float> @fmul3_vec_constexpr(<4 x float> %f1, <4 x float> %f2) { -; CHECK-LABEL: @fmul3_vec_constexpr( -; CHECK-NEXT: [[TMP1:%.*]] = fmul fast <4 x float> [[F1:%.*]], <float 3.000000e+00, float 2.000000e+00, float 1.000000e+00, float 1.000000e+00> -; CHECK-NEXT: ret <4 x float> [[TMP1]] -; - %constExprMul = bitcast i128 trunc (i160 bitcast (<5 x float> <float 6.0e+3, float 6.0e+3, float 2.0e+3, float 1.0e+3, float undef> to i160) to i128) to <4 x float> - %t1 = fdiv <4 x float> %f1, <float 2.0e+3, float 3.0e+3, float 2.0e+3, float 1.0e+3> - %t3 = fmul fast <4 x float> %t1, %constExprMul - ret <4 x float> %t3 -} - -; Rule "X/C1 * C2 => X * (C2/C1) is not applicable if C2/C1 is either a special -; value of a denormal. The 0x3810000000000000 here take value FLT_MIN -; -define float @fmul4(float %f1, float %f2) { -; CHECK-LABEL: @fmul4( -; CHECK-NEXT: [[T1:%.*]] = fdiv float [[F1:%.*]], 2.000000e+03 -; CHECK-NEXT: [[T3:%.*]] = fmul fast float [[T1]], 0x3810000000000000 -; CHECK-NEXT: ret float [[T3]] -; - %t1 = fdiv float %f1, 2.0e+3 - %t3 = fmul fast float %t1, 0x3810000000000000 - ret float %t3 -} - -; X / C1 * C2 => X / (C2/C1) if C1/C2 is either a special value of a denormal, -; and C2/C1 is a normal value. -; TODO: We don't convert the fast fdiv to fmul because that would be multiplication -; by a denormal, but we could do better when we know that denormals are not a problem. - -define float @fmul5(float %f1, float %f2) { -; CHECK-LABEL: @fmul5( -; CHECK-NEXT: [[TMP1:%.*]] = fdiv fast float [[F1:%.*]], 0x47E8000000000000 -; CHECK-NEXT: ret float [[TMP1]] -; - %t1 = fdiv float %f1, 3.0e+0 - %t3 = fmul fast float %t1, 0x3810000000000000 - ret float %t3 -} - ; "(X*Y) * X => (X*X) * Y" is disabled if "X*Y" has multiple uses define float @fmul7(float %f1, float %f2) { ; CHECK-LABEL: @fmul7( diff --git a/llvm/test/Transforms/InstCombine/fmul.ll b/llvm/test/Transforms/InstCombine/fmul.ll index 3637f6c2b59..0cfcb336c73 100644 --- a/llvm/test/Transforms/InstCombine/fmul.ll +++ b/llvm/test/Transforms/InstCombine/fmul.ll @@ -332,3 +332,110 @@ define float @log2half_commute(float %x1, float %y) { ret float %mul } +; C1/X * C2 => (C1*C2) / X + +define float @fdiv_constant_numerator_fmul(float %x) { +; CHECK-LABEL: @fdiv_constant_numerator_fmul( +; CHECK-NEXT: [[TMP1:%.*]] = fdiv fast float 1.200000e+07, [[X:%.*]] +; CHECK-NEXT: ret float [[TMP1]] +; + %t1 = fdiv float 2.0e+3, %x + %t3 = fmul fast float %t1, 6.0e+3 + ret float %t3 +} + +; C1/X * C2 => (C1*C2) / X is disabled if C1/X has multiple uses + +@fmul2_external = external global float + +define float @fdiv_constant_numerator_fmul_extra_use(float %x) { +; CHECK-LABEL: @fdiv_constant_numerator_fmul_extra_use( +; CHECK-NEXT: [[DIV:%.*]] = fdiv fast float 1.000000e+00, [[X:%.*]] +; CHECK-NEXT: store float [[DIV]], float* @fmul2_external, align 4 +; CHECK-NEXT: [[MUL:%.*]] = fmul fast float [[DIV]], 2.000000e+00 +; CHECK-NEXT: ret float [[MUL]] +; + %div = fdiv fast float 1.0, %x + store float %div, float* @fmul2_external + %mul = fmul fast float %div, 2.0 + ret float %mul +} + +; X/C1 * C2 => X * (C2/C1) (if C2/C1 is normal FP) + +define float @fdiv_constant_denominator_fmul(float %x) { +; CHECK-LABEL: @fdiv_constant_denominator_fmul( +; CHECK-NEXT: [[TMP1:%.*]] = fmul fast float [[X:%.*]], 3.000000e+00 +; CHECK-NEXT: ret float [[TMP1]] +; + %t1 = fdiv float %x, 2.0e+3 + %t3 = fmul fast float %t1, 6.0e+3 + ret float %t3 +} + +define <4 x float> @fdiv_constant_denominator_fmul_vec(<4 x float> %x) { +; CHECK-LABEL: @fdiv_constant_denominator_fmul_vec( +; CHECK-NEXT: [[TMP1:%.*]] = fmul fast <4 x float> [[X:%.*]], <float 3.000000e+00, float 2.000000e+00, float 1.000000e+00, float 1.000000e+00> +; CHECK-NEXT: ret <4 x float> [[TMP1]] +; + %t1 = fdiv <4 x float> %x, <float 2.0e+3, float 3.0e+3, float 2.0e+3, float 1.0e+3> + %t3 = fmul fast <4 x float> %t1, <float 6.0e+3, float 6.0e+3, float 2.0e+3, float 1.0e+3> + ret <4 x float> %t3 +} + +; Make sure fmul with constant expression doesn't assert. + +define <4 x float> @fdiv_constant_denominator_fmul_vec_constexpr(<4 x float> %x) { +; CHECK-LABEL: @fdiv_constant_denominator_fmul_vec_constexpr( +; CHECK-NEXT: [[TMP1:%.*]] = fmul fast <4 x float> [[X:%.*]], <float 3.000000e+00, float 2.000000e+00, float 1.000000e+00, float 1.000000e+00> +; CHECK-NEXT: ret <4 x float> [[TMP1]] +; + %constExprMul = bitcast i128 trunc (i160 bitcast (<5 x float> <float 6.0e+3, float 6.0e+3, float 2.0e+3, float 1.0e+3, float undef> to i160) to i128) to <4 x float> + %t1 = fdiv <4 x float> %x, <float 2.0e+3, float 3.0e+3, float 2.0e+3, float 1.0e+3> + %t3 = fmul fast <4 x float> %t1, %constExprMul + ret <4 x float> %t3 +} + +; Rule "X/C1 * C2 => X * (C2/C1) is not applicable if C2/C1 is abnormal +; 0x3810000000000000 == FLT_MIN + +define float @fdiv_constant_denominator_fmul_denorm(float %x) { +; CHECK-LABEL: @fdiv_constant_denominator_fmul_denorm( +; CHECK-NEXT: [[T1:%.*]] = fdiv float [[X:%.*]], 2.000000e+03 +; CHECK-NEXT: [[T3:%.*]] = fmul fast float [[T1]], 0x3810000000000000 +; CHECK-NEXT: ret float [[T3]] +; + %t1 = fdiv float %x, 2.0e+3 + %t3 = fmul fast float %t1, 0x3810000000000000 + ret float %t3 +} + +; X / C1 * C2 => X / (C2/C1) if C1/C2 is abnormal, but C2/C1 is a normal value. +; TODO: We don't convert the fast fdiv to fmul because that would be multiplication +; by a denormal, but we could do better when we know that denormals are not a problem. + +define float @fdiv_constant_denominator_fmul_denorm_try_harder(float %x) { +; CHECK-LABEL: @fdiv_constant_denominator_fmul_denorm_try_harder( +; CHECK-NEXT: [[TMP1:%.*]] = fdiv fast float [[X:%.*]], 0x47E8000000000000 +; CHECK-NEXT: ret float [[TMP1]] +; + %t1 = fdiv float %x, 3.0 + %t3 = fmul fast float %t1, 0x3810000000000000 + ret float %t3 +} + +; FIXME: We have 2 divisions instead of the 1 we started with. + +define float @fdiv_constant_denominator_fmul_denorm_try_harder_extra_use(float %x) { +; CHECK-LABEL: @fdiv_constant_denominator_fmul_denorm_try_harder_extra_use( +; CHECK-NEXT: [[T1:%.*]] = fdiv float [[X:%.*]], 3.000000e+00 +; CHECK-NEXT: [[TMP1:%.*]] = fdiv fast float [[X]], 0x47E8000000000000 +; CHECK-NEXT: [[R:%.*]] = fadd float [[T1]], [[TMP1]] +; CHECK-NEXT: ret float [[R]] +; + %t1 = fdiv float %x, 3.0e+0 + %t3 = fmul fast float %t1, 0x3810000000000000 + %r = fadd float %t1, %t3 + ret float %r +} + |

