18using namespace CodeGen;
24 "asdouble operands types mismatch");
28 llvm::Type *ResultType = CGF.
DoubleTy;
31 N = VTy->getNumElements();
32 ResultType = llvm::FixedVectorType::get(CGF.
DoubleTy, N);
36 return CGF.
Builder.CreateIntrinsic(
37 ResultType, Intrinsic::dx_asdouble,
38 {OpLowBits, OpHighBits},
nullptr,
"hlsl.asdouble");
41 OpLowBits = CGF.
Builder.CreateVectorSplat(1, OpLowBits);
42 OpHighBits = CGF.
Builder.CreateVectorSplat(1, OpHighBits);
46 for (
int i = 0; i < N; i++) {
48 Mask.push_back(i + N);
51 Value *BitVec = CGF.
Builder.CreateShuffleVector(OpLowBits, OpHighBits, Mask);
53 return CGF.
Builder.CreateBitCast(BitVec, ResultType);
59 Constant *FZeroConst = ConstantFP::getZero(CGF->
FloatTy);
64 FZeroConst = ConstantVector::getSplat(
65 ElementCount::getFixed(VecTy->getNumElements()), FZeroConst);
66 auto *FCompInst = CGF->
Builder.CreateFCmpOLT(Op0, FZeroConst);
67 CMP = CGF->
Builder.CreateIntrinsic(
71 CMP = CGF->
Builder.CreateFCmpOLT(Op0, FZeroConst);
75 LastInstr = CGF->
Builder.CreateIntrinsic(Intrinsic::dx_discard, {CMP});
80 CGF->
Builder.CreateCondBr(CMP, LT0, End);
82 CGF->
Builder.SetInsertPoint(LT0);
84 CGF->
Builder.CreateIntrinsic(Intrinsic::spv_discard, {});
86 LastInstr = CGF->
Builder.CreateBr(End);
87 CGF->
Builder.SetInsertPoint(End);
89 llvm_unreachable(
"Backend Codegen not supported.");
97 const auto *OutArg1 = dyn_cast<HLSLOutArgExpr>(
E->getArg(1));
98 const auto *OutArg2 = dyn_cast<HLSLOutArgExpr>(
E->getArg(2));
109 Value *LowBits =
nullptr;
110 Value *HighBits =
nullptr;
113 llvm::Type *RetElementTy = CGF->
Int32Ty;
115 RetElementTy = llvm::VectorType::get(
116 CGF->
Int32Ty, ElementCount::getFixed(Op0VecTy->getNumElements()));
117 auto *RetTy = llvm::StructType::get(RetElementTy, RetElementTy);
119 CallInst *CI = CGF->
Builder.CreateIntrinsic(
120 RetTy, Intrinsic::dx_splitdouble, {Op0},
nullptr,
"hlsl.splitdouble");
122 LowBits = CGF->
Builder.CreateExtractValue(CI, 0);
123 HighBits = CGF->
Builder.CreateExtractValue(CI, 1);
127 if (!Op0->
getType()->isVectorTy()) {
128 FixedVectorType *DestTy = FixedVectorType::get(CGF->
Int32Ty, 2);
129 Value *Bitcast = CGF->
Builder.CreateBitCast(Op0, DestTy);
131 LowBits = CGF->
Builder.CreateExtractElement(Bitcast, (uint64_t)0);
132 HighBits = CGF->
Builder.CreateExtractElement(Bitcast, 1);
135 if (
const auto *VecTy =
137 NumElements = VecTy->getNumElements();
139 FixedVectorType *Uint32VecTy =
140 FixedVectorType::get(CGF->
Int32Ty, NumElements * 2);
141 Value *Uint32Vec = CGF->
Builder.CreateBitCast(Op0, Uint32VecTy);
142 if (NumElements == 1) {
143 LowBits = CGF->
Builder.CreateExtractElement(Uint32Vec, (uint64_t)0);
144 HighBits = CGF->
Builder.CreateExtractElement(Uint32Vec, 1);
147 for (
int I = 0,
E = NumElements; I !=
E; ++I) {
148 EvenMask.push_back(I * 2);
149 OddMask.push_back(I * 2 + 1);
151 LowBits = CGF->
Builder.CreateShuffleVector(Uint32Vec, EvenMask);
152 HighBits = CGF->
Builder.CreateShuffleVector(Uint32Vec, OddMask);
166 return RT.getFDotIntrinsic();
168 return RT.getSDotIntrinsic();
170 return RT.getUDotIntrinsic();
175 return RT.getFirstBitSHighIntrinsic();
179 return RT.getFirstBitUHighIntrinsic();
186 case llvm::Triple::spirv:
187 return Intrinsic::spv_wave_reduce_sum;
188 case llvm::Triple::dxil: {
190 return Intrinsic::dx_wave_reduce_usum;
191 return Intrinsic::dx_wave_reduce_sum;
194 llvm_unreachable(
"Intrinsic WaveActiveSum"
195 " not supported by target architecture");
203 case llvm::Triple::spirv:
205 return Intrinsic::spv_wave_reduce_umax;
206 return Intrinsic::spv_wave_reduce_max;
207 case llvm::Triple::dxil: {
209 return Intrinsic::dx_wave_reduce_umax;
210 return Intrinsic::dx_wave_reduce_max;
213 llvm_unreachable(
"Intrinsic WaveActiveMax"
214 " not supported by target architecture");
223 QualType ClangParamTypes[] = {Context.
IntTy, SpecConstantType};
237 for (
QualType ParamType : ClangParamTypes) {
240 nullptr, ParamType,
nullptr,
SC_None,
242 ParamDecls.push_back(PD);
244 FnDeclForMangling->setParams(ParamDecls);
248 llvm::raw_string_ostream MangledNameStream(Name);
250 Mangler->mangleName(FnDeclForMangling, MangledNameStream);
251 MangledNameStream.flush();
263 case Builtin::BI__builtin_hlsl_adduint64: {
268 assert(Arg0Ty ==
E->getArg(1)->
getType() &&
269 "AddUint64 operand types must match");
271 "AddUint64 operands must have an integer representation");
272 assert((NumElements == 2 || NumElements == 4) &&
273 "AddUint64 operands must have 2 or 4 elements");
281 if (NumElements == 2) {
282 LowA =
Builder.CreateExtractElement(OpA, (uint64_t)0,
"LowA");
283 HighA =
Builder.CreateExtractElement(OpA, (uint64_t)1,
"HighA");
284 LowB =
Builder.CreateExtractElement(OpB, (uint64_t)0,
"LowB");
285 HighB =
Builder.CreateExtractElement(OpB, (uint64_t)1,
"HighB");
287 LowA =
Builder.CreateShuffleVector(OpA, {0, 2},
"LowA");
288 HighA =
Builder.CreateShuffleVector(OpA, {1, 3},
"HighA");
289 LowB =
Builder.CreateShuffleVector(OpB, {0, 2},
"LowB");
290 HighB =
Builder.CreateShuffleVector(OpB, {1, 3},
"HighB");
297 *
this, Intrinsic::uadd_with_overflow, LowA, LowB, Carry);
298 llvm::Value *ZExtCarry =
299 Builder.CreateZExt(Carry, HighA->getType(),
"CarryZExt");
302 llvm::Value *HighSum =
Builder.CreateAdd(HighA, HighB,
"HighSum");
303 llvm::Value *HighSumPlusCarry =
304 Builder.CreateAdd(HighSum, ZExtCarry,
"HighSumPlusCarry");
306 if (NumElements == 4) {
307 return Builder.CreateShuffleVector(LowSum, HighSumPlusCarry, {0, 2, 1, 3},
313 "hlsl.AddUint64.upto0");
318 case Builtin::BI__builtin_hlsl_resource_getpointer: {
323 return Builder.CreateIntrinsic(
327 case Builtin::BI__builtin_hlsl_resource_uninitializedhandle: {
329 return llvm::PoisonValue::get(HandleTy);
331 case Builtin::BI__builtin_hlsl_resource_handlefrombinding: {
338 llvm::Intrinsic::ID IntrinsicID =
341 return Builder.CreateIntrinsic(HandleTy, IntrinsicID, Args);
343 case Builtin::BI__builtin_hlsl_resource_handlefromimplicitbinding: {
350 llvm::Intrinsic::ID IntrinsicID =
353 return Builder.CreateIntrinsic(HandleTy, IntrinsicID, Args);
355 case Builtin::BI__builtin_hlsl_all: {
357 return Builder.CreateIntrinsic(
362 case Builtin::BI__builtin_hlsl_and: {
365 return Builder.CreateAnd(Op0, Op1,
"hlsl.and");
367 case Builtin::BI__builtin_hlsl_or: {
370 return Builder.CreateOr(Op0, Op1,
"hlsl.or");
372 case Builtin::BI__builtin_hlsl_any: {
374 return Builder.CreateIntrinsic(
379 case Builtin::BI__builtin_hlsl_asdouble:
381 case Builtin::BI__builtin_hlsl_elementwise_clamp: {
388 Ty = VecTy->getElementType();
399 return Builder.CreateIntrinsic(
403 case Builtin::BI__builtin_hlsl_crossf16:
404 case Builtin::BI__builtin_hlsl_crossf32: {
409 "cross operands must have a float representation");
414 "input vectors must have 3 elements each");
415 return Builder.CreateIntrinsic(
419 case Builtin::BI__builtin_hlsl_dot: {
422 llvm::Type *T0 = Op0->
getType();
423 llvm::Type *T1 = Op1->
getType();
426 if (!T0->isVectorTy() && !T1->isVectorTy()) {
427 if (T0->isFloatingPointTy())
428 return Builder.CreateFMul(Op0, Op1,
"hlsl.dot");
430 if (T0->isIntegerTy())
431 return Builder.CreateMul(Op0, Op1,
"hlsl.dot");
434 "Scalar dot product is only supported on ints and floats.");
439 "Dot product operands must have the same type.");
442 assert(VecTy0 &&
"Dot product argument must be a vector.");
444 return Builder.CreateIntrinsic(
449 case Builtin::BI__builtin_hlsl_dot4add_i8packed: {
457 return Builder.CreateIntrinsic(
459 nullptr,
"hlsl.dot4add.i8packed");
461 case Builtin::BI__builtin_hlsl_dot4add_u8packed: {
469 return Builder.CreateIntrinsic(
471 nullptr,
"hlsl.dot4add.u8packed");
473 case Builtin::BI__builtin_hlsl_elementwise_firstbithigh: {
476 return Builder.CreateIntrinsic(
481 case Builtin::BI__builtin_hlsl_elementwise_firstbitlow: {
484 return Builder.CreateIntrinsic(
487 nullptr,
"hlsl.firstbitlow");
489 case Builtin::BI__builtin_hlsl_lerp: {
494 llvm_unreachable(
"lerp operand must have a float representation");
495 return Builder.CreateIntrinsic(
499 case Builtin::BI__builtin_hlsl_normalize: {
503 "normalize operand must have a float representation");
505 return Builder.CreateIntrinsic(
508 nullptr,
"hlsl.normalize");
510 case Builtin::BI__builtin_hlsl_elementwise_degrees: {
514 "degree operand must have a float representation");
516 return Builder.CreateIntrinsic(
520 case Builtin::BI__builtin_hlsl_elementwise_frac: {
523 llvm_unreachable(
"frac operand must have a float representation");
524 return Builder.CreateIntrinsic(
528 case Builtin::BI__builtin_hlsl_elementwise_isinf: {
530 llvm::Type *Xty = Op0->
getType();
531 llvm::Type *retType = llvm::Type::getInt1Ty(this->
getLLVMContext());
532 if (Xty->isVectorTy()) {
534 retType = llvm::VectorType::get(
535 retType, ElementCount::getFixed(XVecTy->getNumElements()));
538 llvm_unreachable(
"isinf operand must have a float representation");
539 return Builder.CreateIntrinsic(retType, Intrinsic::dx_isinf,
542 case Builtin::BI__builtin_hlsl_mad: {
547 return Builder.CreateIntrinsic(
548 M->
getType(), Intrinsic::fmuladd,
553 return Builder.CreateIntrinsic(
554 M->
getType(), Intrinsic::dx_imad,
558 return Builder.CreateNSWAdd(Mul, B);
562 return Builder.CreateIntrinsic(
563 M->
getType(), Intrinsic::dx_umad,
567 return Builder.CreateNUWAdd(Mul, B);
569 case Builtin::BI__builtin_hlsl_elementwise_rcp: {
572 llvm_unreachable(
"rcp operand must have a float representation");
573 llvm::Type *Ty = Op0->
getType();
574 llvm::Type *EltTy = Ty->getScalarType();
575 Constant *One = Ty->isVectorTy()
576 ? ConstantVector::getSplat(
577 ElementCount::getFixed(
578 cast<FixedVectorType>(Ty)->getNumElements()),
579 ConstantFP::get(EltTy, 1.0))
580 : ConstantFP::get(EltTy, 1.0);
581 return Builder.CreateFDiv(One, Op0,
"hlsl.rcp");
583 case Builtin::BI__builtin_hlsl_elementwise_rsqrt: {
586 llvm_unreachable(
"rsqrt operand must have a float representation");
587 return Builder.CreateIntrinsic(
591 case Builtin::BI__builtin_hlsl_elementwise_saturate: {
594 "saturate operand must have a float representation");
595 return Builder.CreateIntrinsic(
598 nullptr,
"hlsl.saturate");
600 case Builtin::BI__builtin_hlsl_select: {
613 if (!OpTrue->
getType()->isVectorTy())
615 Builder.CreateVectorSplat(VTy->getNumElements(), OpTrue,
"splat");
616 if (!OpFalse->
getType()->isVectorTy())
618 Builder.CreateVectorSplat(VTy->getNumElements(), OpFalse,
"splat");
622 Builder.CreateSelect(OpCond, OpTrue, OpFalse,
"hlsl.select");
629 case Builtin::BI__builtin_hlsl_step: {
634 "step operands must have a float representation");
635 return Builder.CreateIntrinsic(
639 case Builtin::BI__builtin_hlsl_wave_active_all_true: {
641 assert(Op->
getType()->isIntegerTy(1) &&
642 "Intrinsic WaveActiveAllTrue operand must be a bool");
646 Intrinsic::getOrInsertDeclaration(&
CGM.
getModule(), ID), {Op});
648 case Builtin::BI__builtin_hlsl_wave_active_any_true: {
650 assert(Op->
getType()->isIntegerTy(1) &&
651 "Intrinsic WaveActiveAnyTrue operand must be a bool");
655 Intrinsic::getOrInsertDeclaration(&
CGM.
getModule(), ID), {Op});
657 case Builtin::BI__builtin_hlsl_wave_active_count_bits: {
661 Intrinsic::getOrInsertDeclaration(&
CGM.
getModule(), ID),
664 case Builtin::BI__builtin_hlsl_wave_active_sum: {
673 ArrayRef{OpExpr},
"hlsl.wave.active.sum");
675 case Builtin::BI__builtin_hlsl_wave_active_max: {
684 ArrayRef{OpExpr},
"hlsl.wave.active.max");
686 case Builtin::BI__builtin_hlsl_wave_get_lane_index: {
691 case llvm::Triple::dxil:
694 case llvm::Triple::spirv:
696 llvm::FunctionType::get(
IntTy, {},
false),
697 "__hlsl_wave_get_lane_index", {},
false,
true));
700 "Intrinsic WaveGetLaneIndex not supported by target architecture");
703 case Builtin::BI__builtin_hlsl_wave_is_first_lane: {
706 Intrinsic::getOrInsertDeclaration(&
CGM.
getModule(), ID));
708 case Builtin::BI__builtin_hlsl_wave_get_lane_count: {
711 Intrinsic::getOrInsertDeclaration(&
CGM.
getModule(), ID));
713 case Builtin::BI__builtin_hlsl_wave_read_lane_at: {
719 Intrinsic::getOrInsertDeclaration(
721 {OpExpr->getType()}),
722 ArrayRef{OpExpr, OpIndex},
"hlsl.wave.readlane");
724 case Builtin::BI__builtin_hlsl_elementwise_sign: {
725 auto *Arg0 =
E->getArg(0);
727 llvm::Type *Xty = Op0->
getType();
728 llvm::Type *retType = llvm::Type::getInt32Ty(this->
getLLVMContext());
729 if (Xty->isVectorTy()) {
730 auto *XVecTy = Arg0->getType()->castAs<
VectorType>();
731 retType = llvm::VectorType::get(
732 retType, ElementCount::getFixed(XVecTy->getNumElements()));
734 assert((Arg0->getType()->hasFloatingRepresentation() ||
735 Arg0->getType()->hasIntegerRepresentation()) &&
736 "sign operand must have a float or int representation");
738 if (Arg0->getType()->hasUnsignedIntegerRepresentation()) {
739 Value *Cmp =
Builder.CreateICmpEQ(Op0, ConstantInt::get(Xty, 0));
740 return Builder.CreateSelect(Cmp, ConstantInt::get(retType, 0),
741 ConstantInt::get(retType, 1),
"hlsl.sign");
744 return Builder.CreateIntrinsic(
748 case Builtin::BI__builtin_hlsl_elementwise_radians: {
751 "radians operand must have a float representation");
752 return Builder.CreateIntrinsic(
755 nullptr,
"hlsl.radians");
757 case Builtin::BI__builtin_hlsl_buffer_update_counter: {
761 return Builder.CreateIntrinsic(
766 case Builtin::BI__builtin_hlsl_elementwise_splitdouble: {
771 "asuint operands types mismatch");
774 case Builtin::BI__builtin_hlsl_elementwise_clip:
776 "clip operands types mismatch");
778 case Builtin::BI__builtin_hlsl_group_memory_barrier_with_group_sync: {
782 Intrinsic::getOrInsertDeclaration(&
CGM.
getModule(), ID));
784 case Builtin::BI__builtin_get_spirv_spec_constant_bool:
785 case Builtin::BI__builtin_get_spirv_spec_constant_short:
786 case Builtin::BI__builtin_get_spirv_spec_constant_ushort:
787 case Builtin::BI__builtin_get_spirv_spec_constant_int:
788 case Builtin::BI__builtin_get_spirv_spec_constant_uint:
789 case Builtin::BI__builtin_get_spirv_spec_constant_longlong:
790 case Builtin::BI__builtin_get_spirv_spec_constant_ulonglong:
791 case Builtin::BI__builtin_get_spirv_spec_constant_half:
792 case Builtin::BI__builtin_get_spirv_spec_constant_float:
793 case Builtin::BI__builtin_get_spirv_spec_constant_double: {
797 llvm::Value *Args[] = {SpecId, DefaultVal};
798 return Builder.CreateCall(SpecConstantFn, Args);
808 llvm::Module *M = &CGM.getModule();
809 std::string MangledName =
811 llvm::Function *SpecConstantFn = M->getFunction(MangledName);
813 if (!SpecConstantFn) {
814 llvm::Type *IntType = ConvertType(getContext().IntTy);
815 llvm::Type *RetTy = ConvertType(SpecConstantType);
816 llvm::Type *ArgTypes[] = {IntType, RetTy};
817 llvm::FunctionType *FnTy = llvm::FunctionType::get(RetTy, ArgTypes,
false);
818 SpecConstantFn = llvm::Function::Create(
819 FnTy, llvm::GlobalValue::ExternalLinkage, MangledName, M);
821 return SpecConstantFn;
llvm::Value * EmitOverflowIntrinsic(CodeGenFunction &CGF, const Intrinsic::ID IntrinsicID, llvm::Value *X, llvm::Value *Y, llvm::Value *&Carry)
Emit a call to llvm.
static Intrinsic::ID getWaveActiveSumIntrinsic(llvm::Triple::ArchType Arch, CGHLSLRuntime &RT, QualType QT)
static Intrinsic::ID getWaveActiveMaxIntrinsic(llvm::Triple::ArchType Arch, CGHLSLRuntime &RT, QualType QT)
static Intrinsic::ID getDotProductIntrinsic(CGHLSLRuntime &RT, QualType QT)
static std::string getSpecConstantFunctionName(clang::QualType SpecConstantType, ASTContext &Context)
static Value * handleHlslSplitdouble(const CallExpr *E, CodeGenFunction *CGF)
static Intrinsic::ID getFirstBitHighIntrinsic(CGHLSLRuntime &RT, QualType QT)
static Value * handleAsDoubleBuiltin(CodeGenFunction &CGF, const CallExpr *E)
static Value * handleHlslClip(const CallExpr *E, CodeGenFunction *CGF)
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
TranslationUnitDecl * getTranslationUnitDecl() const
MangleContext * createMangleContext(const TargetInfo *T=nullptr)
If T is null pointer, assume the target in ASTContext.
bool hasSameUnqualifiedType(QualType T1, QualType T2) const
Determine whether the given types are equivalent after cvr-qualifiers have been removed.
QualType getFunctionType(QualType ResultTy, ArrayRef< QualType > Args, const FunctionProtoType::ExtProtoInfo &EPI) const
Return a normal function type with a typed argument list.
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
llvm::StoreInst * CreateStore(llvm::Value *Val, Address Addr, bool IsVolatile=false)
CallArgList - Type for representing both the value and type of arguments in a call.
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
llvm::Type * ConvertType(QualType T)
llvm::BasicBlock * createBasicBlock(const Twine &name="", llvm::Function *parent=nullptr, llvm::BasicBlock *before=nullptr)
createBasicBlock - Create an LLVM basic block.
const LangOptions & getLangOpts() const
const TargetInfo & getTarget() const
llvm::Function * getSpecConstantFunction(const clang::QualType &SpecConstantType)
LValue EmitHLSLOutArgExpr(const HLSLOutArgExpr *E, CallArgList &Args, QualType Ty)
void EmitWritebacks(const CallArgList &Args)
EmitWriteback - Emit callbacks for function.
RValue EmitAnyExpr(const Expr *E, AggValueSlot aggSlot=AggValueSlot::ignored(), bool ignoreResult=false)
EmitAnyExpr - Emit code to compute the specified expression which can have any type.
llvm::CallInst * EmitRuntimeCall(llvm::FunctionCallee callee, const Twine &name="")
llvm::Value * EmitScalarExpr(const Expr *E, bool IgnoreResultAssign=false)
EmitScalarExpr - Emit the computation of the specified expression of LLVM scalar type,...
Address ReturnValue
ReturnValue - The temporary alloca to hold the return value.
llvm::LLVMContext & getLLVMContext()
llvm::Value * EmitHLSLBuiltinExpr(unsigned BuiltinID, const CallExpr *E, ReturnValueSlot ReturnValue)
CGHLSLRuntime & getHLSLRuntime()
Return a reference to the configured HLSL runtime.
llvm::Module & getModule() const
llvm::FunctionCallee CreateRuntimeFunction(llvm::FunctionType *Ty, StringRef Name, llvm::AttributeList ExtraAttrs=llvm::AttributeList(), bool Local=false, bool AssumeConvergent=false)
Create or return a runtime function declaration with the specified type and name.
CodeGenTypes & getTypes()
const TargetInfo & getTarget() const
ASTContext & getContext() const
llvm::Type * ConvertType(QualType T)
ConvertType - Convert type T into a llvm::Type.
LValue - This represents an lvalue references.
Address getAddress() const
RValue - This trivial value class is used to represent the result of an expression that is evaluated.
llvm::Value * getAggregatePointer(QualType PointeeType, CodeGenFunction &CGF) const
llvm::Value * getScalarVal() const
getScalarVal() - Return the Value* of this scalar value.
ReturnValueSlot - Contains the address where the return value of a function can be stored,...
The name of a declaration.
Represents a function declaration or definition.
static FunctionDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation NLoc, DeclarationName N, QualType T, TypeSourceInfo *TInfo, StorageClass SC, bool UsesFPIntrin=false, bool isInlineSpecified=false, bool hasWrittenPrototype=true, ConstexprSpecKind ConstexprKind=ConstexprSpecKind::Unspecified, const AssociatedConstraint &TrailingRequiresClause={})
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
Represents a parameter to a function.
static ParmVarDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, const IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, StorageClass S, Expr *DefArg)
A (possibly-)qualified type.
Encodes a location in the source.
bool areArgsDestroyedLeftToRightInCallee() const
Are arguments to a call destroyed left to right in the callee? This is a fundamental language change,...
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
TargetCXXABI getCXXABI() const
Get the C++ ABI currently in use.
bool isSignedIntegerType() const
Return true if this is an integer type that is signed, according to C99 6.2.5p4 [char,...
bool hasIntegerRepresentation() const
Determine whether this type has an integer representation of some sort, e.g., it is an integer type o...
const T * castAs() const
Member-template castAs<specific type>.
bool hasUnsignedIntegerRepresentation() const
Determine whether this type has an unsigned integer representation of some sort, e....
bool hasSignedIntegerRepresentation() const
Determine whether this type has an signed integer representation of some sort, e.g....
bool hasFloatingRepresentation() const
Determine whether this type has a floating-point representation of some sort, e.g....
bool isVectorType() const
bool isFloatingType() const
bool isUnsignedIntegerType() const
Return true if this is an integer type that is unsigned, according to C99 6.2.5p6 [which returns true...
const T * getAs() const
Member-template getAs<specific type>'.
Represents a GCC generic vector type.
unsigned getNumElements() const
The JSON file list parser is used to communicate input to InstallAPI.
@ Result
The result type of a method or function.
Diagnostic wrappers for TextAPI types for error reporting.
llvm::IntegerType * Int8Ty
i8, i16, i32, and i64
llvm::IntegerType * Int32Ty
llvm::IntegerType * IntTy
int
Extra information about a function prototype.