arsenm created this revision. arsenm added reviewers: bkramer, foad, sepavloff, andrew.w.kaylor, kpn. Herald added a project: All. arsenm requested review of this revision. Herald added a subscriber: wdng.
This was doing an explicit non-canonical isnan check, then two unordered comparisons. We can fold the ordered check into an ordered compare. I recently fixed InstCombine to fold this pattern, but might as well give it less work to do. https://alive2.llvm.org/ce/z/ZWVHhT https://reviews.llvm.org/D140294 Files: clang/lib/CodeGen/CGBuiltin.cpp clang/test/CodeGen/builtins.c Index: clang/test/CodeGen/builtins.c =================================================================== --- clang/test/CodeGen/builtins.c +++ clang/test/CodeGen/builtins.c @@ -261,20 +261,16 @@ // CHECK: fcmp one double {{.*}}, 0x7FF0000000000000 res = __builtin_isnormal(*H); - // CHECK: fcmp oeq half - // CHECK: call half @llvm.fabs.f16(half - // CHECK: fcmp ult half {{.*}}, 0xH7C00 - // CHECK: fcmp uge half {{.*}}, 0xH0400 - // CHECK: and i1 - // CHECK: and i1 + // CHECK: %[[FABS:.*]] = call half @llvm.fabs.f16(half %[[VAL:.*]]) + // CHECK: %[[ISFINITE:.*]] = fcmp olt half %[[FABS]], 0xH7C00 + // CHECK: %[[ISNORMAL:.*]] = fcmp uge half %[[FABS]], 0xH0400 + // CHECK: and i1 %[[ISFINITE]], %[[ISNORMAL]] res = __builtin_isnormal(F); - // CHECK: fcmp oeq float - // CHECK: call float @llvm.fabs.f32(float - // CHECK: fcmp ult float {{.*}}, 0x7FF0000000000000 - // CHECK: fcmp uge float {{.*}}, 0x3810000000000000 - // CHECK: and i1 - // CHECK: and i1 + // CHECK: %[[FABS:.*]] = call float @llvm.fabs.f32(float %[[VAL:.*]]) + // CHECK: %[[ISFINITE:.*]] = fcmp olt float %[[FABS]], 0x7FF0000000000000 + // CHECK: %[[ISNORMAL:.*]] = fcmp uge float %[[FABS]], 0x3810000000000000 + // CHECK: and i1 %[[ISFINITE]], %[[ISNORMAL]] res = __builtin_flt_rounds(); // CHECK: call i32 @llvm.get.rounding( Index: clang/lib/CodeGen/CGBuiltin.cpp =================================================================== --- clang/lib/CodeGen/CGBuiltin.cpp +++ clang/lib/CodeGen/CGBuiltin.cpp @@ -3305,22 +3305,18 @@ } case Builtin::BI__builtin_isnormal: { - // isnormal(x) --> x == x && fabsf(x) < infinity && fabsf(x) >= float_min + // isnormal(x) --> fabs(x) < infinity && !(fabs(x) < float_min) CodeGenFunction::CGFPOptionsRAII FPOptsRAII(*this, E); // FIXME: for strictfp/IEEE-754 we need to not trap on SNaN here. Value *V = EmitScalarExpr(E->getArg(0)); - Value *Eq = Builder.CreateFCmpOEQ(V, V, "iseq"); - Value *Abs = EmitFAbs(*this, V); - Value *IsLessThanInf = - Builder.CreateFCmpULT(Abs, ConstantFP::getInfinity(V->getType()),"isinf"); - APFloat Smallest = APFloat::getSmallestNormalized( - getContext().getFloatTypeSemantics(E->getArg(0)->getType())); - Value *IsNormal = - Builder.CreateFCmpUGE(Abs, ConstantFP::get(V->getContext(), Smallest), - "isnormal"); - V = Builder.CreateAnd(Eq, IsLessThanInf, "and"); - V = Builder.CreateAnd(V, IsNormal, "and"); + Value *IsFinite = Builder.CreateFCmpOLT( + Abs, ConstantFP::getInfinity(V->getType()), "isfinite"); + APFloat SmallestNormal = APFloat::getSmallestNormalized( + getContext().getFloatTypeSemantics(E->getArg(0)->getType())); + Value *IsNormal = Builder.CreateFCmpUGE( + Abs, ConstantFP::get(V->getContext(), SmallestNormal), "isnormal"); + V = Builder.CreateAnd(IsFinite, IsNormal, "and"); return RValue::get(Builder.CreateZExt(V, ConvertType(E->getType()))); }
Index: clang/test/CodeGen/builtins.c =================================================================== --- clang/test/CodeGen/builtins.c +++ clang/test/CodeGen/builtins.c @@ -261,20 +261,16 @@ // CHECK: fcmp one double {{.*}}, 0x7FF0000000000000 res = __builtin_isnormal(*H); - // CHECK: fcmp oeq half - // CHECK: call half @llvm.fabs.f16(half - // CHECK: fcmp ult half {{.*}}, 0xH7C00 - // CHECK: fcmp uge half {{.*}}, 0xH0400 - // CHECK: and i1 - // CHECK: and i1 + // CHECK: %[[FABS:.*]] = call half @llvm.fabs.f16(half %[[VAL:.*]]) + // CHECK: %[[ISFINITE:.*]] = fcmp olt half %[[FABS]], 0xH7C00 + // CHECK: %[[ISNORMAL:.*]] = fcmp uge half %[[FABS]], 0xH0400 + // CHECK: and i1 %[[ISFINITE]], %[[ISNORMAL]] res = __builtin_isnormal(F); - // CHECK: fcmp oeq float - // CHECK: call float @llvm.fabs.f32(float - // CHECK: fcmp ult float {{.*}}, 0x7FF0000000000000 - // CHECK: fcmp uge float {{.*}}, 0x3810000000000000 - // CHECK: and i1 - // CHECK: and i1 + // CHECK: %[[FABS:.*]] = call float @llvm.fabs.f32(float %[[VAL:.*]]) + // CHECK: %[[ISFINITE:.*]] = fcmp olt float %[[FABS]], 0x7FF0000000000000 + // CHECK: %[[ISNORMAL:.*]] = fcmp uge float %[[FABS]], 0x3810000000000000 + // CHECK: and i1 %[[ISFINITE]], %[[ISNORMAL]] res = __builtin_flt_rounds(); // CHECK: call i32 @llvm.get.rounding( Index: clang/lib/CodeGen/CGBuiltin.cpp =================================================================== --- clang/lib/CodeGen/CGBuiltin.cpp +++ clang/lib/CodeGen/CGBuiltin.cpp @@ -3305,22 +3305,18 @@ } case Builtin::BI__builtin_isnormal: { - // isnormal(x) --> x == x && fabsf(x) < infinity && fabsf(x) >= float_min + // isnormal(x) --> fabs(x) < infinity && !(fabs(x) < float_min) CodeGenFunction::CGFPOptionsRAII FPOptsRAII(*this, E); // FIXME: for strictfp/IEEE-754 we need to not trap on SNaN here. Value *V = EmitScalarExpr(E->getArg(0)); - Value *Eq = Builder.CreateFCmpOEQ(V, V, "iseq"); - Value *Abs = EmitFAbs(*this, V); - Value *IsLessThanInf = - Builder.CreateFCmpULT(Abs, ConstantFP::getInfinity(V->getType()),"isinf"); - APFloat Smallest = APFloat::getSmallestNormalized( - getContext().getFloatTypeSemantics(E->getArg(0)->getType())); - Value *IsNormal = - Builder.CreateFCmpUGE(Abs, ConstantFP::get(V->getContext(), Smallest), - "isnormal"); - V = Builder.CreateAnd(Eq, IsLessThanInf, "and"); - V = Builder.CreateAnd(V, IsNormal, "and"); + Value *IsFinite = Builder.CreateFCmpOLT( + Abs, ConstantFP::getInfinity(V->getType()), "isfinite"); + APFloat SmallestNormal = APFloat::getSmallestNormalized( + getContext().getFloatTypeSemantics(E->getArg(0)->getType())); + Value *IsNormal = Builder.CreateFCmpUGE( + Abs, ConstantFP::get(V->getContext(), SmallestNormal), "isnormal"); + V = Builder.CreateAnd(IsFinite, IsNormal, "and"); return RValue::get(Builder.CreateZExt(V, ConvertType(E->getType()))); }
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits