llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang Author: YunQiang Su (wzssyqa) <details> <summary>Changes</summary> See: https://github.com/llvm/llvm-project/pull/112852 We will define llvm.minnum and llvm.maxnum with +0.0>-0.0, by default, while libc doesn't require it. --- Full diff: https://github.com/llvm/llvm-project/pull/113133.diff 4 Files Affected: - (modified) clang/lib/CodeGen/CGBuiltin.cpp (+20-13) - (added) clang/test/CodeGen/fmaxnum_fminnum_use_nsz.c (+33) - (modified) llvm/include/llvm/IR/IRBuilder.h (+10-6) - (modified) llvm/lib/IR/IRBuilder.cpp (+2-2) ``````````diff diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index 28f28c70b5ae52..f2d6049908720b 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -510,19 +510,20 @@ static Value *emitUnaryMaybeConstrainedFPBuiltin(CodeGenFunction &CGF, // Emit an intrinsic that has 2 operands of the same type as its result. // Depending on mode, this may be a constrained floating-point intrinsic. -static Value *emitBinaryMaybeConstrainedFPBuiltin(CodeGenFunction &CGF, - const CallExpr *E, unsigned IntrinsicID, - unsigned ConstrainedIntrinsicID) { +static Value *emitBinaryMaybeConstrainedFPBuiltin( + CodeGenFunction &CGF, const CallExpr *E, unsigned IntrinsicID, + unsigned ConstrainedIntrinsicID, llvm::FastMathFlags *FMF = nullptr) { llvm::Value *Src0 = CGF.EmitScalarExpr(E->getArg(0)); llvm::Value *Src1 = CGF.EmitScalarExpr(E->getArg(1)); CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, E); if (CGF.Builder.getIsFPConstrained()) { Function *F = CGF.CGM.getIntrinsic(ConstrainedIntrinsicID, Src0->getType()); - return CGF.Builder.CreateConstrainedFPCall(F, { Src0, Src1 }); + return CGF.Builder.CreateConstrainedFPCall(F, {Src0, Src1}, "", + std::nullopt, std::nullopt, FMF); } else { Function *F = CGF.CGM.getIntrinsic(IntrinsicID, Src0->getType()); - return CGF.Builder.CreateCall(F, { Src0, Src1 }); + return CGF.Builder.CreateCall(F, {Src0, Src1}, "", nullptr, FMF); } } @@ -2846,10 +2847,13 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, case Builtin::BI__builtin_fmaxf: case Builtin::BI__builtin_fmaxf16: case Builtin::BI__builtin_fmaxl: - case Builtin::BI__builtin_fmaxf128: - return RValue::get(emitBinaryMaybeConstrainedFPBuiltin(*this, E, - Intrinsic::maxnum, - Intrinsic::experimental_constrained_maxnum)); + case Builtin::BI__builtin_fmaxf128: { + llvm::FastMathFlags FMF; + FMF.setNoSignedZeros(); + return RValue::get(emitBinaryMaybeConstrainedFPBuiltin( + *this, E, Intrinsic::maxnum, + Intrinsic::experimental_constrained_maxnum, &FMF)); + } case Builtin::BIfmin: case Builtin::BIfminf: @@ -2858,10 +2862,13 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, case Builtin::BI__builtin_fminf: case Builtin::BI__builtin_fminf16: case Builtin::BI__builtin_fminl: - case Builtin::BI__builtin_fminf128: - return RValue::get(emitBinaryMaybeConstrainedFPBuiltin(*this, E, - Intrinsic::minnum, - Intrinsic::experimental_constrained_minnum)); + case Builtin::BI__builtin_fminf128: { + llvm::FastMathFlags FMF; + FMF.setNoSignedZeros(); + return RValue::get(emitBinaryMaybeConstrainedFPBuiltin( + *this, E, Intrinsic::minnum, + Intrinsic::experimental_constrained_minnum, &FMF)); + } case Builtin::BIfmaximum_num: case Builtin::BIfmaximum_numf: diff --git a/clang/test/CodeGen/fmaxnum_fminnum_use_nsz.c b/clang/test/CodeGen/fmaxnum_fminnum_use_nsz.c new file mode 100644 index 00000000000000..9798baf0432fea --- /dev/null +++ b/clang/test/CodeGen/fmaxnum_fminnum_use_nsz.c @@ -0,0 +1,33 @@ +// RUN: %clang_cc1 -triple x86_64 %s -emit-llvm -o - 2>&1 | FileCheck %s --check-prefix=CHECK + +float fminf (float, float); +double fmin (double, double); +long double fminl (long double, long double); +float fmaxf (float, float); +double fmax (double, double); +long double fmaxl (long double, long double); + +// CHECK: call nsz float @llvm.minnum.f32 +float fmin1(float a, float b) { + return fminf(a, b); +} +// CHECK: call nsz double @llvm.minnum.f64 +float fmin2(double a, double b) { + return fmin(a, b); +} +// CHECK: call nsz x86_fp80 @llvm.minnum.f80 +float fmin3(long double a, long double b) { + return fminl(a, b); +} +// CHECK: call nsz float @llvm.maxnum.f32 +float fmax1(float a, float b) { + return fmaxf(a, b); +} +// CHECK: call nsz double @llvm.maxnum.f64 +float fmax2(double a, double b) { + return fmax(a, b); +} +// CHECK: call nsz x86_fp80 @llvm.maxnum.f80 +float fmax3(long double a, long double b) { + return fmaxl(a, b); +} diff --git a/llvm/include/llvm/IR/IRBuilder.h b/llvm/include/llvm/IR/IRBuilder.h index 23fd8350a29b3d..1baca4f003cad6 100644 --- a/llvm/include/llvm/IR/IRBuilder.h +++ b/llvm/include/llvm/IR/IRBuilder.h @@ -2438,12 +2438,14 @@ class IRBuilderBase { public: CallInst *CreateCall(FunctionType *FTy, Value *Callee, ArrayRef<Value *> Args = {}, const Twine &Name = "", - MDNode *FPMathTag = nullptr) { + MDNode *FPMathTag = nullptr, + FastMathFlags *uFMF = nullptr) { CallInst *CI = CallInst::Create(FTy, Callee, Args, DefaultOperandBundles); if (IsFPConstrained) setConstrainedFPCallAttr(CI); - if (isa<FPMathOperator>(CI)) - setFPAttrs(CI, FPMathTag, FMF); + if (isa<FPMathOperator>(CI)) { + setFPAttrs(CI, FPMathTag, uFMF ? (FMF | *uFMF) : FMF); + } return Insert(CI, Name); } @@ -2459,9 +2461,10 @@ class IRBuilderBase { } CallInst *CreateCall(FunctionCallee Callee, ArrayRef<Value *> Args = {}, - const Twine &Name = "", MDNode *FPMathTag = nullptr) { + const Twine &Name = "", MDNode *FPMathTag = nullptr, + FastMathFlags *uFMF = nullptr) { return CreateCall(Callee.getFunctionType(), Callee.getCallee(), Args, Name, - FPMathTag); + FPMathTag, uFMF); } CallInst *CreateCall(FunctionCallee Callee, ArrayRef<Value *> Args, @@ -2474,7 +2477,8 @@ class IRBuilderBase { CallInst *CreateConstrainedFPCall( Function *Callee, ArrayRef<Value *> Args, const Twine &Name = "", std::optional<RoundingMode> Rounding = std::nullopt, - std::optional<fp::ExceptionBehavior> Except = std::nullopt); + std::optional<fp::ExceptionBehavior> Except = std::nullopt, + FastMathFlags *FMF = nullptr); Value *CreateSelect(Value *C, Value *True, Value *False, const Twine &Name = "", Instruction *MDFrom = nullptr); diff --git a/llvm/lib/IR/IRBuilder.cpp b/llvm/lib/IR/IRBuilder.cpp index f340f7aafdc76f..5feaf956b45a97 100644 --- a/llvm/lib/IR/IRBuilder.cpp +++ b/llvm/lib/IR/IRBuilder.cpp @@ -1031,7 +1031,7 @@ CallInst *IRBuilderBase::CreateConstrainedFPCmp( CallInst *IRBuilderBase::CreateConstrainedFPCall( Function *Callee, ArrayRef<Value *> Args, const Twine &Name, std::optional<RoundingMode> Rounding, - std::optional<fp::ExceptionBehavior> Except) { + std::optional<fp::ExceptionBehavior> Except, FastMathFlags *FMF) { llvm::SmallVector<Value *, 6> UseArgs; append_range(UseArgs, Args); @@ -1040,7 +1040,7 @@ CallInst *IRBuilderBase::CreateConstrainedFPCall( UseArgs.push_back(getConstrainedFPRounding(Rounding)); UseArgs.push_back(getConstrainedFPExcept(Except)); - CallInst *C = CreateCall(Callee, UseArgs, Name); + CallInst *C = CreateCall(Callee, UseArgs, Name, nullptr, FMF); setConstrainedFPCallAttr(C); return C; } `````````` </details> https://github.com/llvm/llvm-project/pull/113133 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits