diff --git a/llvm/include/llvm/IR/IRBuilder.h b/llvm/include/llvm/IR/IRBuilder.h index ebce038201d95..28380a3f606f2 100644 --- a/llvm/include/llvm/IR/IRBuilder.h +++ b/llvm/include/llvm/IR/IRBuilder.h @@ -956,11 +956,21 @@ class IRBuilderBase { /// Create call to the minnum intrinsic. CallInst *CreateMinNum(Value *LHS, Value *RHS, const Twine &Name = "") { + if (IsFPConstrained) { + return CreateConstrainedFPUnroundedBinOp( + Intrinsic::experimental_constrained_minnum, LHS, RHS, nullptr, Name); + } + return CreateBinaryIntrinsic(Intrinsic::minnum, LHS, RHS, nullptr, Name); } /// Create call to the maxnum intrinsic. CallInst *CreateMaxNum(Value *LHS, Value *RHS, const Twine &Name = "") { + if (IsFPConstrained) { + return CreateConstrainedFPUnroundedBinOp( + Intrinsic::experimental_constrained_maxnum, LHS, RHS, nullptr, Name); + } + return CreateBinaryIntrinsic(Intrinsic::maxnum, LHS, RHS, nullptr, Name); } @@ -1658,6 +1668,11 @@ class IRBuilderBase { std::optional Rounding = std::nullopt, std::optional Except = std::nullopt); + CallInst *CreateConstrainedFPUnroundedBinOp( + Intrinsic::ID ID, Value *L, Value *R, Instruction *FMFSource = nullptr, + const Twine &Name = "", MDNode *FPMathTag = nullptr, + std::optional Except = std::nullopt); + Value *CreateNeg(Value *V, const Twine &Name = "", bool HasNUW = false, bool HasNSW = false) { return CreateSub(Constant::getNullValue(V->getType()), V, Name, HasNUW, diff --git a/llvm/lib/IR/IRBuilder.cpp b/llvm/lib/IR/IRBuilder.cpp index 491065dea29ff..a015073f9b367 100644 --- a/llvm/lib/IR/IRBuilder.cpp +++ b/llvm/lib/IR/IRBuilder.cpp @@ -1032,6 +1032,23 @@ CallInst *IRBuilderBase::CreateConstrainedFPBinOp( return C; } +CallInst *IRBuilderBase::CreateConstrainedFPUnroundedBinOp( + Intrinsic::ID ID, Value *L, Value *R, Instruction *FMFSource, + const Twine &Name, MDNode *FPMathTag, + std::optional Except) { + Value *ExceptV = getConstrainedFPExcept(Except); + + FastMathFlags UseFMF = FMF; + if (FMFSource) + UseFMF = FMFSource->getFastMathFlags(); + + CallInst *C = + CreateIntrinsic(ID, {L->getType()}, {L, R, ExceptV}, nullptr, Name); + setConstrainedFPCallAttr(C); + setFPAttrs(C, FPMathTag, UseFMF); + return C; +} + Value *IRBuilderBase::CreateNAryOp(unsigned Opc, ArrayRef Ops, const Twine &Name, MDNode *FPMathTag) { if (Instruction::isBinaryOp(Opc)) { diff --git a/llvm/test/Transforms/AtomicExpand/AMDGPU/expand-atomic-rmw-fmax.ll b/llvm/test/Transforms/AtomicExpand/AMDGPU/expand-atomic-rmw-fmax.ll index 12441d3009bc1..5c4462caafb84 100644 --- a/llvm/test/Transforms/AtomicExpand/AMDGPU/expand-atomic-rmw-fmax.ll +++ b/llvm/test/Transforms/AtomicExpand/AMDGPU/expand-atomic-rmw-fmax.ll @@ -268,7 +268,7 @@ define double @test_atomicrmw_fmax_f64_global_strictfp(ptr addrspace(1) %ptr, do ; GCN-NEXT: br label [[ATOMICRMW_START:%.*]] ; GCN: atomicrmw.start: ; GCN-NEXT: [[LOADED:%.*]] = phi double [ [[TMP1]], [[TMP0:%.*]] ], [ [[TMP6:%.*]], [[ATOMICRMW_START]] ] -; GCN-NEXT: [[TMP2:%.*]] = call double @llvm.maxnum.f64(double [[LOADED]], double [[VALUE:%.*]]) #[[ATTR3:[0-9]+]] +; GCN-NEXT: [[TMP2:%.*]] = call double @llvm.experimental.constrained.maxnum.f64(double [[LOADED]], double [[VALUE:%.*]], metadata !"fpexcept.strict") #[[ATTR4:[0-9]+]] ; GCN-NEXT: [[TMP3:%.*]] = bitcast double [[TMP2]] to i64 ; GCN-NEXT: [[TMP4:%.*]] = bitcast double [[LOADED]] to i64 ; GCN-NEXT: [[TMP5:%.*]] = cmpxchg ptr addrspace(1) [[PTR]], i64 [[TMP4]], i64 [[TMP3]] seq_cst seq_cst, align 8 diff --git a/llvm/test/Transforms/AtomicExpand/AMDGPU/expand-atomic-rmw-fmin.ll b/llvm/test/Transforms/AtomicExpand/AMDGPU/expand-atomic-rmw-fmin.ll index 3eda559f83fdd..0e32489286a16 100644 --- a/llvm/test/Transforms/AtomicExpand/AMDGPU/expand-atomic-rmw-fmin.ll +++ b/llvm/test/Transforms/AtomicExpand/AMDGPU/expand-atomic-rmw-fmin.ll @@ -268,7 +268,7 @@ define double @test_atomicrmw_fmin_f64_global_strictfp(ptr addrspace(1) %ptr, do ; GCN-NEXT: br label [[ATOMICRMW_START:%.*]] ; GCN: atomicrmw.start: ; GCN-NEXT: [[LOADED:%.*]] = phi double [ [[TMP1]], [[TMP0:%.*]] ], [ [[TMP6:%.*]], [[ATOMICRMW_START]] ] -; GCN-NEXT: [[TMP2:%.*]] = call double @llvm.minnum.f64(double [[LOADED]], double [[VALUE:%.*]]) +; GCN-NEXT: [[TMP2:%.*]] = call double @llvm.experimental.constrained.minnum.f64(double [[LOADED]], double [[VALUE:%.*]], metadata !"fpexcept.strict") #[[ATTR4:[0-9]+]] ; GCN-NEXT: [[TMP3:%.*]] = bitcast double [[TMP2]] to i64 ; GCN-NEXT: [[TMP4:%.*]] = bitcast double [[LOADED]] to i64 ; GCN-NEXT: [[TMP5:%.*]] = cmpxchg ptr addrspace(1) [[PTR]], i64 [[TMP4]], i64 [[TMP3]] seq_cst seq_cst, align 8