//===--- NVVMIntrinsicUtils.h -----------------------------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // /// \file /// This file contains the definitions of the enumerations and flags /// associated with NVVM Intrinsics, along with some helper functions. // //===----------------------------------------------------------------------===// #ifndef LLVM_IR_NVVMINTRINSICUTILS_H #define LLVM_IR_NVVMINTRINSICUTILS_H #include #include "llvm/ADT/APFloat.h" #include "llvm/ADT/APInt.h" #include "llvm/IR/Constants.h" #include "llvm/IR/Intrinsics.h" #include "llvm/IR/IntrinsicsNVPTX.h" #include "llvm/Support/raw_ostream.h" namespace llvm { namespace nvvm { // Reduction Ops supported with TMA Copy from Shared // to Global Memory for the "cp.reduce.async.bulk.tensor.*" // family of PTX instructions. enum class TMAReductionOp : uint8_t { ADD = 0, MIN = 1, MAX = 2, INC = 3, DEC = 4, AND = 5, OR = 6, XOR = 7, }; // Enum to represent the cta_group::1 and // cta_group::2 variants in TMA/TCGEN05 family of // PTX instructions. enum class CTAGroupKind : uint8_t { CG_NONE = 0, // default with no cta_group modifier CG_1 = 1, // cta_group::1 modifier CG_2 = 2, // cta_group::2 modifier }; enum class Tcgen05MMAKind : uint8_t { F16 = 0, TF32 = 1, F8F6F4 = 2, I8 = 3 }; enum class Tcgen05CollectorUsageOp : uint8_t { DISCARD = 0, LASTUSE = 1, FILL = 2, USE = 3, }; enum class TensormapElemType : uint8_t { U8 = 0, U16 = 1, U32 = 2, S32 = 3, U64 = 4, S64 = 5, F16 = 6, F32 = 7, F32_FTZ = 8, F64 = 9, BF16 = 10, TF32 = 11, TF32_FTZ = 12, B4x16 = 13, B4x16_p64 = 14, B6x16_p32 = 15, }; enum class TensormapInterleaveLayout : uint8_t { NO_INTERLEAVE = 0, INTERLEAVE_16B = 1, INTERLEAVE_32B = 2, }; enum class TensormapSwizzleMode : uint8_t { NO_SWIZZLE = 0, SWIZZLE_32B = 1, SWIZZLE_64B = 2, SWIZZLE_128B = 3, SWIZZLE_96B = 4, }; enum class TensormapSwizzleAtomicity : uint8_t { SWIZZLE_ATOMICITY_16B = 0, SWIZZLE_ATOMICITY_32B = 1, SWIZZLE_ATOMICITY_32B_FLIP_8B = 2, SWIZZLE_ATOMICITY_64B = 3, }; enum class TensormapFillMode : uint8_t { ZERO_FILL = 0, OOB_NAN_FILL = 1, }; void printTcgen05MMAKind(raw_ostream &OS, const Constant *ImmArgVal); void printTcgen05CollectorUsageOp(raw_ostream &OS, const Constant *ImmArgVal); void printTensormapElemType(raw_ostream &OS, const Constant *ImmArgVal); void printTensormapInterleaveLayout(raw_ostream &OS, const Constant *ImmArgVal); void printTensormapSwizzleMode(raw_ostream &OS, const Constant *ImmArgVal); void printTensormapSwizzleAtomicity(raw_ostream &OS, const Constant *ImmArgVal); void printTensormapFillMode(raw_ostream &OS, const Constant *ImmArgVal); inline bool FPToIntegerIntrinsicShouldFTZ(Intrinsic::ID IntrinsicID) { switch (IntrinsicID) { case Intrinsic::nvvm_f2i_rm_ftz: case Intrinsic::nvvm_f2i_rn_ftz: case Intrinsic::nvvm_f2i_rp_ftz: case Intrinsic::nvvm_f2i_rz_ftz: case Intrinsic::nvvm_f2ui_rm_ftz: case Intrinsic::nvvm_f2ui_rn_ftz: case Intrinsic::nvvm_f2ui_rp_ftz: case Intrinsic::nvvm_f2ui_rz_ftz: case Intrinsic::nvvm_f2ll_rm_ftz: case Intrinsic::nvvm_f2ll_rn_ftz: case Intrinsic::nvvm_f2ll_rp_ftz: case Intrinsic::nvvm_f2ll_rz_ftz: case Intrinsic::nvvm_f2ull_rm_ftz: case Intrinsic::nvvm_f2ull_rn_ftz: case Intrinsic::nvvm_f2ull_rp_ftz: case Intrinsic::nvvm_f2ull_rz_ftz: return true; case Intrinsic::nvvm_f2i_rm: case Intrinsic::nvvm_f2i_rn: case Intrinsic::nvvm_f2i_rp: case Intrinsic::nvvm_f2i_rz: case Intrinsic::nvvm_f2ui_rm: case Intrinsic::nvvm_f2ui_rn: case Intrinsic::nvvm_f2ui_rp: case Intrinsic::nvvm_f2ui_rz: case Intrinsic::nvvm_d2i_rm: case Intrinsic::nvvm_d2i_rn: case Intrinsic::nvvm_d2i_rp: case Intrinsic::nvvm_d2i_rz: case Intrinsic::nvvm_d2ui_rm: case Intrinsic::nvvm_d2ui_rn: case Intrinsic::nvvm_d2ui_rp: case Intrinsic::nvvm_d2ui_rz: case Intrinsic::nvvm_f2ll_rm: case Intrinsic::nvvm_f2ll_rn: case Intrinsic::nvvm_f2ll_rp: case Intrinsic::nvvm_f2ll_rz: case Intrinsic::nvvm_f2ull_rm: case Intrinsic::nvvm_f2ull_rn: case Intrinsic::nvvm_f2ull_rp: case Intrinsic::nvvm_f2ull_rz: case Intrinsic::nvvm_d2ll_rm: case Intrinsic::nvvm_d2ll_rn: case Intrinsic::nvvm_d2ll_rp: case Intrinsic::nvvm_d2ll_rz: case Intrinsic::nvvm_d2ull_rm: case Intrinsic::nvvm_d2ull_rn: case Intrinsic::nvvm_d2ull_rp: case Intrinsic::nvvm_d2ull_rz: return false; } llvm_unreachable("Checking FTZ flag for invalid f2i/d2i intrinsic"); } inline bool FPToIntegerIntrinsicResultIsSigned(Intrinsic::ID IntrinsicID) { switch (IntrinsicID) { // f2i case Intrinsic::nvvm_f2i_rm: case Intrinsic::nvvm_f2i_rm_ftz: case Intrinsic::nvvm_f2i_rn: case Intrinsic::nvvm_f2i_rn_ftz: case Intrinsic::nvvm_f2i_rp: case Intrinsic::nvvm_f2i_rp_ftz: case Intrinsic::nvvm_f2i_rz: case Intrinsic::nvvm_f2i_rz_ftz: // d2i case Intrinsic::nvvm_d2i_rm: case Intrinsic::nvvm_d2i_rn: case Intrinsic::nvvm_d2i_rp: case Intrinsic::nvvm_d2i_rz: // f2ll case Intrinsic::nvvm_f2ll_rm: case Intrinsic::nvvm_f2ll_rm_ftz: case Intrinsic::nvvm_f2ll_rn: case Intrinsic::nvvm_f2ll_rn_ftz: case Intrinsic::nvvm_f2ll_rp: case Intrinsic::nvvm_f2ll_rp_ftz: case Intrinsic::nvvm_f2ll_rz: case Intrinsic::nvvm_f2ll_rz_ftz: // d2ll case Intrinsic::nvvm_d2ll_rm: case Intrinsic::nvvm_d2ll_rn: case Intrinsic::nvvm_d2ll_rp: case Intrinsic::nvvm_d2ll_rz: return true; // f2ui case Intrinsic::nvvm_f2ui_rm: case Intrinsic::nvvm_f2ui_rm_ftz: case Intrinsic::nvvm_f2ui_rn: case Intrinsic::nvvm_f2ui_rn_ftz: case Intrinsic::nvvm_f2ui_rp: case Intrinsic::nvvm_f2ui_rp_ftz: case Intrinsic::nvvm_f2ui_rz: case Intrinsic::nvvm_f2ui_rz_ftz: // d2ui case Intrinsic::nvvm_d2ui_rm: case Intrinsic::nvvm_d2ui_rn: case Intrinsic::nvvm_d2ui_rp: case Intrinsic::nvvm_d2ui_rz: // f2ull case Intrinsic::nvvm_f2ull_rm: case Intrinsic::nvvm_f2ull_rm_ftz: case Intrinsic::nvvm_f2ull_rn: case Intrinsic::nvvm_f2ull_rn_ftz: case Intrinsic::nvvm_f2ull_rp: case Intrinsic::nvvm_f2ull_rp_ftz: case Intrinsic::nvvm_f2ull_rz: case Intrinsic::nvvm_f2ull_rz_ftz: // d2ull case Intrinsic::nvvm_d2ull_rm: case Intrinsic::nvvm_d2ull_rn: case Intrinsic::nvvm_d2ull_rp: case Intrinsic::nvvm_d2ull_rz: return false; } llvm_unreachable( "Checking invalid f2i/d2i intrinsic for signed int conversion"); } inline bool FPToIntegerIntrinsicNaNZero(Intrinsic::ID IntrinsicID) { switch (IntrinsicID) { // f2i case Intrinsic::nvvm_f2i_rm: case Intrinsic::nvvm_f2i_rn: case Intrinsic::nvvm_f2i_rp: case Intrinsic::nvvm_f2i_rz: case Intrinsic::nvvm_f2i_rm_ftz: case Intrinsic::nvvm_f2i_rn_ftz: case Intrinsic::nvvm_f2i_rp_ftz: case Intrinsic::nvvm_f2i_rz_ftz: // f2ui case Intrinsic::nvvm_f2ui_rm: case Intrinsic::nvvm_f2ui_rn: case Intrinsic::nvvm_f2ui_rp: case Intrinsic::nvvm_f2ui_rz: case Intrinsic::nvvm_f2ui_rm_ftz: case Intrinsic::nvvm_f2ui_rn_ftz: case Intrinsic::nvvm_f2ui_rp_ftz: case Intrinsic::nvvm_f2ui_rz_ftz: return true; // d2i case Intrinsic::nvvm_d2i_rm: case Intrinsic::nvvm_d2i_rn: case Intrinsic::nvvm_d2i_rp: case Intrinsic::nvvm_d2i_rz: // d2ui case Intrinsic::nvvm_d2ui_rm: case Intrinsic::nvvm_d2ui_rn: case Intrinsic::nvvm_d2ui_rp: case Intrinsic::nvvm_d2ui_rz: // f2ll case Intrinsic::nvvm_f2ll_rm: case Intrinsic::nvvm_f2ll_rn: case Intrinsic::nvvm_f2ll_rp: case Intrinsic::nvvm_f2ll_rz: case Intrinsic::nvvm_f2ll_rm_ftz: case Intrinsic::nvvm_f2ll_rn_ftz: case Intrinsic::nvvm_f2ll_rp_ftz: case Intrinsic::nvvm_f2ll_rz_ftz: // f2ull case Intrinsic::nvvm_f2ull_rm: case Intrinsic::nvvm_f2ull_rn: case Intrinsic::nvvm_f2ull_rp: case Intrinsic::nvvm_f2ull_rz: case Intrinsic::nvvm_f2ull_rm_ftz: case Intrinsic::nvvm_f2ull_rn_ftz: case Intrinsic::nvvm_f2ull_rp_ftz: case Intrinsic::nvvm_f2ull_rz_ftz: // d2ll case Intrinsic::nvvm_d2ll_rm: case Intrinsic::nvvm_d2ll_rn: case Intrinsic::nvvm_d2ll_rp: case Intrinsic::nvvm_d2ll_rz: // d2ull case Intrinsic::nvvm_d2ull_rm: case Intrinsic::nvvm_d2ull_rn: case Intrinsic::nvvm_d2ull_rp: case Intrinsic::nvvm_d2ull_rz: return false; } llvm_unreachable("Checking NaN result for invalid f2i/d2i intrinsic"); } inline APFloat::roundingMode GetFPToIntegerRoundingMode(Intrinsic::ID IntrinsicID) { switch (IntrinsicID) { // RM: case Intrinsic::nvvm_f2i_rm: case Intrinsic::nvvm_f2ui_rm: case Intrinsic::nvvm_f2i_rm_ftz: case Intrinsic::nvvm_f2ui_rm_ftz: case Intrinsic::nvvm_d2i_rm: case Intrinsic::nvvm_d2ui_rm: case Intrinsic::nvvm_f2ll_rm: case Intrinsic::nvvm_f2ull_rm: case Intrinsic::nvvm_f2ll_rm_ftz: case Intrinsic::nvvm_f2ull_rm_ftz: case Intrinsic::nvvm_d2ll_rm: case Intrinsic::nvvm_d2ull_rm: return APFloat::rmTowardNegative; // RN: case Intrinsic::nvvm_f2i_rn: case Intrinsic::nvvm_f2ui_rn: case Intrinsic::nvvm_f2i_rn_ftz: case Intrinsic::nvvm_f2ui_rn_ftz: case Intrinsic::nvvm_d2i_rn: case Intrinsic::nvvm_d2ui_rn: case Intrinsic::nvvm_f2ll_rn: case Intrinsic::nvvm_f2ull_rn: case Intrinsic::nvvm_f2ll_rn_ftz: case Intrinsic::nvvm_f2ull_rn_ftz: case Intrinsic::nvvm_d2ll_rn: case Intrinsic::nvvm_d2ull_rn: return APFloat::rmNearestTiesToEven; // RP: case Intrinsic::nvvm_f2i_rp: case Intrinsic::nvvm_f2ui_rp: case Intrinsic::nvvm_f2i_rp_ftz: case Intrinsic::nvvm_f2ui_rp_ftz: case Intrinsic::nvvm_d2i_rp: case Intrinsic::nvvm_d2ui_rp: case Intrinsic::nvvm_f2ll_rp: case Intrinsic::nvvm_f2ull_rp: case Intrinsic::nvvm_f2ll_rp_ftz: case Intrinsic::nvvm_f2ull_rp_ftz: case Intrinsic::nvvm_d2ll_rp: case Intrinsic::nvvm_d2ull_rp: return APFloat::rmTowardPositive; // RZ: case Intrinsic::nvvm_f2i_rz: case Intrinsic::nvvm_f2ui_rz: case Intrinsic::nvvm_f2i_rz_ftz: case Intrinsic::nvvm_f2ui_rz_ftz: case Intrinsic::nvvm_d2i_rz: case Intrinsic::nvvm_d2ui_rz: case Intrinsic::nvvm_f2ll_rz: case Intrinsic::nvvm_f2ull_rz: case Intrinsic::nvvm_f2ll_rz_ftz: case Intrinsic::nvvm_f2ull_rz_ftz: case Intrinsic::nvvm_d2ll_rz: case Intrinsic::nvvm_d2ull_rz: return APFloat::rmTowardZero; } llvm_unreachable("Checking rounding mode for invalid f2i/d2i intrinsic"); } inline bool FMinFMaxShouldFTZ(Intrinsic::ID IntrinsicID) { switch (IntrinsicID) { case Intrinsic::nvvm_fmax_ftz_f: case Intrinsic::nvvm_fmax_ftz_nan_f: case Intrinsic::nvvm_fmax_ftz_nan_xorsign_abs_f: case Intrinsic::nvvm_fmax_ftz_xorsign_abs_f: case Intrinsic::nvvm_fmin_ftz_f: case Intrinsic::nvvm_fmin_ftz_nan_f: case Intrinsic::nvvm_fmin_ftz_nan_xorsign_abs_f: case Intrinsic::nvvm_fmin_ftz_xorsign_abs_f: return true; case Intrinsic::nvvm_fmax_d: case Intrinsic::nvvm_fmax_f: case Intrinsic::nvvm_fmax_nan_f: case Intrinsic::nvvm_fmax_nan_xorsign_abs_f: case Intrinsic::nvvm_fmax_xorsign_abs_f: case Intrinsic::nvvm_fmin_d: case Intrinsic::nvvm_fmin_f: case Intrinsic::nvvm_fmin_nan_f: case Intrinsic::nvvm_fmin_nan_xorsign_abs_f: case Intrinsic::nvvm_fmin_xorsign_abs_f: return false; } llvm_unreachable("Checking FTZ flag for invalid fmin/fmax intrinsic"); } inline bool FMinFMaxPropagatesNaNs(Intrinsic::ID IntrinsicID) { switch (IntrinsicID) { case Intrinsic::nvvm_fmax_ftz_nan_f: case Intrinsic::nvvm_fmax_nan_f: case Intrinsic::nvvm_fmax_ftz_nan_xorsign_abs_f: case Intrinsic::nvvm_fmax_nan_xorsign_abs_f: case Intrinsic::nvvm_fmin_ftz_nan_f: case Intrinsic::nvvm_fmin_nan_f: case Intrinsic::nvvm_fmin_ftz_nan_xorsign_abs_f: case Intrinsic::nvvm_fmin_nan_xorsign_abs_f: return true; case Intrinsic::nvvm_fmax_d: case Intrinsic::nvvm_fmax_f: case Intrinsic::nvvm_fmax_ftz_f: case Intrinsic::nvvm_fmax_ftz_xorsign_abs_f: case Intrinsic::nvvm_fmax_xorsign_abs_f: case Intrinsic::nvvm_fmin_d: case Intrinsic::nvvm_fmin_f: case Intrinsic::nvvm_fmin_ftz_f: case Intrinsic::nvvm_fmin_ftz_xorsign_abs_f: case Intrinsic::nvvm_fmin_xorsign_abs_f: return false; } llvm_unreachable("Checking NaN flag for invalid fmin/fmax intrinsic"); } inline bool FMinFMaxIsXorSignAbs(Intrinsic::ID IntrinsicID) { switch (IntrinsicID) { case Intrinsic::nvvm_fmax_ftz_nan_xorsign_abs_f: case Intrinsic::nvvm_fmax_ftz_xorsign_abs_f: case Intrinsic::nvvm_fmax_nan_xorsign_abs_f: case Intrinsic::nvvm_fmax_xorsign_abs_f: case Intrinsic::nvvm_fmin_ftz_nan_xorsign_abs_f: case Intrinsic::nvvm_fmin_ftz_xorsign_abs_f: case Intrinsic::nvvm_fmin_nan_xorsign_abs_f: case Intrinsic::nvvm_fmin_xorsign_abs_f: return true; case Intrinsic::nvvm_fmax_d: case Intrinsic::nvvm_fmax_f: case Intrinsic::nvvm_fmax_ftz_f: case Intrinsic::nvvm_fmax_ftz_nan_f: case Intrinsic::nvvm_fmax_nan_f: case Intrinsic::nvvm_fmin_d: case Intrinsic::nvvm_fmin_f: case Intrinsic::nvvm_fmin_ftz_f: case Intrinsic::nvvm_fmin_ftz_nan_f: case Intrinsic::nvvm_fmin_nan_f: return false; } llvm_unreachable("Checking XorSignAbs flag for invalid fmin/fmax intrinsic"); } inline bool UnaryMathIntrinsicShouldFTZ(Intrinsic::ID IntrinsicID) { switch (IntrinsicID) { case Intrinsic::nvvm_ceil_ftz_f: case Intrinsic::nvvm_fabs_ftz: case Intrinsic::nvvm_floor_ftz_f: case Intrinsic::nvvm_round_ftz_f: case Intrinsic::nvvm_saturate_ftz_f: case Intrinsic::nvvm_sqrt_rn_ftz_f: return true; case Intrinsic::nvvm_ceil_f: case Intrinsic::nvvm_ceil_d: case Intrinsic::nvvm_fabs: case Intrinsic::nvvm_floor_f: case Intrinsic::nvvm_floor_d: case Intrinsic::nvvm_round_f: case Intrinsic::nvvm_round_d: case Intrinsic::nvvm_saturate_d: case Intrinsic::nvvm_saturate_f: case Intrinsic::nvvm_sqrt_f: case Intrinsic::nvvm_sqrt_rn_d: case Intrinsic::nvvm_sqrt_rn_f: return false; } llvm_unreachable("Checking FTZ flag for invalid unary intrinsic"); } inline bool RCPShouldFTZ(Intrinsic::ID IntrinsicID) { switch (IntrinsicID) { case Intrinsic::nvvm_rcp_rm_ftz_f: case Intrinsic::nvvm_rcp_rn_ftz_f: case Intrinsic::nvvm_rcp_rp_ftz_f: case Intrinsic::nvvm_rcp_rz_ftz_f: return true; case Intrinsic::nvvm_rcp_rm_d: case Intrinsic::nvvm_rcp_rm_f: case Intrinsic::nvvm_rcp_rn_d: case Intrinsic::nvvm_rcp_rn_f: case Intrinsic::nvvm_rcp_rp_d: case Intrinsic::nvvm_rcp_rp_f: case Intrinsic::nvvm_rcp_rz_d: case Intrinsic::nvvm_rcp_rz_f: return false; } llvm_unreachable("Checking FTZ flag for invalid rcp intrinsic"); } inline APFloat::roundingMode GetRCPRoundingMode(Intrinsic::ID IntrinsicID) { switch (IntrinsicID) { case Intrinsic::nvvm_rcp_rm_f: case Intrinsic::nvvm_rcp_rm_d: case Intrinsic::nvvm_rcp_rm_ftz_f: return APFloat::rmTowardNegative; case Intrinsic::nvvm_rcp_rn_f: case Intrinsic::nvvm_rcp_rn_d: case Intrinsic::nvvm_rcp_rn_ftz_f: return APFloat::rmNearestTiesToEven; case Intrinsic::nvvm_rcp_rp_f: case Intrinsic::nvvm_rcp_rp_d: case Intrinsic::nvvm_rcp_rp_ftz_f: return APFloat::rmTowardPositive; case Intrinsic::nvvm_rcp_rz_f: case Intrinsic::nvvm_rcp_rz_d: case Intrinsic::nvvm_rcp_rz_ftz_f: return APFloat::rmTowardZero; } llvm_unreachable("Checking rounding mode for invalid rcp intrinsic"); } inline DenormalMode GetNVVMDenormMode(bool ShouldFTZ) { if (ShouldFTZ) return DenormalMode::getPreserveSign(); return DenormalMode::getIEEE(); } inline bool FAddShouldFTZ(Intrinsic::ID IntrinsicID) { switch (IntrinsicID) { case Intrinsic::nvvm_add_rm_ftz_f: case Intrinsic::nvvm_add_rn_ftz_f: case Intrinsic::nvvm_add_rp_ftz_f: case Intrinsic::nvvm_add_rz_ftz_f: return true; case Intrinsic::nvvm_add_rm_f: case Intrinsic::nvvm_add_rn_f: case Intrinsic::nvvm_add_rp_f: case Intrinsic::nvvm_add_rz_f: case Intrinsic::nvvm_add_rm_d: case Intrinsic::nvvm_add_rn_d: case Intrinsic::nvvm_add_rp_d: case Intrinsic::nvvm_add_rz_d: return false; } llvm_unreachable("Checking FTZ flag for invalid NVVM add intrinsic"); } inline APFloat::roundingMode GetFAddRoundingMode(Intrinsic::ID IntrinsicID) { switch (IntrinsicID) { case Intrinsic::nvvm_add_rm_f: case Intrinsic::nvvm_add_rm_d: case Intrinsic::nvvm_add_rm_ftz_f: return APFloat::rmTowardNegative; case Intrinsic::nvvm_add_rn_f: case Intrinsic::nvvm_add_rn_d: case Intrinsic::nvvm_add_rn_ftz_f: return APFloat::rmNearestTiesToEven; case Intrinsic::nvvm_add_rp_f: case Intrinsic::nvvm_add_rp_d: case Intrinsic::nvvm_add_rp_ftz_f: return APFloat::rmTowardPositive; case Intrinsic::nvvm_add_rz_f: case Intrinsic::nvvm_add_rz_d: case Intrinsic::nvvm_add_rz_ftz_f: return APFloat::rmTowardZero; } llvm_unreachable("Invalid FP instrinsic rounding mode for NVVM add"); } inline bool FMulShouldFTZ(Intrinsic::ID IntrinsicID) { switch (IntrinsicID) { case Intrinsic::nvvm_mul_rm_ftz_f: case Intrinsic::nvvm_mul_rn_ftz_f: case Intrinsic::nvvm_mul_rp_ftz_f: case Intrinsic::nvvm_mul_rz_ftz_f: return true; case Intrinsic::nvvm_mul_rm_f: case Intrinsic::nvvm_mul_rn_f: case Intrinsic::nvvm_mul_rp_f: case Intrinsic::nvvm_mul_rz_f: case Intrinsic::nvvm_mul_rm_d: case Intrinsic::nvvm_mul_rn_d: case Intrinsic::nvvm_mul_rp_d: case Intrinsic::nvvm_mul_rz_d: return false; } llvm_unreachable("Checking FTZ flag for invalid NVVM mul intrinsic"); } inline APFloat::roundingMode GetFMulRoundingMode(Intrinsic::ID IntrinsicID) { switch (IntrinsicID) { case Intrinsic::nvvm_mul_rm_f: case Intrinsic::nvvm_mul_rm_d: case Intrinsic::nvvm_mul_rm_ftz_f: return APFloat::rmTowardNegative; case Intrinsic::nvvm_mul_rn_f: case Intrinsic::nvvm_mul_rn_d: case Intrinsic::nvvm_mul_rn_ftz_f: return APFloat::rmNearestTiesToEven; case Intrinsic::nvvm_mul_rp_f: case Intrinsic::nvvm_mul_rp_d: case Intrinsic::nvvm_mul_rp_ftz_f: return APFloat::rmTowardPositive; case Intrinsic::nvvm_mul_rz_f: case Intrinsic::nvvm_mul_rz_d: case Intrinsic::nvvm_mul_rz_ftz_f: return APFloat::rmTowardZero; } llvm_unreachable("Invalid FP instrinsic rounding mode for NVVM mul"); } inline bool FDivShouldFTZ(Intrinsic::ID IntrinsicID) { switch (IntrinsicID) { case Intrinsic::nvvm_div_rm_ftz_f: case Intrinsic::nvvm_div_rn_ftz_f: case Intrinsic::nvvm_div_rp_ftz_f: case Intrinsic::nvvm_div_rz_ftz_f: return true; case Intrinsic::nvvm_div_rm_f: case Intrinsic::nvvm_div_rn_f: case Intrinsic::nvvm_div_rp_f: case Intrinsic::nvvm_div_rz_f: case Intrinsic::nvvm_div_rm_d: case Intrinsic::nvvm_div_rn_d: case Intrinsic::nvvm_div_rp_d: case Intrinsic::nvvm_div_rz_d: return false; } llvm_unreachable("Checking FTZ flag for invalid NVVM div intrinsic"); } inline APFloat::roundingMode GetFDivRoundingMode(Intrinsic::ID IntrinsicID) { switch (IntrinsicID) { case Intrinsic::nvvm_div_rm_f: case Intrinsic::nvvm_div_rm_d: case Intrinsic::nvvm_div_rm_ftz_f: return APFloat::rmTowardNegative; case Intrinsic::nvvm_div_rn_f: case Intrinsic::nvvm_div_rn_d: case Intrinsic::nvvm_div_rn_ftz_f: return APFloat::rmNearestTiesToEven; case Intrinsic::nvvm_div_rp_f: case Intrinsic::nvvm_div_rp_d: case Intrinsic::nvvm_div_rp_ftz_f: return APFloat::rmTowardPositive; case Intrinsic::nvvm_div_rz_f: case Intrinsic::nvvm_div_rz_d: case Intrinsic::nvvm_div_rz_ftz_f: return APFloat::rmTowardZero; } llvm_unreachable("Invalid FP instrinsic rounding mode for NVVM div"); } inline bool FMAShouldFTZ(Intrinsic::ID IntrinsicID) { switch (IntrinsicID) { case Intrinsic::nvvm_fma_rm_ftz_f: case Intrinsic::nvvm_fma_rn_ftz_f: case Intrinsic::nvvm_fma_rp_ftz_f: case Intrinsic::nvvm_fma_rz_ftz_f: return true; case Intrinsic::nvvm_fma_rm_f: case Intrinsic::nvvm_fma_rn_f: case Intrinsic::nvvm_fma_rp_f: case Intrinsic::nvvm_fma_rz_f: case Intrinsic::nvvm_fma_rm_d: case Intrinsic::nvvm_fma_rn_d: case Intrinsic::nvvm_fma_rp_d: case Intrinsic::nvvm_fma_rz_d: return false; } llvm_unreachable("Checking FTZ flag for invalid NVVM fma intrinsic"); } inline APFloat::roundingMode GetFMARoundingMode(Intrinsic::ID IntrinsicID) { switch (IntrinsicID) { case Intrinsic::nvvm_fma_rm_f: case Intrinsic::nvvm_fma_rm_d: case Intrinsic::nvvm_fma_rm_ftz_f: return APFloat::rmTowardNegative; case Intrinsic::nvvm_fma_rn_f: case Intrinsic::nvvm_fma_rn_d: case Intrinsic::nvvm_fma_rn_ftz_f: return APFloat::rmNearestTiesToEven; case Intrinsic::nvvm_fma_rp_f: case Intrinsic::nvvm_fma_rp_d: case Intrinsic::nvvm_fma_rp_ftz_f: return APFloat::rmTowardPositive; case Intrinsic::nvvm_fma_rz_f: case Intrinsic::nvvm_fma_rz_d: case Intrinsic::nvvm_fma_rz_ftz_f: return APFloat::rmTowardZero; } llvm_unreachable("Invalid FP instrinsic rounding mode for NVVM fma"); } } // namespace nvvm } // namespace llvm #endif // LLVM_IR_NVVMINTRINSICUTILS_H