14#ifndef LLVM_IR_FIXEDPOINTBUILDER_H
15#define LLVM_IR_FIXEDPOINTBUILDER_H
37 unsigned SrcWidth = SrcSema.
getWidth();
38 unsigned DstWidth = DstSema.
getWidth();
39 unsigned SrcScale = SrcSema.
getScale();
40 unsigned DstScale = DstSema.
getScale();
41 bool SrcIsSigned = SrcSema.
isSigned();
42 bool DstIsSigned = DstSema.
isSigned();
44 Type *DstIntTy = B.getIntNTy(DstWidth);
47 unsigned ResultWidth = SrcWidth;
50 if (DstScale < SrcScale) {
54 if (DstIsInteger && SrcIsSigned) {
56 Value *IsNegative = B.CreateICmpSLT(Result, Zero);
57 Value *LowBits = ConstantInt::get(
59 Value *Rounded = B.CreateAdd(Result, LowBits);
60 Result = B.CreateSelect(IsNegative, Rounded, Result);
64 ? B.CreateAShr(Result, SrcScale - DstScale,
"downscale")
65 : B.CreateLShr(Result, SrcScale - DstScale,
"downscale");
70 Result = B.CreateIntCast(Result, DstIntTy, SrcIsSigned,
"resize");
73 if (DstScale > SrcScale)
74 Result = B.CreateShl(Result, DstScale - SrcScale,
"upscale");
77 if (DstScale > SrcScale) {
79 ResultWidth = std::max(SrcWidth + DstScale - SrcScale, DstWidth);
80 Type *UpscaledTy = B.getIntNTy(ResultWidth);
81 Result = B.CreateIntCast(Result, UpscaledTy, SrcIsSigned,
"resize");
82 Result = B.CreateShl(Result, DstScale - SrcScale,
"upscale");
88 Value *Max = ConstantInt::get(
91 Value *TooHigh = SrcIsSigned ? B.CreateICmpSGT(Result, Max)
92 : B.CreateICmpUGT(Result, Max);
93 Result = B.CreateSelect(TooHigh, Max, Result,
"satmax");
97 if (SrcIsSigned && (LessIntBits || !DstIsSigned)) {
98 Value *Min = ConstantInt::get(
101 Value *TooLow = B.CreateICmpSLT(Result, Min);
102 Result = B.CreateSelect(TooLow, Min, Result,
"satmin");
106 if (ResultWidth != DstWidth)
107 Result = B.CreateIntCast(Result, DstIntTy, SrcIsSigned,
"resize");
121 C.getWidth() + (
unsigned)(BothPadded &&
C.isSaturated()),
C.getScale(),
122 C.isSigned(),
C.isSaturated(), BothPadded);
145 return Convert(Src, SrcSema, DstSema,
false);
155 unsigned DstWidth,
bool DstIsSigned) {
170 Src->getType()->getScalarSizeInBits(), SrcIsSigned),
177 Type *OpTy = getAccommodatingFloatType(DstTy, SrcSema);
180 Result = SrcSema.
isSigned() ? B.CreateSIToFP(Src, OpTy)
181 : B.CreateUIToFP(Src, OpTy);
184 Result = B.CreateFMul(Result,
185 ConstantFP::get(OpTy, std::pow(2, -(
int)SrcSema.
getScale())));
187 Result = B.CreateFPTrunc(Result, DstTy);
194 Type *OpTy = getAccommodatingFloatType(Src->getType(), DstSema);
195 if (OpTy != Src->getType())
196 Result = B.CreateFPExt(Result, OpTy);
199 Result = B.CreateFMul(Result,
200 ConstantFP::get(OpTy, std::pow(2, DstSema.
getScale())));
205 UseSigned ? Intrinsic::fptosi_sat : Intrinsic::fptoui_sat;
206 Result = B.CreateIntrinsic(IID, {ResultTy, OpTy}, {Result});
208 Result = UseSigned ? B.CreateFPToSI(Result, ResultTy)
209 : B.CreateFPToUI(Result, ResultTy);
217 B.CreateSelect(B.CreateICmpSLT(Result, Zero), Zero, Result,
"satmin");
230 auto CommonSema = getCommonBinopSemantic(LHSSema, RHSSema);
231 bool UseSigned = CommonSema.isSigned() || CommonSema.hasUnsignedPadding();
237 if (CommonSema.isSaturated()) {
238 Intrinsic::ID IID = UseSigned ? Intrinsic::sadd_sat : Intrinsic::uadd_sat;
239 Result = B.CreateBinaryIntrinsic(IID, WideLHS, WideRHS);
241 Result = B.CreateAdd(WideLHS, WideRHS);
256 auto CommonSema = getCommonBinopSemantic(LHSSema, RHSSema);
257 bool UseSigned = CommonSema.isSigned() || CommonSema.hasUnsignedPadding();
263 if (CommonSema.isSaturated()) {
264 Intrinsic::ID IID = UseSigned ? Intrinsic::ssub_sat : Intrinsic::usub_sat;
265 Result = B.CreateBinaryIntrinsic(IID, WideLHS, WideRHS);
267 Result = B.CreateSub(WideLHS, WideRHS);
272 if (CommonSema.isSaturated() && CommonSema.hasUnsignedPadding()) {
275 B.CreateSelect(B.CreateICmpSLT(Result, Zero), Zero, Result,
"satmin");
290 auto CommonSema = getCommonBinopSemantic(LHSSema, RHSSema);
291 bool UseSigned = CommonSema.isSigned() || CommonSema.hasUnsignedPadding();
297 if (CommonSema.isSaturated()) {
298 IID = UseSigned ? Intrinsic::smul_fix_sat : Intrinsic::umul_fix_sat;
300 IID = UseSigned ? Intrinsic::smul_fix : Intrinsic::umul_fix;
302 Value *Result = B.CreateIntrinsic(
304 {WideLHS, WideRHS, B.getInt32(CommonSema.getScale())});
318 auto CommonSema = getCommonBinopSemantic(LHSSema, RHSSema);
319 bool UseSigned = CommonSema.isSigned() || CommonSema.hasUnsignedPadding();
325 if (CommonSema.isSaturated()) {
326 IID = UseSigned ? Intrinsic::sdiv_fix_sat : Intrinsic::udiv_fix_sat;
328 IID = UseSigned ? Intrinsic::sdiv_fix : Intrinsic::udiv_fix;
330 Value *Result = B.CreateIntrinsic(
332 {WideLHS, WideRHS, B.getInt32(CommonSema.getScale())});
346 RHS = B.CreateIntCast(
RHS,
LHS->getType(),
false);
350 Intrinsic::ID IID = UseSigned ? Intrinsic::sshl_sat : Intrinsic::ushl_sat;
351 Result = B.CreateBinaryIntrinsic(IID,
LHS,
RHS);
353 Result = B.CreateShl(
LHS,
RHS);
365 RHS = B.CreateIntCast(
RHS,
LHS->getType(),
false);
377 auto CommonSema = getCommonBinopSemantic(LHSSema, RHSSema);
382 return B.CreateICmpEQ(WideLHS, WideRHS);
392 auto CommonSema = getCommonBinopSemantic(LHSSema, RHSSema);
397 return B.CreateICmpNE(WideLHS, WideRHS);
407 auto CommonSema = getCommonBinopSemantic(LHSSema, RHSSema);
412 return CommonSema.isSigned() ? B.CreateICmpSLT(WideLHS, WideRHS)
413 : B.CreateICmpULT(WideLHS, WideRHS);
423 auto CommonSema = getCommonBinopSemantic(LHSSema, RHSSema);
428 return CommonSema.isSigned() ? B.CreateICmpSLE(WideLHS, WideRHS)
429 : B.CreateICmpULE(WideLHS, WideRHS);
439 auto CommonSema = getCommonBinopSemantic(LHSSema, RHSSema);
444 return CommonSema.isSigned() ? B.CreateICmpSGT(WideLHS, WideRHS)
445 : B.CreateICmpUGT(WideLHS, WideRHS);
455 auto CommonSema = getCommonBinopSemantic(LHSSema, RHSSema);
460 return CommonSema.isSigned() ? B.CreateICmpSGE(WideLHS, WideRHS)
461 : B.CreateICmpUGE(WideLHS, WideRHS);
Defines the fixed point number interface.
This file contains the declarations for the subclasses of Constant, which represent the different fla...
static APFixedPoint getMin(const FixedPointSemantics &Sema)
static const fltSemantics * promoteFloatSemantics(const fltSemantics *S)
Given a floating point semantic, return the next floating point semantic with a larger exponent and l...
static APFixedPoint getMax(const FixedPointSemantics &Sema)
static APInt getLowBitsSet(unsigned numBits, unsigned loBitsSet)
Constructs an APInt value that has the bottom loBitsSet bits set.
APSInt extOrTrunc(uint32_t width) const
This is an important base class in LLVM.
static Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
Value * CreateFixedToFloating(Value *Src, const FixedPointSemantics &SrcSema, Type *DstTy)
Value * CreateDiv(Value *LHS, const FixedPointSemantics &LHSSema, Value *RHS, const FixedPointSemantics &RHSSema)
Divide two fixed-point values and return the result in their common semantic.
Value * CreateFloatingToFixed(Value *Src, const FixedPointSemantics &DstSema)
Value * CreateGT(Value *LHS, const FixedPointSemantics &LHSSema, Value *RHS, const FixedPointSemantics &RHSSema)
Compare two fixed-point values as LHS > RHS.
Value * CreateFixedToInteger(Value *Src, const FixedPointSemantics &SrcSema, unsigned DstWidth, bool DstIsSigned)
Convert an integer value representing a fixed-point number to an integer with the given bit width and...
Value * CreateShl(Value *LHS, const FixedPointSemantics &LHSSema, Value *RHS)
Left shift a fixed-point value by an unsigned integer value.
Value * CreateNE(Value *LHS, const FixedPointSemantics &LHSSema, Value *RHS, const FixedPointSemantics &RHSSema)
Compare two fixed-point values for inequality.
Value * CreateLT(Value *LHS, const FixedPointSemantics &LHSSema, Value *RHS, const FixedPointSemantics &RHSSema)
Compare two fixed-point values as LHS < RHS.
FixedPointBuilder(IRBuilderTy &Builder)
Value * CreateEQ(Value *LHS, const FixedPointSemantics &LHSSema, Value *RHS, const FixedPointSemantics &RHSSema)
Compare two fixed-point values for equality.
Value * CreateShr(Value *LHS, const FixedPointSemantics &LHSSema, Value *RHS)
Right shift a fixed-point value by an unsigned integer value.
Value * CreateLE(Value *LHS, const FixedPointSemantics &LHSSema, Value *RHS, const FixedPointSemantics &RHSSema)
Compare two fixed-point values as LHS <= RHS.
Value * CreateAdd(Value *LHS, const FixedPointSemantics &LHSSema, Value *RHS, const FixedPointSemantics &RHSSema)
Add two fixed-point values and return the result in their common semantic.
Value * CreateGE(Value *LHS, const FixedPointSemantics &LHSSema, Value *RHS, const FixedPointSemantics &RHSSema)
Compare two fixed-point values as LHS >= RHS.
Value * CreateMul(Value *LHS, const FixedPointSemantics &LHSSema, Value *RHS, const FixedPointSemantics &RHSSema)
Multiply two fixed-point values and return the result in their common semantic.
Value * CreateIntegerToFixed(Value *Src, unsigned SrcIsSigned, const FixedPointSemantics &DstSema)
Convert an integer value with the given signedness to an integer value representing the given fixed-p...
Value * CreateSub(Value *LHS, const FixedPointSemantics &LHSSema, Value *RHS, const FixedPointSemantics &RHSSema)
Subtract two fixed-point values and return the result in their common semantic.
Value * CreateFixedToFixed(Value *Src, const FixedPointSemantics &SrcSema, const FixedPointSemantics &DstSema)
Convert an integer value representing a fixed-point number from one fixed-point semantic to another f...
The fixed point semantics work similarly to fltSemantics.
unsigned getWidth() const
bool hasUnsignedPadding() const
unsigned getScale() const
unsigned getIntegralBits() const
Return the number of integral bits represented by these semantics.
FixedPointSemantics getCommonSemantics(const FixedPointSemantics &Other) const
Return the FixedPointSemantics that allows for calculating the full precision semantic that can preci...
bool fitsInFloatSemantics(const fltSemantics &FloatSema) const
Returns true if this fixed-point semantic with its value bits interpreted as an integer can fit in th...
static FixedPointSemantics GetIntegerSemantics(unsigned Width, bool IsSigned)
Return the FixedPointSemantics for an integer type.
The instances of the Type class are immutable: once they are created, they are never changed.
const fltSemantics & getFltSemantics() const
static Type * getFloatingPointTy(LLVMContext &C, const fltSemantics &S)
LLVMContext & getContext() const
Return the LLVMContext in which this type was uniqued.
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
@ C
The default llvm calling convention, compatible with C.
This is an optimization pass for GlobalISel generic memory operations.