From 5d9b2cef51d70f43c48e38836884ac5cd9d94935 Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Sat, 7 Apr 2018 14:07:58 +0000 Subject: [PATCH] [InstCombine] add/move tests for fsub folds; NFC There are a pair of folds that try to merge fneg into fsub with an intervening cast, but as shown in the FIXME tests, they can create extra instructions. llvm-svn: 329501 --- test/Transforms/InstCombine/fneg-ext.ll | 23 ------ test/Transforms/InstCombine/fsub.ll | 101 +++++++++++++++++++++++- 2 files changed, 100 insertions(+), 24 deletions(-) delete mode 100644 test/Transforms/InstCombine/fneg-ext.ll diff --git a/test/Transforms/InstCombine/fneg-ext.ll b/test/Transforms/InstCombine/fneg-ext.ll deleted file mode 100644 index 922d26a465b..00000000000 --- a/test/Transforms/InstCombine/fneg-ext.ll +++ /dev/null @@ -1,23 +0,0 @@ -; RUN: opt -instcombine -S < %s | FileCheck %s - -; CHECK: test1 -define double @test1(float %a, double %b) nounwind readnone ssp uwtable { -; CHECK-NOT: fsub -; CHECK: fpext -; CHECK: fadd - %1 = fsub float -0.000000e+00, %a - %2 = fpext float %1 to double - %3 = fsub double %b, %2 - ret double %3 -} - -; CHECK: test2 -define double @test2(float %a, double %b) nounwind readnone ssp uwtable { -; CHECK-NOT: fsub -; CHECK: fpext -; CHECK: fadd fast - %1 = fsub float -0.000000e+00, %a - %2 = fpext float %1 to double - %3 = fsub fast double %b, %2 - ret double %3 -} diff --git a/test/Transforms/InstCombine/fsub.ll b/test/Transforms/InstCombine/fsub.ll index d3b1fe3d782..78aebc022b2 100644 --- a/test/Transforms/InstCombine/fsub.ll +++ b/test/Transforms/InstCombine/fsub.ll @@ -28,10 +28,11 @@ define float @neg_sub_nsz(float %x, float %y) { } ; If the subtract has another use, we don't do the transform (even though it -; doesn't increase the IR instruction count) because we assume that fneg is +; doesn't increase the IR instruction count) because we assume that fneg is ; easier to analyze and generally cheaper than generic fsub. declare void @use(float) +declare void @use2(float, double) define float @neg_sub_nsz_extra_use(float %x, float %y) { ; CHECK-LABEL: @neg_sub_nsz_extra_use( @@ -146,3 +147,101 @@ define <2 x float> @neg_op1_vec_undef(<2 x float> %x, <2 x float> %y) { ret <2 x float> %r } +; Similar to above - but look through fpext/fptrunc casts to find the fneg. + +define double @neg_ext_op1(float %a, double %b) { +; CHECK-LABEL: @neg_ext_op1( +; CHECK-NEXT: [[TMP1:%.*]] = fpext float [[A:%.*]] to double +; CHECK-NEXT: [[T3:%.*]] = fadd double [[TMP1]], [[B:%.*]] +; CHECK-NEXT: ret double [[T3]] +; + %t1 = fsub float -0.0, %a + %t2 = fpext float %t1 to double + %t3 = fsub double %b, %t2 + ret double %t3 +} + +; Verify that vectors work too. + +define <2 x float> @neg_trunc_op1(<2 x double> %a, <2 x float> %b) { +; CHECK-LABEL: @neg_trunc_op1( +; CHECK-NEXT: [[TMP1:%.*]] = fptrunc <2 x double> [[A:%.*]] to <2 x float> +; CHECK-NEXT: [[T3:%.*]] = fadd <2 x float> [[TMP1]], [[B:%.*]] +; CHECK-NEXT: ret <2 x float> [[T3]] +; + %t1 = fsub <2 x double> , %a + %t2 = fptrunc <2 x double> %t1 to <2 x float> + %t3 = fsub <2 x float> %b, %t2 + ret <2 x float> %t3 +} + +; No FMF needed, but they should propagate to the fadd. + +define double @neg_ext_op1_fast(float %a, double %b) { +; CHECK-LABEL: @neg_ext_op1_fast( +; CHECK-NEXT: [[TMP1:%.*]] = fpext float [[A:%.*]] to double +; CHECK-NEXT: [[T3:%.*]] = fadd fast double [[TMP1]], [[B:%.*]] +; CHECK-NEXT: ret double [[T3]] +; + %t1 = fsub float -0.0, %a + %t2 = fpext float %t1 to double + %t3 = fsub fast double %b, %t2 + ret double %t3 +} + +; FIXME: Extra use should prevent the transform. + +define float @neg_ext_op1_extra_use(half %a, float %b) { +; CHECK-LABEL: @neg_ext_op1_extra_use( +; CHECK-NEXT: [[T1:%.*]] = fsub half 0xH8000, [[A:%.*]] +; CHECK-NEXT: [[T2:%.*]] = fpext half [[T1]] to float +; CHECK-NEXT: [[TMP1:%.*]] = fpext half [[A]] to float +; CHECK-NEXT: [[T3:%.*]] = fadd float [[TMP1]], [[B:%.*]] +; CHECK-NEXT: call void @use(float [[T2]]) +; CHECK-NEXT: ret float [[T3]] +; + %t1 = fsub half -0.0, %a + %t2 = fpext half %t1 to float + %t3 = fsub float %b, %t2 + call void @use(float %t2) + ret float %t3 +} + +; One-use fptrunc is always hoisted above fneg, so the corresponding +; multi-use bug for fptrunc isn't visible with a fold starting from +; the last fsub. + +define float @neg_trunc_op1_extra_use(double %a, float %b) { +; CHECK-LABEL: @neg_trunc_op1_extra_use( +; CHECK-NEXT: [[TMP1:%.*]] = fptrunc double [[A:%.*]] to float +; CHECK-NEXT: [[T2:%.*]] = fsub float -0.000000e+00, [[TMP1]] +; CHECK-NEXT: [[T3:%.*]] = fadd float [[TMP1]], [[B:%.*]] +; CHECK-NEXT: call void @use(float [[T2]]) +; CHECK-NEXT: ret float [[T3]] +; + %t1 = fsub double -0.0, %a + %t2 = fptrunc double %t1 to float + %t3 = fsub float %b, %t2 + call void @use(float %t2) + ret float %t3 +} + +; FIXME: But the bug is visible when both preceding values have other uses. +; Extra uses should prevent the transform. + +define float @neg_trunc_op1_extra_uses(double %a, float %b) { +; CHECK-LABEL: @neg_trunc_op1_extra_uses( +; CHECK-NEXT: [[T1:%.*]] = fsub double -0.000000e+00, [[A:%.*]] +; CHECK-NEXT: [[T2:%.*]] = fptrunc double [[T1]] to float +; CHECK-NEXT: [[TMP1:%.*]] = fptrunc double [[A]] to float +; CHECK-NEXT: [[T3:%.*]] = fadd float [[TMP1]], [[B:%.*]] +; CHECK-NEXT: call void @use2(float [[T2]], double [[T1]]) +; CHECK-NEXT: ret float [[T3]] +; + %t1 = fsub double -0.0, %a + %t2 = fptrunc double %t1 to float + %t3 = fsub float %b, %t2 + call void @use2(float %t2, double %t1) + ret float %t3 +} +