InstCombine: Fold is.fpclass (fneg x) into the test mask
authorMatt Arsenault <Matthew.Arsenault@amd.com>
Sun, 11 Dec 2022 20:23:26 +0000 (15:23 -0500)
committerMatt Arsenault <arsenm2@gmail.com>
Sun, 5 Feb 2023 13:08:41 +0000 (09:08 -0400)
llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
llvm/test/Transforms/InstCombine/is_fpclass.ll

index 2fe8dbe..3a19384 100644 (file)
@@ -837,6 +837,31 @@ Instruction *InstCombinerImpl::foldIntrinsicIsFPClass(IntrinsicInst &II) {
   uint32_t Mask = CMask->getZExtValue();
   const bool IsStrict = II.isStrictFP();
 
+  Value *FNegSrc;
+  if (match(Src0, m_FNeg(m_Value(FNegSrc)))) {
+    // is.fpclass (fneg x), mask -> is.fpclass x, (fneg mask)
+    unsigned NewMask = Mask & fcNan;
+    if (Mask & fcNegInf)
+      NewMask |= fcPosInf;
+    if (Mask & fcNegNormal)
+      NewMask |= fcPosNormal;
+    if (Mask & fcNegSubnormal)
+      NewMask |= fcPosSubnormal;
+    if (Mask & fcNegZero)
+      NewMask |= fcPosZero;
+    if (Mask & fcPosZero)
+      NewMask |= fcNegZero;
+    if (Mask & fcPosSubnormal)
+      NewMask |= fcNegSubnormal;
+    if (Mask & fcPosNormal)
+      NewMask |= fcNegNormal;
+    if (Mask & fcPosInf)
+      NewMask |= fcNegInf;
+
+    II.setArgOperand(1, ConstantInt::get(Src1->getType(), NewMask));
+    return replaceOperand(II, 0, FNegSrc);
+  }
+
   if (Mask == fcNan && !IsStrict) {
     // Equivalent of isnan. Replace with standard fcmp if we don't care about FP
     // exceptions.
index 605f075..e3d11af 100644 (file)
@@ -1129,8 +1129,7 @@ define i1 @test_class_fneg_all(float %arg) {
 ; -> snan
 define i1 @test_class_fneg_snan(float %arg) {
 ; CHECK-LABEL: @test_class_fneg_snan(
-; CHECK-NEXT:    [[FNEG:%.*]] = fneg float [[ARG:%.*]]
-; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[FNEG]], i32 1)
+; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[ARG:%.*]], i32 1)
 ; CHECK-NEXT:    ret i1 [[CLASS]]
 ;
   %fneg = fneg float %arg
@@ -1141,8 +1140,7 @@ define i1 @test_class_fneg_snan(float %arg) {
 ; -> qnan
 define i1 @test_class_fneg_qnan(float %arg) {
 ; CHECK-LABEL: @test_class_fneg_qnan(
-; CHECK-NEXT:    [[FNEG:%.*]] = fneg float [[ARG:%.*]]
-; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[FNEG]], i32 2)
+; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[ARG:%.*]], i32 2)
 ; CHECK-NEXT:    ret i1 [[CLASS]]
 ;
   %fneg = fneg float %arg
@@ -1153,8 +1151,7 @@ define i1 @test_class_fneg_qnan(float %arg) {
 ; -> posinf
 define i1 @test_class_fneg_neginf(float %arg) {
 ; CHECK-LABEL: @test_class_fneg_neginf(
-; CHECK-NEXT:    [[FNEG:%.*]] = fneg float [[ARG:%.*]]
-; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[FNEG]], i32 4)
+; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[ARG:%.*]], i32 512)
 ; CHECK-NEXT:    ret i1 [[CLASS]]
 ;
   %fneg = fneg float %arg
@@ -1165,8 +1162,7 @@ define i1 @test_class_fneg_neginf(float %arg) {
 ; -> posnormal
 define i1 @test_class_fneg_negnormal(float %arg) {
 ; CHECK-LABEL: @test_class_fneg_negnormal(
-; CHECK-NEXT:    [[FNEG:%.*]] = fneg float [[ARG:%.*]]
-; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[FNEG]], i32 8)
+; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[ARG:%.*]], i32 256)
 ; CHECK-NEXT:    ret i1 [[CLASS]]
 ;
   %fneg = fneg float %arg
@@ -1177,8 +1173,7 @@ define i1 @test_class_fneg_negnormal(float %arg) {
 ; -> possubnormal
 define i1 @test_class_fneg_negsubnormal(float %arg) {
 ; CHECK-LABEL: @test_class_fneg_negsubnormal(
-; CHECK-NEXT:    [[FNEG:%.*]] = fneg float [[ARG:%.*]]
-; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[FNEG]], i32 16)
+; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[ARG:%.*]], i32 128)
 ; CHECK-NEXT:    ret i1 [[CLASS]]
 ;
   %fneg = fneg float %arg
@@ -1189,8 +1184,7 @@ define i1 @test_class_fneg_negsubnormal(float %arg) {
 ; -> poszero
 define i1 @test_class_fneg_negzero(float %arg) {
 ; CHECK-LABEL: @test_class_fneg_negzero(
-; CHECK-NEXT:    [[FNEG:%.*]] = fneg float [[ARG:%.*]]
-; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[FNEG]], i32 32)
+; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[ARG:%.*]], i32 64)
 ; CHECK-NEXT:    ret i1 [[CLASS]]
 ;
   %fneg = fneg float %arg
@@ -1201,8 +1195,7 @@ define i1 @test_class_fneg_negzero(float %arg) {
 ; -> negzero
 define i1 @test_class_fneg_poszero(float %arg) {
 ; CHECK-LABEL: @test_class_fneg_poszero(
-; CHECK-NEXT:    [[FNEG:%.*]] = fneg float [[ARG:%.*]]
-; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[FNEG]], i32 64)
+; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[ARG:%.*]], i32 32)
 ; CHECK-NEXT:    ret i1 [[CLASS]]
 ;
   %fneg = fneg float %arg
@@ -1213,8 +1206,7 @@ define i1 @test_class_fneg_poszero(float %arg) {
 ; -> negsubnormal
 define i1 @test_class_fneg_possubnormal(float %arg) {
 ; CHECK-LABEL: @test_class_fneg_possubnormal(
-; CHECK-NEXT:    [[FNEG:%.*]] = fneg float [[ARG:%.*]]
-; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[FNEG]], i32 128)
+; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[ARG:%.*]], i32 16)
 ; CHECK-NEXT:    ret i1 [[CLASS]]
 ;
   %fneg = fneg float %arg
@@ -1225,8 +1217,7 @@ define i1 @test_class_fneg_possubnormal(float %arg) {
 ; -> negnormal
 define i1 @test_class_fneg_posnormal(float %arg) {
 ; CHECK-LABEL: @test_class_fneg_posnormal(
-; CHECK-NEXT:    [[FNEG:%.*]] = fneg float [[ARG:%.*]]
-; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[FNEG]], i32 256)
+; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[ARG:%.*]], i32 8)
 ; CHECK-NEXT:    ret i1 [[CLASS]]
 ;
   %fneg = fneg float %arg
@@ -1237,8 +1228,7 @@ define i1 @test_class_fneg_posnormal(float %arg) {
 ; -> neginf
 define i1 @test_class_fneg_posinf(float %arg) {
 ; CHECK-LABEL: @test_class_fneg_posinf(
-; CHECK-NEXT:    [[FNEG:%.*]] = fneg float [[ARG:%.*]]
-; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[FNEG]], i32 512)
+; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[ARG:%.*]], i32 4)
 ; CHECK-NEXT:    ret i1 [[CLASS]]
 ;
   %fneg = fneg float %arg
@@ -1271,8 +1261,7 @@ define i1 @test_class_fneg_nnan(float %arg) {
 ; -> normal
 define i1 @test_class_fneg_normal(float %arg) {
 ; CHECK-LABEL: @test_class_fneg_normal(
-; CHECK-NEXT:    [[FNEG:%.*]] = fneg float [[ARG:%.*]]
-; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[FNEG]], i32 264)
+; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[ARG:%.*]], i32 264)
 ; CHECK-NEXT:    ret i1 [[CLASS]]
 ;
   %fneg = fneg float %arg
@@ -1284,8 +1273,7 @@ define i1 @test_class_fneg_normal(float %arg) {
 define i1 @test_class_fneg_zero(float %arg) {
 ;
 ; CHECK-LABEL: @test_class_fneg_zero(
-; CHECK-NEXT:    [[FNEG:%.*]] = fneg float [[ARG:%.*]]
-; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[FNEG]], i32 96)
+; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[ARG:%.*]], i32 96)
 ; CHECK-NEXT:    ret i1 [[CLASS]]
 ;
   %fneg = fneg float %arg
@@ -1297,8 +1285,7 @@ define i1 @test_class_fneg_zero(float %arg) {
 define i1 @test_class_fneg_subnormal(float %arg) {
 ;
 ; CHECK-LABEL: @test_class_fneg_subnormal(
-; CHECK-NEXT:    [[FNEG:%.*]] = fneg float [[ARG:%.*]]
-; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[FNEG]], i32 144)
+; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[ARG:%.*]], i32 144)
 ; CHECK-NEXT:    ret i1 [[CLASS]]
 ;
   %fneg = fneg float %arg
@@ -1309,8 +1296,7 @@ define i1 @test_class_fneg_subnormal(float %arg) {
 ; -> normal|pinf
 define i1 @test_class_fneg_normal_neginf(float %arg) {
 ; CHECK-LABEL: @test_class_fneg_normal_neginf(
-; CHECK-NEXT:    [[FNEG:%.*]] = fneg float [[ARG:%.*]]
-; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[FNEG]], i32 268)
+; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[ARG:%.*]], i32 776)
 ; CHECK-NEXT:    ret i1 [[CLASS]]
 ;
   %fneg = fneg float %arg
@@ -1321,8 +1307,7 @@ define i1 @test_class_fneg_normal_neginf(float %arg) {
 ; -> normal|ninf
 define i1 @test_class_fneg_normal_pinf(float %arg) {
 ; CHECK-LABEL: @test_class_fneg_normal_pinf(
-; CHECK-NEXT:    [[FNEG:%.*]] = fneg float [[ARG:%.*]]
-; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[FNEG]], i32 776)
+; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[ARG:%.*]], i32 268)
 ; CHECK-NEXT:    ret i1 [[CLASS]]
 ;
   %fneg = fneg float %arg
@@ -1333,8 +1318,7 @@ define i1 @test_class_fneg_normal_pinf(float %arg) {
 ; -> pinf|nnormal|pnormal|nzero
 define i1 @test_class_fneg_neginf_posnormal_negsubnormal_poszero(float %arg) {
 ; CHECK-LABEL: @test_class_fneg_neginf_posnormal_negsubnormal_poszero(
-; CHECK-NEXT:    [[FNEG:%.*]] = fneg float [[ARG:%.*]]
-; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[FNEG]], i32 340)
+; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[ARG:%.*]], i32 680)
 ; CHECK-NEXT:    ret i1 [[CLASS]]
 ;
   %fneg = fneg float %arg
@@ -1345,8 +1329,7 @@ define i1 @test_class_fneg_neginf_posnormal_negsubnormal_poszero(float %arg) {
 ; -> pinf|nnormal|psubnormal|negzero|snan
 define i1 @test_class_fneg_neginf_posnormal_negsubnormal_poszero_snan(float %arg) {
 ; CHECK-LABEL: @test_class_fneg_neginf_posnormal_negsubnormal_poszero_snan(
-; CHECK-NEXT:    [[FNEG:%.*]] = fneg float [[ARG:%.*]]
-; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[FNEG]], i32 341)
+; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[ARG:%.*]], i32 681)
 ; CHECK-NEXT:    ret i1 [[CLASS]]
 ;
   %fneg = fneg float %arg
@@ -1357,8 +1340,7 @@ define i1 @test_class_fneg_neginf_posnormal_negsubnormal_poszero_snan(float %arg
 ; pinf|negnormal|psubnormal|negzero|qnan
 define i1 @test_class_fneg_neginf_posnormal_negsubnormal_poszero_qnan(float %arg) {
 ; CHECK-LABEL: @test_class_fneg_neginf_posnormal_negsubnormal_poszero_qnan(
-; CHECK-NEXT:    [[FNEG:%.*]] = fneg float [[ARG:%.*]]
-; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[FNEG]], i32 342)
+; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[ARG:%.*]], i32 682)
 ; CHECK-NEXT:    ret i1 [[CLASS]]
 ;
   %fneg = fneg float %arg
@@ -1369,8 +1351,7 @@ define i1 @test_class_fneg_neginf_posnormal_negsubnormal_poszero_qnan(float %arg
 ; -> pinf | nnormal|psubnormal|nzero|nan
 define i1 @test_class_fneg_neginf_posnormal_negsubnormal_poszero_nan(float %arg) {
 ; CHECK-LABEL: @test_class_fneg_neginf_posnormal_negsubnormal_poszero_nan(
-; CHECK-NEXT:    [[FNEG:%.*]] = fneg float [[ARG:%.*]]
-; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[FNEG]], i32 343)
+; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[ARG:%.*]], i32 683)
 ; CHECK-NEXT:    ret i1 [[CLASS]]
 ;
   %fneg = fneg float %arg
@@ -1381,8 +1362,7 @@ define i1 @test_class_fneg_neginf_posnormal_negsubnormal_poszero_nan(float %arg)
 ; -> ninf|pnormal|negsubnormal|pzero
 define i1 @test_class_fneg_posinf_negnormal_possubnormal_negzero(float %arg) {
 ; CHECK-LABEL: @test_class_fneg_posinf_negnormal_possubnormal_negzero(
-; CHECK-NEXT:    [[FNEG:%.*]] = fneg float [[ARG:%.*]]
-; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[FNEG]], i32 680)
+; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[ARG:%.*]], i32 340)
 ; CHECK-NEXT:    ret i1 [[CLASS]]
 ;
   %fneg = fneg float %arg
@@ -1393,8 +1373,7 @@ define i1 @test_class_fneg_posinf_negnormal_possubnormal_negzero(float %arg) {
 ; -> ninf|pnormal|negsubnormal|pzero|snan
 define i1 @test_class_fneg_posinf_negnormal_possubnormal_negzero_snan(float %arg) {
 ; CHECK-LABEL: @test_class_fneg_posinf_negnormal_possubnormal_negzero_snan(
-; CHECK-NEXT:    [[FNEG:%.*]] = fneg float [[ARG:%.*]]
-; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[FNEG]], i32 681)
+; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[ARG:%.*]], i32 341)
 ; CHECK-NEXT:    ret i1 [[CLASS]]
 ;
   %fneg = fneg float %arg
@@ -1405,8 +1384,7 @@ define i1 @test_class_fneg_posinf_negnormal_possubnormal_negzero_snan(float %arg
 ; -> ninf|pnormal|negsubnormal|pzero|qnan
 define i1 @test_class_fneg_posinf_negnormal_possubnormal_negzero_qnan(float %arg) {
 ; CHECK-LABEL: @test_class_fneg_posinf_negnormal_possubnormal_negzero_qnan(
-; CHECK-NEXT:    [[FNEG:%.*]] = fneg float [[ARG:%.*]]
-; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[FNEG]], i32 682)
+; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[ARG:%.*]], i32 342)
 ; CHECK-NEXT:    ret i1 [[CLASS]]
 ;
   %fneg = fneg float %arg
@@ -1417,8 +1395,7 @@ define i1 @test_class_fneg_posinf_negnormal_possubnormal_negzero_qnan(float %arg
 ; -> ninf|pnormal|negsubnormal|pzero
 define i1 @test_class_fneg_posinf_negnormal_possubnormal_negzero_nan(float %arg) {
 ; CHECK-LABEL: @test_class_fneg_posinf_negnormal_possubnormal_negzero_nan(
-; CHECK-NEXT:    [[FNEG:%.*]] = fneg float [[ARG:%.*]]
-; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[FNEG]], i32 683)
+; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[ARG:%.*]], i32 343)
 ; CHECK-NEXT:    ret i1 [[CLASS]]
 ;
   %fneg = fneg float %arg
@@ -1430,8 +1407,7 @@ define i1 @test_class_fneg_posinf_negnormal_possubnormal_negzero_nan(float %arg)
 ; -> ninf|pnormal|negsubnormal|pzero|snan
 define i1 @test_class_fneg_posinf_negnormal_possubnormal_negzero_snan_strictfp(float %arg) strictfp {
 ; CHECK-LABEL: @test_class_fneg_posinf_negnormal_possubnormal_negzero_snan_strictfp(
-; CHECK-NEXT:    [[FNEG:%.*]] = fneg float [[ARG:%.*]]
-; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[FNEG]], i32 681) #[[ATTR2]]
+; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[ARG:%.*]], i32 341) #[[ATTR2]]
 ; CHECK-NEXT:    ret i1 [[CLASS]]
 ;
   %fneg = fneg float %arg
@@ -1444,7 +1420,7 @@ define i1 @test_class_fneg_multiple_use_fneg(float %arg, ptr %ptr) {
 ; CHECK-LABEL: @test_class_fneg_multiple_use_fneg(
 ; CHECK-NEXT:    [[FNEG:%.*]] = fneg float [[ARG:%.*]]
 ; CHECK-NEXT:    store float [[FNEG]], ptr [[PTR:%.*]], align 4
-; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[FNEG]], i32 682)
+; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[ARG]], i32 342)
 ; CHECK-NEXT:    ret i1 [[CLASS]]
 ;
   %fneg = fneg float %arg
@@ -1455,8 +1431,7 @@ define i1 @test_class_fneg_multiple_use_fneg(float %arg, ptr %ptr) {
 
 define <2 x i1> @test_class_fneg_posinf_negnormal_possubnormal_negzero_nan_vector(<2 x float> %arg) {
 ; CHECK-LABEL: @test_class_fneg_posinf_negnormal_possubnormal_negzero_nan_vector(
-; CHECK-NEXT:    [[FNEG:%.*]] = fneg <2 x float> [[ARG:%.*]]
-; CHECK-NEXT:    [[CLASS:%.*]] = call <2 x i1> @llvm.is.fpclass.v2f32(<2 x float> [[FNEG]], i32 683)
+; CHECK-NEXT:    [[CLASS:%.*]] = call <2 x i1> @llvm.is.fpclass.v2f32(<2 x float> [[ARG:%.*]], i32 343)
 ; CHECK-NEXT:    ret <2 x i1> [[CLASS]]
 ;
   %fneg = fneg <2 x float> %arg
@@ -1851,8 +1826,7 @@ define i1 @test_class_fneg_fabs_all(float %arg) {
 define i1 @test_class_fneg_fabs_snan(float %arg) {
 ; CHECK-LABEL: @test_class_fneg_fabs_snan(
 ; CHECK-NEXT:    [[FABS:%.*]] = call float @llvm.fabs.f32(float [[ARG:%.*]])
-; CHECK-NEXT:    [[FNEG_FABS:%.*]] = fneg float [[FABS]]
-; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[FNEG_FABS]], i32 1)
+; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[FABS]], i32 1)
 ; CHECK-NEXT:    ret i1 [[CLASS]]
 ;
   %fabs = call float @llvm.fabs.f32(float %arg)
@@ -1864,8 +1838,7 @@ define i1 @test_class_fneg_fabs_snan(float %arg) {
 define i1 @test_class_fneg_fabs_qnan(float %arg) {
 ; CHECK-LABEL: @test_class_fneg_fabs_qnan(
 ; CHECK-NEXT:    [[FABS:%.*]] = call float @llvm.fabs.f32(float [[ARG:%.*]])
-; CHECK-NEXT:    [[FNEG_FABS:%.*]] = fneg float [[FABS]]
-; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[FNEG_FABS]], i32 2)
+; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[FABS]], i32 2)
 ; CHECK-NEXT:    ret i1 [[CLASS]]
 ;
   %fabs = call float @llvm.fabs.f32(float %arg)
@@ -1877,8 +1850,7 @@ define i1 @test_class_fneg_fabs_qnan(float %arg) {
 define i1 @test_class_fneg_fabs_neginf(float %arg) {
 ; CHECK-LABEL: @test_class_fneg_fabs_neginf(
 ; CHECK-NEXT:    [[FABS:%.*]] = call float @llvm.fabs.f32(float [[ARG:%.*]])
-; CHECK-NEXT:    [[FNEG_FABS:%.*]] = fneg float [[FABS]]
-; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[FNEG_FABS]], i32 4)
+; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[FABS]], i32 512)
 ; CHECK-NEXT:    ret i1 [[CLASS]]
 ;
   %fabs = call float @llvm.fabs.f32(float %arg)
@@ -1890,8 +1862,7 @@ define i1 @test_class_fneg_fabs_neginf(float %arg) {
 define i1 @test_class_fneg_fabs_negnormal(float %arg) {
 ; CHECK-LABEL: @test_class_fneg_fabs_negnormal(
 ; CHECK-NEXT:    [[FABS:%.*]] = call float @llvm.fabs.f32(float [[ARG:%.*]])
-; CHECK-NEXT:    [[FNEG_FABS:%.*]] = fneg float [[FABS]]
-; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[FNEG_FABS]], i32 8)
+; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[FABS]], i32 256)
 ; CHECK-NEXT:    ret i1 [[CLASS]]
 ;
   %fabs = call float @llvm.fabs.f32(float %arg)
@@ -1903,8 +1874,7 @@ define i1 @test_class_fneg_fabs_negnormal(float %arg) {
 define i1 @test_class_fneg_fabs_negsubnormal(float %arg) {
 ; CHECK-LABEL: @test_class_fneg_fabs_negsubnormal(
 ; CHECK-NEXT:    [[FABS:%.*]] = call float @llvm.fabs.f32(float [[ARG:%.*]])
-; CHECK-NEXT:    [[FNEG_FABS:%.*]] = fneg float [[FABS]]
-; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[FNEG_FABS]], i32 16)
+; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[FABS]], i32 128)
 ; CHECK-NEXT:    ret i1 [[CLASS]]
 ;
   %fabs = call float @llvm.fabs.f32(float %arg)
@@ -1916,8 +1886,7 @@ define i1 @test_class_fneg_fabs_negsubnormal(float %arg) {
 define i1 @test_class_fneg_fabs_negzero(float %arg) {
 ; CHECK-LABEL: @test_class_fneg_fabs_negzero(
 ; CHECK-NEXT:    [[FABS:%.*]] = call float @llvm.fabs.f32(float [[ARG:%.*]])
-; CHECK-NEXT:    [[FNEG_FABS:%.*]] = fneg float [[FABS]]
-; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[FNEG_FABS]], i32 32)
+; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[FABS]], i32 64)
 ; CHECK-NEXT:    ret i1 [[CLASS]]
 ;
   %fabs = call float @llvm.fabs.f32(float %arg)
@@ -1929,8 +1898,7 @@ define i1 @test_class_fneg_fabs_negzero(float %arg) {
 define i1 @test_class_fneg_fabs_poszero(float %arg) {
 ; CHECK-LABEL: @test_class_fneg_fabs_poszero(
 ; CHECK-NEXT:    [[FABS:%.*]] = call float @llvm.fabs.f32(float [[ARG:%.*]])
-; CHECK-NEXT:    [[FNEG_FABS:%.*]] = fneg float [[FABS]]
-; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[FNEG_FABS]], i32 64)
+; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[FABS]], i32 32)
 ; CHECK-NEXT:    ret i1 [[CLASS]]
 ;
   %fabs = call float @llvm.fabs.f32(float %arg)
@@ -1942,8 +1910,7 @@ define i1 @test_class_fneg_fabs_poszero(float %arg) {
 define i1 @test_class_fneg_fabs_possubnormal(float %arg) {
 ; CHECK-LABEL: @test_class_fneg_fabs_possubnormal(
 ; CHECK-NEXT:    [[FABS:%.*]] = call float @llvm.fabs.f32(float [[ARG:%.*]])
-; CHECK-NEXT:    [[FNEG_FABS:%.*]] = fneg float [[FABS]]
-; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[FNEG_FABS]], i32 128)
+; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[FABS]], i32 16)
 ; CHECK-NEXT:    ret i1 [[CLASS]]
 ;
   %fabs = call float @llvm.fabs.f32(float %arg)
@@ -1955,8 +1922,7 @@ define i1 @test_class_fneg_fabs_possubnormal(float %arg) {
 define i1 @test_class_fneg_fabs_posnormal(float %arg) {
 ; CHECK-LABEL: @test_class_fneg_fabs_posnormal(
 ; CHECK-NEXT:    [[FABS:%.*]] = call float @llvm.fabs.f32(float [[ARG:%.*]])
-; CHECK-NEXT:    [[FNEG_FABS:%.*]] = fneg float [[FABS]]
-; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[FNEG_FABS]], i32 256)
+; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[FABS]], i32 8)
 ; CHECK-NEXT:    ret i1 [[CLASS]]
 ;
   %fabs = call float @llvm.fabs.f32(float %arg)
@@ -1968,8 +1934,7 @@ define i1 @test_class_fneg_fabs_posnormal(float %arg) {
 define i1 @test_class_fneg_fabs_posinf(float %arg) {
 ; CHECK-LABEL: @test_class_fneg_fabs_posinf(
 ; CHECK-NEXT:    [[FABS:%.*]] = call float @llvm.fabs.f32(float [[ARG:%.*]])
-; CHECK-NEXT:    [[FNEG_FABS:%.*]] = fneg float [[FABS]]
-; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[FNEG_FABS]], i32 512)
+; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[FABS]], i32 4)
 ; CHECK-NEXT:    ret i1 [[CLASS]]
 ;
   %fabs = call float @llvm.fabs.f32(float %arg)
@@ -2003,8 +1968,7 @@ define i1 @test_class_fneg_fabs_nnan(float %arg) {
 define i1 @test_class_fneg_fabs_normal(float %arg) {
 ; CHECK-LABEL: @test_class_fneg_fabs_normal(
 ; CHECK-NEXT:    [[FABS:%.*]] = call float @llvm.fabs.f32(float [[ARG:%.*]])
-; CHECK-NEXT:    [[FNEG_FABS:%.*]] = fneg float [[FABS]]
-; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[FNEG_FABS]], i32 264)
+; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[FABS]], i32 264)
 ; CHECK-NEXT:    ret i1 [[CLASS]]
 ;
   %fabs = call float @llvm.fabs.f32(float %arg)
@@ -2016,8 +1980,7 @@ define i1 @test_class_fneg_fabs_normal(float %arg) {
 define i1 @test_class_fneg_fabs_zero(float %arg) {
 ; CHECK-LABEL: @test_class_fneg_fabs_zero(
 ; CHECK-NEXT:    [[FABS:%.*]] = call float @llvm.fabs.f32(float [[ARG:%.*]])
-; CHECK-NEXT:    [[FNEG_FABS:%.*]] = fneg float [[FABS]]
-; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[FNEG_FABS]], i32 96)
+; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[FABS]], i32 96)
 ; CHECK-NEXT:    ret i1 [[CLASS]]
 ;
   %fabs = call float @llvm.fabs.f32(float %arg)
@@ -2029,8 +1992,7 @@ define i1 @test_class_fneg_fabs_zero(float %arg) {
 define i1 @test_class_fneg_fabs_subnormal(float %arg) {
 ; CHECK-LABEL: @test_class_fneg_fabs_subnormal(
 ; CHECK-NEXT:    [[FABS:%.*]] = call float @llvm.fabs.f32(float [[ARG:%.*]])
-; CHECK-NEXT:    [[FNEG_FABS:%.*]] = fneg float [[FABS]]
-; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[FNEG_FABS]], i32 144)
+; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[FABS]], i32 144)
 ; CHECK-NEXT:    ret i1 [[CLASS]]
 ;
   %fabs = call float @llvm.fabs.f32(float %arg)
@@ -2042,8 +2004,7 @@ define i1 @test_class_fneg_fabs_subnormal(float %arg) {
 define i1 @test_class_fneg_fabs_normal_neginf(float %arg) {
 ; CHECK-LABEL: @test_class_fneg_fabs_normal_neginf(
 ; CHECK-NEXT:    [[FABS:%.*]] = call float @llvm.fabs.f32(float [[ARG:%.*]])
-; CHECK-NEXT:    [[FNEG_FABS:%.*]] = fneg float [[FABS]]
-; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[FNEG_FABS]], i32 268)
+; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[FABS]], i32 776)
 ; CHECK-NEXT:    ret i1 [[CLASS]]
 ;
   %fabs = call float @llvm.fabs.f32(float %arg)
@@ -2055,8 +2016,7 @@ define i1 @test_class_fneg_fabs_normal_neginf(float %arg) {
 define i1 @test_class_fneg_fabs_normal_pinf(float %arg) {
 ; CHECK-LABEL: @test_class_fneg_fabs_normal_pinf(
 ; CHECK-NEXT:    [[FABS:%.*]] = call float @llvm.fabs.f32(float [[ARG:%.*]])
-; CHECK-NEXT:    [[FNEG_FABS:%.*]] = fneg float [[FABS]]
-; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[FNEG_FABS]], i32 776)
+; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[FABS]], i32 268)
 ; CHECK-NEXT:    ret i1 [[CLASS]]
 ;
   %fabs = call float @llvm.fabs.f32(float %arg)
@@ -2068,8 +2028,7 @@ define i1 @test_class_fneg_fabs_normal_pinf(float %arg) {
 define i1 @test_class_fneg_fabs_neginf_posnormal_negsubnormal_poszero(float %arg) {
 ; CHECK-LABEL: @test_class_fneg_fabs_neginf_posnormal_negsubnormal_poszero(
 ; CHECK-NEXT:    [[FABS:%.*]] = call float @llvm.fabs.f32(float [[ARG:%.*]])
-; CHECK-NEXT:    [[FNEG_FABS:%.*]] = fneg float [[FABS]]
-; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[FNEG_FABS]], i32 340)
+; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[FABS]], i32 680)
 ; CHECK-NEXT:    ret i1 [[CLASS]]
 ;
   %fabs = call float @llvm.fabs.f32(float %arg)
@@ -2081,8 +2040,7 @@ define i1 @test_class_fneg_fabs_neginf_posnormal_negsubnormal_poszero(float %arg
 define i1 @test_class_fneg_fabs_neginf_posnormal_negsubnormal_poszero_snan(float %arg) {
 ; CHECK-LABEL: @test_class_fneg_fabs_neginf_posnormal_negsubnormal_poszero_snan(
 ; CHECK-NEXT:    [[FABS:%.*]] = call float @llvm.fabs.f32(float [[ARG:%.*]])
-; CHECK-NEXT:    [[FNEG_FABS:%.*]] = fneg float [[FABS]]
-; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[FNEG_FABS]], i32 341)
+; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[FABS]], i32 681)
 ; CHECK-NEXT:    ret i1 [[CLASS]]
 ;
   %fabs = call float @llvm.fabs.f32(float %arg)
@@ -2094,8 +2052,7 @@ define i1 @test_class_fneg_fabs_neginf_posnormal_negsubnormal_poszero_snan(float
 define i1 @test_class_fneg_fabs_neginf_posnormal_negsubnormal_poszero_qnan(float %arg) {
 ; CHECK-LABEL: @test_class_fneg_fabs_neginf_posnormal_negsubnormal_poszero_qnan(
 ; CHECK-NEXT:    [[FABS:%.*]] = call float @llvm.fabs.f32(float [[ARG:%.*]])
-; CHECK-NEXT:    [[FNEG_FABS:%.*]] = fneg float [[FABS]]
-; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[FNEG_FABS]], i32 342)
+; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[FABS]], i32 682)
 ; CHECK-NEXT:    ret i1 [[CLASS]]
 ;
   %fabs = call float @llvm.fabs.f32(float %arg)
@@ -2107,8 +2064,7 @@ define i1 @test_class_fneg_fabs_neginf_posnormal_negsubnormal_poszero_qnan(float
 define i1 @test_class_fneg_fabs_neginf_posnormal_negsubnormal_poszero_nan(float %arg) {
 ; CHECK-LABEL: @test_class_fneg_fabs_neginf_posnormal_negsubnormal_poszero_nan(
 ; CHECK-NEXT:    [[FABS:%.*]] = call float @llvm.fabs.f32(float [[ARG:%.*]])
-; CHECK-NEXT:    [[FNEG_FABS:%.*]] = fneg float [[FABS]]
-; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[FNEG_FABS]], i32 343)
+; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[FABS]], i32 683)
 ; CHECK-NEXT:    ret i1 [[CLASS]]
 ;
   %fabs = call float @llvm.fabs.f32(float %arg)
@@ -2120,8 +2076,7 @@ define i1 @test_class_fneg_fabs_neginf_posnormal_negsubnormal_poszero_nan(float
 define i1 @test_class_fneg_fabs_posinf_negnormal_possubnormal_negzero(float %arg) {
 ; CHECK-LABEL: @test_class_fneg_fabs_posinf_negnormal_possubnormal_negzero(
 ; CHECK-NEXT:    [[FABS:%.*]] = call float @llvm.fabs.f32(float [[ARG:%.*]])
-; CHECK-NEXT:    [[FNEG_FABS:%.*]] = fneg float [[FABS]]
-; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[FNEG_FABS]], i32 680)
+; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[FABS]], i32 340)
 ; CHECK-NEXT:    ret i1 [[CLASS]]
 ;
   %fabs = call float @llvm.fabs.f32(float %arg)
@@ -2133,8 +2088,7 @@ define i1 @test_class_fneg_fabs_posinf_negnormal_possubnormal_negzero(float %arg
 define i1 @test_class_fneg_fabs_posinf_negnormal_possubnormal_negzero_snan(float %arg) {
 ; CHECK-LABEL: @test_class_fneg_fabs_posinf_negnormal_possubnormal_negzero_snan(
 ; CHECK-NEXT:    [[FABS:%.*]] = call float @llvm.fabs.f32(float [[ARG:%.*]])
-; CHECK-NEXT:    [[FNEG_FABS:%.*]] = fneg float [[FABS]]
-; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[FNEG_FABS]], i32 681)
+; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[FABS]], i32 341)
 ; CHECK-NEXT:    ret i1 [[CLASS]]
 ;
   %fabs = call float @llvm.fabs.f32(float %arg)
@@ -2146,8 +2100,7 @@ define i1 @test_class_fneg_fabs_posinf_negnormal_possubnormal_negzero_snan(float
 define i1 @test_class_fneg_fabs_posinf_negnormal_possubnormal_negzero_qnan(float %arg) {
 ; CHECK-LABEL: @test_class_fneg_fabs_posinf_negnormal_possubnormal_negzero_qnan(
 ; CHECK-NEXT:    [[FABS:%.*]] = call float @llvm.fabs.f32(float [[ARG:%.*]])
-; CHECK-NEXT:    [[FNEG_FABS:%.*]] = fneg float [[FABS]]
-; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[FNEG_FABS]], i32 682)
+; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[FABS]], i32 342)
 ; CHECK-NEXT:    ret i1 [[CLASS]]
 ;
   %fabs = call float @llvm.fabs.f32(float %arg)
@@ -2159,8 +2112,7 @@ define i1 @test_class_fneg_fabs_posinf_negnormal_possubnormal_negzero_qnan(float
 define i1 @test_class_fneg_fabs_posinf_negnormal_possubnormal_negzero_nan(float %arg) {
 ; CHECK-LABEL: @test_class_fneg_fabs_posinf_negnormal_possubnormal_negzero_nan(
 ; CHECK-NEXT:    [[FABS:%.*]] = call float @llvm.fabs.f32(float [[ARG:%.*]])
-; CHECK-NEXT:    [[FNEG_FABS:%.*]] = fneg float [[FABS]]
-; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[FNEG_FABS]], i32 683)
+; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[FABS]], i32 343)
 ; CHECK-NEXT:    ret i1 [[CLASS]]
 ;
   %fabs = call float @llvm.fabs.f32(float %arg)
@@ -2173,8 +2125,7 @@ define i1 @test_class_fneg_fabs_posinf_negnormal_possubnormal_negzero_nan(float
 define i1 @test_class_fneg_fabs_posinf_negnormal_possubnormal_negzero_snan_strictfp(float %arg) strictfp {
 ; CHECK-LABEL: @test_class_fneg_fabs_posinf_negnormal_possubnormal_negzero_snan_strictfp(
 ; CHECK-NEXT:    [[FABS:%.*]] = call float @llvm.fabs.f32(float [[ARG:%.*]])
-; CHECK-NEXT:    [[FNEG_FABS:%.*]] = fneg float [[FABS]]
-; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[FNEG_FABS]], i32 681) #[[ATTR2]]
+; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[FABS]], i32 341) #[[ATTR2]]
 ; CHECK-NEXT:    ret i1 [[CLASS]]
 ;
   %fabs = call float @llvm.fabs.f32(float %arg)
@@ -2189,7 +2140,7 @@ define i1 @test_class_fneg_fabs_multiple_use_fabs(float %arg, ptr %ptr) {
 ; CHECK-NEXT:    [[FABS:%.*]] = call float @llvm.fabs.f32(float [[ARG:%.*]])
 ; CHECK-NEXT:    [[FNEG_FABS:%.*]] = fneg float [[FABS]]
 ; CHECK-NEXT:    store float [[FNEG_FABS]], ptr [[PTR:%.*]], align 4
-; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[FNEG_FABS]], i32 682)
+; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[FABS]], i32 342)
 ; CHECK-NEXT:    ret i1 [[CLASS]]
 ;
   %fabs = call float @llvm.fabs.f32(float %arg)