[InstCombine] add tests for fabs folds with more FMF; NFC
authorSanjay Patel <spatel@rotateright.com>
Fri, 9 Dec 2022 19:36:22 +0000 (14:36 -0500)
committerSanjay Patel <spatel@rotateright.com>
Sat, 10 Dec 2022 15:07:42 +0000 (10:07 -0500)
The existing variants have "nsz", but that's not enough
to get fabs/fneg semantics right with a NAN input, so
I duplicated those with "nnan" tacked on. See discussion
in issue #59279.

llvm/test/Transforms/InstCombine/fabs.ll
llvm/test/Transforms/InstCombine/fneg-fabs.ll
llvm/test/Transforms/InstCombine/fneg.ll

index 1b9f4a3..a000693 100644 (file)
@@ -349,8 +349,8 @@ define fp128 @select_fcmp_ogt_zero(fp128 %x) {
   ret fp128 %fabs
 }
 
-define float @select_fcmp_ogt_fneg(float %a) {
-; CHECK-LABEL: @select_fcmp_ogt_fneg(
+define float @select_nsz_fcmp_ogt_fneg(float %a) {
+; CHECK-LABEL: @select_nsz_fcmp_ogt_fneg(
 ; CHECK-NEXT:    [[TMP1:%.*]] = call nsz float @llvm.fabs.f32(float [[A:%.*]])
 ; CHECK-NEXT:    ret float [[TMP1]]
 ;
@@ -360,6 +360,17 @@ define float @select_fcmp_ogt_fneg(float %a) {
   ret float %r
 }
 
+define float @select_nsz_nnan_fcmp_ogt_fneg(float %a) {
+; CHECK-LABEL: @select_nsz_nnan_fcmp_ogt_fneg(
+; CHECK-NEXT:    [[TMP1:%.*]] = call nnan nsz float @llvm.fabs.f32(float [[A:%.*]])
+; CHECK-NEXT:    ret float [[TMP1]]
+;
+  %fneg = fneg float %a
+  %cmp = fcmp ogt float %a, %fneg
+  %r = select nsz nnan i1 %cmp, float %a, float %fneg
+  ret float %r
+}
+
 define fp128 @select_fcmp_nnan_ogt_zero(fp128 %x) {
 ; CHECK-LABEL: @select_fcmp_nnan_ogt_zero(
 ; CHECK-NEXT:    [[TMP1:%.*]] = call fp128 @llvm.fabs.f128(fp128 [[X:%.*]])
@@ -436,8 +447,8 @@ define half @select_fcmp_nnan_oge_negzero(half %x) {
 
 ; X < 0.0 ? -X : X --> fabs(X)
 
-define double @select_fcmp_olt_zero_unary_fneg(double %x) {
-; CHECK-LABEL: @select_fcmp_olt_zero_unary_fneg(
+define double @select_nsz_fcmp_olt_zero_unary_fneg(double %x) {
+; CHECK-LABEL: @select_nsz_fcmp_olt_zero_unary_fneg(
 ; CHECK-NEXT:    [[TMP1:%.*]] = call nsz double @llvm.fabs.f64(double [[X:%.*]])
 ; CHECK-NEXT:    ret double [[TMP1]]
 ;
@@ -447,6 +458,17 @@ define double @select_fcmp_olt_zero_unary_fneg(double %x) {
   ret double %fabs
 }
 
+define double @select_nsz_nnan_fcmp_olt_zero_unary_fneg(double %x) {
+; CHECK-LABEL: @select_nsz_nnan_fcmp_olt_zero_unary_fneg(
+; CHECK-NEXT:    [[TMP1:%.*]] = call nnan nsz double @llvm.fabs.f64(double [[X:%.*]])
+; CHECK-NEXT:    ret double [[TMP1]]
+;
+  %ltzero = fcmp olt double %x, 0.0
+  %negx = fneg double %x
+  %fabs = select nsz nnan i1 %ltzero, double %negx, double %x
+  ret double %fabs
+}
+
 define double @select_fcmp_nnan_nsz_olt_zero(double %x) {
 ; CHECK-LABEL: @select_fcmp_nnan_nsz_olt_zero(
 ; CHECK-NEXT:    [[LTZERO:%.*]] = fcmp olt double [[X:%.*]], 0.000000e+00
@@ -721,10 +743,10 @@ define float @select_fcmp_nnan_nsz_ule_negzero_unary_fneg(float %x) {
   ret float %fabs
 }
 
-; X > 0.0 ? X : (0.0 - X) --> fabs(X)
+; X > 0.0 ? X : (-X) --> fabs(X)
 
-define <2 x float> @select_fcmp_ogt_zero_unary_fneg(<2 x float> %x) {
-; CHECK-LABEL: @select_fcmp_ogt_zero_unary_fneg(
+define <2 x float> @select_nsz_fcmp_ogt_zero_unary_fneg(<2 x float> %x) {
+; CHECK-LABEL: @select_nsz_fcmp_ogt_zero_unary_fneg(
 ; CHECK-NEXT:    [[TMP1:%.*]] = call nsz <2 x float> @llvm.fabs.v2f32(<2 x float> [[X:%.*]])
 ; CHECK-NEXT:    ret <2 x float> [[TMP1]]
 ;
@@ -734,6 +756,17 @@ define <2 x float> @select_fcmp_ogt_zero_unary_fneg(<2 x float> %x) {
   ret <2 x float> %fabs
 }
 
+define <2 x float> @select_nsz_nnan_fcmp_ogt_zero_unary_fneg(<2 x float> %x) {
+; CHECK-LABEL: @select_nsz_nnan_fcmp_ogt_zero_unary_fneg(
+; CHECK-NEXT:    [[TMP1:%.*]] = call nnan nsz <2 x float> @llvm.fabs.v2f32(<2 x float> [[X:%.*]])
+; CHECK-NEXT:    ret <2 x float> [[TMP1]]
+;
+  %gtzero = fcmp ogt <2 x float> %x, zeroinitializer
+  %negx = fneg <2 x float> %x
+  %fabs = select nsz nnan <2 x i1> %gtzero, <2 x float> %x, <2 x float> %negx
+  ret <2 x float> %fabs
+}
+
 define <2 x float> @select_fcmp_nnan_nsz_ogt_zero(<2 x float> %x) {
 ; CHECK-LABEL: @select_fcmp_nnan_nsz_ogt_zero(
 ; CHECK-NEXT:    [[GTZERO:%.*]] = fcmp ogt <2 x float> [[X:%.*]], zeroinitializer
index 665c011..f47d727 100644 (file)
@@ -30,19 +30,20 @@ define double @select_nsz_nfabs_lt_fmfProp(double %x) {
   ret double %sel
 }
 
-; Tests with various predicate types.
-define double @select_nsz_nfabs_olt(double %x) {
-; CHECK-LABEL: @select_nsz_nfabs_olt(
-; CHECK-NEXT:    [[TMP1:%.*]] = call nsz double @llvm.fabs.f64(double [[X:%.*]])
-; CHECK-NEXT:    [[SEL:%.*]] = fneg nsz double [[TMP1]]
+define double @select_nsz_nnan_nfabs_lt_fmfProp(double %x) {
+; CHECK-LABEL: @select_nsz_nnan_nfabs_lt_fmfProp(
+; CHECK-NEXT:    [[TMP1:%.*]] = call nnan nsz double @llvm.fabs.f64(double [[X:%.*]])
+; CHECK-NEXT:    [[SEL:%.*]] = fneg nnan nsz double [[TMP1]]
 ; CHECK-NEXT:    ret double [[SEL]]
 ;
   %cmp = fcmp olt double %x, 0.000000e+00
-  %negX = fneg double %x
-  %sel = select nsz i1 %cmp, double %x, double %negX
+  %negX = fneg fast double %x
+  %sel = select nsz nnan i1 %cmp, double %x, double %negX
   ret double %sel
 }
 
+; Tests with various predicate types.
+
 define double @select_nsz_nfabs_ult(double %x) {
 ; CHECK-LABEL: @select_nsz_nfabs_ult(
 ; CHECK-NEXT:    [[TMP1:%.*]] = call nsz double @llvm.fabs.f64(double [[X:%.*]])
@@ -55,6 +56,18 @@ define double @select_nsz_nfabs_ult(double %x) {
   ret double %sel
 }
 
+define double @select_nsz_nnan_nfabs_ult(double %x) {
+; CHECK-LABEL: @select_nsz_nnan_nfabs_ult(
+; CHECK-NEXT:    [[TMP1:%.*]] = call nnan nsz double @llvm.fabs.f64(double [[X:%.*]])
+; CHECK-NEXT:    [[SEL:%.*]] = fneg nnan nsz double [[TMP1]]
+; CHECK-NEXT:    ret double [[SEL]]
+;
+  %cmp = fcmp ult double %x, 0.000000e+00
+  %negX = fneg double %x
+  %sel = select nsz nnan i1 %cmp, double %x, double %negX
+  ret double %sel
+}
+
 define double @select_nsz_nfabs_ole(double %x) {
 ; CHECK-LABEL: @select_nsz_nfabs_ole(
 ; CHECK-NEXT:    [[TMP1:%.*]] = call nsz double @llvm.fabs.f64(double [[X:%.*]])
@@ -67,6 +80,18 @@ define double @select_nsz_nfabs_ole(double %x) {
   ret double %sel
 }
 
+define double @select_nsz_nnan_nfabs_ole(double %x) {
+; CHECK-LABEL: @select_nsz_nnan_nfabs_ole(
+; CHECK-NEXT:    [[TMP1:%.*]] = call nnan nsz double @llvm.fabs.f64(double [[X:%.*]])
+; CHECK-NEXT:    [[SEL:%.*]] = fneg nnan nsz double [[TMP1]]
+; CHECK-NEXT:    ret double [[SEL]]
+;
+  %cmp = fcmp ole double %x, 0.000000e+00
+  %negX = fneg double %x
+  %sel = select nsz nnan i1 %cmp, double %x, double %negX
+  ret double %sel
+}
+
 define double @select_nsz_nfabs_ule(double %x) {
 ; CHECK-LABEL: @select_nsz_nfabs_ule(
 ; CHECK-NEXT:    [[TMP1:%.*]] = call nsz double @llvm.fabs.f64(double [[X:%.*]])
@@ -79,6 +104,18 @@ define double @select_nsz_nfabs_ule(double %x) {
   ret double %sel
 }
 
+define double @select_nsz_nnan_nfabs_ule(double %x) {
+; CHECK-LABEL: @select_nsz_nnan_nfabs_ule(
+; CHECK-NEXT:    [[TMP1:%.*]] = call nnan nsz double @llvm.fabs.f64(double [[X:%.*]])
+; CHECK-NEXT:    [[SEL:%.*]] = fneg nnan nsz double [[TMP1]]
+; CHECK-NEXT:    ret double [[SEL]]
+;
+  %cmp = fcmp ule double %x, 0.000000e+00
+  %negX = fneg double %x
+  %sel = select nsz nnan i1 %cmp, double %x, double %negX
+  ret double %sel
+}
+
 ; (X >  +/-0.0) ? -X : X --> -fabs(X)
 ; (X >= +/-0.0) ? -X : X --> -fabs(X)
 ; One negative test with no fmf
@@ -108,6 +145,18 @@ define double @select_nsz_nfabs_gt_fmfProp(double %x) {
   ret double %sel
 }
 
+define double @select_nsz_nnan_nfabs_gt_fmfProp(double %x) {
+; CHECK-LABEL: @select_nsz_nnan_nfabs_gt_fmfProp(
+; CHECK-NEXT:    [[TMP1:%.*]] = call nnan nsz double @llvm.fabs.f64(double [[X:%.*]])
+; CHECK-NEXT:    [[SEL:%.*]] = fneg nnan nsz double [[TMP1]]
+; CHECK-NEXT:    ret double [[SEL]]
+;
+  %cmp = fcmp ogt double %x, 0.000000e+00
+  %negX = fneg fast double %x
+  %sel = select nsz nnan i1 %cmp, double %negX, double %x
+  ret double %sel
+}
+
 ; Tests with various predicate types.
 define double @select_nsz_nfabs_ogt(double %x) {
 ; CHECK-LABEL: @select_nsz_nfabs_ogt(
@@ -121,6 +170,18 @@ define double @select_nsz_nfabs_ogt(double %x) {
   ret double %sel
 }
 
+define double @select_nsz_nnan_nfabs_ogt(double %x) {
+; CHECK-LABEL: @select_nsz_nnan_nfabs_ogt(
+; CHECK-NEXT:    [[TMP1:%.*]] = call nnan nsz double @llvm.fabs.f64(double [[X:%.*]])
+; CHECK-NEXT:    [[SEL:%.*]] = fneg nnan nsz double [[TMP1]]
+; CHECK-NEXT:    ret double [[SEL]]
+;
+  %cmp = fcmp ogt double %x, 0.000000e+00
+  %negX = fneg double %x
+  %sel = select nsz nnan i1 %cmp, double %negX, double %x
+  ret double %sel
+}
+
 define double @select_nsz_nfabs_ugt(double %x) {
 ; CHECK-LABEL: @select_nsz_nfabs_ugt(
 ; CHECK-NEXT:    [[TMP1:%.*]] = call nsz double @llvm.fabs.f64(double [[X:%.*]])
@@ -133,6 +194,18 @@ define double @select_nsz_nfabs_ugt(double %x) {
   ret double %sel
 }
 
+define double @select_nsz_nnan_nfabs_ugt(double %x) {
+; CHECK-LABEL: @select_nsz_nnan_nfabs_ugt(
+; CHECK-NEXT:    [[TMP1:%.*]] = call nnan nsz double @llvm.fabs.f64(double [[X:%.*]])
+; CHECK-NEXT:    [[SEL:%.*]] = fneg nnan nsz double [[TMP1]]
+; CHECK-NEXT:    ret double [[SEL]]
+;
+  %cmp = fcmp ugt double %x, 0.000000e+00
+  %negX = fneg double %x
+  %sel = select nsz nnan i1 %cmp, double %negX, double %x
+  ret double %sel
+}
+
 define double @select_nsz_nfabs_oge(double %x) {
 ; CHECK-LABEL: @select_nsz_nfabs_oge(
 ; CHECK-NEXT:    [[TMP1:%.*]] = call nsz double @llvm.fabs.f64(double [[X:%.*]])
@@ -145,6 +218,18 @@ define double @select_nsz_nfabs_oge(double %x) {
   ret double %sel
 }
 
+define double @select_nsz_nnan_nfabs_oge(double %x) {
+; CHECK-LABEL: @select_nsz_nnan_nfabs_oge(
+; CHECK-NEXT:    [[TMP1:%.*]] = call nnan nsz double @llvm.fabs.f64(double [[X:%.*]])
+; CHECK-NEXT:    [[SEL:%.*]] = fneg nnan nsz double [[TMP1]]
+; CHECK-NEXT:    ret double [[SEL]]
+;
+  %cmp = fcmp oge double %x, 0.000000e+00
+  %negX = fneg double %x
+  %sel = select nsz nnan i1 %cmp, double %negX, double %x
+  ret double %sel
+}
+
 define double @select_nsz_nfabs_uge(double %x) {
 ; CHECK-LABEL: @select_nsz_nfabs_uge(
 ; CHECK-NEXT:    [[TMP1:%.*]] = call nsz double @llvm.fabs.f64(double [[X:%.*]])
@@ -157,6 +242,18 @@ define double @select_nsz_nfabs_uge(double %x) {
   ret double %sel
 }
 
+define double @select_nsz_nnan_nfabs_uge(double %x) {
+; CHECK-LABEL: @select_nsz_nnan_nfabs_uge(
+; CHECK-NEXT:    [[TMP1:%.*]] = call nnan nsz double @llvm.fabs.f64(double [[X:%.*]])
+; CHECK-NEXT:    [[SEL:%.*]] = fneg nnan nsz double [[TMP1]]
+; CHECK-NEXT:    ret double [[SEL]]
+;
+  %cmp = fcmp uge double %x, 0.000000e+00
+  %negX = fneg double %x
+  %sel = select nsz nnan i1 %cmp, double %negX, double %x
+  ret double %sel
+}
+
 ; (X < +/-0.0) ? X : (0.0 - X) --> (0.0 - fabs(X))
 ; One negative test with <=.
 define double @select_noFMF_fsubfabs_le(double %x) {
index 2c47b33..00d8539 100644 (file)
@@ -742,8 +742,8 @@ define float @fnabs_1(float %a) {
   ret float %fneg1
 }
 
-define float @fnabs_2(float %a) {
-; CHECK-LABEL: @fnabs_2(
+define float @fnabs_2_nsz(float %a) {
+; CHECK-LABEL: @fnabs_2_nsz(
 ; CHECK-NEXT:    [[TMP1:%.*]] = call nsz float @llvm.fabs.f32(float [[A:%.*]])
 ; CHECK-NEXT:    [[FNEG1:%.*]] = fneg float [[TMP1]]
 ; CHECK-NEXT:    ret float [[FNEG1]]
@@ -755,6 +755,19 @@ define float @fnabs_2(float %a) {
   ret float %fneg1
 }
 
+define float @fnabs_2_nsz_nnan(float %a) {
+; CHECK-LABEL: @fnabs_2_nsz_nnan(
+; CHECK-NEXT:    [[TMP1:%.*]] = call nnan nsz float @llvm.fabs.f32(float [[A:%.*]])
+; CHECK-NEXT:    [[FNEG1:%.*]] = fneg float [[TMP1]]
+; CHECK-NEXT:    ret float [[FNEG1]]
+;
+  %fneg = fneg float %a
+  %cmp = fcmp olt float %a, %fneg
+  %sel = select nsz nnan i1 %cmp, float %fneg, float %a
+  %fneg1 = fneg float %sel
+  ret float %fneg1
+}
+
 define float @select_fneg_both(float %x, float %y, i1 %b) {
 ; CHECK-LABEL: @select_fneg_both(
 ; CHECK-NEXT:    [[S_V:%.*]] = select i1 [[B:%.*]], float [[X:%.*]], float [[Y:%.*]]