diff --git a/llvm/docs/ReleaseNotes.md b/llvm/docs/ReleaseNotes.md index 79d93d08b8398..15c9aaf3b129b 100644 --- a/llvm/docs/ReleaseNotes.md +++ b/llvm/docs/ReleaseNotes.md @@ -147,6 +147,7 @@ Changes to the C API -------------------- * Add `LLVMGetOrInsertFunction` to get or insert a function, replacing the combination of `LLVMGetNamedFunction` and `LLVMAddFunction`. +* Add `LLVMBuildMinNum` and `LLVMBuildMaxNum` to create calls to the `minnum` and `maxnum` intrinsics. Changes to the CodeGen infrastructure ------------------------------------- diff --git a/llvm/include/llvm-c/Core.h b/llvm/include/llvm-c/Core.h index 3d22f85911e78..2d66050b5acfa 100644 --- a/llvm/include/llvm-c/Core.h +++ b/llvm/include/llvm-c/Core.h @@ -4626,6 +4626,26 @@ LLVM_C_ABI LLVMValueRef LLVMBuildFNeg(LLVMBuilderRef, LLVMValueRef V, LLVM_C_ABI LLVMValueRef LLVMBuildNot(LLVMBuilderRef, LLVMValueRef V, const char *Name); +/** + * Creates and inserts a minnum intrinsic intruction. + * + * Returns the minimum of the two floating point values. + * + * @see llvm::IRBuilder::CreateMinNum() + */ +LLVM_C_ABI LLVMValueRef LLVMBuildMinNum(LLVMBuilderRef B, LLVMValueRef LHS, + LLVMValueRef RHS); + +/** + * Creates and inserts a maxnum intrinsic intruction. + * + * Returns the maximum of the two floating point values. + * + * @see llvm::IRBuilder::CreateMaxNum() + */ +LLVM_C_ABI LLVMValueRef LLVMBuildMaxNum(LLVMBuilderRef B, LLVMValueRef LHS, + LLVMValueRef RHS); + LLVM_C_ABI LLVMBool LLVMGetNUW(LLVMValueRef ArithInst); LLVM_C_ABI void LLVMSetNUW(LLVMValueRef ArithInst, LLVMBool HasNUW); LLVM_C_ABI LLVMBool LLVMGetNSW(LLVMValueRef ArithInst); diff --git a/llvm/lib/IR/Core.cpp b/llvm/lib/IR/Core.cpp index 3f1cc1e4e6d0e..d0285fb4516fa 100644 --- a/llvm/lib/IR/Core.cpp +++ b/llvm/lib/IR/Core.cpp @@ -3804,6 +3804,16 @@ LLVMValueRef LLVMBuildNot(LLVMBuilderRef B, LLVMValueRef V, const char *Name) { return wrap(unwrap(B)->CreateNot(unwrap(V), Name)); } +LLVMValueRef LLVMBuildMinNum(LLVMBuilderRef B, LLVMValueRef LHS, + LLVMValueRef RHS) { + return wrap(unwrap(B)->CreateMinNum(unwrap(LHS), unwrap(RHS))); +} + +LLVMValueRef LLVMBuildMaxNum(LLVMBuilderRef B, LLVMValueRef LHS, + LLVMValueRef RHS) { + return wrap(unwrap(B)->CreateMaxNum(unwrap(LHS), unwrap(RHS))); +} + LLVMBool LLVMGetNUW(LLVMValueRef ArithInst) { Value *P = unwrap(ArithInst); return cast(P)->hasNoUnsignedWrap(); diff --git a/llvm/unittests/IR/InstructionsTest.cpp b/llvm/unittests/IR/InstructionsTest.cpp index fe9e7e8228490..cb79a14d0ee7f 100644 --- a/llvm/unittests/IR/InstructionsTest.cpp +++ b/llvm/unittests/IR/InstructionsTest.cpp @@ -1933,5 +1933,28 @@ TEST(InstructionsTest, StripAndAccumulateConstantOffset) { EXPECT_TRUE(Offset.isZero()); } +TEST(InstructionsTest, LLVMBuildMinMaxNum) { + LLVMContext Ctx; + Module M("Mod", Ctx); + FunctionType *FT = FunctionType::get(Type::getVoidTy(Ctx), {}, false); + Function *F = Function::Create(FT, Function::ExternalLinkage, "f", M); + BasicBlock *BB = BasicBlock::Create(Ctx, "entry", F); + IRBuilder<> B(BB); + + Type *FTy = B.getFloatTy(); + Value *LHS = ConstantFP::get(FTy, 1.0); + Value *RHS = ConstantFP::get(FTy, 2.0); + + auto *Min = unwrap(LLVMBuildMinNum(wrap(&B), wrap(LHS), wrap(RHS))); + Function *MinFunc = Min->getCalledFunction(); + EXPECT_EQ(MinFunc->getIntrinsicID(), Intrinsic::minnum); + EXPECT_EQ(Min->getType(), FTy); + + auto *Max = unwrap(LLVMBuildMaxNum(wrap(&B), wrap(LHS), wrap(RHS))); + Function *MaxFunc = Max->getCalledFunction(); + EXPECT_EQ(MaxFunc->getIntrinsicID(), Intrinsic::maxnum); + EXPECT_EQ(Max->getType(), FTy); +} + } // end anonymous namespace } // end namespace llvm