Index: include/llvm/IR/IRBuilder.h =================================================================== --- include/llvm/IR/IRBuilder.h +++ include/llvm/IR/IRBuilder.h @@ -960,6 +960,30 @@ return (LC && RC) ? Insert(Folder.CreateBinOp(Opc, LC, RC), Name) : nullptr; } + Value *getConstrainedRounding(MDNode *RoundingMD) { + MDString *Rounding = nullptr; + + if (RoundingMD) + Rounding = cast(RoundingMD->getOperand(0)); + + if (!Rounding) + Rounding = MDString::get(Context, "round.dynamic"); + + return MetadataAsValue::get(Context, Rounding); + } + + Value *getConstrainedExcept(MDNode *ExceptMD) { + MDString *Except = nullptr; + + if (ExceptMD) + Except = cast(ExceptMD->getOperand(0)); + + if (!Except) + Except = MDString::get(Context, "fpexcept.strict"); + + return MetadataAsValue::get(Context, Except); + } + public: Value *CreateAdd(Value *LHS, Value *RHS, const Twine &Name = "", bool HasNUW = false, bool HasNSW = false) { @@ -1177,6 +1201,19 @@ return Insert(I, Name); } + Value *CreateConstrainedFAdd(Value *L, Value *R, const Twine &Name = "", + MDNode *RoundingMD = nullptr, MDNode *ExceptMD = nullptr) { + + Value *Rounding = getConstrainedRounding(RoundingMD); + Value *Except = getConstrainedExcept(ExceptMD); + + Value *F = Intrinsic::getDeclaration( + BB->getModule(), Intrinsic::experimental_constrained_fadd, + {L->getType()}); + + return CreateCall(F, { L, R, Rounding, Except }, Name); + } + Value *CreateFSub(Value *L, Value *R, const Twine &Name = "", MDNode *FPMD = nullptr) { if (Value *V = foldConstant(Instruction::FSub, L, R, Name)) return V; @@ -1194,6 +1231,19 @@ return Insert(I, Name); } + Value *CreateConstrainedFSub(Value *L, Value *R, const Twine &Name = "", + MDNode *RoundingMD = nullptr, MDNode *ExceptMD = nullptr) { + + Value *Rounding = getConstrainedRounding(RoundingMD); + Value *Except = getConstrainedExcept(ExceptMD); + + Value *F = Intrinsic::getDeclaration( + BB->getModule(), Intrinsic::experimental_constrained_fsub, + {L->getType()}); + + return CreateCall(F, { L, R, Rounding, Except }); + } + Value *CreateFMul(Value *L, Value *R, const Twine &Name = "", MDNode *FPMD = nullptr) { if (Value *V = foldConstant(Instruction::FMul, L, R, Name)) return V; @@ -1211,6 +1261,19 @@ return Insert(I, Name); } + Value *CreateConstrainedFMul(Value *L, Value *R, const Twine &Name = "", + MDNode *RoundingMD = nullptr, MDNode *ExceptMD = nullptr) { + + Value *Rounding = getConstrainedRounding(RoundingMD); + Value *Except = getConstrainedExcept(ExceptMD); + + Value *F = Intrinsic::getDeclaration( + BB->getModule(), Intrinsic::experimental_constrained_fmul, + {L->getType()}); + + return CreateCall(F, { L, R, Rounding, Except }); + } + Value *CreateFDiv(Value *L, Value *R, const Twine &Name = "", MDNode *FPMD = nullptr) { if (Value *V = foldConstant(Instruction::FDiv, L, R, Name)) return V; @@ -1228,6 +1291,19 @@ return Insert(I, Name); } + Value *CreateConstrainedFDiv(Value *L, Value *R, const Twine &Name = "", + MDNode *RoundingMD = nullptr, MDNode *ExceptMD = nullptr) { + + Value *Rounding = getConstrainedRounding(RoundingMD); + Value *Except = getConstrainedExcept(ExceptMD); + + Value *F = Intrinsic::getDeclaration( + BB->getModule(), Intrinsic::experimental_constrained_fdiv, + {L->getType()}); + + return CreateCall(F, { L, R, Rounding, Except }); + } + Value *CreateFRem(Value *L, Value *R, const Twine &Name = "", MDNode *FPMD = nullptr) { if (Value *V = foldConstant(Instruction::FRem, L, R, Name)) return V; @@ -1245,6 +1321,19 @@ return Insert(I, Name); } + Value *CreateConstrainedFRem(Value *L, Value *R, const Twine &Name = "", + MDNode *RoundingMD = nullptr, MDNode *ExceptMD = nullptr) { + + Value *Rounding = getConstrainedRounding(RoundingMD); + Value *Except = getConstrainedExcept(ExceptMD); + + Value *F = Intrinsic::getDeclaration( + BB->getModule(), Intrinsic::experimental_constrained_frem, + {L->getType()}); + + return CreateCall(F, { L, R, Rounding, Except }); + } + Value *CreateBinOp(Instruction::BinaryOps Opc, Value *LHS, Value *RHS, const Twine &Name = "", MDNode *FPMathTag = nullptr) {