https://github.com/wzssyqa updated https://github.com/llvm/llvm-project/pull/113133
>From 4cb7472aaa8973651a85057ee2f7ca7415d8ea72 Mon Sep 17 00:00:00 2001 From: YunQiang Su <yunqi...@isrc.iscas.ac.cn> Date: Mon, 21 Oct 2024 15:18:38 +0800 Subject: [PATCH 1/6] Clang: emit llvm.minnum and llvm.maxnum with nsz always 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. --- clang/lib/CodeGen/CGBuiltin.cpp | 33 ++++++++++++-------- clang/test/CodeGen/fmaxnum_fminnum_use_nsz.c | 33 ++++++++++++++++++++ llvm/include/llvm/IR/IRBuilder.h | 16 ++++++---- llvm/lib/IR/IRBuilder.cpp | 4 +-- 4 files changed, 65 insertions(+), 21 deletions(-) create mode 100644 clang/test/CodeGen/fmaxnum_fminnum_use_nsz.c diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index 3f28b7f26c36f..d738c710f0c2c 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 0000000000000..9798baf0432fe --- /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 23fd8350a29b3..1baca4f003cad 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 f340f7aafdc76..5feaf956b45a9 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; } >From 77ad097505c1a810cc4e652edd86909cef72d6f0 Mon Sep 17 00:00:00 2001 From: YunQiang Su <yunqi...@isrc.iscas.ac.cn> Date: Tue, 22 Oct 2024 09:56:06 +0800 Subject: [PATCH 2/6] fix testcases --- clang/test/CodeGen/fmaxnum_fminnum_use_nsz.c | 36 ++++++++++++--- clang/test/Headers/__clang_hip_math.hip | 48 ++++++++++---------- 2 files changed, 54 insertions(+), 30 deletions(-) diff --git a/clang/test/CodeGen/fmaxnum_fminnum_use_nsz.c b/clang/test/CodeGen/fmaxnum_fminnum_use_nsz.c index 9798baf0432fe..a708d5cd3ac9e 100644 --- a/clang/test/CodeGen/fmaxnum_fminnum_use_nsz.c +++ b/clang/test/CodeGen/fmaxnum_fminnum_use_nsz.c @@ -8,26 +8,50 @@ double fmax (double, double); long double fmaxl (long double, long double); // CHECK: call nsz float @llvm.minnum.f32 -float fmin1(float a, float b) { +float fmin32(float a, float b) { return fminf(a, b); } +// CHECK: call nsz float @llvm.minnum.f32 +float fmin32b(float a, float b) { + return __builtin_fminf(a, b); +} // CHECK: call nsz double @llvm.minnum.f64 -float fmin2(double a, double b) { +float fmin64(double a, double b) { return fmin(a, b); } +// CHECK: call nsz double @llvm.minnum.f64 +float fmin64b(double a, double b) { + return __builtin_fmin(a, b); +} // CHECK: call nsz x86_fp80 @llvm.minnum.f80 -float fmin3(long double a, long double b) { +float fmin80(long double a, long double b) { return fminl(a, b); } +// CHECK: call nsz x86_fp80 @llvm.minnum.f80 +float fmin80b(long double a, long double b) { + return __builtin_fminl(a, b); +} // CHECK: call nsz float @llvm.maxnum.f32 -float fmax1(float a, float b) { +float fmax32(float a, float b) { return fmaxf(a, b); } +// CHECK: call nsz float @llvm.maxnum.f32 +float fmax32b(float a, float b) { + return __builtin_fmaxf(a, b); +} // CHECK: call nsz double @llvm.maxnum.f64 -float fmax2(double a, double b) { +float fmax64(double a, double b) { return fmax(a, b); } +// CHECK: call nsz double @llvm.maxnum.f64 +float fmax64b(double a, double b) { + return __builtin_fmax(a, b); +} // CHECK: call nsz x86_fp80 @llvm.maxnum.f80 -float fmax3(long double a, long double b) { +float fmax80(long double a, long double b) { return fmaxl(a, b); } +// CHECK: call nsz x86_fp80 @llvm.maxnum.f80 +float fmax80b(long double a, long double b) { + return __builtin_fmaxl(a, b); +} diff --git a/clang/test/Headers/__clang_hip_math.hip b/clang/test/Headers/__clang_hip_math.hip index e4254d1e64bec..b37f11e16fbd4 100644 --- a/clang/test/Headers/__clang_hip_math.hip +++ b/clang/test/Headers/__clang_hip_math.hip @@ -1248,17 +1248,17 @@ extern "C" __device__ double test_fma_rn(double x, double y, double z) { // DEFAULT-LABEL: @test_fmaxf( // DEFAULT-NEXT: entry: -// DEFAULT-NEXT: [[TMP0:%.*]] = tail call contract noundef float @llvm.maxnum.f32(float [[X:%.*]], float [[Y:%.*]]) +// DEFAULT-NEXT: [[TMP0:%.*]] = tail call nsz contract noundef float @llvm.maxnum.f32(float [[X:%.*]], float [[Y:%.*]]) // DEFAULT-NEXT: ret float [[TMP0]] // // FINITEONLY-LABEL: @test_fmaxf( // FINITEONLY-NEXT: entry: -// FINITEONLY-NEXT: [[TMP0:%.*]] = tail call nnan ninf contract noundef float @llvm.maxnum.f32(float [[X:%.*]], float [[Y:%.*]]) +// FINITEONLY-NEXT: [[TMP0:%.*]] = tail call nnan ninf nsz contract noundef float @llvm.maxnum.f32(float [[X:%.*]], float [[Y:%.*]]) // FINITEONLY-NEXT: ret float [[TMP0]] // // APPROX-LABEL: @test_fmaxf( // APPROX-NEXT: entry: -// APPROX-NEXT: [[TMP0:%.*]] = tail call contract noundef float @llvm.maxnum.f32(float [[X:%.*]], float [[Y:%.*]]) +// APPROX-NEXT: [[TMP0:%.*]] = tail call nsz contract noundef float @llvm.maxnum.f32(float [[X:%.*]], float [[Y:%.*]]) // APPROX-NEXT: ret float [[TMP0]] // extern "C" __device__ float test_fmaxf(float x, float y) { @@ -1267,17 +1267,17 @@ extern "C" __device__ float test_fmaxf(float x, float y) { // DEFAULT-LABEL: @test_fmax( // DEFAULT-NEXT: entry: -// DEFAULT-NEXT: [[TMP0:%.*]] = tail call contract noundef double @llvm.maxnum.f64(double [[X:%.*]], double [[Y:%.*]]) +// DEFAULT-NEXT: [[TMP0:%.*]] = tail call nsz contract noundef double @llvm.maxnum.f64(double [[X:%.*]], double [[Y:%.*]]) // DEFAULT-NEXT: ret double [[TMP0]] // // FINITEONLY-LABEL: @test_fmax( // FINITEONLY-NEXT: entry: -// FINITEONLY-NEXT: [[TMP0:%.*]] = tail call nnan ninf contract noundef double @llvm.maxnum.f64(double [[X:%.*]], double [[Y:%.*]]) +// FINITEONLY-NEXT: [[TMP0:%.*]] = tail call nnan ninf nsz contract noundef double @llvm.maxnum.f64(double [[X:%.*]], double [[Y:%.*]]) // FINITEONLY-NEXT: ret double [[TMP0]] // // APPROX-LABEL: @test_fmax( // APPROX-NEXT: entry: -// APPROX-NEXT: [[TMP0:%.*]] = tail call contract noundef double @llvm.maxnum.f64(double [[X:%.*]], double [[Y:%.*]]) +// APPROX-NEXT: [[TMP0:%.*]] = tail call nsz contract noundef double @llvm.maxnum.f64(double [[X:%.*]], double [[Y:%.*]]) // APPROX-NEXT: ret double [[TMP0]] // extern "C" __device__ double test_fmax(double x, double y) { @@ -1286,17 +1286,17 @@ extern "C" __device__ double test_fmax(double x, double y) { // DEFAULT-LABEL: @test_fminf( // DEFAULT-NEXT: entry: -// DEFAULT-NEXT: [[TMP0:%.*]] = tail call contract noundef float @llvm.minnum.f32(float [[X:%.*]], float [[Y:%.*]]) +// DEFAULT-NEXT: [[TMP0:%.*]] = tail call nsz contract noundef float @llvm.minnum.f32(float [[X:%.*]], float [[Y:%.*]]) // DEFAULT-NEXT: ret float [[TMP0]] // // FINITEONLY-LABEL: @test_fminf( // FINITEONLY-NEXT: entry: -// FINITEONLY-NEXT: [[TMP0:%.*]] = tail call nnan ninf contract noundef float @llvm.minnum.f32(float [[X:%.*]], float [[Y:%.*]]) +// FINITEONLY-NEXT: [[TMP0:%.*]] = tail call nnan ninf nsz contract noundef float @llvm.minnum.f32(float [[X:%.*]], float [[Y:%.*]]) // FINITEONLY-NEXT: ret float [[TMP0]] // // APPROX-LABEL: @test_fminf( // APPROX-NEXT: entry: -// APPROX-NEXT: [[TMP0:%.*]] = tail call contract noundef float @llvm.minnum.f32(float [[X:%.*]], float [[Y:%.*]]) +// APPROX-NEXT: [[TMP0:%.*]] = tail call nsz contract noundef float @llvm.minnum.f32(float [[X:%.*]], float [[Y:%.*]]) // APPROX-NEXT: ret float [[TMP0]] // extern "C" __device__ float test_fminf(float x, float y) { @@ -1305,17 +1305,17 @@ extern "C" __device__ float test_fminf(float x, float y) { // DEFAULT-LABEL: @test_fmin( // DEFAULT-NEXT: entry: -// DEFAULT-NEXT: [[TMP0:%.*]] = tail call contract noundef double @llvm.minnum.f64(double [[X:%.*]], double [[Y:%.*]]) +// DEFAULT-NEXT: [[TMP0:%.*]] = tail call nsz contract noundef double @llvm.minnum.f64(double [[X:%.*]], double [[Y:%.*]]) // DEFAULT-NEXT: ret double [[TMP0]] // // FINITEONLY-LABEL: @test_fmin( // FINITEONLY-NEXT: entry: -// FINITEONLY-NEXT: [[TMP0:%.*]] = tail call nnan ninf contract noundef double @llvm.minnum.f64(double [[X:%.*]], double [[Y:%.*]]) +// FINITEONLY-NEXT: [[TMP0:%.*]] = tail call nnan ninf nsz contract noundef double @llvm.minnum.f64(double [[X:%.*]], double [[Y:%.*]]) // FINITEONLY-NEXT: ret double [[TMP0]] // // APPROX-LABEL: @test_fmin( // APPROX-NEXT: entry: -// APPROX-NEXT: [[TMP0:%.*]] = tail call contract noundef double @llvm.minnum.f64(double [[X:%.*]], double [[Y:%.*]]) +// APPROX-NEXT: [[TMP0:%.*]] = tail call nsz contract noundef double @llvm.minnum.f64(double [[X:%.*]], double [[Y:%.*]]) // APPROX-NEXT: ret double [[TMP0]] // extern "C" __device__ double test_fmin(double x, double y) { @@ -5114,17 +5114,17 @@ extern "C" __device__ double test__fma_rn(double x, double y, double z) { // DEFAULT-LABEL: @test_float_min( // DEFAULT-NEXT: entry: -// DEFAULT-NEXT: [[TMP0:%.*]] = tail call contract noundef float @llvm.minnum.f32(float [[X:%.*]], float [[Y:%.*]]) +// DEFAULT-NEXT: [[TMP0:%.*]] = tail call nsz contract noundef float @llvm.minnum.f32(float [[X:%.*]], float [[Y:%.*]]) // DEFAULT-NEXT: ret float [[TMP0]] // // FINITEONLY-LABEL: @test_float_min( // FINITEONLY-NEXT: entry: -// FINITEONLY-NEXT: [[TMP0:%.*]] = tail call nnan ninf contract noundef float @llvm.minnum.f32(float [[X:%.*]], float [[Y:%.*]]) +// FINITEONLY-NEXT: [[TMP0:%.*]] = tail call nnan ninf nsz contract noundef float @llvm.minnum.f32(float [[X:%.*]], float [[Y:%.*]]) // FINITEONLY-NEXT: ret float [[TMP0]] // // APPROX-LABEL: @test_float_min( // APPROX-NEXT: entry: -// APPROX-NEXT: [[TMP0:%.*]] = tail call contract noundef float @llvm.minnum.f32(float [[X:%.*]], float [[Y:%.*]]) +// APPROX-NEXT: [[TMP0:%.*]] = tail call nsz contract noundef float @llvm.minnum.f32(float [[X:%.*]], float [[Y:%.*]]) // APPROX-NEXT: ret float [[TMP0]] // extern "C" __device__ float test_float_min(float x, float y) { @@ -5133,17 +5133,17 @@ extern "C" __device__ float test_float_min(float x, float y) { // DEFAULT-LABEL: @test_float_max( // DEFAULT-NEXT: entry: -// DEFAULT-NEXT: [[TMP0:%.*]] = tail call contract noundef float @llvm.maxnum.f32(float [[X:%.*]], float [[Y:%.*]]) +// DEFAULT-NEXT: [[TMP0:%.*]] = tail call nsz contract noundef float @llvm.maxnum.f32(float [[X:%.*]], float [[Y:%.*]]) // DEFAULT-NEXT: ret float [[TMP0]] // // FINITEONLY-LABEL: @test_float_max( // FINITEONLY-NEXT: entry: -// FINITEONLY-NEXT: [[TMP0:%.*]] = tail call nnan ninf contract noundef float @llvm.maxnum.f32(float [[X:%.*]], float [[Y:%.*]]) +// FINITEONLY-NEXT: [[TMP0:%.*]] = tail call nnan ninf nsz contract noundef float @llvm.maxnum.f32(float [[X:%.*]], float [[Y:%.*]]) // FINITEONLY-NEXT: ret float [[TMP0]] // // APPROX-LABEL: @test_float_max( // APPROX-NEXT: entry: -// APPROX-NEXT: [[TMP0:%.*]] = tail call contract noundef float @llvm.maxnum.f32(float [[X:%.*]], float [[Y:%.*]]) +// APPROX-NEXT: [[TMP0:%.*]] = tail call nsz contract noundef float @llvm.maxnum.f32(float [[X:%.*]], float [[Y:%.*]]) // APPROX-NEXT: ret float [[TMP0]] // extern "C" __device__ float test_float_max(float x, float y) { @@ -5152,17 +5152,17 @@ extern "C" __device__ float test_float_max(float x, float y) { // DEFAULT-LABEL: @test_double_min( // DEFAULT-NEXT: entry: -// DEFAULT-NEXT: [[TMP0:%.*]] = tail call contract noundef double @llvm.minnum.f64(double [[X:%.*]], double [[Y:%.*]]) +// DEFAULT-NEXT: [[TMP0:%.*]] = tail call nsz contract noundef double @llvm.minnum.f64(double [[X:%.*]], double [[Y:%.*]]) // DEFAULT-NEXT: ret double [[TMP0]] // // FINITEONLY-LABEL: @test_double_min( // FINITEONLY-NEXT: entry: -// FINITEONLY-NEXT: [[TMP0:%.*]] = tail call nnan ninf contract noundef double @llvm.minnum.f64(double [[X:%.*]], double [[Y:%.*]]) +// FINITEONLY-NEXT: [[TMP0:%.*]] = tail call nnan ninf nsz contract noundef double @llvm.minnum.f64(double [[X:%.*]], double [[Y:%.*]]) // FINITEONLY-NEXT: ret double [[TMP0]] // // APPROX-LABEL: @test_double_min( // APPROX-NEXT: entry: -// APPROX-NEXT: [[TMP0:%.*]] = tail call contract noundef double @llvm.minnum.f64(double [[X:%.*]], double [[Y:%.*]]) +// APPROX-NEXT: [[TMP0:%.*]] = tail call nsz contract noundef double @llvm.minnum.f64(double [[X:%.*]], double [[Y:%.*]]) // APPROX-NEXT: ret double [[TMP0]] // extern "C" __device__ double test_double_min(double x, double y) { @@ -5171,17 +5171,17 @@ extern "C" __device__ double test_double_min(double x, double y) { // DEFAULT-LABEL: @test_double_max( // DEFAULT-NEXT: entry: -// DEFAULT-NEXT: [[TMP0:%.*]] = tail call contract noundef double @llvm.maxnum.f64(double [[X:%.*]], double [[Y:%.*]]) +// DEFAULT-NEXT: [[TMP0:%.*]] = tail call nsz contract noundef double @llvm.maxnum.f64(double [[X:%.*]], double [[Y:%.*]]) // DEFAULT-NEXT: ret double [[TMP0]] // // FINITEONLY-LABEL: @test_double_max( // FINITEONLY-NEXT: entry: -// FINITEONLY-NEXT: [[TMP0:%.*]] = tail call nnan ninf contract noundef double @llvm.maxnum.f64(double [[X:%.*]], double [[Y:%.*]]) +// FINITEONLY-NEXT: [[TMP0:%.*]] = tail call nnan ninf nsz contract noundef double @llvm.maxnum.f64(double [[X:%.*]], double [[Y:%.*]]) // FINITEONLY-NEXT: ret double [[TMP0]] // // APPROX-LABEL: @test_double_max( // APPROX-NEXT: entry: -// APPROX-NEXT: [[TMP0:%.*]] = tail call contract noundef double @llvm.maxnum.f64(double [[X:%.*]], double [[Y:%.*]]) +// APPROX-NEXT: [[TMP0:%.*]] = tail call nsz contract noundef double @llvm.maxnum.f64(double [[X:%.*]], double [[Y:%.*]]) // APPROX-NEXT: ret double [[TMP0]] // extern "C" __device__ double test_double_max(double x, double y) { >From 6214605187c7d5b8681ce0ed30761a32853fc01e Mon Sep 17 00:00:00 2001 From: YunQiang Su <yunqi...@isrc.iscas.ac.cn> Date: Tue, 22 Oct 2024 10:21:35 +0800 Subject: [PATCH 3/6] -ffp-exception-behavior=strict --- clang/test/CodeGen/fmaxnum_fminnum_use_nsz.c | 45 +++++++------------- 1 file changed, 15 insertions(+), 30 deletions(-) diff --git a/clang/test/CodeGen/fmaxnum_fminnum_use_nsz.c b/clang/test/CodeGen/fmaxnum_fminnum_use_nsz.c index a708d5cd3ac9e..f2ae4a49f6303 100644 --- a/clang/test/CodeGen/fmaxnum_fminnum_use_nsz.c +++ b/clang/test/CodeGen/fmaxnum_fminnum_use_nsz.c @@ -1,4 +1,5 @@ // RUN: %clang_cc1 -triple x86_64 %s -emit-llvm -o - 2>&1 | FileCheck %s --check-prefix=CHECK +// RUN: %clang_cc1 -ffp-exception-behavior=strict -triple x86_64 %s -emit-llvm -o - 2>&1 | FileCheck %s --check-prefix=CHECK-STRICT float fminf (float, float); double fmin (double, double); @@ -8,50 +9,34 @@ double fmax (double, double); long double fmaxl (long double, long double); // CHECK: call nsz float @llvm.minnum.f32 -float fmin32(float a, float b) { +// CHECK-STRICT: call nsz float @llvm.experimental.constrained.minnum.f32{{.*}} #2 +float fmin1(float a, float b) { return fminf(a, b); } -// CHECK: call nsz float @llvm.minnum.f32 -float fmin32b(float a, float b) { - return __builtin_fminf(a, b); -} // CHECK: call nsz double @llvm.minnum.f64 -float fmin64(double a, double b) { +// CHECK-STRICT: call nsz double @llvm.experimental.constrained.minnum.f64{{.*}} #2 +float fmin2(double a, double b) { return fmin(a, b); } -// CHECK: call nsz double @llvm.minnum.f64 -float fmin64b(double a, double b) { - return __builtin_fmin(a, b); -} // CHECK: call nsz x86_fp80 @llvm.minnum.f80 -float fmin80(long double a, long double b) { +// CHECK-STRICT: call nsz x86_fp80 @llvm.experimental.constrained.minnum.f80{{.*}} #2 +float fmin3(long double a, long double b) { return fminl(a, b); } -// CHECK: call nsz x86_fp80 @llvm.minnum.f80 -float fmin80b(long double a, long double b) { - return __builtin_fminl(a, b); -} // CHECK: call nsz float @llvm.maxnum.f32 -float fmax32(float a, float b) { +// CHECK-STRICT: call nsz float @llvm.experimental.constrained.maxnum.f32{{.*}} #2 +float fmax1(float a, float b) { return fmaxf(a, b); } -// CHECK: call nsz float @llvm.maxnum.f32 -float fmax32b(float a, float b) { - return __builtin_fmaxf(a, b); -} // CHECK: call nsz double @llvm.maxnum.f64 -float fmax64(double a, double b) { +// CHECK-STRICT: call nsz double @llvm.experimental.constrained.maxnum.f64{{.*}} #2 +float fmax2(double a, double b) { return fmax(a, b); } -// CHECK: call nsz double @llvm.maxnum.f64 -float fmax64b(double a, double b) { - return __builtin_fmax(a, b); -} // CHECK: call nsz x86_fp80 @llvm.maxnum.f80 -float fmax80(long double a, long double b) { +// CHECK-STRICT: call nsz x86_fp80 @llvm.experimental.constrained.maxnum.f80{{.*}} #2 +float fmax3(long double a, long double b) { return fmaxl(a, b); } -// CHECK: call nsz x86_fp80 @llvm.maxnum.f80 -float fmax80b(long double a, long double b) { - return __builtin_fmaxl(a, b); -} + +//CHECK-STRICT: attributes #2 = { strictfp } >From 77a9aad34a72242a26297d4a14200c04ab0c2b3e Mon Sep 17 00:00:00 2001 From: YunQiang Su <yunqi...@isrc.iscas.ac.cn> Date: Tue, 22 Oct 2024 10:36:46 +0800 Subject: [PATCH 4/6] add missing builtin test --- clang/test/CodeGen/fmaxnum_fminnum_use_nsz.c | 40 +++++++++++++++++--- 1 file changed, 35 insertions(+), 5 deletions(-) diff --git a/clang/test/CodeGen/fmaxnum_fminnum_use_nsz.c b/clang/test/CodeGen/fmaxnum_fminnum_use_nsz.c index f2ae4a49f6303..afe626d921125 100644 --- a/clang/test/CodeGen/fmaxnum_fminnum_use_nsz.c +++ b/clang/test/CodeGen/fmaxnum_fminnum_use_nsz.c @@ -10,33 +10,63 @@ long double fmaxl (long double, long double); // CHECK: call nsz float @llvm.minnum.f32 // CHECK-STRICT: call nsz float @llvm.experimental.constrained.minnum.f32{{.*}} #2 -float fmin1(float a, float b) { +float fmin32(float a, float b) { return fminf(a, b); } +// CHECK: call nsz float @llvm.minnum.f32 +// CHECK-STRICT: call nsz float @llvm.experimental.constrained.minnum.f32{{.*}} #2 +float fmin32b(float a, float b) { + return __builtin_fminf(a, b); +} // CHECK: call nsz double @llvm.minnum.f64 // CHECK-STRICT: call nsz double @llvm.experimental.constrained.minnum.f64{{.*}} #2 -float fmin2(double a, double b) { +float fmin64(double a, double b) { return fmin(a, b); } +// CHECK: call nsz double @llvm.minnum.f64 +// CHECK-STRICT: call nsz double @llvm.experimental.constrained.minnum.f64{{.*}} #2 +float fmin64b(double a, double b) { + return __builtin_fmin(a, b); +} // CHECK: call nsz x86_fp80 @llvm.minnum.f80 // CHECK-STRICT: call nsz x86_fp80 @llvm.experimental.constrained.minnum.f80{{.*}} #2 -float fmin3(long double a, long double b) { +float fmin80(long double a, long double b) { return fminl(a, b); } +// CHECK: call nsz x86_fp80 @llvm.minnum.f80 +// CHECK-STRICT: call nsz x86_fp80 @llvm.experimental.constrained.minnum.f80{{.*}} #2 +float fmin80b(long double a, long double b) { + return __builtin_fminl(a, b); +} // CHECK: call nsz float @llvm.maxnum.f32 // CHECK-STRICT: call nsz float @llvm.experimental.constrained.maxnum.f32{{.*}} #2 -float fmax1(float a, float b) { +float fmax32(float a, float b) { return fmaxf(a, b); } +// CHECK: call nsz float @llvm.maxnum.f32 +// CHECK-STRICT: call nsz float @llvm.experimental.constrained.maxnum.f32{{.*}} #2 +float fmax32b(float a, float b) { + return __builtin_fmaxf(a, b); +} // CHECK: call nsz double @llvm.maxnum.f64 // CHECK-STRICT: call nsz double @llvm.experimental.constrained.maxnum.f64{{.*}} #2 -float fmax2(double a, double b) { +float fmax64(double a, double b) { return fmax(a, b); } +// CHECK: call nsz double @llvm.maxnum.f64 +// CHECK-STRICT: call nsz double @llvm.experimental.constrained.maxnum.f64{{.*}} #2 +float fmax64b(double a, double b) { + return __builtin_fmax(a, b); +} // CHECK: call nsz x86_fp80 @llvm.maxnum.f80 // CHECK-STRICT: call nsz x86_fp80 @llvm.experimental.constrained.maxnum.f80{{.*}} #2 float fmax3(long double a, long double b) { return fmaxl(a, b); } +// CHECK: call nsz x86_fp80 @llvm.maxnum.f80 +// CHECK-STRICT: call nsz x86_fp80 @llvm.experimental.constrained.maxnum.f80{{.*}} #2 +float fmax80b(long double a, long double b) { + return __builtin_fmaxl(a, b); +} //CHECK-STRICT: attributes #2 = { strictfp } >From 90f25cd15ea385361cc4958519d06bb3d9268964 Mon Sep 17 00:00:00 2001 From: YunQiang Su <yunqi...@isrc.iscas.ac.cn> Date: Tue, 22 Oct 2024 11:03:09 +0800 Subject: [PATCH 5/6] test auto vectorize --- clang/test/CodeGen/fmaxnum_fminnum_use_nsz.c | 60 +++++++++++++++++++- 1 file changed, 58 insertions(+), 2 deletions(-) diff --git a/clang/test/CodeGen/fmaxnum_fminnum_use_nsz.c b/clang/test/CodeGen/fmaxnum_fminnum_use_nsz.c index afe626d921125..4729fd6e27896 100644 --- a/clang/test/CodeGen/fmaxnum_fminnum_use_nsz.c +++ b/clang/test/CodeGen/fmaxnum_fminnum_use_nsz.c @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -triple x86_64 %s -emit-llvm -o - 2>&1 | FileCheck %s --check-prefix=CHECK -// RUN: %clang_cc1 -ffp-exception-behavior=strict -triple x86_64 %s -emit-llvm -o - 2>&1 | FileCheck %s --check-prefix=CHECK-STRICT +// RUN: %clang_cc1 -vectorize-loops -vectorize-slp -O3 -triple x86_64 %s -emit-llvm -o - 2>&1 | FileCheck %s --check-prefix=CHECK +// RUN: %clang_cc1 -vectorize-loops -vectorize-slp -O3 -ffp-exception-behavior=strict -DENSTRICT=1 -triple x86_64 %s -emit-llvm -o - 2>&1 | FileCheck %s --check-prefix=CHECK-STRICT float fminf (float, float); double fmin (double, double); @@ -18,6 +18,20 @@ float fmin32(float a, float b) { float fmin32b(float a, float b) { return __builtin_fminf(a, b); } +#if !defined(ENSTRICT) +// CHECK: call nsz <4 x float> @llvm.minnum.v4f32(<4 x float> %0, <4 x float> %1) +float *pfmin32(float* a, float* b, float* restrict c) { + for (int i=0; i<4; i++) + c[i] = fminf(a[i], b[i]); + return c; +} +// CHECK: call nsz <4 x float> @llvm.minnum.v4f32(<4 x float> %0, <4 x float> %1) +float *pfmin32b(float* a, float* b, float* restrict c) { + for (int i=0; i<4; i++) + c[i] = __builtin_fminf(a[i], b[i]); + return c; +} +#endif // CHECK: call nsz double @llvm.minnum.f64 // CHECK-STRICT: call nsz double @llvm.experimental.constrained.minnum.f64{{.*}} #2 float fmin64(double a, double b) { @@ -28,6 +42,20 @@ float fmin64(double a, double b) { float fmin64b(double a, double b) { return __builtin_fmin(a, b); } +#if !defined(ENSTRICT) +// CHECK: call nsz <2 x double> @llvm.minnum.v2f64(<2 x double> %0, <2 x double> %1) +double *pfmin64(double* a, double* b, double* restrict c) { + for (int i=0; i<2; i++) + c[i] = fmin(a[i], b[i]); + return c; +} +// CHECK: call nsz <2 x double> @llvm.minnum.v2f64(<2 x double> %0, <2 x double> %1) +double *pfmin64b(double* a, double* b, double* restrict c) { + for (int i=0; i<2; i++) + c[i] = __builtin_fmin(a[i], b[i]); + return c; +} +#endif // CHECK: call nsz x86_fp80 @llvm.minnum.f80 // CHECK-STRICT: call nsz x86_fp80 @llvm.experimental.constrained.minnum.f80{{.*}} #2 float fmin80(long double a, long double b) { @@ -48,6 +76,20 @@ float fmax32(float a, float b) { float fmax32b(float a, float b) { return __builtin_fmaxf(a, b); } +#if !defined(ENSTRICT) +// CHECK: call nsz <4 x float> @llvm.maxnum.v4f32(<4 x float> %0, <4 x float> %1) +float *pfmax32(float* a, float* b, float* restrict c) { + for (int i=0; i<4; i++) + c[i] = fmaxf(a[i], b[i]); + return c; +} +// CHECK: call nsz <4 x float> @llvm.maxnum.v4f32(<4 x float> %0, <4 x float> %1) +float *pfmax32b(float* a, float* b, float* restrict c) { + for (int i=0; i<4; i++) + c[i] = __builtin_fmaxf(a[i], b[i]); + return c; +} +#endif // CHECK: call nsz double @llvm.maxnum.f64 // CHECK-STRICT: call nsz double @llvm.experimental.constrained.maxnum.f64{{.*}} #2 float fmax64(double a, double b) { @@ -63,6 +105,20 @@ float fmax64b(double a, double b) { float fmax3(long double a, long double b) { return fmaxl(a, b); } +#if !defined(ENSTRICT) +// CHECK: call nsz <2 x double> @llvm.maxnum.v2f64(<2 x double> %0, <2 x double> %1) +double *pfmax64(double* a, double* b, double* restrict c) { + for (int i=0; i<2; i++) + c[i] = fmax(a[i], b[i]); + return c; +} +// CHECK: call nsz <2 x double> @llvm.maxnum.v2f64(<2 x double> %0, <2 x double> %1) +double *pfmax64b(double* a, double* b, double* restrict c) { + for (int i=0; i<2; i++) + c[i] = __builtin_fmax(a[i], b[i]); + return c; +} +#endif // CHECK: call nsz x86_fp80 @llvm.maxnum.f80 // CHECK-STRICT: call nsz x86_fp80 @llvm.experimental.constrained.maxnum.f80{{.*}} #2 float fmax80b(long double a, long double b) { >From 8655cb0793e8e0fad88e8a12ec7e225b60036791 Mon Sep 17 00:00:00 2001 From: YunQiang Su <yunqi...@isrc.iscas.ac.cn> Date: Wed, 23 Oct 2024 11:10:52 +0800 Subject: [PATCH 6/6] fix test cases --- clang/test/CodeGen/RISCV/math-builtins.c | 24 +++++++++---------- clang/test/CodeGen/builtins.c | 12 +++++----- .../test/CodeGen/constrained-math-builtins.c | 16 ++++++------- clang/test/CodeGen/math-builtins-long.c | 16 ++++++------- clang/test/CodeGenOpenCL/builtins-f16.cl | 4 ++-- .../amdgcn_openmp_device_math_constexpr.cpp | 8 +++---- 6 files changed, 40 insertions(+), 40 deletions(-) diff --git a/clang/test/CodeGen/RISCV/math-builtins.c b/clang/test/CodeGen/RISCV/math-builtins.c index 9630d62f0f482..e4f456c8eabd7 100644 --- a/clang/test/CodeGen/RISCV/math-builtins.c +++ b/clang/test/CodeGen/RISCV/math-builtins.c @@ -134,22 +134,22 @@ long double truncl(long double); // RV32-NEXT: [[TMP44:%.*]] = call fp128 @llvm.floor.f128(fp128 [[TMP43]]) // RV32-NEXT: [[TMP45:%.*]] = load float, ptr [[FARG_ADDR]], align 4 // RV32-NEXT: [[TMP46:%.*]] = load float, ptr [[FARG_ADDR]], align 4 -// RV32-NEXT: [[TMP47:%.*]] = call float @llvm.maxnum.f32(float [[TMP45]], float [[TMP46]]) +// RV32-NEXT: [[TMP47:%.*]] = call nsz float @llvm.maxnum.f32(float [[TMP45]], float [[TMP46]]) // RV32-NEXT: [[TMP48:%.*]] = load double, ptr [[DARG_ADDR]], align 8 // RV32-NEXT: [[TMP49:%.*]] = load double, ptr [[DARG_ADDR]], align 8 -// RV32-NEXT: [[TMP50:%.*]] = call double @llvm.maxnum.f64(double [[TMP48]], double [[TMP49]]) +// RV32-NEXT: [[TMP50:%.*]] = call nsz double @llvm.maxnum.f64(double [[TMP48]], double [[TMP49]]) // RV32-NEXT: [[TMP51:%.*]] = load fp128, ptr [[LDARG_ADDR]], align 16 // RV32-NEXT: [[TMP52:%.*]] = load fp128, ptr [[LDARG_ADDR]], align 16 -// RV32-NEXT: [[TMP53:%.*]] = call fp128 @llvm.maxnum.f128(fp128 [[TMP51]], fp128 [[TMP52]]) +// RV32-NEXT: [[TMP53:%.*]] = call nsz fp128 @llvm.maxnum.f128(fp128 [[TMP51]], fp128 [[TMP52]]) // RV32-NEXT: [[TMP54:%.*]] = load float, ptr [[FARG_ADDR]], align 4 // RV32-NEXT: [[TMP55:%.*]] = load float, ptr [[FARG_ADDR]], align 4 -// RV32-NEXT: [[TMP56:%.*]] = call float @llvm.minnum.f32(float [[TMP54]], float [[TMP55]]) +// RV32-NEXT: [[TMP56:%.*]] = call nsz float @llvm.minnum.f32(float [[TMP54]], float [[TMP55]]) // RV32-NEXT: [[TMP57:%.*]] = load double, ptr [[DARG_ADDR]], align 8 // RV32-NEXT: [[TMP58:%.*]] = load double, ptr [[DARG_ADDR]], align 8 -// RV32-NEXT: [[TMP59:%.*]] = call double @llvm.minnum.f64(double [[TMP57]], double [[TMP58]]) +// RV32-NEXT: [[TMP59:%.*]] = call nsz double @llvm.minnum.f64(double [[TMP57]], double [[TMP58]]) // RV32-NEXT: [[TMP60:%.*]] = load fp128, ptr [[LDARG_ADDR]], align 16 // RV32-NEXT: [[TMP61:%.*]] = load fp128, ptr [[LDARG_ADDR]], align 16 -// RV32-NEXT: [[TMP62:%.*]] = call fp128 @llvm.minnum.f128(fp128 [[TMP60]], fp128 [[TMP61]]) +// RV32-NEXT: [[TMP62:%.*]] = call nsz fp128 @llvm.minnum.f128(fp128 [[TMP60]], fp128 [[TMP61]]) // RV32-NEXT: [[TMP63:%.*]] = load float, ptr [[FARG_ADDR]], align 4 // RV32-NEXT: [[TMP64:%.*]] = load float, ptr [[FARG_ADDR]], align 4 // RV32-NEXT: [[FMOD:%.*]] = frem float [[TMP63]], [[TMP64]] @@ -310,22 +310,22 @@ long double truncl(long double); // RV64-NEXT: [[TMP44:%.*]] = call fp128 @llvm.floor.f128(fp128 [[TMP43]]) // RV64-NEXT: [[TMP45:%.*]] = load float, ptr [[FARG_ADDR]], align 4 // RV64-NEXT: [[TMP46:%.*]] = load float, ptr [[FARG_ADDR]], align 4 -// RV64-NEXT: [[TMP47:%.*]] = call float @llvm.maxnum.f32(float [[TMP45]], float [[TMP46]]) +// RV64-NEXT: [[TMP47:%.*]] = call nsz float @llvm.maxnum.f32(float [[TMP45]], float [[TMP46]]) // RV64-NEXT: [[TMP48:%.*]] = load double, ptr [[DARG_ADDR]], align 8 // RV64-NEXT: [[TMP49:%.*]] = load double, ptr [[DARG_ADDR]], align 8 -// RV64-NEXT: [[TMP50:%.*]] = call double @llvm.maxnum.f64(double [[TMP48]], double [[TMP49]]) +// RV64-NEXT: [[TMP50:%.*]] = call nsz double @llvm.maxnum.f64(double [[TMP48]], double [[TMP49]]) // RV64-NEXT: [[TMP51:%.*]] = load fp128, ptr [[LDARG_ADDR]], align 16 // RV64-NEXT: [[TMP52:%.*]] = load fp128, ptr [[LDARG_ADDR]], align 16 -// RV64-NEXT: [[TMP53:%.*]] = call fp128 @llvm.maxnum.f128(fp128 [[TMP51]], fp128 [[TMP52]]) +// RV64-NEXT: [[TMP53:%.*]] = call nsz fp128 @llvm.maxnum.f128(fp128 [[TMP51]], fp128 [[TMP52]]) // RV64-NEXT: [[TMP54:%.*]] = load float, ptr [[FARG_ADDR]], align 4 // RV64-NEXT: [[TMP55:%.*]] = load float, ptr [[FARG_ADDR]], align 4 -// RV64-NEXT: [[TMP56:%.*]] = call float @llvm.minnum.f32(float [[TMP54]], float [[TMP55]]) +// RV64-NEXT: [[TMP56:%.*]] = call nsz float @llvm.minnum.f32(float [[TMP54]], float [[TMP55]]) // RV64-NEXT: [[TMP57:%.*]] = load double, ptr [[DARG_ADDR]], align 8 // RV64-NEXT: [[TMP58:%.*]] = load double, ptr [[DARG_ADDR]], align 8 -// RV64-NEXT: [[TMP59:%.*]] = call double @llvm.minnum.f64(double [[TMP57]], double [[TMP58]]) +// RV64-NEXT: [[TMP59:%.*]] = call nsz double @llvm.minnum.f64(double [[TMP57]], double [[TMP58]]) // RV64-NEXT: [[TMP60:%.*]] = load fp128, ptr [[LDARG_ADDR]], align 16 // RV64-NEXT: [[TMP61:%.*]] = load fp128, ptr [[LDARG_ADDR]], align 16 -// RV64-NEXT: [[TMP62:%.*]] = call fp128 @llvm.minnum.f128(fp128 [[TMP60]], fp128 [[TMP61]]) +// RV64-NEXT: [[TMP62:%.*]] = call nsz fp128 @llvm.minnum.f128(fp128 [[TMP60]], fp128 [[TMP61]]) // RV64-NEXT: [[TMP63:%.*]] = load float, ptr [[FARG_ADDR]], align 4 // RV64-NEXT: [[TMP64:%.*]] = load float, ptr [[FARG_ADDR]], align 4 // RV64-NEXT: [[FMOD:%.*]] = frem float [[TMP63]], [[TMP64]] diff --git a/clang/test/CodeGen/builtins.c b/clang/test/CodeGen/builtins.c index eda6c67fdad00..72e195e82d424 100644 --- a/clang/test/CodeGen/builtins.c +++ b/clang/test/CodeGen/builtins.c @@ -343,22 +343,22 @@ void test_float_builtin_ops(float F, double D, long double LD, int I) { // CHECK: call x86_fp80 @llvm.canonicalize.f80(x86_fp80 resf = __builtin_fminf(F, F); - // CHECK: call float @llvm.minnum.f32 + // CHECK: call nsz float @llvm.minnum.f32 resd = __builtin_fmin(D, D); - // CHECK: call double @llvm.minnum.f64 + // CHECK: call nsz double @llvm.minnum.f64 resld = __builtin_fminl(LD, LD); - // CHECK: call x86_fp80 @llvm.minnum.f80 + // CHECK: call nsz x86_fp80 @llvm.minnum.f80 resf = __builtin_fmaxf(F, F); - // CHECK: call float @llvm.maxnum.f32 + // CHECK: call nsz float @llvm.maxnum.f32 resd = __builtin_fmax(D, D); - // CHECK: call double @llvm.maxnum.f64 + // CHECK: call nsz double @llvm.maxnum.f64 resld = __builtin_fmaxl(LD, LD); - // CHECK: call x86_fp80 @llvm.maxnum.f80 + // CHECK: call nsz x86_fp80 @llvm.maxnum.f80 resf = __builtin_fminimum_numf(F, F); // CHECK: call float @llvm.minimumnum.f32 diff --git a/clang/test/CodeGen/constrained-math-builtins.c b/clang/test/CodeGen/constrained-math-builtins.c index aa77620b44535..3f3da8b6b0818 100644 --- a/clang/test/CodeGen/constrained-math-builtins.c +++ b/clang/test/CodeGen/constrained-math-builtins.c @@ -116,17 +116,17 @@ __builtin_atan(f); __builtin_atanf(f); __builtin_atanl(f); __builti __builtin_fmax(f,f); __builtin_fmaxf(f,f); __builtin_fmaxl(f,f); __builtin_fmaxf128(f,f); -// CHECK: call double @llvm.experimental.constrained.maxnum.f64(double %{{.*}}, double %{{.*}}, metadata !"fpexcept.strict") -// CHECK: call float @llvm.experimental.constrained.maxnum.f32(float %{{.*}}, float %{{.*}}, metadata !"fpexcept.strict") -// CHECK: call x86_fp80 @llvm.experimental.constrained.maxnum.f80(x86_fp80 %{{.*}}, x86_fp80 %{{.*}}, metadata !"fpexcept.strict") -// CHECK: call fp128 @llvm.experimental.constrained.maxnum.f128(fp128 %{{.*}}, fp128 %{{.*}}, metadata !"fpexcept.strict") +// CHECK: call nsz double @llvm.experimental.constrained.maxnum.f64(double %{{.*}}, double %{{.*}}, metadata !"fpexcept.strict") +// CHECK: call nsz float @llvm.experimental.constrained.maxnum.f32(float %{{.*}}, float %{{.*}}, metadata !"fpexcept.strict") +// CHECK: call nsz x86_fp80 @llvm.experimental.constrained.maxnum.f80(x86_fp80 %{{.*}}, x86_fp80 %{{.*}}, metadata !"fpexcept.strict") +// CHECK: call nsz fp128 @llvm.experimental.constrained.maxnum.f128(fp128 %{{.*}}, fp128 %{{.*}}, metadata !"fpexcept.strict") __builtin_fmin(f,f); __builtin_fminf(f,f); __builtin_fminl(f,f); __builtin_fminf128(f,f); -// CHECK: call double @llvm.experimental.constrained.minnum.f64(double %{{.*}}, double %{{.*}}, metadata !"fpexcept.strict") -// CHECK: call float @llvm.experimental.constrained.minnum.f32(float %{{.*}}, float %{{.*}}, metadata !"fpexcept.strict") -// CHECK: call x86_fp80 @llvm.experimental.constrained.minnum.f80(x86_fp80 %{{.*}}, x86_fp80 %{{.*}}, metadata !"fpexcept.strict") -// CHECK: call fp128 @llvm.experimental.constrained.minnum.f128(fp128 %{{.*}}, fp128 %{{.*}}, metadata !"fpexcept.strict") +// CHECK: call nsz double @llvm.experimental.constrained.minnum.f64(double %{{.*}}, double %{{.*}}, metadata !"fpexcept.strict") +// CHECK: call nsz float @llvm.experimental.constrained.minnum.f32(float %{{.*}}, float %{{.*}}, metadata !"fpexcept.strict") +// CHECK: call nsz x86_fp80 @llvm.experimental.constrained.minnum.f80(x86_fp80 %{{.*}}, x86_fp80 %{{.*}}, metadata !"fpexcept.strict") +// CHECK: call nsz fp128 @llvm.experimental.constrained.minnum.f128(fp128 %{{.*}}, fp128 %{{.*}}, metadata !"fpexcept.strict") __builtin_llrint(f); __builtin_llrintf(f); __builtin_llrintl(f); __builtin_llrintf128(f); diff --git a/clang/test/CodeGen/math-builtins-long.c b/clang/test/CodeGen/math-builtins-long.c index 183349e0f0173..f1e4988e37871 100644 --- a/clang/test/CodeGen/math-builtins-long.c +++ b/clang/test/CodeGen/math-builtins-long.c @@ -148,16 +148,16 @@ void foo(long double f, long double *l, int *i, const char *c) { // PPCF128: call fp128 @llvm.floor.f128(fp128 %{{.+}}) __builtin_floorl(f); - // F80: call x86_fp80 @llvm.maxnum.f80(x86_fp80 %{{.+}}, x86_fp80 %{{.+}}) - // PPC: call ppc_fp128 @llvm.maxnum.ppcf128(ppc_fp128 %{{.+}}, ppc_fp128 %{{.+}}) - // X86F128: call fp128 @llvm.maxnum.f128(fp128 %{{.+}}, fp128 %{{.+}}) - // PPCF128: call fp128 @llvm.maxnum.f128(fp128 %{{.+}}, fp128 %{{.+}}) + // F80: call nsz x86_fp80 @llvm.maxnum.f80(x86_fp80 %{{.+}}, x86_fp80 %{{.+}}) + // PPC: call nsz ppc_fp128 @llvm.maxnum.ppcf128(ppc_fp128 %{{.+}}, ppc_fp128 %{{.+}}) + // X86F128: call nsz fp128 @llvm.maxnum.f128(fp128 %{{.+}}, fp128 %{{.+}}) + // PPCF128: call nsz fp128 @llvm.maxnum.f128(fp128 %{{.+}}, fp128 %{{.+}}) __builtin_fmaxl(f,f); - // F80: call x86_fp80 @llvm.minnum.f80(x86_fp80 %{{.+}}, x86_fp80 %{{.+}}) - // PPC: call ppc_fp128 @llvm.minnum.ppcf128(ppc_fp128 %{{.+}}, ppc_fp128 %{{.+}}) - // X86F128: call fp128 @llvm.minnum.f128(fp128 %{{.+}}, fp128 %{{.+}}) - // PPCF128: call fp128 @llvm.minnum.f128(fp128 %{{.+}}, fp128 %{{.+}}) + // F80: call nsz x86_fp80 @llvm.minnum.f80(x86_fp80 %{{.+}}, x86_fp80 %{{.+}}) + // PPC: call nsz ppc_fp128 @llvm.minnum.ppcf128(ppc_fp128 %{{.+}}, ppc_fp128 %{{.+}}) + // X86F128: call nsz fp128 @llvm.minnum.f128(fp128 %{{.+}}, fp128 %{{.+}}) + // PPCF128: call nsz fp128 @llvm.minnum.f128(fp128 %{{.+}}, fp128 %{{.+}}) __builtin_fminl(f,f); // F80: call x86_fp80 @llvm.nearbyint.f80(x86_fp80 %{{.+}}) diff --git a/clang/test/CodeGenOpenCL/builtins-f16.cl b/clang/test/CodeGenOpenCL/builtins-f16.cl index 8150bc1ac9e2d..d519be230c343 100644 --- a/clang/test/CodeGenOpenCL/builtins-f16.cl +++ b/clang/test/CodeGenOpenCL/builtins-f16.cl @@ -45,10 +45,10 @@ void test_half_builtins(half h0, half h1, half h2, int i0) { // CHECK: call half @llvm.fma.f16(half %h0, half %h1, half %h2) res = __builtin_fmaf16(h0, h1 ,h2); - // CHECK: call half @llvm.maxnum.f16(half %h0, half %h1) + // CHECK: call nsz half @llvm.maxnum.f16(half %h0, half %h1) res = __builtin_fmaxf16(h0, h1); - // CHECK: call half @llvm.minnum.f16(half %h0, half %h1) + // CHECK: call nsz half @llvm.minnum.f16(half %h0, half %h1) res = __builtin_fminf16(h0, h1); // CHECK: frem half %h0, %h1 diff --git a/clang/test/Headers/amdgcn_openmp_device_math_constexpr.cpp b/clang/test/Headers/amdgcn_openmp_device_math_constexpr.cpp index 0fdc02edc1508..855333132c4de 100644 --- a/clang/test/Headers/amdgcn_openmp_device_math_constexpr.cpp +++ b/clang/test/Headers/amdgcn_openmp_device_math_constexpr.cpp @@ -208,7 +208,7 @@ const float constexpr_fmaxf_f32 = fmaxf(2.0f, -4.0f); // CHECK-NEXT: store float -4.000000e+00, ptr [[__Y_ADDR_ASCAST_I]], align 4 // CHECK-NEXT: [[TMP0:%.*]] = load float, ptr [[__X_ADDR_ASCAST_I]], align 4 // CHECK-NEXT: [[TMP1:%.*]] = load float, ptr [[__Y_ADDR_ASCAST_I]], align 4 -// CHECK-NEXT: [[TMP2:%.*]] = call noundef float @llvm.minnum.f32(float [[TMP0]], float [[TMP1]]) +// CHECK-NEXT: [[TMP2:%.*]] = call nsz noundef float @llvm.minnum.f32(float [[TMP0]], float [[TMP1]]) // CHECK-NEXT: store float [[TMP2]], ptr addrspacecast (ptr addrspace(1) @_ZL17constexpr_min_f32 to ptr), align 4 // CHECK-NEXT: ret void // @@ -226,7 +226,7 @@ const float constexpr_fmaxf_f32 = fmaxf(2.0f, -4.0f); // CHECK-NEXT: store float -4.000000e+00, ptr [[__Y_ADDR_ASCAST_I]], align 4 // CHECK-NEXT: [[TMP0:%.*]] = load float, ptr [[__X_ADDR_ASCAST_I]], align 4 // CHECK-NEXT: [[TMP1:%.*]] = load float, ptr [[__Y_ADDR_ASCAST_I]], align 4 -// CHECK-NEXT: [[TMP2:%.*]] = call noundef float @llvm.maxnum.f32(float [[TMP0]], float [[TMP1]]) +// CHECK-NEXT: [[TMP2:%.*]] = call nsz noundef float @llvm.maxnum.f32(float [[TMP0]], float [[TMP1]]) // CHECK-NEXT: store float [[TMP2]], ptr addrspacecast (ptr addrspace(1) @_ZL17constexpr_max_f32 to ptr), align 4 // CHECK-NEXT: ret void // @@ -260,7 +260,7 @@ const float constexpr_fmaxf_f32 = fmaxf(2.0f, -4.0f); // CHECK-NEXT: store float -4.000000e+00, ptr [[__Y_ADDR_ASCAST_I]], align 4 // CHECK-NEXT: [[TMP0:%.*]] = load float, ptr [[__X_ADDR_ASCAST_I]], align 4 // CHECK-NEXT: [[TMP1:%.*]] = load float, ptr [[__Y_ADDR_ASCAST_I]], align 4 -// CHECK-NEXT: [[TMP2:%.*]] = call noundef float @llvm.minnum.f32(float [[TMP0]], float [[TMP1]]) +// CHECK-NEXT: [[TMP2:%.*]] = call nsz noundef float @llvm.minnum.f32(float [[TMP0]], float [[TMP1]]) // CHECK-NEXT: store float [[TMP2]], ptr addrspacecast (ptr addrspace(1) @_ZL19constexpr_fminf_f32 to ptr), align 4 // CHECK-NEXT: ret void // @@ -278,7 +278,7 @@ const float constexpr_fmaxf_f32 = fmaxf(2.0f, -4.0f); // CHECK-NEXT: store float -4.000000e+00, ptr [[__Y_ADDR_ASCAST_I]], align 4 // CHECK-NEXT: [[TMP0:%.*]] = load float, ptr [[__X_ADDR_ASCAST_I]], align 4 // CHECK-NEXT: [[TMP1:%.*]] = load float, ptr [[__Y_ADDR_ASCAST_I]], align 4 -// CHECK-NEXT: [[TMP2:%.*]] = call noundef float @llvm.maxnum.f32(float [[TMP0]], float [[TMP1]]) +// CHECK-NEXT: [[TMP2:%.*]] = call nsz noundef float @llvm.maxnum.f32(float [[TMP0]], float [[TMP1]]) // CHECK-NEXT: store float [[TMP2]], ptr addrspacecast (ptr addrspace(1) @_ZL19constexpr_fmaxf_f32 to ptr), align 4 // CHECK-NEXT: ret void // _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits